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

Side by Side Diff: Source/core/rendering/InlineTextBox.cpp

Issue 367973003: Refactor color selection out of InlineTextBox::paint. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org) 3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 467
468 if (!containingBlock->parent()->isRubyRun()) 468 if (!containingBlock->parent()->isRubyRun())
469 return true; // Cannot get the ruby text. 469 return true; // Cannot get the ruby text.
470 470
471 RenderRubyText* rubyText = toRenderRubyRun(containingBlock->parent())->rubyT ext(); 471 RenderRubyText* rubyText = toRenderRubyRun(containingBlock->parent())->rubyT ext();
472 472
473 // The emphasis marks over are suppressed only if there is a ruby text box a nd it not empty. 473 // The emphasis marks over are suppressed only if there is a ruby text box a nd it not empty.
474 return !rubyText || !rubyText->firstLineBox(); 474 return !rubyText || !rubyText->firstLineBox();
475 } 475 }
476 476
477 namespace {
478
479 struct TextPaintingStyle {
480 Color fillColor;
481 Color strokeColor;
482 Color emphasisMarkColor;
483 float strokeWidth;
484 const ShadowList* shadow;
485
486 bool operator==(const TextPaintingStyle& other)
487 {
488 return fillColor == other.fillColor
489 && strokeColor == other.strokeColor
490 && emphasisMarkColor == other.emphasisMarkColor
491 && strokeWidth == other.strokeWidth
492 && shadow == other.shadow;
493 }
494 bool operator!=(const TextPaintingStyle& other) { return !(*this == other); }
495 };
496
497 TextPaintingStyle textPaintingStyle(RenderText& renderer, RenderStyle* style, bo ol forceBlackText, bool isPrinting)
498 {
499 TextPaintingStyle textStyle;
500
501 if (forceBlackText) {
502 textStyle.fillColor = Color::black;
503 textStyle.strokeColor = Color::black;
504 textStyle.emphasisMarkColor = Color::black;
505 textStyle.strokeWidth = style->textStrokeWidth();
506 textStyle.shadow = 0;
507 } else {
508 textStyle.fillColor = renderer.resolveColor(style, CSSPropertyWebkitText FillColor);
509 textStyle.strokeColor = renderer.resolveColor(style, CSSPropertyWebkitTe xtStrokeColor);
510 textStyle.emphasisMarkColor = renderer.resolveColor(style, CSSPropertyWe bkitTextEmphasisColor);
511 textStyle.strokeWidth = style->textStrokeWidth();
512 textStyle.shadow = style->textShadow();
513
514 // Adjust text color when printing with a white background.
515 bool forceBackgroundToWhite = false;
516 if (isPrinting) {
517 if (style->printColorAdjust() == PrintColorAdjustEconomy)
518 forceBackgroundToWhite = true;
519 if (renderer.document().settings() && renderer.document().settings() ->shouldPrintBackgrounds())
520 forceBackgroundToWhite = false;
521 }
522 if (forceBackgroundToWhite) {
523 textStyle.fillColor = correctedTextColor(textStyle.fillColor, Color: :white);
524 textStyle.strokeColor = correctedTextColor(textStyle.strokeColor, Co lor::white);
525 textStyle.emphasisMarkColor = correctedTextColor(textStyle.emphasisM arkColor, Color::white);
526 }
527
528 // Text shadows are disabled when printing. http://crbug.com/258321
529 if (isPrinting)
530 textStyle.shadow = 0;
531 }
532
533 return textStyle;
534 }
535
536 TextPaintingStyle selectionPaintingStyle(RenderText& renderer, bool haveSelectio n, bool forceBlackText, bool isPrinting, const TextPaintingStyle& textStyle)
537 {
538 TextPaintingStyle selectionStyle = textStyle;
539
540 if (haveSelection) {
541 if (!forceBlackText) {
542 selectionStyle.fillColor = renderer.selectionForegroundColor();
543 selectionStyle.emphasisMarkColor = renderer.selectionEmphasisMarkCol or();
544 }
545
546 if (RenderStyle* pseudoStyle = renderer.getCachedPseudoStyle(SELECTION)) {
547 selectionStyle.strokeColor = forceBlackText ? Color::black : rendere r.resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
548 selectionStyle.strokeWidth = pseudoStyle->textStrokeWidth();
549 selectionStyle.shadow = forceBlackText ? 0 : pseudoStyle->textShadow ();
550 }
551
552 // Text shadows are disabled when printing. http://crbug.com/258321
553 if (isPrinting)
554 selectionStyle.shadow = 0;
555 }
556
557 return selectionStyle;
558 }
559
560 } // namespace
561
477 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) 562 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
478 { 563 {
479 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || render er().style()->visibility() != VISIBLE 564 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || render er().style()->visibility() != VISIBLE
480 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len) 565 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len)
481 return; 566 return;
482 567
483 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines); 568 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines);
484 569
485 LayoutRect logicalVisualOverflow = logicalOverflowRect(); 570 LayoutRect logicalVisualOverflow = logicalOverflowRect();
486 LayoutUnit logicalStart = logicalVisualOverflow.x() + (isHorizontal() ? pain tOffset.x() : paintOffset.y()); 571 LayoutUnit logicalStart = logicalVisualOverflow.x() + (isHorizontal() ? pain tOffset.x() : paintOffset.y());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRender er().isCombineText() && toRenderCombineText(textRenderer()).isCombined() ? &toRe nderCombineText(textRenderer()) : 0; 623 RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRender er().isCombineText() && toRenderCombineText(textRenderer()).isCombined() ? &toRe nderCombineText(textRenderer()) : 0;
539 624
540 bool shouldRotate = !isHorizontal() && !combinedText; 625 bool shouldRotate = !isHorizontal() && !combinedText;
541 if (shouldRotate) 626 if (shouldRotate)
542 context->concatCTM(rotation(boxRect, Clockwise)); 627 context->concatCTM(rotation(boxRect, Clockwise));
543 628
544 // Determine whether or not we have composition underlines to draw. 629 // Determine whether or not we have composition underlines to draw.
545 bool containsComposition = renderer().node() && renderer().frame()->inputMet hodController().compositionNode() == renderer().node(); 630 bool containsComposition = renderer().node() && renderer().frame()->inputMet hodController().compositionNode() == renderer().node();
546 bool useCustomUnderlines = containsComposition && renderer().frame()->inputM ethodController().compositionUsesCustomUnderlines(); 631 bool useCustomUnderlines = containsComposition && renderer().frame()->inputM ethodController().compositionUsesCustomUnderlines();
547 632
548 // Determine the text colors and selection colors. 633 // Determine text colors.
549 Color textFillColor; 634 TextPaintingStyle textStyle = textPaintingStyle(textRenderer(), styleToUse, paintInfo.forceBlackText(), isPrinting);
550 Color textStrokeColor; 635 TextPaintingStyle selectionStyle = selectionPaintingStyle(textRenderer(), ha veSelection, paintInfo.forceBlackText(), isPrinting, textStyle);
551 Color emphasisMarkColor;
552 float textStrokeWidth = styleToUse->textStrokeWidth();
553
554 // Text shadows are disabled when printing. http://crbug.com/258321
555 const ShadowList* textShadow = (context->printing() || paintInfo.forceBlackT ext()) ? 0 : styleToUse->textShadow();
556
557 if (paintInfo.forceBlackText()) {
558 textFillColor = Color::black;
559 textStrokeColor = Color::black;
560 emphasisMarkColor = Color::black;
561 } else {
562 textFillColor = renderer().resolveColor(styleToUse, CSSPropertyWebkitTex tFillColor);
563
564 bool forceBackgroundToWhite = false;
565 if (isPrinting) {
566 if (styleToUse->printColorAdjust() == PrintColorAdjustEconomy)
567 forceBackgroundToWhite = true;
568 if (textRenderer().document().settings() && textRenderer().document( ).settings()->shouldPrintBackgrounds())
569 forceBackgroundToWhite = false;
570 }
571
572 // Make the text fill color legible against a white background
573 if (forceBackgroundToWhite)
574 textFillColor = correctedTextColor(textFillColor, Color::white);
575
576 textStrokeColor = renderer().resolveColor(styleToUse, CSSPropertyWebkitT extStrokeColor);
577
578 // Make the text stroke color legible against a white background
579 if (forceBackgroundToWhite)
580 textStrokeColor = correctedTextColor(textStrokeColor, Color::white);
581
582 emphasisMarkColor = renderer().resolveColor(styleToUse, CSSPropertyWebki tTextEmphasisColor);
583
584 // Make the text stroke color legible against a white background
585 if (forceBackgroundToWhite)
586 emphasisMarkColor = correctedTextColor(emphasisMarkColor, Color::whi te);
587 }
588
589 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); 636 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection);
590 bool paintSelectedTextSeparately = false; 637 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se lectionStyle;
591
592 Color selectionFillColor = textFillColor;
593 Color selectionStrokeColor = textStrokeColor;
594 Color selectionEmphasisMarkColor = emphasisMarkColor;
595 float selectionStrokeWidth = textStrokeWidth;
596 const ShadowList* selectionShadow = textShadow;
597 if (haveSelection) {
598 // Check foreground color first.
599 Color foreground = paintInfo.forceBlackText() ? Color::black : renderer( ).selectionForegroundColor();
600 if (foreground != selectionFillColor) {
601 if (!paintSelectedTextOnly)
602 paintSelectedTextSeparately = true;
603 selectionFillColor = foreground;
604 }
605
606 Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer().selectionEmphasisMarkColor();
607 if (emphasisMarkForeground != selectionEmphasisMarkColor) {
608 if (!paintSelectedTextOnly)
609 paintSelectedTextSeparately = true;
610 selectionEmphasisMarkColor = emphasisMarkForeground;
611 }
612
613 if (RenderStyle* pseudoStyle = renderer().getCachedPseudoStyle(SELECTION )) {
614 // Text shadows are disabled when printing. http://crbug.com/258321
615 const ShadowList* shadow = (context->printing() || paintInfo.forceBl ackText()) ? 0 : pseudoStyle->textShadow();
616 if (shadow != selectionShadow) {
617 if (!paintSelectedTextOnly)
618 paintSelectedTextSeparately = true;
619 selectionShadow = shadow;
620 }
621
622 float strokeWidth = pseudoStyle->textStrokeWidth();
623 if (strokeWidth != selectionStrokeWidth) {
624 if (!paintSelectedTextOnly)
625 paintSelectedTextSeparately = true;
626 selectionStrokeWidth = strokeWidth;
627 }
628
629 Color stroke = paintInfo.forceBlackText() ? Color::black : renderer( ).resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
630 if (stroke != selectionStrokeColor) {
631 if (!paintSelectedTextOnly)
632 paintSelectedTextSeparately = true;
633 selectionStrokeColor = stroke;
634 }
635 }
636 }
637 638
638 // Set our font. 639 // Set our font.
639 const Font& font = styleToUse->font(); 640 const Font& font = styleToUse->font();
640 641
641 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM etrics().ascent()); 642 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM etrics().ascent());
642
643 if (combinedText) 643 if (combinedText)
644 combinedText->adjustTextOrigin(textOrigin, boxRect); 644 combinedText->adjustTextOrigin(textOrigin, boxRect);
645 645
646 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection 646 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
647 // and composition highlights. 647 // and composition highlights.
648 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT extClip && !isPrinting) { 648 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT extClip && !isPrinting) {
649 if (containsComposition) { 649 if (containsComposition) {
650 paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, us eCustomUnderlines); 650 paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, us eCustomUnderlines);
651 } 651 }
652 652
653 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); 653 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true);
654 654
655 if (haveSelection && !useCustomUnderlines) 655 if (haveSelection && !useCustomUnderlines)
656 paintSelection(context, boxOrigin, styleToUse, font, selectionFillCo lor); 656 paintSelection(context, boxOrigin, styleToUse, font, selectionStyle. fillColor);
657 } 657 }
658 658
659 // 2. Now paint the foreground, including text and decorations like underlin e/overline (in quirks mode only). 659 // 2. Now paint the foreground, including text and decorations like underlin e/overline (in quirks mode only).
660 int length = m_len; 660 int length = m_len;
661 int maximumLength; 661 int maximumLength;
662 StringView string; 662 StringView string;
663 if (!combinedText) { 663 if (!combinedText) {
664 string = textRenderer().text().createView(); 664 string = textRenderer().text().createView();
665 if (static_cast<unsigned>(length) != string.length() || m_start) 665 if (static_cast<unsigned>(length) != string.length() || m_start)
666 string.narrow(m_start, length); 666 string.narrow(m_start, length);
(...skipping 30 matching lines...) Expand all
697 // FIXME: Truncate right-to-left text correctly. 697 // FIXME: Truncate right-to-left text correctly.
698 int startOffset = 0; 698 int startOffset = 0;
699 int endOffset = length; 699 int endOffset = length;
700 if (paintSelectedTextSeparately && ePos > sPos) { 700 if (paintSelectedTextSeparately && ePos > sPos) {
701 startOffset = ePos; 701 startOffset = ePos;
702 endOffset = sPos; 702 endOffset = sPos;
703 } 703 }
704 704
705 // For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side 705 // For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side
706 // effect, so only when we know we're stroking, do a save/restore. 706 // effect, so only when we know we're stroking, do a save/restore.
707 GraphicsContextStateSaver stateSaver(*context, textStrokeWidth > 0); 707 GraphicsContextStateSaver stateSaver(*context, textStyle.strokeWidth > 0 );
708 708
709 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok eWidth); 709 updateGraphicsContext(context, textStyle.fillColor, textStyle.strokeColo r, textStyle.strokeWidth);
710 paintTextWithShadows(context, font, textRun, nullAtom, 0, startOffset, e ndOffset, length, textOrigin, boxRect, textShadow, isHorizontal()); 710 paintTextWithShadows(context, font, textRun, nullAtom, 0, startOffset, e ndOffset, length, textOrigin, boxRect, textStyle.shadow, isHorizontal());
711 711
712 if (!emphasisMark.isEmpty()) 712 if (!emphasisMark.isEmpty())
713 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOf fset, endOffset, length, font, emphasisMarkColor, textStrokeColor, textStrokeWid th, textShadow, combinedText, textRun, textOrigin, boxRect, isHorizontal()); 713 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOf fset, endOffset, length, font, textStyle.emphasisMarkColor, textStyle.strokeColo r, textStyle.strokeWidth, textStyle.shadow, combinedText, textRun, textOrigin, b oxRect, isHorizontal());
714 } 714 }
715 715
716 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { 716 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) {
717 // paint only the text that is selected 717 // paint only the text that is selected
718 GraphicsContextStateSaver stateSaver(*context, selectionStrokeWidth > 0) ; 718 GraphicsContextStateSaver stateSaver(*context, selectionStyle.strokeWidt h > 0);
719 719
720 updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth); 720 updateGraphicsContext(context, selectionStyle.fillColor, selectionStyle. strokeColor, selectionStyle.strokeWidth);
721 paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, le ngth, textOrigin, boxRect, selectionShadow, isHorizontal()); 721 paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, le ngth, textOrigin, boxRect, selectionStyle.shadow, isHorizontal());
722 722
723 if (!emphasisMark.isEmpty()) 723 if (!emphasisMark.isEmpty())
724 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, sPos, e Pos, length, font, selectionEmphasisMarkColor, textStrokeColor, textStrokeWidth, selectionShadow, combinedText, textRun, textOrigin, boxRect, isHorizontal()); 724 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, sPos, e Pos, length, font, selectionStyle.emphasisMarkColor, selectionStyle.strokeColor, textStyle.strokeWidth, selectionStyle.shadow, combinedText, textRun, textOrigin , boxRect, isHorizontal());
725 } 725 }
726 726
727 // Paint decorations 727 // Paint decorations
728 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); 728 TextDecoration textDecorations = styleToUse->textDecorationsInEffect();
729 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe lection) { 729 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe lection) {
730 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok eWidth); 730 updateGraphicsContext(context, textStyle.fillColor, textStyle.strokeColo r, textStyle.strokeWidth);
731 if (combinedText) 731 if (combinedText)
732 context->concatCTM(rotation(boxRect, Clockwise)); 732 context->concatCTM(rotation(boxRect, Clockwise));
733 paintDecoration(context, boxOrigin, textDecorations, textShadow); 733 paintDecoration(context, boxOrigin, textDecorations, textStyle.shadow);
734 if (combinedText) 734 if (combinedText)
735 context->concatCTM(rotation(boxRect, Counterclockwise)); 735 context->concatCTM(rotation(boxRect, Counterclockwise));
736 } 736 }
737 737
738 if (paintInfo.phase == PaintPhaseForeground) { 738 if (paintInfo.phase == PaintPhaseForeground) {
739 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); 739 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);
740 740
741 // Paint custom underlines for compositions. 741 // Paint custom underlines for compositions.
742 if (useCustomUnderlines) { 742 if (useCustomUnderlines) {
743 const Vector<CompositionUnderline>& underlines = renderer().frame()- >inputMethodController().customCompositionUnderlines(); 743 const Vector<CompositionUnderline>& underlines = renderer().frame()- >inputMethodController().customCompositionUnderlines();
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); 1552 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj);
1553 const int rendererCharacterOffset = 24; 1553 const int rendererCharacterOffset = 24;
1554 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) 1554 for (; printedCharacters < rendererCharacterOffset; printedCharacters++)
1555 fputc(' ', stderr); 1555 fputc(' ', stderr);
1556 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); 1556 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata());
1557 } 1557 }
1558 1558
1559 #endif 1559 #endif
1560 1560
1561 } // namespace WebCore 1561 } // namespace WebCore
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698