| 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 typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap; | 60 typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap; |
| 58 static InlineTextBoxOverflowMap* gTextBoxesWithOverflow; | 61 static InlineTextBoxOverflowMap* gTextBoxesWithOverflow; |
| 59 | 62 |
| 60 static const int misspellingLineThickness = 3; | 63 static const int misspellingLineThickness = 3; |
| 61 | 64 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 FloatRect shadowRect(textRect); | 405 FloatRect shadowRect(textRect); |
| 403 shadowRect.inflate(shadowBlur); | 406 shadowRect.inflate(shadowBlur); |
| 404 shadowRect.move(shadowOffset); | 407 shadowRect.move(shadowOffset); |
| 405 context->save(); | 408 context->save(); |
| 406 context->clip(shadowRect); | 409 context->clip(shadowRect); |
| 407 | 410 |
| 408 extraOffset = FloatSize(0, 2 * textRect.height() + max(0.0f, shadowOffse
t.height()) + shadowBlur); | 411 extraOffset = FloatSize(0, 2 * textRect.height() + max(0.0f, shadowOffse
t.height()) + shadowBlur); |
| 409 shadowOffset -= extraOffset; | 412 shadowOffset -= extraOffset; |
| 410 } | 413 } |
| 411 | 414 |
| 412 context->setShadow(shadowOffset, shadowBlur, shadowColor, context->fillColor
Space()); | 415 context->setShadow(shadowOffset, shadowBlur, shadowColor); |
| 413 return extraOffset; | 416 return extraOffset; |
| 414 } | 417 } |
| 415 | 418 |
| 416 static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
st TextRun& textRun, | 419 static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
st TextRun& textRun, |
| 417 const AtomicString& emphasisMark, int emphasisM
arkOffset, | 420 const AtomicString& emphasisMark, int emphasisM
arkOffset, |
| 418 int startOffset, int endOffset, int truncationP
oint, | 421 int startOffset, int endOffset, int truncationP
oint, |
| 419 const FloatPoint& textOrigin, const FloatRect&
boxRect, | 422 const FloatPoint& textOrigin, const FloatRect&
boxRect, |
| 420 const ShadowData* shadow, bool stroked, bool ho
rizontal) | 423 const ShadowData* shadow, bool stroked, bool ho
rizontal) |
| 421 { | 424 { |
| 425 bool hasShadow = !!shadow; |
| 422 Color fillColor = context->fillColor(); | 426 Color fillColor = context->fillColor(); |
| 423 ColorSpace fillColorSpace = context->fillColorSpace(); | 427 |
| 424 bool opaque = fillColor.alpha() == 255; | 428 if (hasShadow) { |
| 425 if (!opaque) | 429 // FIXME: it would be better if we could get the shadows top-to-bottom f
rom the style. |
| 426 context->setFillColor(Color::black, fillColorSpace); | 430 Vector<const ShadowData*, 4> shadows; |
| 431 do { |
| 432 shadows.append(shadow); |
| 433 } while ((shadow = shadow->next())); |
| 434 |
| 435 DrawLooper drawLooper; |
| 436 drawLooper.addUnmodifiedContent(); |
| 437 for (int i = shadows.size() - 1; i >= 0; i--) { |
| 438 shadow = shadows[i]; |
| 439 int shadowX = horizontal ? shadow->x() : shadow->y(); |
| 440 int shadowY = horizontal ? shadow->y() : -shadow->x(); |
| 441 FloatSize offset(shadowX, shadowY); |
| 442 drawLooper.addShadow(offset, shadow->blur(), shadow->color(), |
| 443 DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresA
lpha); |
| 444 } |
| 445 context->setDrawLooper(drawLooper); |
| 446 } |
| 427 | 447 |
| 428 TextRunPaintInfo textRunPaintInfo(textRun); | 448 TextRunPaintInfo textRunPaintInfo(textRun); |
| 429 textRunPaintInfo.bounds = boxRect; | 449 textRunPaintInfo.bounds = boxRect; |
| 430 do { | 450 if (startOffset <= endOffset) { |
| 431 IntSize extraOffset; | 451 textRunPaintInfo.from = startOffset; |
| 432 if (shadow) | 452 textRunPaintInfo.to = endOffset; |
| 433 extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsCon
text(context, shadow, boxRect, stroked, opaque, horizontal)); | 453 if (emphasisMark.isEmpty()) |
| 434 else if (!opaque) | 454 context->drawText(font, textRunPaintInfo, textOrigin); |
| 435 context->setFillColor(fillColor, fillColorSpace); | 455 else |
| 436 | 456 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark, tex
tOrigin + IntSize(0, emphasisMarkOffset)); |
| 437 if (startOffset <= endOffset) { | 457 } else { |
| 438 textRunPaintInfo.from = startOffset; | 458 if (endOffset > 0) { |
| 459 textRunPaintInfo.from = 0; |
| 439 textRunPaintInfo.to = endOffset; | 460 textRunPaintInfo.to = endOffset; |
| 440 if (emphasisMark.isEmpty()) | 461 if (emphasisMark.isEmpty()) |
| 441 context->drawText(font, textRunPaintInfo, textOrigin + extraOffs
et); | 462 context->drawText(font, textRunPaintInfo, textOrigin); |
| 442 else | 463 else |
| 443 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark,
textOrigin + extraOffset + IntSize(0, emphasisMarkOffset)); | 464 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark,
textOrigin + IntSize(0, emphasisMarkOffset)); |
| 444 } else { | |
| 445 if (endOffset > 0) { | |
| 446 textRunPaintInfo.from = 0; | |
| 447 textRunPaintInfo.to = endOffset; | |
| 448 if (emphasisMark.isEmpty()) | |
| 449 context->drawText(font, textRunPaintInfo, textOrigin + extra
Offset); | |
| 450 else | |
| 451 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisM
ark, textOrigin + extraOffset + IntSize(0, emphasisMarkOffset)); | |
| 452 } | |
| 453 if (startOffset < truncationPoint) { | |
| 454 textRunPaintInfo.from = startOffset; | |
| 455 textRunPaintInfo.to = truncationPoint; | |
| 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 } | 465 } |
| 466 if (startOffset < truncationPoint) { |
| 467 textRunPaintInfo.from = startOffset; |
| 468 textRunPaintInfo.to = truncationPoint; |
| 469 if (emphasisMark.isEmpty()) |
| 470 context->drawText(font, textRunPaintInfo, textOrigin); |
| 471 else |
| 472 context->drawEmphasisMarks(font, textRunPaintInfo, emphasisMark,
textOrigin + IntSize(0, emphasisMarkOffset)); |
| 473 } |
| 474 } |
| 462 | 475 |
| 463 if (!shadow) | 476 if (hasShadow) |
| 464 break; | 477 context->clearDrawLooper(); |
| 465 | |
| 466 if (shadow->next() || stroked || !opaque) | |
| 467 context->restore(); | |
| 468 else | |
| 469 context->clearShadow(); | |
| 470 | |
| 471 shadow = shadow->next(); | |
| 472 } while (shadow || stroked || !opaque); | |
| 473 } | 478 } |
| 474 | 479 |
| 475 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
tion& emphasisPosition) const | 480 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
tion& emphasisPosition) const |
| 476 { | 481 { |
| 477 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. | 482 // This function returns true if there are text emphasis marks and they are
suppressed by ruby text. |
| 478 if (style->textEmphasisMark() == TextEmphasisMarkNone) | 483 if (style->textEmphasisMark() == TextEmphasisMarkNone) |
| 479 return false; | 484 return false; |
| 480 | 485 |
| 481 emphasisPosition = style->textEmphasisPosition(); | 486 emphasisPosition = style->textEmphasisPosition(); |
| 482 if (emphasisPosition == TextEmphasisPositionUnder) | 487 if (emphasisPosition == TextEmphasisPositionUnder) |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 | 1167 |
| 1163 do { | 1168 do { |
| 1164 if (shadow) { | 1169 if (shadow) { |
| 1165 if (!shadow->next()) { | 1170 if (!shadow->next()) { |
| 1166 // The last set of lines paints normally inside the clip. | 1171 // The last set of lines paints normally inside the clip. |
| 1167 localOrigin.move(0, -extraOffset); | 1172 localOrigin.move(0, -extraOffset); |
| 1168 extraOffset = 0; | 1173 extraOffset = 0; |
| 1169 } | 1174 } |
| 1170 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); | 1175 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); |
| 1171 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); | 1176 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); |
| 1172 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color(), colorSpace); | 1177 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color()); |
| 1173 setShadow = true; | 1178 setShadow = true; |
| 1174 shadow = shadow->next(); | 1179 shadow = shadow->next(); |
| 1175 } | 1180 } |
| 1176 | 1181 |
| 1177 #if ENABLE(CSS3_TEXT) | 1182 #if ENABLE(CSS3_TEXT) |
| 1178 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1183 // Offset between lines - always non-zero, so lines never cross each oth
er. |
| 1179 float doubleOffset = textDecorationThickness + 1.f; | 1184 float doubleOffset = textDecorationThickness + 1.f; |
| 1180 #endif // CSS3_TEXT | 1185 #endif // CSS3_TEXT |
| 1181 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); | 1186 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); |
| 1182 if (deco & UNDERLINE) { | 1187 if (deco & UNDERLINE) { |
| (...skipping 429 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 |