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

Side by Side Diff: sky/engine/core/rendering/RenderImage.cpp

Issue 715963003: Remove alt text from images. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: minor improvement Created 6 years, 1 month 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
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "platform/graphics/GraphicsContextStateSaver.h" 45 #include "platform/graphics/GraphicsContextStateSaver.h"
46 46
47 namespace blink { 47 namespace blink {
48 48
49 float deviceScaleFactor(LocalFrame*); 49 float deviceScaleFactor(LocalFrame*);
50 50
51 RenderImage::RenderImage(Element* element) 51 RenderImage::RenderImage(Element* element)
52 : RenderReplaced(element, IntSize()) 52 : RenderReplaced(element, IntSize())
53 , m_imageDevicePixelRatio(1.0f) 53 , m_imageDevicePixelRatio(1.0f)
54 { 54 {
55 updateAltText();
56 } 55 }
57 56
58 RenderImage* RenderImage::createAnonymous(Document* document) 57 RenderImage* RenderImage::createAnonymous(Document* document)
59 { 58 {
60 RenderImage* image = new RenderImage(0); 59 RenderImage* image = new RenderImage(0);
61 image->setDocumentForAnonymous(document); 60 image->setDocumentForAnonymous(document);
62 return image; 61 return image;
63 } 62 }
64 63
65 RenderImage::~RenderImage() 64 RenderImage::~RenderImage()
66 { 65 {
67 } 66 }
68 67
69 void RenderImage::destroy() 68 void RenderImage::destroy()
70 { 69 {
71 ASSERT(m_imageResource); 70 ASSERT(m_imageResource);
72 m_imageResource->shutdown(); 71 m_imageResource->shutdown();
73 RenderReplaced::destroy(); 72 RenderReplaced::destroy();
74 } 73 }
75 74
76 void RenderImage::setImageResource(PassOwnPtr<RenderImageResource> imageResource ) 75 void RenderImage::setImageResource(PassOwnPtr<RenderImageResource> imageResource )
77 { 76 {
78 ASSERT(!m_imageResource); 77 ASSERT(!m_imageResource);
79 m_imageResource = imageResource; 78 m_imageResource = imageResource;
80 m_imageResource->initialize(this); 79 m_imageResource->initialize(this);
81 } 80 }
82 81
83 // If we'll be displaying either alt text or an image, add some padding.
84 static const unsigned short paddingWidth = 4;
85 static const unsigned short paddingHeight = 4;
86
87 // Alt text is restricted to this maximum size, in pixels. These are
88 // signed integers because they are compared with other signed values.
89 static const float maxAltTextWidth = 1024;
90 static const int maxAltTextHeight = 256;
91
92 IntSize RenderImage::imageSizeForError(ImageResource* newImage) const
93 {
94 ASSERT_ARG(newImage, newImage);
95 ASSERT_ARG(newImage, newImage->imageForRenderer(this));
96
97 IntSize imageSize;
98 if (newImage->willPaintBrokenImage()) {
99 float deviceScaleFactor = blink::deviceScaleFactor(frame());
100 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResource::brok enImage(deviceScaleFactor);
101 imageSize = brokenImageAndImageScaleFactor.first->size();
102 imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
103 } else
104 imageSize = newImage->imageForRenderer(this)->size();
105
106 // imageSize() returns 0 for the error image. We need the true size of the
107 // error image, so we have to get it by grabbing image() directly.
108 return IntSize(paddingWidth + imageSize.width(), paddingHeight + imageSize.h eight());
109 }
110
111 // Sets the image height and width to fit the alt text. Returns true if the
112 // image size changed.
113 bool RenderImage::setImageSizeForAltText(ImageResource* newImage /* = 0 */)
114 {
115 IntSize imageSize;
116 if (newImage && newImage->imageForRenderer(this))
117 imageSize = imageSizeForError(newImage);
118 else if (!m_altText.isEmpty() || newImage) {
119 // If we'll be displaying either text or an image, add a little padding.
120 imageSize = IntSize(paddingWidth, paddingHeight);
121 }
122
123 // we have an alt and the user meant it (its not a text we invented)
124 if (!m_altText.isEmpty()) {
125 FontCachePurgePreventer fontCachePurgePreventer;
126
127 const Font& font = style()->font();
128 IntSize paddedTextSize(paddingWidth + std::min(ceilf(font.width(construc tTextRun(this, font, m_altText, style()))), maxAltTextWidth), paddingHeight + st d::min(font.fontMetrics().height(), maxAltTextHeight));
129 imageSize = imageSize.expandedTo(paddedTextSize);
130 }
131
132 if (imageSize == intrinsicSize())
133 return false;
134
135 setIntrinsicSize(imageSize);
136 return true;
137 }
138
139 void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect) 82 void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
140 { 83 {
141 if (documentBeingDestroyed()) 84 if (documentBeingDestroyed())
142 return; 85 return;
143 86
144 if (hasBoxDecorationBackground() || hasMask()) 87 if (hasBoxDecorationBackground() || hasMask())
145 RenderReplaced::imageChanged(newImage, rect); 88 RenderReplaced::imageChanged(newImage, rect);
146 89
147 if (!m_imageResource) 90 if (!m_imageResource)
148 return; 91 return;
149 92
150 if (newImage != m_imageResource->imagePtr()) 93 if (newImage != m_imageResource->imagePtr())
151 return; 94 return;
152 95
153 // Per the spec, we let the server-sent header override srcset/other sources of dpr. 96 // Per the spec, we let the server-sent header override srcset/other sources of dpr.
154 // https://github.com/igrigorik/http-client-hints/blob/master/draft-grigorik -http-client-hints-01.txt#L255 97 // https://github.com/igrigorik/http-client-hints/blob/master/draft-grigorik -http-client-hints-01.txt#L255
155 if (m_imageResource->cachedImage() && m_imageResource->cachedImage()->hasDev icePixelRatioHeaderValue()) 98 if (m_imageResource->cachedImage() && m_imageResource->cachedImage()->hasDev icePixelRatioHeaderValue())
156 m_imageDevicePixelRatio = 1 / m_imageResource->cachedImage()->devicePixe lRatioHeaderValue(); 99 m_imageDevicePixelRatio = 1 / m_imageResource->cachedImage()->devicePixe lRatioHeaderValue();
157 100
158 bool imageSizeChanged = false; 101 paintInvalidationOrMarkForLayout(rect);
159
160 // Set image dimensions, taking into account the size of the alt text.
161 if (m_imageResource->errorOccurred() || !newImage)
162 imageSizeChanged = setImageSizeForAltText(m_imageResource->cachedImage() );
163
164 paintInvalidationOrMarkForLayout(imageSizeChanged, rect);
165 } 102 }
166 103
167 void RenderImage::updateIntrinsicSizeIfNeeded(const LayoutSize& newSize) 104 void RenderImage::updateIntrinsicSizeIfNeeded(const LayoutSize& newSize)
168 { 105 {
169 if (m_imageResource->errorOccurred() || !m_imageResource->hasImage()) 106 if (m_imageResource->errorOccurred() || !m_imageResource->hasImage())
170 return; 107 return;
171 setIntrinsicSize(newSize); 108 setIntrinsicSize(newSize);
172 } 109 }
173 110
174 void RenderImage::updateInnerContentRect() 111 void RenderImage::updateInnerContentRect()
175 { 112 {
176 // Propagate container size to the image resource. 113 // Propagate container size to the image resource.
177 LayoutRect containerRect = replacedContentRect(); 114 LayoutRect containerRect = replacedContentRect();
178 IntSize containerSize(containerRect.width(), containerRect.height()); 115 IntSize containerSize(containerRect.width(), containerRect.height());
179 if (!containerSize.isEmpty()) 116 if (!containerSize.isEmpty())
180 m_imageResource->setContainerSizeForRenderer(containerSize); 117 m_imageResource->setContainerSizeForRenderer(containerSize);
181 } 118 }
182 119
183 void RenderImage::paintInvalidationOrMarkForLayout(bool imageSizeChangedToAccomo dateAltText, const IntRect* rect) 120 void RenderImage::paintInvalidationOrMarkForLayout(const IntRect* rect)
184 { 121 {
185 LayoutSize oldIntrinsicSize = intrinsicSize(); 122 LayoutSize oldIntrinsicSize = intrinsicSize();
186 LayoutSize newIntrinsicSize = m_imageResource->intrinsicSize(); 123 LayoutSize newIntrinsicSize = m_imageResource->intrinsicSize();
187 updateIntrinsicSizeIfNeeded(newIntrinsicSize); 124 updateIntrinsicSizeIfNeeded(newIntrinsicSize);
188 125
189 // In the case of generated image content using :before/:after/content, we m ight not be 126 // In the case of generated image content using :before/:after/content, we m ight not be
190 // in the render tree yet. In that case, we just need to update our intrinsi c size. 127 // in the render tree yet. In that case, we just need to update our intrinsi c size.
191 // layout() will be called after we are inserted in the tree which will take care of 128 // layout() will be called after we are inserted in the tree which will take care of
192 // what we are doing here. 129 // what we are doing here.
193 if (!containingBlock()) 130 if (!containingBlock())
194 return; 131 return;
195 132
196 bool imageSourceHasChangedSize = oldIntrinsicSize != newIntrinsicSize || ima geSizeChangedToAccomodateAltText; 133 bool imageSourceHasChangedSize = oldIntrinsicSize != newIntrinsicSize;
197 if (imageSourceHasChangedSize) 134 if (imageSourceHasChangedSize)
198 setPreferredLogicalWidthsDirty(); 135 setPreferredLogicalWidthsDirty();
199 136
200 // If the actual area occupied by the image has changed and it is not constr ained by style then a layout is required. 137 // If the actual area occupied by the image has changed and it is not constr ained by style then a layout is required.
201 bool imageSizeIsConstrained = style()->logicalWidth().isSpecified() && style ()->logicalHeight().isSpecified(); 138 bool imageSizeIsConstrained = style()->logicalWidth().isSpecified() && style ()->logicalHeight().isSpecified();
202 139
203 // FIXME: We only need to recompute the containing block's preferred size if the containing block's size 140 // FIXME: We only need to recompute the containing block's preferred size if the containing block's size
204 // depends on the image's size (i.e., the container uses shrink-to-fit sizin g). 141 // depends on the image's size (i.e., the container uses shrink-to-fit sizin g).
205 // There's no easy way to detect that shrink-to-fit is needed, always force a layout. 142 // There's no easy way to detect that shrink-to-fit is needed, always force a layout.
206 bool containingBlockNeedsToRecomputePreferredSize = style()->logicalWidth(). isPercent() || style()->logicalMaxWidth().isPercent() || style()->logicalMinWid th().isPercent(); 143 bool containingBlockNeedsToRecomputePreferredSize = style()->logicalWidth(). isPercent() || style()->logicalMaxWidth().isPercent() || style()->logicalMinWid th().isPercent();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 190
254 if (newImage == m_imageResource->cachedImage()) { 191 if (newImage == m_imageResource->cachedImage()) {
255 // tell any potential compositing layers 192 // tell any potential compositing layers
256 // that the image is done and they can reference it directly. 193 // that the image is done and they can reference it directly.
257 contentChanged(ImageChanged); 194 contentChanged(ImageChanged);
258 } 195 }
259 } 196 }
260 197
261 void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf fset) 198 void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf fset)
262 { 199 {
263 LayoutUnit cWidth = contentWidth();
264 LayoutUnit cHeight = contentHeight();
265
266 GraphicsContext* context = paintInfo.context; 200 GraphicsContext* context = paintInfo.context;
267 201
268 if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) { 202 if (m_imageResource->hasImage() && contentWidth() > 0 && contentHeight() > 0 ) {
269 if (paintInfo.phase == PaintPhaseSelection)
270 return;
271
272 if (cWidth > 2 && cHeight > 2) {
273 const int borderWidth = 1;
274
275 LayoutUnit leftBorder = borderLeft();
276 LayoutUnit topBorder = borderTop();
277 LayoutUnit leftPad = paddingLeft();
278 LayoutUnit topPad = paddingTop();
279
280 // Draw an outline rect where the image should be.
281 context->setStrokeStyle(SolidStroke);
282 context->setStrokeColor(Color::lightGray);
283 context->setFillColor(Color::transparent);
284 context->drawRect(pixelSnappedIntRect(LayoutRect(paintOffset.x() + l eftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight)));
285
286 bool errorPictureDrawn = false;
287 LayoutSize imageOffset;
288 // When calculating the usable dimensions, exclude the pixels of
289 // the ouline rect so the error image/alt text doesn't draw on it.
290 LayoutUnit usableWidth = cWidth - 2 * borderWidth;
291 LayoutUnit usableHeight = cHeight - 2 * borderWidth;
292
293 RefPtr<Image> image = m_imageResource->image();
294
295 if (m_imageResource->errorOccurred() && !image->isNull() && usableWi dth >= image->width() && usableHeight >= image->height()) {
296 float deviceScaleFactor = blink::deviceScaleFactor(frame());
297 // Call brokenImage() explicitly to ensure we get the broken ima ge icon at the appropriate resolution.
298 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResour ce::brokenImage(deviceScaleFactor);
299 image = brokenImageAndImageScaleFactor.first;
300 IntSize imageSize = image->size();
301 imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
302 // Center the error image, accounting for border and padding.
303 LayoutUnit centerX = (usableWidth - imageSize.width()) / 2;
304 if (centerX < 0)
305 centerX = 0;
306 LayoutUnit centerY = (usableHeight - imageSize.height()) / 2;
307 if (centerY < 0)
308 centerY = 0;
309 imageOffset = LayoutSize(leftBorder + leftPad + centerX + border Width, topBorder + topPad + centerY + borderWidth);
310 context->drawImage(image.get(), pixelSnappedIntRect(LayoutRect(p aintOffset + imageOffset, imageSize)), CompositeSourceOver, shouldRespectImageOr ientation());
311 errorPictureDrawn = true;
312 }
313
314 if (!m_altText.isEmpty()) {
315 const Font& font = style()->font();
316 const FontMetrics& fontMetrics = font.fontMetrics();
317 LayoutUnit ascent = fontMetrics.ascent();
318 LayoutPoint textRectOrigin = paintOffset;
319 textRectOrigin.move(leftBorder + leftPad + (paddingWidth / 2) - borderWidth, topBorder + topPad + (paddingHeight / 2) - borderWidth);
320 LayoutPoint textOrigin(textRectOrigin.x(), textRectOrigin.y() + ascent);
321
322 // Only draw the alt text if it'll fit within the content box,
323 // and only if it fits above the error image.
324 TextRun textRun = constructTextRun(this, font, m_altText, style( ), TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, DefaultTex tRunFlags | RespectDirection);
325 float textWidth = font.width(textRun);
326 TextRunPaintInfo textRunPaintInfo(textRun);
327 textRunPaintInfo.bounds = FloatRect(textRectOrigin, FloatSize(te xtWidth, fontMetrics.height()));
328 context->setFillColor(resolveColor(CSSPropertyColor));
329 if (textRun.direction() == RTL) {
330 int availableWidth = cWidth - static_cast<int>(paddingWidth) ;
331 textOrigin.move(availableWidth - ceilf(textWidth), 0);
332 }
333 if (errorPictureDrawn) {
334 if (usableWidth >= textWidth && fontMetrics.height() <= imag eOffset.height())
335 context->drawBidiText(font, textRunPaintInfo, textOrigin );
336 } else if (usableWidth >= textWidth && usableHeight >= fontMetri cs.height()) {
337 context->drawBidiText(font, textRunPaintInfo, textOrigin);
338 }
339 }
340 }
341 } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
342 LayoutRect contentRect = contentBoxRect(); 203 LayoutRect contentRect = contentBoxRect();
343 contentRect.moveBy(paintOffset); 204 contentRect.moveBy(paintOffset);
344 LayoutRect paintRect = replacedContentRect(); 205 LayoutRect paintRect = replacedContentRect();
345 paintRect.moveBy(paintOffset); 206 paintRect.moveBy(paintOffset);
346 bool clip = !contentRect.contains(paintRect); 207 bool clip = !contentRect.contains(paintRect);
347 if (clip) { 208 if (clip) {
348 context->save(); 209 context->save();
349 context->clip(contentRect); 210 context->clip(contentRect);
350 } 211 }
351 212
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 HitTestResult tempResult(result.hitTestLocation()); 304 HitTestResult tempResult(result.hitTestLocation());
444 bool inside = RenderReplaced::nodeAtPoint(request, tempResult, locationInCon tainer, accumulatedOffset, hitTestAction); 305 bool inside = RenderReplaced::nodeAtPoint(request, tempResult, locationInCon tainer, accumulatedOffset, hitTestAction);
445 306
446 if (!inside && result.isRectBasedTest()) 307 if (!inside && result.isRectBasedTest())
447 result.append(tempResult); 308 result.append(tempResult);
448 if (inside) 309 if (inside)
449 result = tempResult; 310 result = tempResult;
450 return inside; 311 return inside;
451 } 312 }
452 313
453 void RenderImage::updateAltText()
454 {
455 if (!node())
456 return;
457
458 if (isHTMLImageElement(*node()))
459 m_altText = toHTMLImageElement(node())->altText();
460 }
461
462 void RenderImage::layout() 314 void RenderImage::layout()
463 { 315 {
464 LayoutRect oldContentRect = replacedContentRect(); 316 LayoutRect oldContentRect = replacedContentRect();
465 RenderReplaced::layout(); 317 RenderReplaced::layout();
466 if (replacedContentRect() != oldContentRect) { 318 if (replacedContentRect() != oldContentRect) {
467 setShouldDoFullPaintInvalidation(true); 319 setShouldDoFullPaintInvalidation(true);
468 updateInnerContentRect(); 320 updateInnerContentRect();
469 } 321 }
470 } 322 }
471 323
(...skipping 17 matching lines...) Expand all
489 return; 341 return;
490 } 342 }
491 } 343 }
492 344
493 bool RenderImage::needsPreferredWidthsRecalculation() const 345 bool RenderImage::needsPreferredWidthsRecalculation() const
494 { 346 {
495 return RenderReplaced::needsPreferredWidthsRecalculation(); 347 return RenderReplaced::needsPreferredWidthsRecalculation();
496 } 348 }
497 349
498 } // namespace blink 350 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderImage.h ('k') | sky/engine/public/platform/WebLocalizedString.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698