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

Side by Side Diff: third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp

Issue 2416033003: Remove unsafe getFontMetrics methods (Closed)
Patch Set: Address wkroman suggestions Created 4 years, 2 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 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/InlineTextBoxPainter.h" 5 #include "core/paint/InlineTextBoxPainter.h"
6 6
7 #include "core/editing/CompositionUnderline.h" 7 #include "core/editing/CompositionUnderline.h"
8 #include "core/editing/Editor.h" 8 #include "core/editing/Editor.h"
9 #include "core/editing/markers/DocumentMarkerController.h" 9 #include "core/editing/markers/DocumentMarkerController.h"
10 #include "core/frame/LocalFrame.h" 10 #include "core/frame/LocalFrame.h"
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 TextPainter::Style textStyle = TextPainter::textPaintingStyle( 178 TextPainter::Style textStyle = TextPainter::textPaintingStyle(
179 m_inlineTextBox.getLineLayoutItem(), styleToUse, paintInfo); 179 m_inlineTextBox.getLineLayoutItem(), styleToUse, paintInfo);
180 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle( 180 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(
181 m_inlineTextBox.getLineLayoutItem(), haveSelection, paintInfo, textStyle); 181 m_inlineTextBox.getLineLayoutItem(), haveSelection, paintInfo, textStyle);
182 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); 182 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection);
183 bool paintSelectedTextSeparately = 183 bool paintSelectedTextSeparately =
184 !paintSelectedTextOnly && textStyle != selectionStyle; 184 !paintSelectedTextOnly && textStyle != selectionStyle;
185 185
186 // Set our font. 186 // Set our font.
187 const Font& font = styleToUse.font(); 187 const Font& font = styleToUse.font();
188 const SimpleFontData* fontData = font.primaryFont();
189 DCHECK(fontData);
188 190
189 LayoutPoint textOrigin(boxOrigin.x(), 191 int ascent = fontData ? fontData->getFontMetrics().ascent() : 0;
190 boxOrigin.y() + font.getFontMetrics().ascent()); 192 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + ascent);
191 193
192 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds 194 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
193 // include selection and composition highlights. 195 // include selection and composition highlights.
194 if (paintInfo.phase != PaintPhaseSelection && 196 if (paintInfo.phase != PaintPhaseSelection &&
195 paintInfo.phase != PaintPhaseTextClip && !isPrinting) { 197 paintInfo.phase != PaintPhaseTextClip && !isPrinting) {
196 paintDocumentMarkers(paintInfo, boxOrigin, styleToUse, font, 198 paintDocumentMarkers(paintInfo, boxOrigin, styleToUse, font,
197 DocumentMarkerPaintPhase::Background); 199 DocumentMarkerPaintPhase::Background);
198 200
199 const LayoutObject& textBoxLayoutObject = inlineLayoutObject(); 201 const LayoutObject& textBoxLayoutObject = inlineLayoutObject();
200 if (haveSelection && !paintsCompositionMarkers(textBoxLayoutObject)) { 202 if (haveSelection && !paintsCompositionMarkers(textBoxLayoutObject)) {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 547
546 // IMPORTANT: The misspelling underline is not considered when calculating the 548 // IMPORTANT: The misspelling underline is not considered when calculating the
547 // text bounds, so we have to make sure to fit within those bounds. This 549 // text bounds, so we have to make sure to fit within those bounds. This
548 // means the top pixel(s) of the underline will overlap the bottom pixel(s) of 550 // means the top pixel(s) of the underline will overlap the bottom pixel(s) of
549 // the glyphs in smaller font sizes. The alternatives are to increase the 551 // the glyphs in smaller font sizes. The alternatives are to increase the
550 // line spacing (bad!!) or decrease the underline thickness. The overlap is 552 // line spacing (bad!!) or decrease the underline thickness. The overlap is
551 // actually the most useful, and matches what AppKit does. So, we generally 553 // actually the most useful, and matches what AppKit does. So, we generally
552 // place the underline at the bottom of the text, but in larger fonts that's 554 // place the underline at the bottom of the text, but in larger fonts that's
553 // not so good so we pin to two pixels under the baseline. 555 // not so good so we pin to two pixels under the baseline.
554 int lineThickness = misspellingLineThickness; 556 int lineThickness = misspellingLineThickness;
555 int baseline = m_inlineTextBox.getLineLayoutItem() 557
556 .style(m_inlineTextBox.isFirstLineStyle()) 558 const SimpleFontData* fontData =
557 ->getFontMetrics() 559 m_inlineTextBox.getLineLayoutItem()
558 .ascent(); 560 .style(m_inlineTextBox.isFirstLineStyle())
561 ->font()
562 .primaryFont();
563 DCHECK(fontData);
564 int baseline = fontData ? fontData->getFontMetrics().ascent() : 0;
559 int descent = (m_inlineTextBox.logicalHeight() - baseline).toInt(); 565 int descent = (m_inlineTextBox.logicalHeight() - baseline).toInt();
560 int underlineOffset; 566 int underlineOffset;
561 if (descent <= (lineThickness + 2)) { 567 if (descent <= (lineThickness + 2)) {
562 // Place the underline at the very bottom of the text in small/medium fonts. 568 // Place the underline at the very bottom of the text in small/medium fonts.
563 underlineOffset = (m_inlineTextBox.logicalHeight() - lineThickness).toInt(); 569 underlineOffset = (m_inlineTextBox.logicalHeight() - lineThickness).toInt();
564 } else { 570 } else {
565 // In larger fonts, though, place the underline up near the baseline to 571 // In larger fonts, though, place the underline up near the baseline to
566 // prevent a big gap. 572 // prevent a big gap.
567 underlineOffset = baseline + 2; 573 underlineOffset = baseline + 2;
568 } 574 }
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 true); 952 true);
947 if (m_inlineTextBox.isFirstLineStyle()) 953 if (m_inlineTextBox.isFirstLineStyle())
948 textBoxLayoutObject.getTextDecorations(deco, underline, overline, 954 textBoxLayoutObject.getTextDecorations(deco, underline, overline,
949 linethrough, true, true); 955 linethrough, true, true);
950 956
951 // Use a special function for underlines to get the positioning exactly right. 957 // Use a special function for underlines to get the positioning exactly right.
952 bool isPrinting = paintInfo.isPrinting(); 958 bool isPrinting = paintInfo.isPrinting();
953 959
954 const ComputedStyle& styleToUse = 960 const ComputedStyle& styleToUse =
955 textBoxLayoutObject.styleRef(m_inlineTextBox.isFirstLineStyle()); 961 textBoxLayoutObject.styleRef(m_inlineTextBox.isFirstLineStyle());
956 float baseline = styleToUse.getFontMetrics().ascent(); 962 const SimpleFontData* fontData = styleToUse.font().primaryFont();
963 DCHECK(fontData);
964 float baseline = fontData ? fontData->getFontMetrics().ascent() : 0;
957 965
958 // Set the thick of the line to be 10% (or something else ?)of the computed 966 // Set the thick of the line to be 10% (or something else ?)of the computed
959 // font size and not less than 1px. Using computedFontSize should take care 967 // font size and not less than 1px. Using computedFontSize should take care
960 // of zoom as well. 968 // of zoom as well.
961 969
962 // Update Underline thickness, in case we have Faulty Font Metrics calculating 970 // Update Underline thickness, in case we have Faulty Font Metrics calculating
963 // underline thickness by old method. 971 // underline thickness by old method.
964 float textDecorationThickness = 972 float textDecorationThickness = 0.0;
965 styleToUse.getFontMetrics().underlineThickness(); 973 int fontHeightInt = 0;
966 int fontHeightInt = (int)(styleToUse.getFontMetrics().floatHeight() + 0.5); 974 if (fontData) {
975 textDecorationThickness = fontData->getFontMetrics().underlineThickness();
976 fontHeightInt = (int)(fontData->getFontMetrics().floatHeight() + 0.5);
977 }
967 if ((textDecorationThickness == 0.f) || 978 if ((textDecorationThickness == 0.f) ||
968 (textDecorationThickness >= (fontHeightInt >> 1))) 979 (textDecorationThickness >= (fontHeightInt >> 1)))
969 textDecorationThickness = 980 textDecorationThickness =
970 std::max(1.f, styleToUse.computedFontSize() / 10.f); 981 std::max(1.f, styleToUse.computedFontSize() / 10.f);
971 982
972 context.setStrokeThickness(textDecorationThickness); 983 context.setStrokeThickness(textDecorationThickness);
973 984
974 bool antialiasDecoration = shouldSetDecorationAntialias( 985 bool antialiasDecoration = shouldSetDecorationAntialias(
975 overline.style, underline.style, linethrough.style); 986 overline.style, underline.style, linethrough.style);
976 987
977 // Offset between lines - always non-zero, so lines never cross each other. 988 // Offset between lines - always non-zero, so lines never cross each other.
978 float doubleOffset = textDecorationThickness + 1.f; 989 float doubleOffset = textDecorationThickness + 1.f;
979 990
980 if (deco & TextDecorationUnderline) { 991 if ((deco & TextDecorationUnderline) && fontData) {
981 const int underlineOffset = computeUnderlineOffset( 992 const int underlineOffset = computeUnderlineOffset(
982 styleToUse.getTextUnderlinePosition(), styleToUse.getFontMetrics(), 993 styleToUse.getTextUnderlinePosition(), fontData->getFontMetrics(),
983 &m_inlineTextBox, textDecorationThickness); 994 &m_inlineTextBox, textDecorationThickness);
984 paintAppliedDecoration( 995 paintAppliedDecoration(
985 context, FloatPoint(localOrigin) + FloatPoint(0, underlineOffset), 996 context, FloatPoint(localOrigin) + FloatPoint(0, underlineOffset),
986 width.toFloat(), doubleOffset, 1, underline, textDecorationThickness, 997 width.toFloat(), doubleOffset, 1, underline, textDecorationThickness,
987 antialiasDecoration, isPrinting); 998 antialiasDecoration, isPrinting);
988 } 999 }
989 if (deco & TextDecorationOverline) { 1000 if (deco & TextDecorationOverline) {
990 paintAppliedDecoration(context, FloatPoint(localOrigin), width.toFloat(), 1001 paintAppliedDecoration(context, FloatPoint(localOrigin), width.toFloat(),
991 -doubleOffset, 1, overline, textDecorationThickness, 1002 -doubleOffset, 1, overline, textDecorationThickness,
992 antialiasDecoration, isPrinting); 1003 antialiasDecoration, isPrinting);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 // |logicalWidth| - |start| - |width|. We will draw that line, but backwards: 1057 // |logicalWidth| - |start| - |width|. We will draw that line, but backwards:
1047 // |logicalWidth| - |start| - |width| to |logicalWidth| - |start|. 1058 // |logicalWidth| - |start| - |width| to |logicalWidth| - |start|.
1048 if (!flowIsLTR) 1059 if (!flowIsLTR)
1049 start = m_inlineTextBox.logicalWidth().toFloat() - width - start; 1060 start = m_inlineTextBox.logicalWidth().toFloat() - width - start;
1050 1061
1051 // Thick marked text underlines are 2px thick as long as there is room for the 1062 // Thick marked text underlines are 2px thick as long as there is room for the
1052 // 2px line under the baseline. All other marked text underlines are 1px 1063 // 2px line under the baseline. All other marked text underlines are 1px
1053 // thick. If there's not enough space the underline will touch or overlap 1064 // thick. If there's not enough space the underline will touch or overlap
1054 // characters. 1065 // characters.
1055 int lineThickness = 1; 1066 int lineThickness = 1;
1056 int baseline = m_inlineTextBox.getLineLayoutItem() 1067 const SimpleFontData* fontData =
1057 .style(m_inlineTextBox.isFirstLineStyle()) 1068 m_inlineTextBox.getLineLayoutItem()
1058 ->getFontMetrics() 1069 .style(m_inlineTextBox.isFirstLineStyle())
1059 .ascent(); 1070 ->font()
1071 .primaryFont();
1072 DCHECK(fontData);
1073 int baseline = fontData ? fontData->getFontMetrics().ascent() : 0;
1060 if (underline.thick() && m_inlineTextBox.logicalHeight() - baseline >= 2) 1074 if (underline.thick() && m_inlineTextBox.logicalHeight() - baseline >= 2)
1061 lineThickness = 2; 1075 lineThickness = 2;
1062 1076
1063 // We need to have some space between underlines of subsequent clauses, 1077 // We need to have some space between underlines of subsequent clauses,
1064 // because some input methods do not use different underline styles for those. 1078 // because some input methods do not use different underline styles for those.
1065 // We make each line shorter, which has a harmless side effect of shortening 1079 // We make each line shorter, which has a harmless side effect of shortening
1066 // the first and last clauses, too. 1080 // the first and last clauses, too.
1067 start += 1; 1081 start += 1;
1068 width -= 2; 1082 width -= 2;
1069 1083
(...skipping 21 matching lines...) Expand all
1091 int sPos = 1105 int sPos =
1092 std::max(marker->startOffset() - m_inlineTextBox.start(), (unsigned)0); 1106 std::max(marker->startOffset() - m_inlineTextBox.start(), (unsigned)0);
1093 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), 1107 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(),
1094 m_inlineTextBox.len()); 1108 m_inlineTextBox.len());
1095 TextRun run = m_inlineTextBox.constructTextRun(style); 1109 TextRun run = m_inlineTextBox.constructTextRun(style);
1096 1110
1097 Color textColor = 1111 Color textColor =
1098 LayoutTheme::theme().platformTextSearchColor(marker->activeMatch()); 1112 LayoutTheme::theme().platformTextSearchColor(marker->activeMatch());
1099 if (style.visitedDependentColor(CSSPropertyColor) == textColor) 1113 if (style.visitedDependentColor(CSSPropertyColor) == textColor)
1100 return; 1114 return;
1115
1116 const SimpleFontData* fontData = font.primaryFont();
1117 DCHECK(fontData);
1118 if (!fontData)
1119 return;
1120
1101 TextPainter::Style textStyle; 1121 TextPainter::Style textStyle;
1102 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = 1122 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor =
1103 textStyle.emphasisMarkColor = textColor; 1123 textStyle.emphasisMarkColor = textColor;
1104 textStyle.strokeWidth = style.textStrokeWidth(); 1124 textStyle.strokeWidth = style.textStrokeWidth();
1105 textStyle.shadow = 0; 1125 textStyle.shadow = 0;
1106 1126
1107 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), 1127 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(),
1108 m_inlineTextBox.logicalHeight())); 1128 m_inlineTextBox.logicalHeight()));
1109 LayoutPoint textOrigin(boxOrigin.x(), 1129 LayoutPoint textOrigin(boxOrigin.x(),
1110 boxOrigin.y() + font.getFontMetrics().ascent()); 1130 boxOrigin.y() + fontData->getFontMetrics().ascent());
1111 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, 1131 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect,
1112 m_inlineTextBox.isHorizontal()); 1132 m_inlineTextBox.isHorizontal());
1113 1133
1114 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0); 1134 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0);
1115 } 1135 }
1116 1136
1117 void InlineTextBoxPainter::paintTextMatchMarkerBackground( 1137 void InlineTextBoxPainter::paintTextMatchMarkerBackground(
1118 const PaintInfo& paintInfo, 1138 const PaintInfo& paintInfo,
1119 const LayoutPoint& boxOrigin, 1139 const LayoutPoint& boxOrigin,
1120 DocumentMarker* marker, 1140 DocumentMarker* marker,
(...skipping 17 matching lines...) Expand all
1138 GraphicsContextStateSaver stateSaver(context); 1158 GraphicsContextStateSaver stateSaver(context);
1139 1159
1140 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), 1160 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(),
1141 m_inlineTextBox.logicalHeight())); 1161 m_inlineTextBox.logicalHeight()));
1142 context.clip(FloatRect(boxRect)); 1162 context.clip(FloatRect(boxRect));
1143 context.drawHighlightForText(font, run, FloatPoint(boxOrigin), 1163 context.drawHighlightForText(font, run, FloatPoint(boxOrigin),
1144 boxRect.height().toInt(), color, sPos, ePos); 1164 boxRect.height().toInt(), color, sPos, ePos);
1145 } 1165 }
1146 1166
1147 } // namespace blink 1167 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698