Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 unsigned variables[1]; | 57 unsigned variables[1]; |
| 58 unsigned short variables2[2]; | 58 unsigned short variables2[2]; |
| 59 void* pointers[2]; | 59 void* pointers[2]; |
| 60 }; | 60 }; |
| 61 | 61 |
| 62 COMPILE_ASSERT(sizeof(InlineTextBox) == sizeof(SameSizeAsInlineTextBox), InlineT extBox_should_stay_small); | 62 COMPILE_ASSERT(sizeof(InlineTextBox) == sizeof(SameSizeAsInlineTextBox), InlineT extBox_should_stay_small); |
| 63 | 63 |
| 64 typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap; | 64 typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap; |
| 65 static InlineTextBoxOverflowMap* gTextBoxesWithOverflow; | 65 static InlineTextBoxOverflowMap* gTextBoxesWithOverflow; |
| 66 | 66 |
| 67 typedef WTF::HashMap<const InlineTextBox*, TextBlobPtr> InlineTextBoxBlobCacheMa p; | |
| 68 static InlineTextBoxBlobCacheMap* gTextBlobCache; | |
|
esprehn
2015/01/21 09:58:57
Lets just add a ptr to InlineTextBox. I don't know
abarth-chromium
2015/01/21 19:30:35
It was part of the first CL. I think they were wo
| |
| 69 | |
| 67 static const int misspellingLineThickness = 3; | 70 static const int misspellingLineThickness = 3; |
| 68 | 71 |
| 69 void InlineTextBox::destroy() | 72 void InlineTextBox::destroy() |
| 70 { | 73 { |
| 71 if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow) | 74 if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow) |
| 72 gTextBoxesWithOverflow->remove(this); | 75 gTextBoxesWithOverflow->remove(this); |
| 76 if (gTextBlobCache) | |
| 77 gTextBlobCache->remove(this); | |
| 73 InlineBox::destroy(); | 78 InlineBox::destroy(); |
| 74 } | 79 } |
| 75 | 80 |
| 76 void InlineTextBox::markDirty() | 81 void InlineTextBox::markDirty() |
| 77 { | 82 { |
| 78 m_len = 0; | 83 m_len = 0; |
| 79 m_start = 0; | 84 m_start = 0; |
| 80 InlineBox::markDirty(); | 85 InlineBox::markDirty(); |
| 81 } | 86 } |
| 82 | 87 |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 if (!stateSaver.saved()) | 414 if (!stateSaver.saved()) |
| 410 stateSaver.save(); | 415 stateSaver.save(); |
| 411 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil der::ShadowIgnoresAlpha)); | 416 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil der::ShadowIgnoresAlpha)); |
| 412 } | 417 } |
| 413 } | 418 } |
| 414 | 419 |
| 415 void paintText(GraphicsContext* context, | 420 void paintText(GraphicsContext* context, |
| 416 const Font& font, const TextRun& textRun, | 421 const Font& font, const TextRun& textRun, |
| 417 const AtomicString& emphasisMark, int emphasisMarkOffset, | 422 const AtomicString& emphasisMark, int emphasisMarkOffset, |
| 418 int startOffset, int endOffset, int truncationPoint, | 423 int startOffset, int endOffset, int truncationPoint, |
| 419 const FloatPoint& textOrigin, const FloatRect& boxRect) | 424 const FloatPoint& textOrigin, const FloatRect& boxRect, |
| 425 TextBlobPtr* cachedTextBlob = 0) | |
| 420 { | 426 { |
| 421 TextRunPaintInfo textRunPaintInfo(textRun); | 427 TextRunPaintInfo textRunPaintInfo(textRun); |
| 422 textRunPaintInfo.bounds = boxRect; | 428 textRunPaintInfo.bounds = boxRect; |
| 423 if (startOffset <= endOffset) { | 429 if (startOffset <= endOffset) { |
| 424 textRunPaintInfo.from = startOffset; | 430 textRunPaintInfo.from = startOffset; |
| 425 textRunPaintInfo.to = endOffset; | 431 textRunPaintInfo.to = endOffset; |
| 432 // FIXME: We should be able to use cachedTextBlob in more cases. | |
| 433 textRunPaintInfo.cachedTextBlob = cachedTextBlob; | |
| 426 if (emphasisMark.isEmpty()) | 434 if (emphasisMark.isEmpty()) |
| 427 context->drawText(font, textRunPaintInfo, textOrigin); | 435 context->drawText(font, textRunPaintInfo, textOrigin); |
| 428 else | 436 else |
| 429 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex tOrigin + IntSize(0, emphasisMarkOffset)); | 437 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex tOrigin + IntSize(0, emphasisMarkOffset)); |
| 430 } else { | 438 } else { |
| 431 if (endOffset > 0) { | 439 if (endOffset > 0) { |
| 432 textRunPaintInfo.from = 0; | 440 textRunPaintInfo.from = 0; |
| 433 textRunPaintInfo.to = endOffset; | 441 textRunPaintInfo.to = endOffset; |
| 434 if (emphasisMark.isEmpty()) | 442 if (emphasisMark.isEmpty()) |
| 435 context->drawText(font, textRunPaintInfo, textOrigin); | 443 context->drawText(font, textRunPaintInfo, textOrigin); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 453 const Font& font, const TextRun& textRun, | 461 const Font& font, const TextRun& textRun, |
| 454 const FloatPoint& textOrigin, const FloatRect& boxRect) | 462 const FloatPoint& textOrigin, const FloatRect& boxRect) |
| 455 { | 463 { |
| 456 ASSERT(!emphasisMark.isEmpty()); | 464 ASSERT(!emphasisMark.isEmpty()); |
| 457 paintText(context, font, textRun, emphasisMark, emphasisMarkOffset, startOff set, endOffset, paintRunLength, textOrigin, boxRect); | 465 paintText(context, font, textRun, emphasisMark, emphasisMarkOffset, startOff set, endOffset, paintRunLength, textOrigin, boxRect); |
| 458 } | 466 } |
| 459 | 467 |
| 460 void paintTextWithEmphasisMark( | 468 void paintTextWithEmphasisMark( |
| 461 GraphicsContext* context, const Font& font, const TextPaintingStyle& textSty le, const TextRun& textRun, | 469 GraphicsContext* context, const Font& font, const TextPaintingStyle& textSty le, const TextRun& textRun, |
| 462 const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, i nt endOffset, int length, | 470 const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, i nt endOffset, int length, |
| 463 const FloatPoint& textOrigin, const FloatRect& boxRect) | 471 const FloatPoint& textOrigin, const FloatRect& boxRect, TextBlobPtr* cachedT extBlob = 0) |
| 464 { | 472 { |
| 465 GraphicsContextStateSaver stateSaver(*context, false); | 473 GraphicsContextStateSaver stateSaver(*context, false); |
| 466 updateGraphicsContext(context, textStyle, stateSaver); | 474 updateGraphicsContext(context, textStyle, stateSaver); |
| 467 paintText(context, font, textRun, nullAtom, 0, startOffset, endOffset, lengt h, textOrigin, boxRect); | 475 paintText(context, font, textRun, nullAtom, 0, startOffset, endOffset, lengt h, textOrigin, boxRect, cachedTextBlob); |
| 468 | 476 |
| 469 if (!emphasisMark.isEmpty()) { | 477 if (!emphasisMark.isEmpty()) { |
| 470 if (textStyle.emphasisMarkColor != textStyle.fillColor) | 478 if (textStyle.emphasisMarkColor != textStyle.fillColor) |
| 471 context->setFillColor(textStyle.emphasisMarkColor); | 479 context->setFillColor(textStyle.emphasisMarkColor); |
| 472 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOffset , endOffset, length, font, textRun, textOrigin, boxRect); | 480 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOffset , endOffset, length, font, textRun, textOrigin, boxRect); |
| 473 } | 481 } |
| 474 } | 482 } |
| 475 | 483 |
| 484 TextBlobPtr* addToTextBlobCache(InlineTextBox& inlineTextBox) | |
| 485 { | |
| 486 if (!gTextBlobCache) | |
| 487 gTextBlobCache = new InlineTextBoxBlobCacheMap; | |
| 488 return &gTextBlobCache->add(&inlineTextBox, nullptr).storedValue->value; | |
| 489 } | |
| 490 | |
| 476 } // namespace | 491 } // namespace |
| 477 | 492 |
| 478 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) | 493 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) |
| 479 { | 494 { |
| 480 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) | 495 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) |
| 481 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len) | 496 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len) |
| 482 return; | 497 return; |
| 483 | 498 |
| 484 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines); | 499 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines); |
| 485 | 500 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon tMetrics().descent() + font.emphasisMarkAscent(emphasisMark); | 611 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon tMetrics().descent() + font.emphasisMarkAscent(emphasisMark); |
| 597 | 612 |
| 598 if (!paintSelectedTextOnly) { | 613 if (!paintSelectedTextOnly) { |
| 599 // FIXME: Truncate right-to-left text correctly. | 614 // FIXME: Truncate right-to-left text correctly. |
| 600 int startOffset = 0; | 615 int startOffset = 0; |
| 601 int endOffset = length; | 616 int endOffset = length; |
| 602 if (paintSelectedTextSeparately && ePos > sPos) { | 617 if (paintSelectedTextSeparately && ePos > sPos) { |
| 603 startOffset = ePos; | 618 startOffset = ePos; |
| 604 endOffset = sPos; | 619 endOffset = sPos; |
| 605 } | 620 } |
| 606 paintTextWithEmphasisMark(context, font, textStyle, textRun, emphasisMar k, emphasisMarkOffset, startOffset, endOffset, length, textOrigin, boxRect); | 621 // FIXME: This cache should probably ultimately be held somewhere else. |
| 622 // A hashmap is convenient to avoid a memory hit when the | |
| 623 // RuntimeEnabledFeature is off. | |
| 624 bool textBlobIsCacheable = RuntimeEnabledFeatures::textBlobEnabled() && startOffset == 0 && endOffset == length; | |
| 625 TextBlobPtr* cachedTextBlob = 0; | |
| 626 if (textBlobIsCacheable) | |
| 627 cachedTextBlob = addToTextBlobCache(*this); | |
| 628 paintTextWithEmphasisMark(context, font, textStyle, textRun, emphasisMar k, emphasisMarkOffset, startOffset, endOffset, length, textOrigin, boxRect, cach edTextBlob); | |
| 607 } | 629 } |
| 608 | 630 |
| 609 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { | 631 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { |
| 610 // paint only the text that is selected | 632 // paint only the text that is selected |
| 611 paintTextWithEmphasisMark(context, font, selectionStyle, textRun, emphas isMark, emphasisMarkOffset, sPos, ePos, length, textOrigin, boxRect); | 633 bool textBlobIsCacheable = RuntimeEnabledFeatures::textBlobEnabled() && sPos == 0 && ePos == length; |
| 634 TextBlobPtr* cachedTextBlob = 0; | |
| 635 if (textBlobIsCacheable) | |
| 636 cachedTextBlob = addToTextBlobCache(*this); | |
| 637 paintTextWithEmphasisMark(context, font, selectionStyle, textRun, emphas isMark, emphasisMarkOffset, sPos, ePos, length, textOrigin, boxRect, cachedTextB lob); | |
| 612 } | 638 } |
| 613 | 639 |
| 614 // Paint decorations | 640 // Paint decorations |
| 615 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); | 641 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); |
| 616 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) { | 642 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) { |
| 617 GraphicsContextStateSaver stateSaver(*context, false); | 643 GraphicsContextStateSaver stateSaver(*context, false); |
| 618 updateGraphicsContext(context, textStyle, stateSaver); | 644 updateGraphicsContext(context, textStyle, stateSaver); |
| 619 paintDecoration(context, boxOrigin, textDecorations); | 645 paintDecoration(context, boxOrigin, textDecorations); |
| 620 } | 646 } |
| 621 | 647 |
| (...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1339 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 1365 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
| 1340 const int rendererCharacterOffset = 24; | 1366 const int rendererCharacterOffset = 24; |
| 1341 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1367 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
| 1342 fputc(' ', stderr); | 1368 fputc(' ', stderr); |
| 1343 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); | 1369 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); |
| 1344 } | 1370 } |
| 1345 | 1371 |
| 1346 #endif | 1372 #endif |
| 1347 | 1373 |
| 1348 } // namespace blink | 1374 } // namespace blink |
| OLD | NEW |