summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/InlineTextBox.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-06-08 08:26:01 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-06-08 08:26:01 -0700
commit3742ac093d35d923c81693096ab6671e9b147700 (patch)
treec2add9100f789dad45ef1ec5328bddde02c47a4c /Source/WebCore/rendering/InlineTextBox.cpp
parent901401d90459bc22580842455d4588b9a697514d (diff)
parente5926f4a0d6adc9ad4a75824129f117181953560 (diff)
downloadexternal_webkit-3742ac093d35d923c81693096ab6671e9b147700.zip
external_webkit-3742ac093d35d923c81693096ab6671e9b147700.tar.gz
external_webkit-3742ac093d35d923c81693096ab6671e9b147700.tar.bz2
Merge changes I55c6d71a,Ifb3277d4,Ia1b847a2,I7ba9cf3f,Ida2b2a8a,I1280ec90,I72f818d5,I2e3b588b,I9a4e6289,Ia724c78b,Icd8612c8,Ie31b15d7,Ie125edae,I77941a88,I89dae78b,I3516e5ca,I1a4c17b5,I2c4ecc1a,I9c8e6537,Ifac13115,Ie1f80e09,Ia541ed77,I60ce9d78
* changes: Merge WebKit at r82507: Update ThirdPartyProject.prop Merge WebKit at r82507: Cherry-pick change r88166 to add INSPECTOR guards to ScriptProfiler Merge WebKit at r82507: Work around a V8 bug Merge WebKit at r82507: JNIType renamed to JavaType Merge WebKit at r82507: IconDatabaseClient interface expanded Merge WebKit at r82507: Don't use new loss-free code path in HTMLCanvasElement::toDataURL() Merge WebKit at r82507: IcondDatabaseBase::iconForPageURL() renamed Merge WebKit at r82507: IconDatabaseBase::Open() signature changed Merge WebKit at r82507: Node::isContentEditable() renamed Merge WebKit at r82507: Use icon database through IconDatabaseBase Merge WebKit at r82507: toInputElement() is now a member of Node Merge WebKit at r82507: FrameLoaderClient::objectContentType() signature changed Merge WebKit at r82507: StringImpl::computeHash() removed Merge WebKit at r82507: Stub out FontPlatformData::setOrientation() Merge WebKit at r82507: Path::strokeBoundingRect() is now const Merge WebKit at r82507: Add missing UnusedParam.h include in ApplicationCacheGroup.cpp Merge WebKit at r82507: Continue to use Android's version of FontPlatformData.h Merge WebKit at r82507: Update signature of FontCustomPlatformData::fontPlatformData() Merge WebKit at r82507: Fix conflicts due to JNI refactoring Merge WebKit at r82507: Fix conflicts due to new StorageTracker Merge WebKit at r82507: Fix conflicts Merge WebKit at r82507: Fix makefiles Merge WebKit at r82507: Initial merge by git
Diffstat (limited to 'Source/WebCore/rendering/InlineTextBox.cpp')
-rw-r--r--Source/WebCore/rendering/InlineTextBox.cpp79
1 files changed, 52 insertions, 27 deletions
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index 3c3e450..b614f0f 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -163,7 +163,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
ePos = len;
}
- IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
+ IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
IntPoint(), selHeight, sPos, ePos));
int logicalWidth = r.width();
@@ -427,6 +427,14 @@ bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
return !rubyText || !rubyText->firstLineBox();
}
+enum RotationDirection { Counterclockwise, Clockwise };
+
+static inline AffineTransform rotation(const FloatRect& boxRect, RotationDirection clockwise)
+{
+ return clockwise ? AffineTransform(0, 1, -1, 0, boxRect.x() + boxRect.maxY(), boxRect.maxY() - boxRect.x())
+ : AffineTransform(0, -1, 1, 0, boxRect.x() - boxRect.maxY(), boxRect.x() + boxRect.maxY());
+}
+
void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
{
if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE ||
@@ -485,26 +493,22 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
FloatPoint boxOrigin = locationIncludingFlipping();
boxOrigin.move(tx, ty);
FloatRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
- FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
- RenderCombineText* combinedText = styleToUse->hasTextCombine() ? toRenderCombineText(textRenderer()) : 0;
- bool shouldRotate = !isHorizontal() && (!combinedText || !combinedText->isCombined());
- if (shouldRotate) {
- context->save();
- context->translate(boxRect.x(), boxRect.maxY());
- context->rotate(static_cast<float>(deg2rad(90.)));
- context->translate(-boxRect.x(), -boxRect.maxY());
- }
-
-
+ RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRenderer()->isCombineText() && toRenderCombineText(textRenderer())->isCombined() ? toRenderCombineText(textRenderer()) : 0;
+
+ bool shouldRotate = !isHorizontal() && !combinedText;
+ if (shouldRotate)
+ context->concatCTM(rotation(boxRect, Clockwise));
+
// Determine whether or not we have composition underlines to draw.
bool containsComposition = renderer()->node() && renderer()->frame()->editor()->compositionNode() == renderer()->node();
bool useCustomUnderlines = containsComposition && renderer()->frame()->editor()->compositionUsesCustomUnderlines();
// Set our font.
- int d = styleToUse->textDecorationsInEffect();
const Font& font = styleToUse->font();
+ FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
+
if (combinedText)
combinedText->adjustTextOrigin(textOrigin, boxRect);
@@ -618,7 +622,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
if (hasHyphen())
adjustCharactersAndLengthForHyphen(charactersWithHyphen, styleToUse, characters, length);
- TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
+ TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
int sPos = 0;
int ePos = 0;
@@ -653,11 +657,21 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
if (!emphasisMark.isEmpty()) {
updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
+
+ static TextRun objectReplacementCharacterTextRun(&objectReplacementCharacter, 1);
+ TextRun& emphasisMarkTextRun = combinedText ? objectReplacementCharacterTextRun : textRun;
+ FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : textOrigin;
+ if (combinedText)
+ context->concatCTM(rotation(boxRect, Clockwise));
+
if (!paintSelectedTextSeparately || ePos <= sPos) {
// FIXME: Truncate right-to-left text correctly.
- paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkOffset, 0, length, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
+ paintTextWithShadows(context, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, 0, length, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
} else
- paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkOffset, ePos, sPos, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
+ paintTextWithShadows(context, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, ePos, sPos, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
+
+ if (combinedText)
+ context->concatCTM(rotation(boxRect, Counterclockwise));
}
if (textStrokeWidth > 0)
@@ -673,16 +687,27 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
if (!emphasisMark.isEmpty()) {
updateGraphicsContext(context, selectionEmphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
- paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
+
+ static TextRun objectReplacementCharacterTextRun(&objectReplacementCharacter, 1);
+ TextRun& emphasisMarkTextRun = combinedText ? objectReplacementCharacterTextRun : textRun;
+ FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : textOrigin;
+ if (combinedText)
+ context->concatCTM(rotation(boxRect, Clockwise));
+
+ paintTextWithShadows(context, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
+
+ if (combinedText)
+ context->concatCTM(rotation(boxRect, Counterclockwise));
}
if (selectionStrokeWidth > 0)
context->restore();
}
// Paint decorations
- if (d != TDNONE && paintInfo.phase != PaintPhaseSelection) {
+ int textDecorations = styleToUse->textDecorationsInEffect();
+ if (textDecorations != TDNONE && paintInfo.phase != PaintPhaseSelection) {
updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
- paintDecoration(context, boxOrigin, d, textShadow);
+ paintDecoration(context, boxOrigin, textDecorations, textShadow);
}
if (paintInfo.phase == PaintPhaseForeground) {
@@ -715,7 +740,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
}
if (shouldRotate)
- context->restore();
+ context->concatCTM(rotation(boxRect, Counterclockwise));
}
void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
@@ -772,7 +797,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
int selHeight = selectionHeight();
FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
context->clip(FloatRect(localOrigin, FloatSize(m_logicalWidth, selHeight)));
- context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
+ context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(),
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
context->restore();
@@ -796,7 +821,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
- context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
+ context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(),
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
context->restore();
@@ -958,7 +983,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const Floa
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
- TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
// FIXME: Convert the document markers to float rects.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
@@ -1003,7 +1028,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
- TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, selectionTop()), selHeight, sPos, ePos));
@@ -1031,7 +1056,7 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
- TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
IntPoint startPoint = IntPoint(m_x, y);
// Compute and store the rect associated with this marker.
@@ -1192,7 +1217,7 @@ int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs
RenderStyle* style = text->style(m_firstLine);
const Font* f = &style->font();
int offset = f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len,
- textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
+ textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
lineOffset - logicalLeft(), includePartialGlyphs);
if (blockIsInOppositeDirection && (!offset || offset == m_len))
return !offset ? m_len : 0;
@@ -1212,7 +1237,7 @@ float InlineTextBox::positionForOffset(int offset) const
int from = !isLeftToRightDirection() ? offset - m_start : 0;
int to = !isLeftToRightDirection() ? m_len : offset - m_start;
// FIXME: Do we need to add rightBearing here?
- return f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
+ return f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
IntPoint(logicalLeft(), 0), 0, from, to).maxX();
}