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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #include "sky/engine/wtf/text/CString.h" | 49 #include "sky/engine/wtf/text/CString.h" |
50 #include "sky/engine/wtf/text/StringBuilder.h" | 50 #include "sky/engine/wtf/text/StringBuilder.h" |
51 | 51 |
52 #include <algorithm> | 52 #include <algorithm> |
53 | 53 |
54 namespace blink { | 54 namespace blink { |
55 | 55 |
56 struct SameSizeAsInlineTextBox : public InlineBox { | 56 struct SameSizeAsInlineTextBox : public InlineBox { |
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[3]; |
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 static const int misspellingLineThickness = 3; | 67 static const int misspellingLineThickness = 3; |
68 | 68 |
69 void InlineTextBox::destroy() | 69 void InlineTextBox::destroy() |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 if (!stateSaver.saved()) | 409 if (!stateSaver.saved()) |
410 stateSaver.save(); | 410 stateSaver.save(); |
411 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil
der::ShadowIgnoresAlpha)); | 411 context->setDrawLooper(textStyle.shadow->createDrawLooper(DrawLooperBuil
der::ShadowIgnoresAlpha)); |
412 } | 412 } |
413 } | 413 } |
414 | 414 |
415 void paintText(GraphicsContext* context, | 415 void paintText(GraphicsContext* context, |
416 const Font& font, const TextRun& textRun, | 416 const Font& font, const TextRun& textRun, |
417 const AtomicString& emphasisMark, int emphasisMarkOffset, | 417 const AtomicString& emphasisMark, int emphasisMarkOffset, |
418 int startOffset, int endOffset, int truncationPoint, | 418 int startOffset, int endOffset, int truncationPoint, |
419 const FloatPoint& textOrigin, const FloatRect& boxRect) | 419 const FloatPoint& textOrigin, const FloatRect& boxRect, |
| 420 TextBlobPtr* cachedTextBlob = 0) |
420 { | 421 { |
421 TextRunPaintInfo textRunPaintInfo(textRun); | 422 TextRunPaintInfo textRunPaintInfo(textRun); |
422 textRunPaintInfo.bounds = boxRect; | 423 textRunPaintInfo.bounds = boxRect; |
423 if (startOffset <= endOffset) { | 424 if (startOffset <= endOffset) { |
424 textRunPaintInfo.from = startOffset; | 425 textRunPaintInfo.from = startOffset; |
425 textRunPaintInfo.to = endOffset; | 426 textRunPaintInfo.to = endOffset; |
| 427 // FIXME: We should be able to use cachedTextBlob in more cases. |
| 428 textRunPaintInfo.cachedTextBlob = cachedTextBlob; |
426 if (emphasisMark.isEmpty()) | 429 if (emphasisMark.isEmpty()) |
427 context->drawText(font, textRunPaintInfo, textOrigin); | 430 context->drawText(font, textRunPaintInfo, textOrigin); |
428 else | 431 else |
429 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex
tOrigin + IntSize(0, emphasisMarkOffset)); | 432 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex
tOrigin + IntSize(0, emphasisMarkOffset)); |
430 } else { | 433 } else { |
431 if (endOffset > 0) { | 434 if (endOffset > 0) { |
432 textRunPaintInfo.from = 0; | 435 textRunPaintInfo.from = 0; |
433 textRunPaintInfo.to = endOffset; | 436 textRunPaintInfo.to = endOffset; |
434 if (emphasisMark.isEmpty()) | 437 if (emphasisMark.isEmpty()) |
435 context->drawText(font, textRunPaintInfo, textOrigin); | 438 context->drawText(font, textRunPaintInfo, textOrigin); |
(...skipping 17 matching lines...) Expand all Loading... |
453 const Font& font, const TextRun& textRun, | 456 const Font& font, const TextRun& textRun, |
454 const FloatPoint& textOrigin, const FloatRect& boxRect) | 457 const FloatPoint& textOrigin, const FloatRect& boxRect) |
455 { | 458 { |
456 ASSERT(!emphasisMark.isEmpty()); | 459 ASSERT(!emphasisMark.isEmpty()); |
457 paintText(context, font, textRun, emphasisMark, emphasisMarkOffset, startOff
set, endOffset, paintRunLength, textOrigin, boxRect); | 460 paintText(context, font, textRun, emphasisMark, emphasisMarkOffset, startOff
set, endOffset, paintRunLength, textOrigin, boxRect); |
458 } | 461 } |
459 | 462 |
460 void paintTextWithEmphasisMark( | 463 void paintTextWithEmphasisMark( |
461 GraphicsContext* context, const Font& font, const TextPaintingStyle& textSty
le, const TextRun& textRun, | 464 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, | 465 const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, i
nt endOffset, int length, |
463 const FloatPoint& textOrigin, const FloatRect& boxRect) | 466 const FloatPoint& textOrigin, const FloatRect& boxRect, TextBlobPtr* cachedT
extBlob = 0) |
464 { | 467 { |
465 GraphicsContextStateSaver stateSaver(*context, false); | 468 GraphicsContextStateSaver stateSaver(*context, false); |
466 updateGraphicsContext(context, textStyle, stateSaver); | 469 updateGraphicsContext(context, textStyle, stateSaver); |
467 paintText(context, font, textRun, nullAtom, 0, startOffset, endOffset, lengt
h, textOrigin, boxRect); | 470 paintText(context, font, textRun, nullAtom, 0, startOffset, endOffset, lengt
h, textOrigin, boxRect, cachedTextBlob); |
468 | 471 |
469 if (!emphasisMark.isEmpty()) { | 472 if (!emphasisMark.isEmpty()) { |
470 if (textStyle.emphasisMarkColor != textStyle.fillColor) | 473 if (textStyle.emphasisMarkColor != textStyle.fillColor) |
471 context->setFillColor(textStyle.emphasisMarkColor); | 474 context->setFillColor(textStyle.emphasisMarkColor); |
472 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOffset
, endOffset, length, font, textRun, textOrigin, boxRect); | 475 paintEmphasisMark(context, emphasisMark, emphasisMarkOffset, startOffset
, endOffset, length, font, textRun, textOrigin, boxRect); |
473 } | 476 } |
474 } | 477 } |
475 | 478 |
476 } // namespace | 479 } // namespace |
477 | 480 |
(...skipping 118 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); | 599 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ?
-font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon
tMetrics().descent() + font.emphasisMarkAscent(emphasisMark); |
597 | 600 |
598 if (!paintSelectedTextOnly) { | 601 if (!paintSelectedTextOnly) { |
599 // FIXME: Truncate right-to-left text correctly. | 602 // FIXME: Truncate right-to-left text correctly. |
600 int startOffset = 0; | 603 int startOffset = 0; |
601 int endOffset = length; | 604 int endOffset = length; |
602 if (paintSelectedTextSeparately && ePos > sPos) { | 605 if (paintSelectedTextSeparately && ePos > sPos) { |
603 startOffset = ePos; | 606 startOffset = ePos; |
604 endOffset = sPos; | 607 endOffset = sPos; |
605 } | 608 } |
606 paintTextWithEmphasisMark(context, font, textStyle, textRun, emphasisMar
k, emphasisMarkOffset, startOffset, endOffset, length, textOrigin, boxRect); | 609 // FIXME: This cache should probably ultimately be held somewhere else. |
| 610 // A hashmap is convenient to avoid a memory hit when the |
| 611 // RuntimeEnabledFeature is off. |
| 612 bool textBlobIsCacheable = RuntimeEnabledFeatures::textBlobEnabled() &&
startOffset == 0 && endOffset == length; |
| 613 TextBlobPtr* cachedTextBlob = textBlobIsCacheable ? &m_cachedTextBlob :
nullptr; |
| 614 paintTextWithEmphasisMark(context, font, textStyle, textRun, emphasisMar
k, emphasisMarkOffset, startOffset, endOffset, length, textOrigin, boxRect, cach
edTextBlob); |
607 } | 615 } |
608 | 616 |
609 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { | 617 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { |
610 // paint only the text that is selected | 618 // paint only the text that is selected |
611 paintTextWithEmphasisMark(context, font, selectionStyle, textRun, emphas
isMark, emphasisMarkOffset, sPos, ePos, length, textOrigin, boxRect); | 619 bool textBlobIsCacheable = RuntimeEnabledFeatures::textBlobEnabled() &&
sPos == 0 && ePos == length; |
| 620 TextBlobPtr* cachedTextBlob = textBlobIsCacheable ? &m_cachedTextBlob :
nullptr; |
| 621 paintTextWithEmphasisMark(context, font, selectionStyle, textRun, emphas
isMark, emphasisMarkOffset, sPos, ePos, length, textOrigin, boxRect, cachedTextB
lob); |
612 } | 622 } |
613 | 623 |
614 // Paint decorations | 624 // Paint decorations |
615 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); | 625 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); |
616 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) { | 626 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) { |
617 GraphicsContextStateSaver stateSaver(*context, false); | 627 GraphicsContextStateSaver stateSaver(*context, false); |
618 updateGraphicsContext(context, textStyle, stateSaver); | 628 updateGraphicsContext(context, textStyle, stateSaver); |
619 paintDecoration(context, boxOrigin, textDecorations); | 629 paintDecoration(context, boxOrigin, textDecorations); |
620 } | 630 } |
621 | 631 |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 1349 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
1340 const int rendererCharacterOffset = 24; | 1350 const int rendererCharacterOffset = 24; |
1341 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1351 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
1342 fputc(' ', stderr); | 1352 fputc(' ', stderr); |
1343 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 1353 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
1344 } | 1354 } |
1345 | 1355 |
1346 #endif | 1356 #endif |
1347 | 1357 |
1348 } // namespace blink | 1358 } // namespace blink |
OLD | NEW |