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

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

Issue 472083002: Move the shadows out of paintTextWithShadows. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 4 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/rendering/InlineTextBox.h ('k') | 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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 return -1; 322 return -1;
323 } 323 }
324 324
325 static Color textColorForWhiteBackground(Color textColor) 325 static Color textColorForWhiteBackground(Color textColor)
326 { 326 {
327 int distanceFromWhite = differenceSquared(textColor, Color::white); 327 int distanceFromWhite = differenceSquared(textColor, Color::white);
328 // semi-arbitrarily chose 65025 (255^2) value here after a few tests; 328 // semi-arbitrarily chose 65025 (255^2) value here after a few tests;
329 return distanceFromWhite > 65025 ? textColor : textColor.dark(); 329 return distanceFromWhite > 65025 ? textColor : textColor.dark();
330 } 330 }
331 331
332 static void updateGraphicsContext(GraphicsContext* context, const Color& fillCol or, const Color& strokeColor, float strokeThickness)
333 {
334 TextDrawingModeFlags mode = context->textDrawingMode();
335 if (strokeThickness > 0) {
336 TextDrawingModeFlags newMode = mode | TextModeStroke;
337 if (mode != newMode) {
338 context->setTextDrawingMode(newMode);
339 mode = newMode;
340 }
341 }
342
343 if (mode & TextModeFill && fillColor != context->fillColor())
344 context->setFillColor(fillColor);
345
346 if (mode & TextModeStroke) {
347 if (strokeColor != context->strokeColor())
348 context->setStrokeColor(strokeColor);
349 if (strokeThickness != context->strokeThickness())
350 context->setStrokeThickness(strokeThickness);
351 }
352 }
353
354 bool InlineTextBox::isLineBreak() const 332 bool InlineTextBox::isLineBreak() const
355 { 333 {
356 return renderer().isBR() || (renderer().style()->preserveNewline() && len() == 1 && (*renderer().text().impl())[start()] == '\n'); 334 return renderer().isBR() || (renderer().style()->preserveNewline() && len() == 1 && (*renderer().text().impl())[start()] == '\n');
357 } 335 }
358 336
359 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) 337 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
360 { 338 {
361 if (isLineBreak()) 339 if (isLineBreak())
362 return false; 340 return false;
363 341
364 FloatPoint boxOrigin = locationIncludingFlipping(); 342 FloatPoint boxOrigin = locationIncludingFlipping();
365 boxOrigin.moveBy(accumulatedOffset); 343 boxOrigin.moveBy(accumulatedOffset);
366 FloatRect rect(boxOrigin, size()); 344 FloatRect rect(boxOrigin, size());
367 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l ocationInContainer.intersects(rect)) { 345 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l ocationInContainer.intersects(rect)) {
368 renderer().updateHitTestResult(result, flipForWritingMode(locationInCont ainer.point() - toLayoutSize(accumulatedOffset))); 346 renderer().updateHitTestResult(result, flipForWritingMode(locationInCont ainer.point() - toLayoutSize(accumulatedOffset)));
369 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc ationInContainer, rect)) 347 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc ationInContainer, rect))
370 return true; 348 return true;
371 } 349 }
372 return false; 350 return false;
373 } 351 }
374 352
375 static void paintTextWithShadows(GraphicsContext* context, 353 static void paintText(GraphicsContext* context,
376 const Font& font, const TextRun& textRun, 354 const Font& font, const TextRun& textRun,
377 const AtomicString& emphasisMark, int emphasisMarkOffset, 355 const AtomicString& emphasisMark, int emphasisMarkOffset,
378 int startOffset, int endOffset, int truncationPoint, 356 int startOffset, int endOffset, int truncationPoint,
379 const FloatPoint& textOrigin, const FloatRect& boxRect, 357 const FloatPoint& textOrigin, const FloatRect& boxRect)
380 const ShadowList* shadowList, bool horizontal)
381 { 358 {
382 // Text shadows are disabled when printing. http://crbug.com/258321
383 bool hasShadow = shadowList && !context->printing();
384 if (hasShadow)
385 context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::S hadowIgnoresAlpha, horizontal));
386
387 TextRunPaintInfo textRunPaintInfo(textRun); 359 TextRunPaintInfo textRunPaintInfo(textRun);
388 textRunPaintInfo.bounds = boxRect; 360 textRunPaintInfo.bounds = boxRect;
389 if (startOffset <= endOffset) { 361 if (startOffset <= endOffset) {
390 textRunPaintInfo.from = startOffset; 362 textRunPaintInfo.from = startOffset;
391 textRunPaintInfo.to = endOffset; 363 textRunPaintInfo.to = endOffset;
392 if (emphasisMark.isEmpty()) 364 if (emphasisMark.isEmpty())
393 context->drawText(font, textRunPaintInfo, textOrigin); 365 context->drawText(font, textRunPaintInfo, textOrigin);
394 else 366 else
395 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex tOrigin + IntSize(0, emphasisMarkOffset)); 367 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex tOrigin + IntSize(0, emphasisMarkOffset));
396 } else { 368 } else {
397 if (endOffset > 0) { 369 if (endOffset > 0) {
398 textRunPaintInfo.from = 0; 370 textRunPaintInfo.from = 0;
399 textRunPaintInfo.to = endOffset; 371 textRunPaintInfo.to = endOffset;
400 if (emphasisMark.isEmpty()) 372 if (emphasisMark.isEmpty())
401 context->drawText(font, textRunPaintInfo, textOrigin); 373 context->drawText(font, textRunPaintInfo, textOrigin);
402 else 374 else
403 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset)); 375 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset));
404 } 376 }
405 if (startOffset < truncationPoint) { 377 if (startOffset < truncationPoint) {
406 textRunPaintInfo.from = startOffset; 378 textRunPaintInfo.from = startOffset;
407 textRunPaintInfo.to = truncationPoint; 379 textRunPaintInfo.to = truncationPoint;
408 if (emphasisMark.isEmpty()) 380 if (emphasisMark.isEmpty())
409 context->drawText(font, textRunPaintInfo, textOrigin); 381 context->drawText(font, textRunPaintInfo, textOrigin);
410 else 382 else
411 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset)); 383 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset));
412 } 384 }
413 } 385 }
414
415 if (hasShadow)
416 context->clearDrawLooper();
417 } 386 }
418 387
419 static void paintEmphasisMark(GraphicsContext* context, 388 static void paintEmphasisMark(GraphicsContext* context,
420 const AtomicString& emphasisMark, int emphasisMarkOffset, 389 const AtomicString& emphasisMark, int emphasisMarkOffset,
421 int startOffset, int endOffset, int paintRunLength, 390 int startOffset, int endOffset, int paintRunLength,
422 const Font& font, Color emphasisMarkColor, Color textStrokeColor, float text StrokeWidth, const ShadowList* textShadow, 391 const Font& font, RenderCombineText* combinedText, const TextRun& textRun,
423 RenderCombineText* combinedText, const TextRun& textRun, 392 const FloatPoint& textOrigin, const FloatRect& boxRect)
424 const FloatPoint& textOrigin, const FloatRect& boxRect, bool horizontal)
425 { 393 {
426 ASSERT(!emphasisMark.isEmpty()); 394 ASSERT(!emphasisMark.isEmpty());
427 updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, textStrok eWidth);
428 395
429 if (combinedText) { 396 if (combinedText) {
430 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&object ReplacementCharacter, 1)); 397 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&object ReplacementCharacter, 1));
431 FloatPoint emphasisMarkTextOrigin(boxRect.x() + boxRect.width() / 2, box Rect.y() + font.fontMetrics().ascent()); 398 FloatPoint emphasisMarkTextOrigin(boxRect.x() + boxRect.width() / 2, box Rect.y() + font.fontMetrics().ascent());
432 context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clock wise)); 399 context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clock wise));
433 paintTextWithShadows(context, combinedText->originalFont(), objectReplac ementCharacterTextRun, emphasisMark, emphasisMarkOffset, 0, 1, 1, emphasisMarkTe xtOrigin, boxRect, textShadow, horizontal); 400 paintText(context, combinedText->originalFont(), objectReplacementCharac terTextRun, emphasisMark, emphasisMarkOffset, 0, 1, 1, emphasisMarkTextOrigin, b oxRect);
434 context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Count erclockwise)); 401 context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Count erclockwise));
435 } else { 402 } else {
436 paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkO ffset, startOffset, endOffset, paintRunLength, textOrigin, boxRect, textShadow, horizontal); 403 paintText(context, font, textRun, emphasisMark, emphasisMarkOffset, star tOffset, endOffset, paintRunLength, textOrigin, boxRect);
437 } 404 }
438 } 405 }
439 406
440 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi tion& emphasisPosition) const 407 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi tion& emphasisPosition) const
441 { 408 {
442 // This function returns true if there are text emphasis marks and they are suppressed by ruby text. 409 // This function returns true if there are text emphasis marks and they are suppressed by ruby text.
443 if (style->textEmphasisMark() == TextEmphasisMarkNone) 410 if (style->textEmphasisMark() == TextEmphasisMarkNone)
444 return false; 411 return false;
445 412
446 emphasisPosition = style->textEmphasisPosition(); 413 emphasisPosition = style->textEmphasisPosition();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 // Text shadows are disabled when printing. http://crbug.com/258321 505 // Text shadows are disabled when printing. http://crbug.com/258321
539 if (isPrinting) 506 if (isPrinting)
540 selectionStyle.shadow = 0; 507 selectionStyle.shadow = 0;
541 } 508 }
542 509
543 return selectionStyle; 510 return selectionStyle;
544 } 511 }
545 512
546 } // namespace 513 } // namespace
547 514
515 static void updateGraphicsContext(GraphicsContext* context, const TextPaintingSt yle& textStyle, bool horizontal, GraphicsContextStateSaver* stateSaver = 0)
f(malita) 2014/08/20 18:55:45 Nit: this could live in the anonymous namespace ab
jbroman 2014/08/20 19:32:25 Okay. At this point, I might as well push paintTex
516 {
517 TextDrawingModeFlags mode = context->textDrawingMode();
518 if (textStyle.strokeWidth > 0) {
519 if (stateSaver) {
f(malita) 2014/08/20 18:55:46 Can we skip this when mode == newMode (move it ins
jbroman 2014/08/20 19:32:25 Done.
520 stateSaver->save();
521 stateSaver = 0;
522 }
523
524 TextDrawingModeFlags newMode = mode | TextModeStroke;
525 if (mode != newMode) {
526 context->setTextDrawingMode(newMode);
527 mode = newMode;
528 }
529 }
530
531 if (mode & TextModeFill && textStyle.fillColor != context->fillColor())
532 context->setFillColor(textStyle.fillColor);
533
534 if (mode & TextModeStroke) {
535 if (textStyle.strokeColor != context->strokeColor())
536 context->setStrokeColor(textStyle.strokeColor);
537 if (textStyle.strokeWidth != context->strokeThickness())
538 context->setStrokeThickness(textStyle.strokeWidth);
539 }
540
541 // Text shadows are disabled when printing. http://crbug.com/258321
542 if (textStyle.shadow && !context->printing()) {
543 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil der::ShadowIgnoresAlpha, horizontal));
544 if (stateSaver) {
545 stateSaver->save();
f(malita) 2014/08/20 18:55:46 We should save before touching the looper.
jbroman 2014/08/20 19:32:25 Err, yes, of course. Hazard of "p" and "P" being s
546 stateSaver = 0;
547 }
548 }
549 }
550
551 static void paintTextWithEmphasisMark(
552 GraphicsContext* context, const Font& font, const TextPaintingStyle& textSty le, const TextRun& textRun,
553 const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, i nt endOffset, int length,
554 RenderCombineText* combinedText, const FloatPoint& textOrigin, const FloatRe ct& boxRect, bool horizontal)
555 {
556 GraphicsContextStateSaver stateSaver(*context, false);
557 updateGraphicsContext(context, textStyle, horizontal, &stateSaver);
558 paintText(context, font, textRun, nullAtom, 0, startOffset, endOffset, lengt h, textOrigin, boxRect);
559
560 if (!emphasisMark.isEmpty()) {
561 if (textStyle.emphasisMarkColor != textStyle.fillColor)
562 context->setFillColor(textStyle.emphasisMarkColor);
563 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOffset , endOffset, length, font, combinedText, textRun, textOrigin, boxRect);
564 }
565 }
566
548 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) 567 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
549 { 568 {
550 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || render er().style()->visibility() != VISIBLE 569 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || render er().style()->visibility() != VISIBLE
551 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len) 570 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len)
552 return; 571 return;
553 572
554 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines); 573 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines);
555 574
556 LayoutRect logicalVisualOverflow = logicalOverflowRect(); 575 LayoutRect logicalVisualOverflow = logicalOverflowRect();
557 LayoutUnit logicalStart = logicalVisualOverflow.x() + (isHorizontal() ? pain tOffset.x() : paintOffset.y()); 576 LayoutUnit logicalStart = logicalVisualOverflow.x() + (isHorizontal() ? pain tOffset.x() : paintOffset.y());
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon tMetrics().descent() + font.emphasisMarkAscent(emphasisMark); 699 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon tMetrics().descent() + font.emphasisMarkAscent(emphasisMark);
681 700
682 if (!paintSelectedTextOnly) { 701 if (!paintSelectedTextOnly) {
683 // FIXME: Truncate right-to-left text correctly. 702 // FIXME: Truncate right-to-left text correctly.
684 int startOffset = 0; 703 int startOffset = 0;
685 int endOffset = length; 704 int endOffset = length;
686 if (paintSelectedTextSeparately && ePos > sPos) { 705 if (paintSelectedTextSeparately && ePos > sPos) {
687 startOffset = ePos; 706 startOffset = ePos;
688 endOffset = sPos; 707 endOffset = sPos;
689 } 708 }
690 709 paintTextWithEmphasisMark(context, font, textStyle, textRun, emphasisMar k, emphasisMarkOffset, startOffset, endOffset, length, combinedText, textOrigin, boxRect, isHorizontal());
691 // For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side
692 // effect, so only when we know we're stroking, do a save/restore.
693 GraphicsContextStateSaver stateSaver(*context, textStyle.strokeWidth > 0 );
694
695 updateGraphicsContext(context, textStyle.fillColor, textStyle.strokeColo r, textStyle.strokeWidth);
696 paintTextWithShadows(context, font, textRun, nullAtom, 0, startOffset, e ndOffset, length, textOrigin, boxRect, textStyle.shadow, isHorizontal());
697
698 if (!emphasisMark.isEmpty())
699 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOf fset, endOffset, length, font, textStyle.emphasisMarkColor, textStyle.strokeColo r, textStyle.strokeWidth, textStyle.shadow, combinedText, textRun, textOrigin, b oxRect, isHorizontal());
700 } 710 }
701 711
702 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { 712 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) {
703 // paint only the text that is selected 713 // paint only the text that is selected
704 GraphicsContextStateSaver stateSaver(*context, selectionStyle.strokeWidt h > 0); 714 paintTextWithEmphasisMark(context, font, selectionStyle, textRun, emphas isMark, emphasisMarkOffset, sPos, ePos, length, combinedText, textOrigin, boxRec t, isHorizontal());
705
706 updateGraphicsContext(context, selectionStyle.fillColor, selectionStyle. strokeColor, selectionStyle.strokeWidth);
707 paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, le ngth, textOrigin, boxRect, selectionStyle.shadow, isHorizontal());
708
709 if (!emphasisMark.isEmpty())
710 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, sPos, e Pos, length, font, selectionStyle.emphasisMarkColor, selectionStyle.strokeColor, textStyle.strokeWidth, selectionStyle.shadow, combinedText, textRun, textOrigin , boxRect, isHorizontal());
711 } 715 }
712 716
713 // Paint decorations 717 // Paint decorations
714 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); 718 TextDecoration textDecorations = styleToUse->textDecorationsInEffect();
715 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe lection) { 719 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) {
716 updateGraphicsContext(context, textStyle.fillColor, textStyle.strokeColo r, textStyle.strokeWidth); 720 GraphicsContextStateSaver stateSaver(*context);
f(malita) 2014/08/20 18:55:45 Can't this save be deferred also? Why weren't we s
jbroman 2014/08/20 19:32:24 In the combinedText case, there's also the CTM rot
721 updateGraphicsContext(context, textStyle, isHorizontal());
717 if (combinedText) 722 if (combinedText)
718 context->concatCTM(rotation(boxRect, Clockwise)); 723 context->concatCTM(rotation(boxRect, Clockwise));
719 paintDecoration(context, boxOrigin, textDecorations, textStyle.shadow); 724 paintDecoration(context, boxOrigin, textDecorations);
720 if (combinedText)
721 context->concatCTM(rotation(boxRect, Counterclockwise));
722 } 725 }
723 726
724 if (paintInfo.phase == PaintPhaseForeground) { 727 if (paintInfo.phase == PaintPhaseForeground) {
725 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); 728 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);
726 729
727 // Paint custom underlines for compositions. 730 // Paint custom underlines for compositions.
728 if (useCustomUnderlines) { 731 if (useCustomUnderlines) {
729 const Vector<CompositionUnderline>& underlines = renderer().frame()- >inputMethodController().customCompositionUnderlines(); 732 const Vector<CompositionUnderline>& underlines = renderer().frame()- >inputMethodController().customCompositionUnderlines();
730 CompositionUnderlineRangeFilter filter(underlines, start(), end()); 733 CompositionUnderlineRangeFilter filter(underlines, start(), end());
731 for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begi n(); it != filter.end(); ++it) { 734 for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begi n(); it != filter.end(); ++it) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 771
769 Color c = renderer().selectionBackgroundColor(); 772 Color c = renderer().selectionBackgroundColor();
770 if (!c.alpha()) 773 if (!c.alpha())
771 return; 774 return;
772 775
773 // If the text color ends up being the same as the selection background, inv ert the selection 776 // If the text color ends up being the same as the selection background, inv ert the selection
774 // background. 777 // background.
775 if (textColor == c) 778 if (textColor == c)
776 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); 779 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
777 780
778
779 // If the text is truncated, let the thing being painted in the truncation 781 // If the text is truncated, let the thing being painted in the truncation
780 // draw its own highlight. 782 // draw its own highlight.
781 int length = m_truncation != cNoTruncation ? m_truncation : m_len; 783 int length = m_truncation != cNoTruncation ? m_truncation : m_len;
782 StringView string = renderer().text().createView(); 784 StringView string = renderer().text().createView();
783 785
784 if (string.length() != static_cast<unsigned>(length) || m_start) 786 if (string.length() != static_cast<unsigned>(length) || m_start)
785 string.narrow(m_start, length); 787 string.narrow(m_start, length);
786 788
787 StringBuilder charactersWithHyphen; 789 StringBuilder charactersWithHyphen;
788 bool respectHyphen = ePos == length && hasHyphen(); 790 bool respectHyphen = ePos == length && hasHyphen();
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 context->setShouldAntialias(antialiasDecoration); 1037 context->setShouldAntialias(antialiasDecoration);
1036 // Fall through 1038 // Fall through
1037 default: 1039 default:
1038 context->drawLineForText(start, width, isPrinting); 1040 context->drawLineForText(start, width, isPrinting);
1039 1041
1040 if (decoration.style == TextDecorationStyleDouble) 1042 if (decoration.style == TextDecorationStyleDouble)
1041 context->drawLineForText(start + FloatPoint(0, doubleOffset), width, isPrinting); 1043 context->drawLineForText(start + FloatPoint(0, doubleOffset), width, isPrinting);
1042 } 1044 }
1043 } 1045 }
1044 1046
1045 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, const ShadowList* shadowList) 1047 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco)
1046 { 1048 {
1047 GraphicsContextStateSaver stateSaver(*context); 1049 GraphicsContextStateSaver stateSaver(*context);
1048 1050
1049 if (m_truncation == cFullTruncation) 1051 if (m_truncation == cFullTruncation)
1050 return; 1052 return;
1051 1053
1052 FloatPoint localOrigin = boxOrigin; 1054 FloatPoint localOrigin = boxOrigin;
1053 1055
1054 float width = m_logicalWidth; 1056 float width = m_logicalWidth;
1055 if (m_truncation != cNoTruncation) { 1057 if (m_truncation != cNoTruncation) {
1056 width = renderer().width(m_start, m_truncation, textPos(), isLeftToRight Direction() ? LTR : RTL, isFirstLineStyle()); 1058 width = renderer().width(m_start, m_truncation, textPos(), isLeftToRight Direction() ? LTR : RTL, isFirstLineStyle());
1057 if (!isLeftToRightDirection()) 1059 if (!isLeftToRightDirection())
1058 localOrigin.move(m_logicalWidth - width, 0); 1060 localOrigin.move(m_logicalWidth - width, 0);
1059 } 1061 }
1060 1062
1061 // Get the text decoration colors. 1063 // Get the text decoration colors.
1062 RenderObject::AppliedTextDecoration underline, overline, linethrough; 1064 RenderObject::AppliedTextDecoration underline, overline, linethrough;
1063
1064 renderer().getTextDecorations(deco, underline, overline, linethrough, true); 1065 renderer().getTextDecorations(deco, underline, overline, linethrough, true);
1065 if (isFirstLineStyle()) 1066 if (isFirstLineStyle())
1066 renderer().getTextDecorations(deco, underline, overline, linethrough, tr ue, true); 1067 renderer().getTextDecorations(deco, underline, overline, linethrough, tr ue, true);
1067 1068
1068 // Use a special function for underlines to get the positioning exactly righ t. 1069 // Use a special function for underlines to get the positioning exactly righ t.
1069 bool isPrinting = renderer().document().printing(); 1070 bool isPrinting = renderer().document().printing();
1070 1071
1071 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u nderline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline. color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.col or.alpha() == 255);
1072
1073 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); 1072 RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
1074 int baseline = styleToUse->fontMetrics().ascent(); 1073 int baseline = styleToUse->fontMetrics().ascent();
1075 1074
1076 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0;
1077 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px. 1075 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px.
1078 // Using computedFontSize should take care of zoom as well. 1076 // Using computedFontSize should take care of zoom as well.
1079 1077
1080 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method. 1078 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method.
1081 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness (); 1079 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness ();
1082 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); 1080 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5);
1083 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1))) 1081 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1)))
1084 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); 1082 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f);
1085 1083
1086 context->setStrokeThickness(textDecorationThickness); 1084 context->setStrokeThickness(textDecorationThickness);
1087 1085
1088 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde rline.style, linethrough.style) 1086 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde rline.style, linethrough.style)
1089 && RenderBoxModelObject::shouldAntialiasLines(context); 1087 && RenderBoxModelObject::shouldAntialiasLines(context);
1090 1088
1091 float extraOffset = 0; 1089 // Offset between lines - always non-zero, so lines never cross each other.
1092 if (!linesAreOpaque && shadowCount > 1) { 1090 float doubleOffset = textDecorationThickness + 1.f;
1093 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); 1091
1094 for (size_t i = shadowCount; i--; ) { 1092 if (deco & TextDecorationUnderline) {
1095 const ShadowData& s = shadowList->shadows()[i]; 1093 const int underlineOffset = computeUnderlineOffset(styleToUse->textUnder linePosition(), styleToUse->fontMetrics(), this, textDecorationThickness);
1096 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); 1094 paintAppliedDecoration(context, localOrigin + FloatPoint(0, underlineOff set), width, doubleOffset, 1, underline, textDecorationThickness, antialiasDecor ation, isPrinting);
1097 shadowRect.inflate(s.blur());
1098 float shadowX = isHorizontal() ? s.x() : s.y();
1099 float shadowY = isHorizontal() ? s.y() : -s.x();
1100 shadowRect.move(shadowX, shadowY);
1101 clipRect.unite(shadowRect);
1102 extraOffset = std::max(extraOffset, std::max(0.0f, shadowY) + s.blur ());
1103 }
1104 context->clip(clipRect);
1105 extraOffset += baseline + 2;
1106 localOrigin.move(0, extraOffset);
1107 } 1095 }
1108 1096 if (deco & TextDecorationOverline) {
1109 for (size_t i = std::max(static_cast<size_t>(1), shadowCount); i--; ) { 1097 paintAppliedDecoration(context, localOrigin, width, -doubleOffset, 1, ov erline, textDecorationThickness, antialiasDecoration, isPrinting);
1110 // Even if we have no shadows, we still want to run the code below this once. 1098 }
1111 if (i < shadowCount) { 1099 if (deco & TextDecorationLineThrough) {
1112 if (!i) { 1100 const float lineThroughOffset = 2 * baseline / 3;
1113 // The last set of lines paints normally inside the clip. 1101 paintAppliedDecoration(context, localOrigin + FloatPoint(0, lineThroughO ffset), width, doubleOffset, 0, linethrough, textDecorationThickness, antialiasD ecoration, isPrinting);
1114 localOrigin.move(0, -extraOffset);
1115 extraOffset = 0;
1116 }
1117 const ShadowData& shadow = shadowList->shadows()[i];
1118 float shadowX = isHorizontal() ? shadow.x() : shadow.y();
1119 float shadowY = isHorizontal() ? shadow.y() : -shadow.x();
1120 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow .blur(), shadow.color());
1121 }
1122
1123 // Offset between lines - always non-zero, so lines never cross each oth er.
1124 float doubleOffset = textDecorationThickness + 1.f;
1125
1126 if (deco & TextDecorationUnderline) {
1127 const int underlineOffset = computeUnderlineOffset(styleToUse->textU nderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness);
1128 paintAppliedDecoration(context, localOrigin + FloatPoint(0, underlin eOffset), width, doubleOffset, 1, underline, textDecorationThickness, antialiasD ecoration, isPrinting);
1129 }
1130 if (deco & TextDecorationOverline) {
1131 paintAppliedDecoration(context, localOrigin, width, -doubleOffset, 1 , overline, textDecorationThickness, antialiasDecoration, isPrinting);
1132 }
1133 if (deco & TextDecorationLineThrough) {
1134 const float lineThroughOffset = 2 * baseline / 3;
1135 paintAppliedDecoration(context, localOrigin + FloatPoint(0, lineThro ughOffset), width, doubleOffset, 0, linethrough, textDecorationThickness, antial iasDecoration, isPrinting);
1136 }
1137 } 1102 }
1138 } 1103 }
1139 1104
1140 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM arker::MarkerType markerType) 1105 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM arker::MarkerType markerType)
1141 { 1106 {
1142 switch (markerType) { 1107 switch (markerType) {
1143 case DocumentMarker::Spelling: 1108 case DocumentMarker::Spelling:
1144 return GraphicsContext::DocumentMarkerSpellingLineStyle; 1109 return GraphicsContext::DocumentMarkerSpellingLineStyle;
1145 case DocumentMarker::Grammar: 1110 case DocumentMarker::Grammar:
1146 return GraphicsContext::DocumentMarkerGrammarLineStyle; 1111 return GraphicsContext::DocumentMarkerGrammarLineStyle;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); 1485 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj);
1521 const int rendererCharacterOffset = 24; 1486 const int rendererCharacterOffset = 24;
1522 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) 1487 for (; printedCharacters < rendererCharacterOffset; printedCharacters++)
1523 fputc(' ', stderr); 1488 fputc(' ', stderr);
1524 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); 1489 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata());
1525 } 1490 }
1526 1491
1527 #endif 1492 #endif
1528 1493
1529 } // namespace blink 1494 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/rendering/InlineTextBox.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698