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

Side by Side Diff: Source/core/rendering/style/RenderStyle.cpp

Issue 219633002: Proper support for multiple text decorations. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix review issues. Created 6 years, 7 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) 2 * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
4 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. 4 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 10 matching lines...) Expand all
21 */ 21 */
22 22
23 #include "config.h" 23 #include "config.h"
24 #include "core/rendering/style/RenderStyle.h" 24 #include "core/rendering/style/RenderStyle.h"
25 25
26 #include <algorithm> 26 #include <algorithm>
27 #include "RuntimeEnabledFeatures.h" 27 #include "RuntimeEnabledFeatures.h"
28 #include "core/css/resolver/StyleResolver.h" 28 #include "core/css/resolver/StyleResolver.h"
29 #include "core/rendering/RenderTheme.h" 29 #include "core/rendering/RenderTheme.h"
30 #include "core/rendering/TextAutosizer.h" 30 #include "core/rendering/TextAutosizer.h"
31 #include "core/rendering/style/AppliedTextDecoration.h"
31 #include "core/rendering/style/ContentData.h" 32 #include "core/rendering/style/ContentData.h"
32 #include "core/rendering/style/CursorList.h" 33 #include "core/rendering/style/CursorList.h"
33 #include "core/rendering/style/QuotesData.h" 34 #include "core/rendering/style/QuotesData.h"
34 #include "core/rendering/style/ShadowList.h" 35 #include "core/rendering/style/ShadowList.h"
35 #include "core/rendering/style/StyleImage.h" 36 #include "core/rendering/style/StyleImage.h"
36 #include "core/rendering/style/StyleInheritedData.h" 37 #include "core/rendering/style/StyleInheritedData.h"
37 #include "platform/LengthFunctions.h" 38 #include "platform/LengthFunctions.h"
38 #include "platform/fonts/Font.h" 39 #include "platform/fonts/Font.h"
39 #include "platform/fonts/FontSelector.h" 40 #include "platform/fonts/FontSelector.h"
40 #include "platform/geometry/FloatRoundedRect.h" 41 #include "platform/geometry/FloatRoundedRect.h"
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 682
682 if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity ) 683 if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity )
683 changedContextSensitiveProperties |= ContextSensitivePropertyOpacity ; 684 changedContextSensitiveProperties |= ContextSensitivePropertyOpacity ;
684 685
685 if (rareNonInheritedData->m_filter != other.rareNonInheritedData->m_filt er) 686 if (rareNonInheritedData->m_filter != other.rareNonInheritedData->m_filt er)
686 changedContextSensitiveProperties |= ContextSensitivePropertyFilter; 687 changedContextSensitiveProperties |= ContextSensitivePropertyFilter;
687 } 688 }
688 689
689 if (!diff.needsRepaint()) { 690 if (!diff.needsRepaint()) {
690 if (inherited->color != other.inherited->color 691 if (inherited->color != other.inherited->color
691 || inherited_flags._text_decorations != other.inherited_flags._text_ decorations 692 || inherited_flags.m_textUnderline != other.inherited_flags.m_textUn derline
692 || visual->textDecoration != other.visual->textDecoration) { 693 || visual->textDecoration != other.visual->textDecoration) {
693 changedContextSensitiveProperties |= ContextSensitivePropertyTextOrC olor; 694 changedContextSensitiveProperties |= ContextSensitivePropertyTextOrC olor;
694 } else if (rareNonInheritedData.get() != other.rareNonInheritedData.get( )) { 695 } else if (rareNonInheritedData.get() != other.rareNonInheritedData.get( )) {
695 if (rareNonInheritedData->m_textDecorationStyle != other.rareNonInhe ritedData->m_textDecorationStyle 696 if (rareNonInheritedData->m_textDecorationStyle != other.rareNonInhe ritedData->m_textDecorationStyle
696 || rareNonInheritedData->m_textDecorationColor != other.rareNonI nheritedData->m_textDecorationColor) 697 || rareNonInheritedData->m_textDecorationColor != other.rareNonI nheritedData->m_textDecorationColor)
697 changedContextSensitiveProperties |= ContextSensitivePropertyTex tOrColor; 698 changedContextSensitiveProperties |= ContextSensitivePropertyTex tOrColor;
698 } else if (rareInheritedData.get() != other.rareInheritedData.get()) { 699 } else if (rareInheritedData.get() != other.rareInheritedData.get()) {
699 if (rareInheritedData->textFillColor() != other.rareInheritedData->t extFillColor() 700 if (rareInheritedData->textFillColor() != other.rareInheritedData->t extFillColor()
700 || rareInheritedData->textStrokeColor() != other.rareInheritedDa ta->textStrokeColor() 701 || rareInheritedData->textStrokeColor() != other.rareInheritedDa ta->textStrokeColor()
701 || rareInheritedData->textEmphasisColor() != other.rareInherited Data->textEmphasisColor() 702 || rareInheritedData->textEmphasisColor() != other.rareInherited Data->textEmphasisColor()
702 || rareInheritedData->textEmphasisFill != other.rareInheritedDat a->textEmphasisFill) 703 || rareInheritedData->textEmphasisFill != other.rareInheritedDat a->textEmphasisFill
704 || rareInheritedData->appliedTextDecorations != other.rareInheri tedData->appliedTextDecorations)
703 changedContextSensitiveProperties |= ContextSensitivePropertyTex tOrColor; 705 changedContextSensitiveProperties |= ContextSensitivePropertyTex tOrColor;
704 } 706 }
705 } 707 }
706 708
707 return changedContextSensitiveProperties; 709 return changedContextSensitiveProperties;
708 } 710 }
709 711
710 void RenderStyle::setClip(Length top, Length right, Length bottom, Length left) 712 void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
711 { 713 {
712 StyleVisualData* data = visual.access(); 714 StyleVisualData* data = visual.access();
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1199 }
1198 1200
1199 const Font& RenderStyle::font() const { return inherited->font; } 1201 const Font& RenderStyle::font() const { return inherited->font; }
1200 const FontMetrics& RenderStyle::fontMetrics() const { return inherited->font.fon tMetrics(); } 1202 const FontMetrics& RenderStyle::fontMetrics() const { return inherited->font.fon tMetrics(); }
1201 const FontDescription& RenderStyle::fontDescription() const { return inherited-> font.fontDescription(); } 1203 const FontDescription& RenderStyle::fontDescription() const { return inherited-> font.fontDescription(); }
1202 float RenderStyle::specifiedFontSize() const { return fontDescription().specifie dSize(); } 1204 float RenderStyle::specifiedFontSize() const { return fontDescription().specifie dSize(); }
1203 float RenderStyle::computedFontSize() const { return fontDescription().computedS ize(); } 1205 float RenderStyle::computedFontSize() const { return fontDescription().computedS ize(); }
1204 int RenderStyle::fontSize() const { return fontDescription().computedPixelSize() ; } 1206 int RenderStyle::fontSize() const { return fontDescription().computedPixelSize() ; }
1205 FontWeight RenderStyle::fontWeight() const { return fontDescription().weight(); } 1207 FontWeight RenderStyle::fontWeight() const { return fontDescription().weight(); }
1206 1208
1209 TextDecoration RenderStyle::textDecorationsInEffect() const
1210 {
1211 int decorations = 0;
1212
1213 const Vector<AppliedTextDecoration>& applied = appliedTextDecorations();
1214
1215 for (size_t i = 0; i < applied.size(); ++i)
1216 decorations |= applied[i].line();
1217
1218 return static_cast<TextDecoration>(decorations);
1219 }
1220
1221 const Vector<AppliedTextDecoration>& RenderStyle::appliedTextDecorations() const
1222 {
1223 DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, empty, ());
1224 DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, underline, (1, AppliedTex tDecoration(TextDecorationUnderline)));
Julien - ping for review 2014/05/05 17:45:08 I would prefer the vectors to be defined inside th
andersr 2014/05/06 13:15:29 Done.
1225
1226 if (!inherited_flags.m_textUnderline && !rareInheritedData->appliedTextDecor ations)
Julien - ping for review 2014/05/05 17:45:08 This line makes me think that when inherited_flags
andersr 2014/05/06 13:15:29 Do you mean that it does not read well, or that it
1227 return empty;
1228 if (inherited_flags.m_textUnderline && !rareInheritedData->appliedTextDecora tions)
Julien - ping for review 2014/05/05 17:45:08 Wouldn't rareInheritedData->appliedTextDecorations
andersr 2014/05/06 13:15:29 That's true. Fixed.
1229 return underline;
1230
1231 return rareInheritedData->appliedTextDecorations->vector();
1232 }
1233
1207 float RenderStyle::wordSpacing() const { return fontDescription().wordSpacing(); } 1234 float RenderStyle::wordSpacing() const { return fontDescription().wordSpacing(); }
1208 float RenderStyle::letterSpacing() const { return fontDescription().letterSpacin g(); } 1235 float RenderStyle::letterSpacing() const { return fontDescription().letterSpacin g(); }
1209 1236
1210 bool RenderStyle::setFontDescription(const FontDescription& v) 1237 bool RenderStyle::setFontDescription(const FontDescription& v)
1211 { 1238 {
1212 if (inherited->font.fontDescription() != v) { 1239 if (inherited->font.fontDescription() != v) {
1213 inherited.access()->font = Font(v); 1240 inherited.access()->font = Font(v);
1214 return true; 1241 return true;
1215 } 1242 }
1216 return false; 1243 return false;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 1319
1293 void RenderStyle::setFontWeight(FontWeight weight) 1320 void RenderStyle::setFontWeight(FontWeight weight)
1294 { 1321 {
1295 FontSelector* currentFontSelector = font().fontSelector(); 1322 FontSelector* currentFontSelector = font().fontSelector();
1296 FontDescription desc(fontDescription()); 1323 FontDescription desc(fontDescription());
1297 desc.setWeight(weight); 1324 desc.setWeight(weight);
1298 setFontDescription(desc); 1325 setFontDescription(desc);
1299 font().update(currentFontSelector); 1326 font().update(currentFontSelector);
1300 } 1327 }
1301 1328
1329 void RenderStyle::setTextDecorationsInEffect(TextDecoration decorations)
1330 {
1331 clearAppliedTextDecorations();
1332
1333 if (decorations & TextDecorationUnderline)
1334 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationUnderline)) ;
1335 if (decorations & TextDecorationOverline)
1336 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationOverline));
1337 if (decorations & TextDecorationLineThrough)
1338 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationLineThrough ));
1339 }
1340
1341 void RenderStyle::addAppliedTextDecoration(const AppliedTextDecoration& decorati on)
1342 {
1343 bool isSimpleUnderline = decoration.isSimple() && decoration.line() == TextD ecorationUnderline;
Julien - ping for review 2014/05/05 17:45:08 It's weird that we check for this simple case repe
andersr 2014/05/06 13:15:29 I don't know ... is that really weird? Currently,
1344
1345 if (!rareInheritedData->appliedTextDecorations && isSimpleUnderline) {
1346 // To save memory, we don't use AppliedTextDecoration objects in the
1347 // common case of a single solid underline with the current color. Inste ad,
1348 // we set a bit to indicate that a solid underline must be drawn with th e
1349 // current color.
1350 inherited_flags.m_textUnderline = true;
1351 return;
1352 }
1353
1354 RefPtr<AppliedTextDecorationList>& list = rareInheritedData.access()->applie dTextDecorations;
1355
1356 if (!list)
1357 list = AppliedTextDecorationList::create();
1358 else if (!list->hasOneRef())
1359 list = list->copy();
Julien - ping for review 2014/05/05 17:45:08 It's probably me but I have a hard time understand
andersr 2014/05/06 13:15:29 A) The same reason we copy DataRef objects? When t
1360
1361 if (inherited_flags.m_textUnderline) {
1362 inherited_flags.m_textUnderline = false;
1363 list->append(AppliedTextDecoration(TextDecorationUnderline, TextDecorati onStyleSolid, StyleColor::currentColor()));
1364 }
1365
1366 list->append(decoration);
1367 }
1368
1369 void RenderStyle::applyTextDecorations()
1370 {
1371 if (textDecoration() == TextDecorationNone)
1372 return;
1373
1374 TextDecorationStyle style = textDecorationStyle();
1375 StyleColor styleColor = visitedDependentDecorationStyleColor();
1376
1377 int decorations = textDecoration();
1378
1379 if (decorations & TextDecorationUnderline)
1380 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationUnderline, style, styleColor));
1381 if (decorations & TextDecorationOverline)
1382 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationOverline, s tyle, styleColor));
1383 if (decorations & TextDecorationLineThrough)
1384 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationLineThrough , style, styleColor));
1385 }
1386
1387 void RenderStyle::clearAppliedTextDecorations()
1388 {
1389 inherited_flags.m_textUnderline = false;
1390
1391 if (rareInheritedData->appliedTextDecorations)
1392 rareInheritedData.access()->appliedTextDecorations = nullptr;
1393 }
1394
1302 void RenderStyle::getShadowExtent(const ShadowList* shadowList, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const 1395 void RenderStyle::getShadowExtent(const ShadowList* shadowList, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const
1303 { 1396 {
1304 top = 0; 1397 top = 0;
1305 right = 0; 1398 right = 0;
1306 bottom = 0; 1399 bottom = 0;
1307 left = 0; 1400 left = 0;
1308 1401
1309 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; 1402 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0;
1310 for (size_t i = 0; i < shadowCount; ++i) { 1403 for (size_t i = 0; i < shadowCount; ++i) {
1311 const ShadowData& shadow = shadowList->shadows()[i]; 1404 const ShadowData& shadow = shadowList->shadows()[i];
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 const ShadowData& shadow = shadowList->shadows()[i]; 1462 const ShadowData& shadow = shadowList->shadows()[i];
1370 if (shadow.style() == Inset) 1463 if (shadow.style() == Inset)
1371 continue; 1464 continue;
1372 float blurAndSpread = shadow.blur() + shadow.spread(); 1465 float blurAndSpread = shadow.blur() + shadow.spread();
1373 1466
1374 top = min<LayoutUnit>(top, shadow.y() - blurAndSpread); 1467 top = min<LayoutUnit>(top, shadow.y() - blurAndSpread);
1375 bottom = max<LayoutUnit>(bottom, shadow.y() + blurAndSpread); 1468 bottom = max<LayoutUnit>(bottom, shadow.y() + blurAndSpread);
1376 } 1469 }
1377 } 1470 }
1378 1471
1379 StyleColor RenderStyle::visitedDependentDecorationColor() const 1472 StyleColor RenderStyle::visitedDependentDecorationStyleColor() const
1380 { 1473 {
1381 // Text decoration color fallback is handled in RenderObject::decorationColo r. 1474 bool visitedLink = insideLink() == InsideVisitedLink;
1382 return insideLink() == InsideVisitedLink ? visitedLinkTextDecorationColor() : textDecorationColor(); 1475
1476 StyleColor styleColor = visitedLink ? visitedLinkTextDecorationColor() : tex tDecorationColor();
1477
1478 if (!styleColor.isCurrentColor())
1479 return styleColor;
1480
1481 if (textStrokeWidth()) {
1482 // Prefer stroke color if possible but not if it's fully transparent.
1483 StyleColor textStrokeStyleColor = visitedLink ? visitedLinkTextStrokeCol or() : textStrokeColor();
1484 if (!textStrokeStyleColor.isCurrentColor() && textStrokeStyleColor.color ().alpha())
1485 return textStrokeStyleColor;
1486 }
1487
1488 return visitedLink ? visitedLinkTextFillColor() : textFillColor();
1489 }
1490
1491 Color RenderStyle::visitedDependentDecorationColor() const
1492 {
1493 bool visitedLink = insideLink() == InsideVisitedLink;
1494 return visitedDependentDecorationStyleColor().resolve(visitedLink ? visitedL inkColor() : color());
1383 } 1495 }
1384 1496
1385 Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c onst 1497 Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c onst
1386 { 1498 {
1387 StyleColor result(StyleColor::currentColor()); 1499 StyleColor result(StyleColor::currentColor());
1388 EBorderStyle borderStyle = BNONE; 1500 EBorderStyle borderStyle = BNONE;
1389 switch (colorProperty) { 1501 switch (colorProperty) {
1390 case CSSPropertyBackgroundColor: 1502 case CSSPropertyBackgroundColor:
1391 result = visitedLink ? visitedLinkBackgroundColor() : backgroundColor(); 1503 result = visitedLink ? visitedLinkBackgroundColor() : backgroundColor();
1392 break; 1504 break;
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 // right 1784 // right
1673 radiiSum = radii.topRight().height() + radii.bottomRight().height(); 1785 radiiSum = radii.topRight().height() + radii.bottomRight().height();
1674 if (radiiSum > rect.height()) 1786 if (radiiSum > rect.height())
1675 factor = std::min(rect.height() / radiiSum, factor); 1787 factor = std::min(rect.height() / radiiSum, factor);
1676 1788
1677 ASSERT(factor <= 1); 1789 ASSERT(factor <= 1);
1678 return factor; 1790 return factor;
1679 } 1791 }
1680 1792
1681 } // namespace WebCore 1793 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698