Changeset 286955 in webkit
- Timestamp:
- Dec 13, 2021 10:23:00 AM (7 months ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/TestExpectations (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/rendering/TextBoxPainter.cpp (modified) (5 diffs)
-
Source/WebCore/rendering/TextBoxPainter.h (modified) (2 diffs)
-
Source/WebCore/rendering/TextDecorationPainter.cpp (modified) (4 diffs)
-
Source/WebCore/rendering/TextDecorationPainter.h (modified) (1 diff)
-
Source/WebCore/style/InlineTextBoxStyle.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r286952 r286955 1 2021-12-13 Tim Nguyen <ntim@apple.com> 2 3 Fix paint order of CSS text decorations 4 https://bugs.webkit.org/show_bug.cgi?id=227445 5 6 Reviewed by Simon Fraser. 7 8 * TestExpectations: 9 1 10 2021-12-13 Sergio Villar Senin <svillar@igalia.com> 2 11 -
trunk/LayoutTests/TestExpectations
r286952 r286955 3432 3432 webkit.org/b/230041 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-color-selection-pseudo-01.html [ ImageOnlyFailure ] 3433 3433 webkit.org/b/203530 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-line-recalc.html [ ImageOnlyFailure ] 3434 webkit.org/b/203531 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-propagation-shadow.html [ ImageOnlyFailure ]3435 3434 webkit.org/b/203528 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-thickness-linethrough-001.html [ ImageOnlyFailure ] 3436 3435 webkit.org/b/203528 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-thickness-overline-001.html [ ImageOnlyFailure ] … … 3472 3471 imported/w3c/web-platform-tests/css/css-text-decor/text-emphasis-style-string-001.xht [ ImageOnlyFailure ] 3473 3472 webkit.org/b/230083 imported/w3c/web-platform-tests/css/css-text-decor/text-underline-offset-001.html [ ImageOnlyFailure ] 3474 imported/w3c/web-platform-tests/css/css-text-decor/text-underline-offset-zero-position.html [ ImageOnlyFailure ]3475 3473 3476 3474 # wpt css-position failures -
trunk/Source/WebCore/ChangeLog
r286953 r286955 1 2021-12-13 Tim Nguyen <ntim@apple.com> 2 3 Fix paint order of CSS text decorations 4 https://bugs.webkit.org/show_bug.cgi?id=227445 5 6 Reviewed by Simon Fraser. 7 8 * rendering/TextBoxPainter.cpp: 9 (WebCore::TextBoxPainter::paintForegroundAndDecorations): 10 (WebCore::TextBoxPainter::createDecorationPainter): 11 (WebCore::TextBoxPainter::paintBackgroundDecorations): 12 (WebCore::TextBoxPainter::paintForegroundDecorations): 13 (WebCore::TextBoxPainter::paintDecoration): Deleted. 14 * rendering/TextBoxPainter.h: 15 * rendering/TextDecorationPainter.cpp: 16 (WebCore::TextDecorationPainter::paintBackgroundDecorations): 17 (WebCore::TextDecorationPainter::paintForegroundDecorations): 18 (WebCore::TextDecorationPainter::paintLineThrough): 19 (WebCore::TextDecorationPainter::paintTextDecoration): Deleted. 20 * rendering/TextDecorationPainter.h: 21 1 22 2021-12-13 Jer Noble <jer.noble@apple.com> 2 23 -
trunk/Source/WebCore/rendering/TextBoxPainter.cpp
r284437 r286955 189 189 auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualForeground(styledMarkedTexts); 190 190 191 for (auto& markedText : coalescedStyledMarkedTexts)192 paintForeground(markedText);193 194 191 auto textDecorations = m_style.textDecorationsInEffect(); 195 192 bool highlightDecorations = !MarkedText::collectForHighlights(m_renderer, m_selectableRange, MarkedText::PaintPhase::Decoration).isEmpty(); … … 225 222 auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualDecorations(styledMarkedTexts); 226 223 224 for (auto& markedText : coalescedStyledMarkedTexts) { 225 unsigned startOffset = markedText.startOffset; 226 unsigned endOffset = markedText.endOffset; 227 if (startOffset < endOffset) { 228 // Avoid measuring the text when the entire line box is selected as an optimization. 229 FloatRect snappedSelectionRect = m_paintRect; 230 if (startOffset || endOffset != m_paintTextRun.length()) { 231 LayoutRect selectionRect = { m_paintRect.x(), m_paintRect.y(), m_paintRect.width(), m_paintRect.height() }; 232 fontCascade().adjustSelectionRectForText(m_paintTextRun, selectionRect, startOffset, endOffset); 233 snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), m_paintTextRun.ltr()); 234 } 235 236 TextDecorationPainter decorationPainter = createDecorationPainter(markedText, textDecorationSelectionClipOutRect, snappedSelectionRect); 237 paintBackgroundDecorations(decorationPainter, markedText, snappedSelectionRect); 238 paintForeground(markedText); 239 paintForegroundDecorations(decorationPainter, snappedSelectionRect); 240 } 241 } 242 } else { 227 243 for (auto& markedText : coalescedStyledMarkedTexts) 228 paint Decoration(markedText, textDecorationSelectionClipOutRect);244 paintForeground(markedText); 229 245 } 230 246 } … … 340 356 } 341 357 342 void TextBoxPainter::paintDecoration(const StyledMarkedText& markedText, const FloatRect& clipOutRect) 343 { 344 // 1. Compute text selection 345 unsigned startOffset = markedText.startOffset; 346 unsigned endOffset = markedText.endOffset; 347 if (startOffset >= endOffset) 348 return; 349 358 TextDecorationPainter TextBoxPainter::createDecorationPainter(const StyledMarkedText& markedText, const FloatRect& clipOutRect, const FloatRect& snappedSelectionRect) 359 { 350 360 GraphicsContext& context = m_paintInfo.context(); 351 const FontCascade& font = fontCascade();352 361 353 362 updateGraphicsContext(context, markedText.style.textStyles); … … 359 368 // Note that if the text is truncated, we let the thing being painted in the truncation 360 369 // draw its own decoration. 361 362 // Avoid measuring the text when the entire line box is selected as an optimization. 363 FloatRect snappedSelectionRect = m_paintRect; 364 if (startOffset || endOffset != m_paintTextRun.length()) { 365 LayoutRect selectionRect = { m_paintRect.x(), m_paintRect.y(), m_paintRect.width(), m_paintRect.height() }; 366 font.adjustSelectionRectForText(m_paintTextRun, selectionRect, startOffset, endOffset); 367 snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), m_paintTextRun.ltr()); 368 } 369 370 // 2. Paint 370 GraphicsContextStateSaver stateSaver { context, false }; 371 bool isDraggedContent = markedText.type == MarkedText::DraggedContent; 372 if (isDraggedContent || !clipOutRect.isEmpty()) { 373 stateSaver.save(); 374 if (isDraggedContent) 375 context.setAlpha(markedText.style.alpha); 376 if (!clipOutRect.isEmpty()) 377 context.clipOut(clipOutRect); 378 } 379 380 // Create painter 381 const FontCascade& font = fontCascade(); 371 382 auto textDecorations = m_style.textDecorationsInEffect(); 372 383 textDecorations.add(TextDecorationPainter::textDecorationsInEffectForStyle(markedText.style.textDecorationStyles)); … … 381 392 } 382 393 383 { 384 GraphicsContextStateSaver stateSaver { context, false }; 385 bool isDraggedContent = markedText.type == MarkedText::DraggedContent; 386 if (isDraggedContent || !clipOutRect.isEmpty()) { 387 stateSaver.save(); 388 if (isDraggedContent) 389 context.setAlpha(markedText.style.alpha); 390 if (!clipOutRect.isEmpty()) 391 context.clipOut(clipOutRect); 392 } 393 decorationPainter.paintTextDecoration(m_paintTextRun.subRun(startOffset, endOffset - startOffset), textOriginFromPaintRect(snappedSelectionRect), snappedSelectionRect.location()); 394 } 395 396 if (isCombinedText) 394 return decorationPainter; 395 } 396 397 void TextBoxPainter::paintBackgroundDecorations(TextDecorationPainter& decorationPainter, const StyledMarkedText& markedText, const FloatRect& snappedSelectionRect) 398 { 399 decorationPainter.paintBackgroundDecorations(m_paintTextRun.subRun(markedText.startOffset, markedText.endOffset - markedText.startOffset), textOriginFromPaintRect(snappedSelectionRect), snappedSelectionRect.location()); 400 401 if (textBox().isCombinedText()) { 402 GraphicsContext& context = m_paintInfo.context(); 397 403 context.concatCTM(rotation(m_paintRect, Counterclockwise)); 404 } 405 } 406 407 void TextBoxPainter::paintForegroundDecorations(TextDecorationPainter& decorationPainter, const FloatRect& snappedSelectionRect) 408 { 409 decorationPainter.paintForegroundDecorations(snappedSelectionRect.location()); 410 411 if (textBox().isCombinedText()) { 412 GraphicsContext& context = m_paintInfo.context(); 413 context.concatCTM(rotation(m_paintRect, Counterclockwise)); 414 } 398 415 } 399 416 -
trunk/Source/WebCore/rendering/TextBoxPainter.h
r284334 r286955 40 40 class RenderText; 41 41 class ShadowData; 42 class TextDecorationPainter; 42 43 struct CompositionUnderline; 43 44 struct MarkedText; … … 72 73 void paintBackground(const StyledMarkedText&); 73 74 void paintForeground(const StyledMarkedText&); 74 void paintDecoration(const StyledMarkedText&, const FloatRect& clipOutRect); 75 TextDecorationPainter createDecorationPainter(const StyledMarkedText&, const FloatRect&, const FloatRect&); 76 void paintBackgroundDecorations(TextDecorationPainter&, const StyledMarkedText&, const FloatRect&); 77 void paintForegroundDecorations(TextDecorationPainter&, const FloatRect&); 75 78 void paintCompositionUnderline(const CompositionUnderline&); 76 79 void paintPlatformDocumentMarker(const MarkedText&); -
trunk/Source/WebCore/rendering/TextDecorationPainter.cpp
r285904 r286955 202 202 } 203 203 204 void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& boxOrigin) 204 // Paint text-shadow, underline, overline 205 void TextDecorationPainter::paintBackgroundDecorations(const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& boxOrigin) 205 206 { 206 207 const auto& fontMetrics = m_lineStyle.fontMetrics(); … … 229 230 m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 230 231 } 231 } else { 232 ASSERT(decoration == TextDecorationLine::LineThrough); 233 m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 234 } 232 } else 233 ASSERT_NOT_REACHED(); 235 234 }; 236 235 … … 294 293 paintDecoration(TextDecorationLine::Overline, m_styles.overlineStyle, m_styles.overlineColor, rect); 295 294 } 296 if (m_decorations.contains(TextDecorationLine::LineThrough)) { 297 FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness)); 298 float autoTextDecorationThickness = TextDecorationThickness::createWithAuto().resolve(m_lineStyle.computedFontSize(), fontMetrics); 299 auto center = 2 * fontMetrics.floatAscent() / 3 + autoTextDecorationThickness / 2; 300 rect.move(0, center - textDecorationThickness / 2); 301 paintDecoration(TextDecorationLine::LineThrough, m_styles.linethroughStyle, m_styles.linethroughColor, rect); 302 } 295 296 // We only want to paint the shadow, hence the transparent color, not the actual line-through, 297 // which will be painted in paintForegroundDecorations(). 298 if (shadow && m_decorations.contains(TextDecorationLine::LineThrough)) 299 paintLineThrough(Color::transparentBlack, textDecorationThickness, localOrigin); 303 300 } while (shadow); 304 301 … … 307 304 else if (m_shadow) 308 305 m_context.clearShadow(); 306 } 307 308 void TextDecorationPainter::paintForegroundDecorations(const FloatPoint& boxOrigin) 309 { 310 if (!m_decorations.contains(TextDecorationLine::LineThrough)) 311 return; 312 313 float textDecorationThickness = m_lineStyle.textDecorationThickness().resolve(m_lineStyle.computedFontSize(), m_lineStyle.fontMetrics()); 314 paintLineThrough(m_styles.linethroughColor, textDecorationThickness, boxOrigin); 315 } 316 317 void TextDecorationPainter::paintLineThrough(const Color& color, float thickness, const FloatPoint& localOrigin) 318 { 319 const auto& fontMetrics = m_lineStyle.fontMetrics(); 320 FloatRect rect(localOrigin, FloatSize(m_width, thickness)); 321 float autoTextDecorationThickness = TextDecorationThickness::createWithAuto().resolve(m_lineStyle.computedFontSize(), fontMetrics); 322 auto center = 2 * fontMetrics.floatAscent() / 3 + autoTextDecorationThickness / 2; 323 rect.move(0, center - thickness / 2); 324 325 m_context.setStrokeColor(color); 326 327 TextDecorationStyle style = m_styles.linethroughStyle; 328 auto strokeStyle = textDecorationStyleToStrokeStyle(style); 329 330 if (style == TextDecorationStyle::Wavy) 331 strokeWavyTextDecoration(m_context, rect, m_lineStyle.computedFontPixelSize()); 332 else 333 m_context.drawLineForText(rect, m_isPrinting, style == TextDecorationStyle::Double, strokeStyle); 309 334 } 310 335 -
trunk/Source/WebCore/rendering/TextDecorationPainter.h
r285904 r286955 53 53 void setShadowColorFilter(const FilterOperations* colorFilter) { m_shadowColorFilter = colorFilter; } 54 54 55 void paintTextDecoration(const TextRun&, const FloatPoint& textOrigin, const FloatPoint& boxOrigin); 55 void paintBackgroundDecorations(const TextRun&, const FloatPoint& textOrigin, const FloatPoint& boxOrigin); 56 void paintForegroundDecorations(const FloatPoint& boxOrigin); 57 void paintLineThrough(const Color&, float thickness, const FloatPoint& localOrigin); 56 58 57 59 struct Styles { -
trunk/Source/WebCore/style/InlineTextBoxStyle.cpp
r285904 r286955 190 190 191 191 // These metrics must match where underlines get drawn. 192 // FIXME: Share the code in TextDecorationPainter::paint TextDecoration() so we can just query it for the painted geometry.192 // FIXME: Share the code in TextDecorationPainter::paintBackgroundDecorations() so we can just query it for the painted geometry. 193 193 if (decoration & TextDecorationLine::Underline) { 194 194 // Compensate for the integral ceiling in GraphicsContext::computeLineBoundsAndAntialiasingModeForText()
Note: See TracChangeset
for help on using the changeset viewer.