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

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

Issue 419453003: Show alt text when source image is missing or broken or not found. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebaselining newly added Layout test cases Created 6 years, 4 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
« no previous file with comments | « LayoutTests/platform/linux/fast/dom/HTMLImageElement/image-alt-text-width-expected.txt ('k') | no next file » | 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 { 88 {
89 ASSERT(!m_imageResource); 89 ASSERT(!m_imageResource);
90 m_imageResource = imageResource; 90 m_imageResource = imageResource;
91 m_imageResource->initialize(this); 91 m_imageResource->initialize(this);
92 } 92 }
93 93
94 // If we'll be displaying either alt text or an image, add some padding. 94 // If we'll be displaying either alt text or an image, add some padding.
95 static const unsigned short paddingWidth = 4; 95 static const unsigned short paddingWidth = 4;
96 static const unsigned short paddingHeight = 4; 96 static const unsigned short paddingHeight = 4;
97 97
98 // Alt text is restricted to this maximum size, in pixels. These are
99 // signed integers because they are compared with other signed values.
100 static const float maxAltTextWidth = 1024;
101 static const int maxAltTextHeight = 256;
102
103 IntSize RenderImage::imageSizeForError(ImageResource* newImage) const 98 IntSize RenderImage::imageSizeForError(ImageResource* newImage) const
104 { 99 {
105 ASSERT_ARG(newImage, newImage); 100 ASSERT_ARG(newImage, newImage);
106 ASSERT_ARG(newImage, newImage->imageForRenderer(this)); 101 ASSERT_ARG(newImage, newImage->imageForRenderer(this));
107 102
108 IntSize imageSize; 103 IntSize imageSize;
109 if (newImage->willPaintBrokenImage()) { 104 if (newImage->willPaintBrokenImage()) {
110 float deviceScaleFactor = blink::deviceScaleFactor(frame()); 105 float deviceScaleFactor = blink::deviceScaleFactor(frame());
111 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResource::brok enImage(deviceScaleFactor); 106 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResource::brok enImage(deviceScaleFactor);
112 imageSize = brokenImageAndImageScaleFactor.first->size(); 107 imageSize = brokenImageAndImageScaleFactor.first->size();
(...skipping 16 matching lines...) Expand all
129 else if (!m_altText.isEmpty() || newImage) { 124 else if (!m_altText.isEmpty() || newImage) {
130 // If we'll be displaying either text or an image, add a little padding. 125 // If we'll be displaying either text or an image, add a little padding.
131 imageSize = IntSize(paddingWidth, paddingHeight); 126 imageSize = IntSize(paddingWidth, paddingHeight);
132 } 127 }
133 128
134 // we have an alt and the user meant it (its not a text we invented) 129 // we have an alt and the user meant it (its not a text we invented)
135 if (!m_altText.isEmpty()) { 130 if (!m_altText.isEmpty()) {
136 FontCachePurgePreventer fontCachePurgePreventer; 131 FontCachePurgePreventer fontCachePurgePreventer;
137 132
138 const Font& font = style()->font(); 133 const Font& font = style()->font();
139 IntSize paddedTextSize(paddingWidth + std::min(ceilf(font.width(construc tTextRun(this, font, m_altText, style()))), maxAltTextWidth), paddingHeight + st d::min(font.fontMetrics().height(), maxAltTextHeight)); 134 IntSize paddedTextSize(paddingWidth + ceilf(font.width(constructTextRun( this, font, m_altText, style()))), paddingHeight + font.fontMetrics().height());
140 imageSize = imageSize.expandedTo(paddedTextSize); 135 imageSize = imageSize.expandedTo(paddedTextSize);
141 } 136 }
142 137
143 if (imageSize == intrinsicSize()) 138 if (imageSize == intrinsicSize())
144 return false; 139 return false;
145 140
146 setIntrinsicSize(imageSize); 141 setIntrinsicSize(imageSize);
147 return true; 142 return true;
148 } 143 }
149 144
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 287
293 if (cWidth > 2 && cHeight > 2) { 288 if (cWidth > 2 && cHeight > 2) {
294 const int borderWidth = 1; 289 const int borderWidth = 1;
295 290
296 // Draw an outline rect where the image should be. 291 // Draw an outline rect where the image should be.
297 context->setStrokeStyle(SolidStroke); 292 context->setStrokeStyle(SolidStroke);
298 context->setStrokeColor(Color::lightGray); 293 context->setStrokeColor(Color::lightGray);
299 context->setFillColor(Color::transparent); 294 context->setFillColor(Color::transparent);
300 context->drawRect(pixelSnappedIntRect(LayoutRect(paintOffset.x() + l eftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight))); 295 context->drawRect(pixelSnappedIntRect(LayoutRect(paintOffset.x() + l eftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight)));
301 296
302 bool errorPictureDrawn = false;
303 LayoutSize imageOffset; 297 LayoutSize imageOffset;
304 // When calculating the usable dimensions, exclude the pixels of 298 // When calculating the usable dimensions, exclude the pixels of
305 // the ouline rect so the error image/alt text doesn't draw on it. 299 // the ouline rect so the error image/alt text doesn't draw on it.
306 LayoutUnit usableWidth = cWidth - 2 * borderWidth; 300 LayoutUnit usableWidth = cWidth - 2 * borderWidth;
307 LayoutUnit usableHeight = cHeight - 2 * borderWidth; 301 LayoutUnit usableHeight = cHeight - 2 * borderWidth;
308 302
309 RefPtr<Image> image = m_imageResource->image(); 303 RefPtr<Image> image = m_imageResource->image();
310 304
311 if (m_imageResource->errorOccurred() && !image->isNull() && usableWi dth >= image->width() && usableHeight >= image->height()) { 305 if (m_imageResource->errorOccurred() && !image->isNull() && usableWi dth >= image->width() && usableHeight >= image->height() && m_altText.isEmpty()) {
312 float deviceScaleFactor = blink::deviceScaleFactor(frame()); 306 float deviceScaleFactor = blink::deviceScaleFactor(frame());
313 // Call brokenImage() explicitly to ensure we get the broken ima ge icon at the appropriate resolution. 307 // Call brokenImage() explicitly to ensure we get the broken ima ge icon at the appropriate resolution.
314 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResour ce::brokenImage(deviceScaleFactor); 308 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResour ce::brokenImage(deviceScaleFactor);
315 image = brokenImageAndImageScaleFactor.first; 309 image = brokenImageAndImageScaleFactor.first;
316 IntSize imageSize = image->size(); 310 IntSize imageSize = image->size();
317 imageSize.scale(1 / brokenImageAndImageScaleFactor.second); 311 imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
318 // Center the error image, accounting for border and padding. 312 // Center the error image, accounting for border and padding.
319 LayoutUnit centerX = (usableWidth - imageSize.width()) / 2; 313 LayoutUnit centerX = (usableWidth - imageSize.width()) / 2;
320 if (centerX < 0) 314 if (centerX < 0)
321 centerX = 0; 315 centerX = 0;
322 LayoutUnit centerY = (usableHeight - imageSize.height()) / 2; 316 LayoutUnit centerY = (usableHeight - imageSize.height()) / 2;
323 if (centerY < 0) 317 if (centerY < 0)
324 centerY = 0; 318 centerY = 0;
325 imageOffset = LayoutSize(leftBorder + leftPad + centerX + border Width, topBorder + topPad + centerY + borderWidth); 319 imageOffset = LayoutSize(leftBorder + leftPad + centerX + border Width, topBorder + topPad + centerY + borderWidth);
326 context->drawImage(image.get(), pixelSnappedIntRect(LayoutRect(p aintOffset + imageOffset, imageSize)), CompositeSourceOver, shouldRespectImageOr ientation()); 320 context->drawImage(image.get(), pixelSnappedIntRect(LayoutRect(p aintOffset + imageOffset, imageSize)), CompositeSourceOver, shouldRespectImageOr ientation());
327 errorPictureDrawn = true;
328 } 321 }
329 322
330 if (!m_altText.isEmpty()) { 323 if (!m_altText.isEmpty()) {
331 const Font& font = style()->font(); 324 const Font& font = style()->font();
332 const FontMetrics& fontMetrics = font.fontMetrics(); 325 const FontMetrics& fontMetrics = font.fontMetrics();
333 LayoutUnit ascent = fontMetrics.ascent(); 326 LayoutUnit ascent = fontMetrics.ascent();
334 LayoutPoint textRectOrigin = paintOffset; 327 LayoutPoint textRectOrigin = paintOffset;
335 textRectOrigin.move(leftBorder + leftPad + (paddingWidth / 2) - borderWidth, topBorder + topPad + (paddingHeight / 2) - borderWidth); 328 textRectOrigin.move(leftBorder + leftPad + (paddingWidth / 2) - borderWidth, topBorder + topPad + (paddingHeight / 2) - borderWidth);
336 LayoutPoint textOrigin(textRectOrigin.x(), textRectOrigin.y() + ascent); 329 LayoutPoint textOrigin(textRectOrigin.x(), textRectOrigin.y() + ascent);
337 330
338 // Only draw the alt text if it'll fit within the content box, 331 // Only draw the alt text if it'll fit within the content box,
339 // and only if it fits above the error image. 332 // and only if it fits above the error image.
340 TextRun textRun = constructTextRun(this, font, m_altText, style( ), TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, DefaultTex tRunFlags | RespectDirection); 333 TextRun textRun = constructTextRun(this, font, m_altText, style( ), TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, DefaultTex tRunFlags | RespectDirection);
341 float textWidth = font.width(textRun); 334 float textWidth = font.width(textRun);
342 TextRunPaintInfo textRunPaintInfo(textRun); 335 TextRunPaintInfo textRunPaintInfo(textRun);
343 textRunPaintInfo.bounds = FloatRect(textRectOrigin, FloatSize(te xtWidth, fontMetrics.height())); 336 textRunPaintInfo.bounds = FloatRect(textRectOrigin, FloatSize(te xtWidth, fontMetrics.height()));
344 context->setFillColor(resolveColor(CSSPropertyColor)); 337 context->setFillColor(resolveColor(CSSPropertyColor));
345 if (textRun.direction() == RTL) { 338 if (textRun.direction() == RTL) {
346 int availableWidth = cWidth - static_cast<int>(paddingWidth) ; 339 int availableWidth = cWidth - static_cast<int>(paddingWidth) ;
347 textOrigin.move(availableWidth - ceilf(textWidth), 0); 340 textOrigin.move(availableWidth - ceilf(textWidth), 0);
348 } 341 }
349 if (errorPictureDrawn) { 342 context->drawBidiText(font, textRunPaintInfo, textOrigin);
350 if (usableWidth >= textWidth && fontMetrics.height() <= imag eOffset.height())
351 context->drawBidiText(font, textRunPaintInfo, textOrigin );
352 } else if (usableWidth >= textWidth && usableHeight >= fontMetri cs.height()) {
353 context->drawBidiText(font, textRunPaintInfo, textOrigin);
354 }
355 } 343 }
356 } 344 }
357 } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) { 345 } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
358 RefPtr<Image> img = m_imageResource->image(cWidth, cHeight); 346 RefPtr<Image> img = m_imageResource->image(cWidth, cHeight);
359 if (!img || img->isNull()) 347 if (!img || img->isNull())
360 return; 348 return;
361 349
362 LayoutRect contentRect = contentBoxRect(); 350 LayoutRect contentRect = contentBoxRect();
363 contentRect.moveBy(paintOffset); 351 contentRect.moveBy(paintOffset);
364 LayoutRect paintRect = replacedContentRect(); 352 LayoutRect paintRect = replacedContentRect();
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 return 0; 616 return 0;
629 617
630 ImageResource* cachedImage = m_imageResource->cachedImage(); 618 ImageResource* cachedImage = m_imageResource->cachedImage();
631 if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage( )) 619 if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage( ))
632 return toSVGImage(cachedImage->image())->embeddedContentBox(); 620 return toSVGImage(cachedImage->image())->embeddedContentBox();
633 621
634 return 0; 622 return 0;
635 } 623 }
636 624
637 } // namespace blink 625 } // namespace blink
OLDNEW
« no previous file with comments | « LayoutTests/platform/linux/fast/dom/HTMLImageElement/image-alt-text-width-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698