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

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

Issue 1328283005: Add support for multiple text decorations with same line positioning (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Review feedback Created 5 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/layout/LayoutObject.cpp ('k') | Source/core/paint/SVGInlineTextBoxPainter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "config.h" 5 #include "config.h"
6 #include "core/paint/InlineTextBoxPainter.h" 6 #include "core/paint/InlineTextBoxPainter.h"
7 7
8 #include "core/editing/CompositionUnderline.h" 8 #include "core/editing/CompositionUnderline.h"
9 #include "core/editing/Editor.h" 9 #include "core/editing/Editor.h"
10 #include "core/editing/markers/DocumentMarkerController.h" 10 #include "core/editing/markers/DocumentMarkerController.h"
11 #include "core/editing/markers/RenderedDocumentMarker.h" 11 #include "core/editing/markers/RenderedDocumentMarker.h"
12 #include "core/frame/LocalFrame.h" 12 #include "core/frame/LocalFrame.h"
13 #include "core/layout/LayoutBlock.h" 13 #include "core/layout/LayoutBlock.h"
14 #include "core/layout/LayoutTextCombine.h" 14 #include "core/layout/LayoutTextCombine.h"
15 #include "core/layout/LayoutTheme.h" 15 #include "core/layout/LayoutTheme.h"
16 #include "core/layout/line/InlineTextBox.h" 16 #include "core/layout/line/InlineTextBox.h"
17 #include "core/paint/BoxPainter.h" 17 #include "core/paint/BoxPainter.h"
18 #include "core/paint/LayoutObjectDrawingRecorder.h" 18 #include "core/paint/LayoutObjectDrawingRecorder.h"
19 #include "core/paint/PaintInfo.h" 19 #include "core/paint/PaintInfo.h"
20 #include "core/paint/TextPainter.h" 20 #include "core/paint/TextPainter.h"
21 #include "core/style/AppliedTextDecoration.h"
21 #include "platform/graphics/GraphicsContextStateSaver.h" 22 #include "platform/graphics/GraphicsContextStateSaver.h"
22 #include "wtf/Optional.h" 23 #include "wtf/Optional.h"
23 24
24 namespace blink { 25 namespace blink {
25 26
26 typedef WTF::HashMap<const InlineTextBox*, TextBlobPtr> InlineTextBoxBlobCacheMa p; 27 typedef WTF::HashMap<const InlineTextBox*, TextBlobPtr> InlineTextBoxBlobCacheMa p;
27 static InlineTextBoxBlobCacheMap* gTextBlobCache; 28 static InlineTextBoxBlobCacheMap* gTextBlobCache;
28 29
29 static const int misspellingLineThickness = 3; 30 static const int misspellingLineThickness = 3;
30 31
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 539
539 ASSERT_NOT_REACHED(); 540 ASSERT_NOT_REACHED();
540 return fontMetrics.ascent() + gap; 541 return fontMetrics.ascent() + gap;
541 } 542 }
542 543
543 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) 544 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle)
544 { 545 {
545 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te xtDecorationStyleDashed; 546 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te xtDecorationStyleDashed;
546 } 547 }
547 548
548 static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDeco rationStyle overline, TextDecorationStyle linethrough)
549 {
550 return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntiali as(overline) || shouldSetDecorationAntialias(linethrough);
551 }
552
553 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati onStyle) 549 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati onStyle)
554 { 550 {
555 StrokeStyle strokeStyle = SolidStroke; 551 StrokeStyle strokeStyle = SolidStroke;
556 switch (decorationStyle) { 552 switch (decorationStyle) {
557 case TextDecorationStyleSolid: 553 case TextDecorationStyleSolid:
558 strokeStyle = SolidStroke; 554 strokeStyle = SolidStroke;
559 break; 555 break;
560 case TextDecorationStyleDouble: 556 case TextDecorationStyleDouble:
561 strokeStyle = DoubleStroke; 557 strokeStyle = DoubleStroke;
562 break; 558 break;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 x += 2 * step; 686 x += 2 * step;
691 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA xis)); 687 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA xis));
692 } 688 }
693 } 689 }
694 690
695 context->setShouldAntialias(true); 691 context->setShouldAntialias(true);
696 context->strokePath(path); 692 context->strokePath(path);
697 } 693 }
698 694
699 static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, f loat width, float doubleOffset, int wavyOffsetFactor, 695 static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, f loat width, float doubleOffset, int wavyOffsetFactor,
700 LayoutObject::AppliedTextDecoration decoration, float thickness, bool antial iasDecoration, bool isPrinting) 696 AppliedTextDecoration decoration, float thickness, bool antialiasDecoration, bool isPrinting)
701 { 697 {
702 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style)); 698 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style()) );
703 context->setStrokeColor(decoration.color); 699 context->setStrokeColor(decoration.color());
704 700
705 switch (decoration.style) { 701 switch (decoration.style()) {
706 case TextDecorationStyleWavy: 702 case TextDecorationStyleWavy:
707 strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * w avyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), th ickness); 703 strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * w avyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), th ickness);
708 break; 704 break;
709 case TextDecorationStyleDotted: 705 case TextDecorationStyleDotted:
710 case TextDecorationStyleDashed: 706 case TextDecorationStyleDashed:
711 context->setShouldAntialias(antialiasDecoration); 707 context->setShouldAntialias(antialiasDecoration);
712 // Fall through 708 // Fall through
713 default: 709 default:
714 context->drawLineForText(FloatPoint(start), width, isPrinting); 710 context->drawLineForText(FloatPoint(start), width, isPrinting);
715 711
716 if (decoration.style == TextDecorationStyleDouble) 712 if (decoration.style() == TextDecorationStyleDouble)
717 context->drawLineForText(start + FloatPoint(0, doubleOffset), width, isPrinting); 713 context->drawLineForText(start + FloatPoint(0, doubleOffset), width, isPrinting);
718 } 714 }
719 } 715 }
720 716
721 void InlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, const Lay outPoint& boxOrigin, TextDecoration deco) 717 void InlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, const Lay outPoint& boxOrigin, TextDecoration deco)
Timothy Loh 2015/09/22 05:00:23 Does this patch remove our usage of TextDecoration
sashab 2015/09/24 01:19:27 No, SVGInlineTextBoxPainter and InlineTextBoxPaint
Timothy Loh 2015/09/24 01:38:15 Are the TextDecoration argument here and the textD
722 { 718 {
723 if (m_inlineTextBox.truncation() == cFullTruncation) 719 if (m_inlineTextBox.truncation() == cFullTruncation)
724 return; 720 return;
725 721
726 GraphicsContext* context = paintInfo.context; 722 GraphicsContext* context = paintInfo.context;
727 GraphicsContextStateSaver stateSaver(*context); 723 GraphicsContextStateSaver stateSaver(*context);
728 724
729 LayoutPoint localOrigin(boxOrigin); 725 LayoutPoint localOrigin(boxOrigin);
730 726
731 LayoutUnit width = m_inlineTextBox.logicalWidth(); 727 LayoutUnit width = m_inlineTextBox.logicalWidth();
732 if (m_inlineTextBox.truncation() != cNoTruncation) { 728 if (m_inlineTextBox.truncation() != cNoTruncation) {
733 width = m_inlineTextBox.layoutObject().width(m_inlineTextBox.start(), m_ inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToR ightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); 729 width = m_inlineTextBox.layoutObject().width(m_inlineTextBox.start(), m_ inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToR ightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle());
734 if (!m_inlineTextBox.isLeftToRightDirection()) 730 if (!m_inlineTextBox.isLeftToRightDirection())
735 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); 731 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0);
736 } 732 }
737 733
738 // Get the text decoration colors. 734 const Vector<AppliedTextDecoration>& decorations = m_inlineTextBox.layoutObj ect().style(m_inlineTextBox.isFirstLineStyle())->appliedTextDecorations();
739 LayoutObject::AppliedTextDecoration underline, overline, linethrough;
740 m_inlineTextBox.layoutObject().getTextDecorations(deco, underline, overline, linethrough, true);
741 if (m_inlineTextBox.isFirstLineStyle())
742 m_inlineTextBox.layoutObject().getTextDecorations(deco, underline, overl ine, linethrough, true, true);
743 735
744 // Use a special function for underlines to get the positioning exactly righ t. 736 // Use a special function for underlines to get the positioning exactly righ t.
745 bool isPrinting = paintInfo.isPrinting(); 737 bool isPrinting = paintInfo.isPrinting();
746 738
747 const ComputedStyle& styleToUse = m_inlineTextBox.layoutObject().styleRef(m_ inlineTextBox.isFirstLineStyle()); 739 const ComputedStyle& styleToUse = m_inlineTextBox.layoutObject().styleRef(m_ inlineTextBox.isFirstLineStyle());
748 float baseline = styleToUse.fontMetrics().ascent(); 740 float baseline = styleToUse.fontMetrics().ascent();
749 741
750 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px. 742 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px.
751 // Using computedFontSize should take care of zoom as well. 743 // Using computedFontSize should take care of zoom as well.
752 744
753 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method. 745 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method.
754 float textDecorationThickness = styleToUse.fontMetrics().underlineThickness( ); 746 float textDecorationThickness = styleToUse.fontMetrics().underlineThickness( );
755 int fontHeightInt = (int)(styleToUse.fontMetrics().floatHeight() + 0.5); 747 int fontHeightInt = (int)(styleToUse.fontMetrics().floatHeight() + 0.5);
756 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1))) 748 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1)))
757 textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() / 10.f); 749 textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() / 10.f);
758 750
759 context->setStrokeThickness(textDecorationThickness); 751 context->setStrokeThickness(textDecorationThickness);
760 752
761 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde rline.style, linethrough.style); 753 bool antialiasDecoration = false;
754 for (const auto& decoration : decorations)
755 antialiasDecoration |= shouldSetDecorationAntialias(decoration.style());
762 756
763 // Offset between lines - always non-zero, so lines never cross each other. 757 // Offset between lines - always non-zero, so lines never cross each other.
764 float doubleOffset = textDecorationThickness + 1.f; 758 float doubleOffset = textDecorationThickness + 1.f;
765 759
766 if (deco & TextDecorationUnderline) { 760 for (const auto& decoration : decorations) {
767 const int underlineOffset = computeUnderlineOffset(styleToUse.textUnderl inePosition(), styleToUse.fontMetrics(), &m_inlineTextBox, textDecorationThickne ss); 761 if (decoration.lines() & TextDecorationUnderline) {
768 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0, underlineOffset), width.toFloat(), doubleOffset, 1, underline, textDecorationThi ckness, antialiasDecoration, isPrinting); 762 const int underlineOffset = computeUnderlineOffset(styleToUse.textUn derlinePosition(), styleToUse.fontMetrics(), &m_inlineTextBox, textDecorationThi ckness);
769 } 763 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint (0, underlineOffset), width.toFloat(), doubleOffset, 1, decoration, textDecorati onThickness, antialiasDecoration, isPrinting);
770 if (deco & TextDecorationOverline) { 764 }
771 paintAppliedDecoration(context, FloatPoint(localOrigin), width.toFloat() , -doubleOffset, 1, overline, textDecorationThickness, antialiasDecoration, isPr inting); 765 if (decoration.lines() & TextDecorationOverline) {
772 } 766 paintAppliedDecoration(context, FloatPoint(localOrigin), width.toFlo at(), -doubleOffset, 1, decoration, textDecorationThickness, antialiasDecoration , isPrinting);
773 if (deco & TextDecorationLineThrough) { 767 }
774 const float lineThroughOffset = 2 * baseline / 3; 768 if (decoration.lines() & TextDecorationLineThrough) {
775 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0, lineThroughOffset), width.toFloat(), doubleOffset, 0, linethrough, textDecoratio nThickness, antialiasDecoration, isPrinting); 769 const float lineThroughOffset = 2 * baseline / 3;
770 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint (0, lineThroughOffset), width.toFloat(), doubleOffset, 0, decoration, textDecora tionThickness, antialiasDecoration, isPrinting);
771 }
776 } 772 }
777 } 773 }
778 774
779 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext* ctx, const LayoutPoint& boxOrigin, const CompositionUnderline& underline) 775 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext* ctx, const LayoutPoint& boxOrigin, const CompositionUnderline& underline)
780 { 776 {
781 if (underline.color == Color::transparent) 777 if (underline.color == Color::transparent)
782 return; 778 return;
783 779
784 if (m_inlineTextBox.truncation() == cFullTruncation) 780 if (m_inlineTextBox.truncation() == cFullTruncation)
785 return; 781 return;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetri cs().ascent()); 841 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetri cs().ascent());
846 TextPainter textPainter(pt, font, run, textOrigin, boxRect, m_inline TextBox.isHorizontal()); 842 TextPainter textPainter(pt, font, run, textOrigin, boxRect, m_inline TextBox.isHorizontal());
847 843
848 textPainter.paint(sPos, ePos, length, textStyle, 0); 844 textPainter.paint(sPos, ePos, length, textStyle, 0);
849 } 845 }
850 } 846 }
851 } 847 }
852 848
853 849
854 } // namespace blink 850 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutObject.cpp ('k') | Source/core/paint/SVGInlineTextBoxPainter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698