| 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 |