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 16 matching lines...) Expand all Loading... |
27 #include "core/dom/DocumentMarkerController.h" | 27 #include "core/dom/DocumentMarkerController.h" |
28 #include "core/dom/RenderedDocumentMarker.h" | 28 #include "core/dom/RenderedDocumentMarker.h" |
29 #include "core/dom/Text.h" | 29 #include "core/dom/Text.h" |
30 #include "core/dom/WebCoreMemoryInstrumentation.h" | 30 #include "core/dom/WebCoreMemoryInstrumentation.h" |
31 #include "core/editing/Editor.h" | 31 #include "core/editing/Editor.h" |
32 #include "core/page/Chrome.h" | 32 #include "core/page/Chrome.h" |
33 #include "core/page/ChromeClient.h" | 33 #include "core/page/ChromeClient.h" |
34 #include "core/page/Frame.h" | 34 #include "core/page/Frame.h" |
35 #include "core/page/Page.h" | 35 #include "core/page/Page.h" |
36 #include "core/page/Settings.h" | 36 #include "core/page/Settings.h" |
| 37 #include "core/platform/graphics/DrawLooper.h" |
37 #include "core/platform/graphics/FontCache.h" | 38 #include "core/platform/graphics/FontCache.h" |
38 #include "core/platform/graphics/GraphicsContextStateSaver.h" | 39 #include "core/platform/graphics/GraphicsContextStateSaver.h" |
39 #include "core/rendering/EllipsisBox.h" | 40 #include "core/rendering/EllipsisBox.h" |
40 #include "core/rendering/HitTestResult.h" | 41 #include "core/rendering/HitTestResult.h" |
41 #include "core/rendering/PaintInfo.h" | 42 #include "core/rendering/PaintInfo.h" |
42 #include "core/rendering/RenderArena.h" | 43 #include "core/rendering/RenderArena.h" |
43 #include "core/rendering/RenderBR.h" | 44 #include "core/rendering/RenderBR.h" |
44 #include "core/rendering/RenderBlock.h" | 45 #include "core/rendering/RenderBlock.h" |
45 #include "core/rendering/RenderCombineText.h" | 46 #include "core/rendering/RenderCombineText.h" |
46 #include "core/rendering/RenderRubyRun.h" | 47 #include "core/rendering/RenderRubyRun.h" |
47 #include "core/rendering/RenderRubyText.h" | 48 #include "core/rendering/RenderRubyText.h" |
48 #include "core/rendering/RenderTheme.h" | 49 #include "core/rendering/RenderTheme.h" |
49 #include "core/rendering/break_lines.h" | 50 #include "core/rendering/break_lines.h" |
| 51 #include "core/rendering/style/ShadowData.h" |
50 #include "core/rendering/svg/SVGTextRunRenderingContext.h" | 52 #include "core/rendering/svg/SVGTextRunRenderingContext.h" |
51 #include <wtf/text/CString.h> | 53 #include "wtf/Vector.h" |
| 54 #include "wtf/text/CString.h" |
52 | 55 |
53 using namespace std; | 56 using namespace std; |
54 | 57 |
55 namespace WebCore { | 58 namespace WebCore { |
56 | 59 |
57 struct SameSizeAsInlineTextBox : public InlineBox { | 60 struct SameSizeAsInlineTextBox : public InlineBox { |
58 unsigned variables[1]; | 61 unsigned variables[1]; |
59 unsigned short variables2[2]; | 62 unsigned short variables2[2]; |
60 void* pointers[2]; | 63 void* pointers[2]; |
61 }; | 64 }; |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 FloatRect shadowRect(textRect); | 413 FloatRect shadowRect(textRect); |
411 shadowRect.inflate(shadowBlur); | 414 shadowRect.inflate(shadowBlur); |
412 shadowRect.move(shadowOffset); | 415 shadowRect.move(shadowOffset); |
413 context->save(); | 416 context->save(); |
414 context->clip(shadowRect); | 417 context->clip(shadowRect); |
415 | 418 |
416 extraOffset = FloatSize(0, 2 * textRect.height() + max(0.0f, shadowOffse
t.height()) + shadowBlur); | 419 extraOffset = FloatSize(0, 2 * textRect.height() + max(0.0f, shadowOffse
t.height()) + shadowBlur); |
417 shadowOffset -= extraOffset; | 420 shadowOffset -= extraOffset; |
418 } | 421 } |
419 | 422 |
420 context->setShadow(shadowOffset, shadowBlur, shadowColor, context->fillColor
Space()); | 423 context->setShadow(shadowOffset, shadowBlur, shadowColor); |
421 return extraOffset; | 424 return extraOffset; |
422 } | 425 } |
423 | 426 |
424 static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
st TextRun& textRun, | 427 static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
st TextRun& textRun, |
425 const AtomicString& emphasisMark, int emphasisM
arkOffset, | 428 const AtomicString& emphasisMark, int emphasisM
arkOffset, |
426 int startOffset, int endOffset, int truncationP
oint, | 429 int startOffset, int endOffset, int truncationP
oint, |
427 const FloatPoint& textOrigin, const FloatRect&
boxRect, | 430 const FloatPoint& textOrigin, const FloatRect&
boxRect, |
428 const ShadowData* shadow, bool stroked, bool ho
rizontal) | 431 const ShadowData* shadow, bool stroked, bool ho
rizontal) |
429 { | 432 { |
| 433 bool hasShadow = shadow; |
430 Color fillColor = context->fillColor(); | 434 Color fillColor = context->fillColor(); |
431 ColorSpace fillColorSpace = context->fillColorSpace(); | 435 |
432 bool opaque = fillColor.alpha() == 255; | 436 if (hasShadow) { |
433 if (!opaque) | 437 // FIXME: it would be better if we could get the shadows top-to-bottom f
rom the style. |
434 context->setFillColor(Color::black, fillColorSpace); | 438 Vector<const ShadowData*, 4> shadows; |
| 439 do { |
| 440 shadows.append(shadow); |
| 441 } while ((shadow = shadow->next())); |
| 442 |
| 443 DrawLooper drawLooper; |
| 444 drawLooper.addUnmodifiedContent(); |
| 445 for (int i = shadows.size() - 1; i >= 0; i--) { |
| 446 shadow = shadows[i]; |
| 447 int shadowX = horizontal ? shadow->x() : shadow->y(); |
| 448 int shadowY = horizontal ? shadow->y() : -shadow->x(); |
| 449 FloatSize offset(shadowX, shadowY); |
| 450 drawLooper.addShadow(offset, shadow->blur(), shadow->color(), |
| 451 DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresA
lpha); |
| 452 } |
| 453 context->setDrawLooper(drawLooper); |
| 454 } |
435 | 455 |
436 TextRunPaintInfo textRunPaintInfo(textRun); | 456 TextRunPaintInfo textRunPaintInfo(textRun); |
437 textRunPaintInfo.bounds = boxRect; | 457 textRunPaintInfo.bounds = boxRect; |
438 do { | 458 if (startOffset <= endOffset) { |
439 IntSize extraOffset; | 459 textRunPaintInfo.from = startOffset; |
440 if (shadow) | 460 textRunPaintInfo.to = endOffset; |
441 extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsCon
text(context, shadow, boxRect, stroked, opaque, horizontal)); | 461 if (emphasisMark.isEmpty()) |
442 else if (!opaque) | 462 context->drawText(font, textRunPaintInfo, textOrigin); |
443 context->setFillColor(fillColor, fillColorSpace); | 463 else |
444 | 464 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex
tOrigin + IntSize(0, emphasisMarkOffset)); |
445 if (startOffset <= endOffset) { | 465 } else { |
446 textRunPaintInfo.from = startOffset; | 466 if (endOffset > 0) { |
| 467 textRunPaintInfo.from = 0; |
447 textRunPaintInfo.to = endOffset; | 468 textRunPaintInfo.to = endOffset; |
448 if (emphasisMark.isEmpty()) | 469 if (emphasisMark.isEmpty()) |
449 context->drawText(font, textRunPaintInfo, textOrigin + extraOffs
et); | 470 context->drawText(font, textRunPaintInfo, textOrigin); |
450 else | 471 else |
451 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark,
textOrigin + extraOffset + IntSize(0, emphasisMarkOffset)); | 472 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark,
textOrigin + IntSize(0, emphasisMarkOffset)); |
452 } else { | |
453 if (endOffset > 0) { | |
454 textRunPaintInfo.from = 0; | |
455 textRunPaintInfo.to = endOffset; | |
456 if (emphasisMark.isEmpty()) | |
457 context->drawText(font, textRunPaintInfo, textOrigin + extra
Offset); | |
458 else | |
459 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisM
ark, textOrigin + extraOffset + IntSize(0, emphasisMarkOffset)); | |
460 } | |
461 if (startOffset < truncationPoint) { | |
462 textRunPaintInfo.from = startOffset; | |
463 textRunPaintInfo.to = truncationPoint; | |
464 if (emphasisMark.isEmpty()) | |
465 context->drawText(font, textRunPaintInfo, textOrigin + extra
Offset); | |
466 else | |
467 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisM
ark, textOrigin + extraOffset + IntSize(0, emphasisMarkOffset)); | |
468 } | |
469 } | 473 } |
| 474 if (startOffset < truncationPoint) { |
| 475 textRunPaintInfo.from = startOffset; |
| 476 textRunPaintInfo.to = truncationPoint; |
| 477 if (emphasisMark.isEmpty()) |
| 478 context->drawText(font, textRunPaintInfo, textOrigin); |
| 479 else |
| 480 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark,
textOrigin + IntSize(0, emphasisMarkOffset)); |
| 481 } |
| 482 } |
470 | 483 |
471 if (!shadow) | 484 if (hasShadow) |
472 break; | 485 context->clearDrawLooper(); |
473 | |
474 if (shadow->next() || stroked || !opaque) | |
475 context->restore(); | |
476 else | |
477 context->clearShadow(); | |
478 | |
479 shadow = shadow->next(); | |
480 } while (shadow || stroked || !opaque); | |
481 } | 486 } |
482 | 487 |
483 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
tion& emphasisPosition) const | 488 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
tion& emphasisPosition) const |
484 { | 489 { |
485 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. | 490 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. |
486 if (style->textEmphasisMark() == TextEmphasisMarkNone) | 491 if (style->textEmphasisMark() == TextEmphasisMarkNone) |
487 return false; | 492 return false; |
488 | 493 |
489 emphasisPosition = style->textEmphasisPosition(); | 494 emphasisPosition = style->textEmphasisPosition(); |
490 if (emphasisPosition == TextEmphasisPositionUnder) | 495 if (emphasisPosition == TextEmphasisPositionUnder) |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 | 1173 |
1169 do { | 1174 do { |
1170 if (shadow) { | 1175 if (shadow) { |
1171 if (!shadow->next()) { | 1176 if (!shadow->next()) { |
1172 // The last set of lines paints normally inside the clip. | 1177 // The last set of lines paints normally inside the clip. |
1173 localOrigin.move(0, -extraOffset); | 1178 localOrigin.move(0, -extraOffset); |
1174 extraOffset = 0; | 1179 extraOffset = 0; |
1175 } | 1180 } |
1176 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); | 1181 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); |
1177 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); | 1182 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); |
1178 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color(), colorSpace); | 1183 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color()); |
1179 shadow = shadow->next(); | 1184 shadow = shadow->next(); |
1180 } | 1185 } |
1181 | 1186 |
1182 #if ENABLE(CSS3_TEXT) | 1187 #if ENABLE(CSS3_TEXT) |
1183 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1188 // Offset between lines - always non-zero, so lines never cross each oth
er. |
1184 float doubleOffset = textDecorationThickness + 1.f; | 1189 float doubleOffset = textDecorationThickness + 1.f; |
1185 #endif // CSS3_TEXT | 1190 #endif // CSS3_TEXT |
1186 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); | 1191 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); |
1187 if (deco & UNDERLINE) { | 1192 if (deco & UNDERLINE) { |
1188 context->setStrokeColor(underline, colorSpace); | 1193 context->setStrokeColor(underline, colorSpace); |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 | 1617 |
1613 void InlineTextBox::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | 1618 void InlineTextBox::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
1614 { | 1619 { |
1615 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Rendering); | 1620 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Rendering); |
1616 InlineBox::reportMemoryUsage(memoryObjectInfo); | 1621 InlineBox::reportMemoryUsage(memoryObjectInfo); |
1617 info.addMember(m_prevTextBox, "prevTextBox"); | 1622 info.addMember(m_prevTextBox, "prevTextBox"); |
1618 info.addMember(m_nextTextBox, "nextTextBox"); | 1623 info.addMember(m_nextTextBox, "nextTextBox"); |
1619 } | 1624 } |
1620 | 1625 |
1621 } // namespace WebCore | 1626 } // namespace WebCore |
OLD | NEW |