WebCore/ChangeLog

 12010-10-25 David Hyatt <hyatt@apple.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 https://bugs.webkit.org/show_bug.cgi?id=48257
 6
 7 Make "rl" and "bt" writing-modes work for blocks and lines. InlineTextBox is refactored to compute the correct
 8 top left corner and left baseline edge once so that can be passed down to all the painting functions instead of
 9 tx and ty.
 10
 11 adjustment helpers have been added that can be called before painting children or lines and that fix up
 12 the coordinates from flipped to physical.
 13
 14 Added fast/blockflow/english-rl-text.html and fast/blockflow/english-bt-text.html
 15
 16 * rendering/InlineBox.cpp:
 17 (WebCore::InlineBox::adjustForFlippedBlocksWritingMode):
 18 * rendering/InlineBox.h:
 19 * rendering/InlineFlowBox.cpp:
 20 (WebCore::InlineFlowBox::paintBoxDecorations):
 21 (WebCore::InlineFlowBox::paintMask):
 22 * rendering/InlineTextBox.cpp:
 23 (WebCore::paintTextWithShadows):
 24 (WebCore::InlineTextBox::paint):
 25 (WebCore::InlineTextBox::paintSelection):
 26 (WebCore::InlineTextBox::paintCompositionBackground):
 27 (WebCore::InlineTextBox::paintDecoration):
 28 (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
 29 (WebCore::InlineTextBox::paintTextMatchMarker):
 30 (WebCore::InlineTextBox::computeRectForReplacementMarker):
 31 (WebCore::InlineTextBox::paintDocumentMarkers):
 32 (WebCore::InlineTextBox::paintCompositionUnderline):
 33 * rendering/InlineTextBox.h:
 34 * rendering/RenderBlock.cpp:
 35 (WebCore::RenderBlock::paintChildren):
 36 (WebCore::RenderBlock::paintFloats):
 37 * rendering/RenderBox.cpp:
 38 (WebCore::RenderBox::adjustForFlippedBlocksWritingMode):
 39 * rendering/RenderBox.h:
 40 * rendering/style/RenderStyle.h:
 41 (WebCore::InheritedFlags::isFlippedBlocksWritingMode):
 42
1432010-10-25 Cris Neckar <cdn@chromium.org>
244
345 Reviewed by Dimitri Glazkov.
70473

WebCore/rendering/InlineBox.cpp

2323#include "HitTestResult.h"
2424#include "InlineFlowBox.h"
2525#include "RenderArena.h"
26 #include "RenderBox.h"
 26#include "RenderBlock.h"
2727#include "RootInlineBox.h"
2828
2929using namespace std;

@@int InlineBox::placeEllipsisBox(bool, in
279279 return -1;
280280}
281281
 282void InlineBox::adjustForFlippedBlocksWritingMode(int& x, int& y)
 283{
 284 if (!renderer()->style()->isFlippedBlocksWritingMode())
 285 return;
 286
 287 RenderBlock* block = root()->block();
 288 if (block->style()->isHorizontalWritingMode())
 289 y = block->height() - height() - y;
 290 else
 291 x = block->width() - width() - x;
 292}
 293
282294} // namespace WebCore
283295
284296#ifndef NDEBUG
70260

WebCore/rendering/InlineBox.h

@@public:
290290 return 0;
291291 }
292292
 293 void adjustForFlippedBlocksWritingMode(int& x, int& y);
 294
293295private:
294296 InlineBox* m_next; // The next element on the same line as us.
295297 InlineBox* m_prev; // The previous element on the same line as us.
70356

WebCore/rendering/InlineFlowBox.cpp

@@void InlineFlowBox::paintBoxDecorations(
809809 }
810810
811811 // Move x/y to our coordinates.
 812 adjustForFlippedBlocksWritingMode(x, y);
812813 tx += x;
813814 ty += y;
814815

@@void InlineFlowBox::paintMask(PaintInfo&
887888 }
888889
889890 // Move x/y to our coordinates.
 891 adjustForFlippedBlocksWritingMode(x, y);
890892 tx += x;
891893 ty += y;
892894
70356

WebCore/rendering/InlineTextBox.cpp

@@FloatSize InlineTextBox::applyShadowToGr
346346}
347347
348348static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin,
349  int x, int y, int w, int h, const ShadowData* shadow, bool stroked, bool vertical)
 349 const IntRect& boxRect, const ShadowData* shadow, bool stroked, bool vertical)
350350{
351351 Color fillColor = context->fillColor();
352352 ColorSpace fillColorSpace = context->fillColorSpace();

@@static void paintTextWithShadows(Graphic
357357 do {
358358 IntSize extraOffset;
359359 if (shadow)
360  extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsContext(context, shadow, FloatRect(x, y, w, h), stroked, opaque, vertical));
 360 extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsContext(context, shadow, boxRect, stroked, opaque, vertical));
361361 else if (!opaque)
362362 context->setFillColor(fillColor, fillColorSpace);
363363

@@void InlineTextBox::paint(PaintInfo& pai
431431
432432 RenderStyle* styleToUse = renderer()->style(m_firstLine);
433433 int baseline = styleToUse->font().ascent();
434  ty -= styleToUse->isFlippedLinesWritingMode() ? baseline : 0;
435  IntPoint textOrigin(m_x + tx, m_y + ty + baseline);
 434 ty -= styleToUse->isHorizontalWritingMode() ? 0 : baseline;
436435
 436 int x = m_x;
 437 int y = m_y;
 438 adjustForFlippedBlocksWritingMode(x, y);
 439
 440 IntPoint boxOrigin(tx + x, ty + y);
 441 IntPoint textOrigin(tx + x, ty + y + baseline);
 442 IntRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
 443
437444 if (m_isVertical) {
438445 context->save();
439446 context->translate(textOrigin.x(), textOrigin.y());

@@void InlineTextBox::paint(PaintInfo& pai
459466#endif
460467
461468 if (containsComposition && !useCustomUnderlines)
462  paintCompositionBackground(context, tx, ty, styleToUse, font,
 469 paintCompositionBackground(context, boxOrigin, styleToUse, font,
463470 renderer()->frame()->editor()->compositionStart(),
464471 renderer()->frame()->editor()->compositionEnd());
465472
466  paintDocumentMarkers(context, tx, ty, styleToUse, font, true);
 473 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true);
467474
468475 if (haveSelection && !useCustomUnderlines)
469  paintSelection(context, tx, ty, styleToUse, font);
 476 paintSelection(context, boxOrigin, styleToUse, font);
470477 }
471478
472479 // 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only).

@@void InlineTextBox::paint(PaintInfo& pai
560567 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
561568 if (!paintSelectedTextSeparately || ePos <= sPos) {
562569 // FIXME: Truncate right-to-left text correctly.
563  paintTextWithShadows(context, font, textRun, 0, length, length, textOrigin, m_x + tx, m_y + ty, logicalWidth(), logicalHeight(), textShadow, textStrokeWidth > 0, m_isVertical);
 570 paintTextWithShadows(context, font, textRun, 0, length, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, m_isVertical);
564571 } else
565  paintTextWithShadows(context, font, textRun, ePos, sPos, length, textOrigin, m_x + tx, m_y + ty, logicalWidth(), logicalHeight(), textShadow, textStrokeWidth > 0, m_isVertical);
 572 paintTextWithShadows(context, font, textRun, ePos, sPos, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, m_isVertical);
566573
567574 if (textStrokeWidth > 0)
568575 context->restore();

@@void InlineTextBox::paint(PaintInfo& pai
574581 context->save();
575582
576583 updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth, styleToUse->colorSpace());
577  paintTextWithShadows(context, font, textRun, sPos, ePos, length, textOrigin, m_x + tx, m_y + ty, logicalWidth(), logicalHeight(), selectionShadow, selectionStrokeWidth > 0, m_isVertical);
 584 paintTextWithShadows(context, font, textRun, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, m_isVertical);
578585
579586 if (selectionStrokeWidth > 0)
580587 context->restore();

@@void InlineTextBox::paint(PaintInfo& pai
583590 // Paint decorations
584591 if (d != TDNONE && paintInfo.phase != PaintPhaseSelection) {
585592 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
586  paintDecoration(context, tx, ty, d, textShadow);
 593 paintDecoration(context, boxOrigin, d, textShadow);
587594 }
588595
589596 if (paintInfo.phase == PaintPhaseForeground) {
590  paintDocumentMarkers(context, tx, ty, styleToUse, font, false);
 597 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);
591598
592599 if (useCustomUnderlines) {
593600 const Vector<CompositionUnderline>& underlines = renderer()->frame()->editor()->customCompositionUnderlines();

@@void InlineTextBox::paint(PaintInfo& pai
604611
605612 if (underline.startOffset <= end()) {
606613 // underline intersects this run. Paint it.
607  paintCompositionUnderline(context, tx, ty, underline);
 614 paintCompositionUnderline(context, boxOrigin, underline);
608615 if (underline.endOffset > end() + 1)
609616 // underline also runs into the next run. Bail now, no more marker advancement.
610617 break;

@@void InlineTextBox::selectionStartEnd(in
637644 ePos = min(endPos - m_start, (int)m_len);
638645}
639646
640 void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font)
 647void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& boxOrigin, RenderStyle* style, const Font& font)
641648{
642649 // See if we have a selection to paint at all.
643650 int sPos, ePos;

@@void InlineTextBox::paintSelection(Graph
657664
658665 context->save();
659666 updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
660  int y = selectionTop();
661  int h = selectionHeight();
 667
662668 // If the text is truncated, let the thing being painted in the truncation
663669 // draw its own highlight.
664670 int length = m_truncation != cNoTruncation ? m_truncation : m_len;

@@void InlineTextBox::paintSelection(Graph
670676 ePos = length;
671677 }
672678
673  context->clip(IntRect(m_x + tx, y + ty, m_logicalWidth, h));
 679 int deltaY = logicalTop() - selectionTop();
 680 int selHeight = selectionHeight();
 681 IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
 682 context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight)));
674683 context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
675684 !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
676  IntPoint(m_x + tx, y + ty), h, c, style->colorSpace(), sPos, ePos);
 685 localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
677686 context->restore();
678687}
679688
680 void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font, int startPos, int endPos)
 689void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const IntPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos)
681690{
682691 int offset = m_start;
683692 int sPos = max(startPos - offset, 0);

@@void InlineTextBox::paintCompositionBack
692701
693702 updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
694703
695  int y = selectionTop();
696  int h = selectionHeight();
 704 int deltaY = logicalTop() - selectionTop();
 705 int selHeight = selectionHeight();
 706 IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
697707 context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
698708 !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
699  IntPoint(m_x + tx, y + ty), h, c, style->colorSpace(), sPos, ePos);
 709 localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
700710 context->restore();
701711}
702712

@@void InlineTextBox::paintCustomHighlight
720730
721731#endif
722732
723 void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, int deco, const ShadowData* shadow)
 733void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& boxOrigin, int deco, const ShadowData* shadow)
724734{
725  tx += m_x;
726  ty += m_y;
727 
728735 if (m_truncation == cFullTruncation)
729736 return;
730737
 738 IntPoint localOrigin = boxOrigin;
 739
731740 int width = m_logicalWidth;
732741 if (m_truncation != cNoTruncation) {
733742 width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), m_firstLine);
734743 if (!isLeftToRightDirection())
735  tx += (m_logicalWidth - width);
 744 localOrigin.move(m_logicalWidth - width, 0);
736745 }
737746
738747 // Get the text decoration colors.

@@void InlineTextBox::paintDecoration(Grap
752761 int extraOffset = 0;
753762 if (!linesAreOpaque && shadow && shadow->next()) {
754763 context->save();
755  IntRect clipRect(tx, ty, width, baseline + 2);
 764 IntRect clipRect(localOrigin, IntSize(width, baseline + 2));
756765 for (const ShadowData* s = shadow; s; s = s->next()) {
757  IntRect shadowRect(tx, ty, width, baseline + 2);
 766 IntRect shadowRect(localOrigin, IntSize(width, baseline + 2));
758767 shadowRect.inflate(s->blur());
759768 int shadowX = m_isVertical ? s->y() : s->x();
760769 int shadowY = m_isVertical ? -s->x() : s->y();

@@void InlineTextBox::paintDecoration(Grap
765774 context->save();
766775 context->clip(clipRect);
767776 extraOffset += baseline + 2;
768  ty += extraOffset;
 777 localOrigin.move(0, extraOffset);
769778 setClip = true;
770779 }
771780

@@void InlineTextBox::paintDecoration(Grap
776785 if (shadow) {
777786 if (!shadow->next()) {
778787 // The last set of lines paints normally inside the clip.
779  ty -= extraOffset;
 788 localOrigin.move(0, -extraOffset);
780789 extraOffset = 0;
781790 }
782791 int shadowX = m_isVertical ? shadow->y() : shadow->x();

@@void InlineTextBox::paintDecoration(Grap
790799 context->setStrokeColor(underline, colorSpace);
791800 context->setStrokeStyle(SolidStroke);
792801 // Leave one pixel of white between the baseline and the underline.
793  context->drawLineForText(IntPoint(tx, ty + baseline + 1), width, isPrinting);
 802 context->drawLineForText(IntPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
794803 }
795804 if (deco & OVERLINE) {
796805 context->setStrokeColor(overline, colorSpace);
797806 context->setStrokeStyle(SolidStroke);
798  context->drawLineForText(IntPoint(tx, ty), width, isPrinting);
 807 context->drawLineForText(localOrigin, width, isPrinting);
799808 }
800809 if (deco & LINE_THROUGH) {
801810 context->setStrokeColor(linethrough, colorSpace);
802811 context->setStrokeStyle(SolidStroke);
803  context->drawLineForText(IntPoint(tx, ty + 2 * baseline / 3), width, isPrinting);
 812 context->drawLineForText(IntPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
804813 }
805814 } while (shadow);
806815

@@static GraphicsContext::TextCheckingLine
825834 }
826835}
827836
828 void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
 837void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
829838{
830839 // Never print spelling/grammar markers (5327887)
831840 if (textRenderer()->document()->printing())

@@void InlineTextBox::paintSpellingOrGramm
854863 endPosition = min<int>(endPosition, m_truncation);
855864
856865 // Calculate start & width
857  IntPoint startPoint(tx + m_x, ty + selectionTop());
 866 int deltaY = logicalTop() - selectionTop();
 867 int selHeight = selectionHeight();
 868 IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
858869 TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
859  int h = selectionHeight();
860 
861  IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, startPosition, endPosition));
 870
 871 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
862872 start = markerRect.x() - startPoint.x();
863873 width = markerRect.width();
864874
865875 // Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to
866876 // display a toolTip. We don't do this for misspelling markers.
867877 if (grammar) {
868  markerRect.move(-tx, -ty);
 878 markerRect.move(-boxOrigin.x(), -boxOrigin.y());
869879 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
870880 renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
871881 }

@@void InlineTextBox::paintSpellingOrGramm
888898 // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
889899 underlineOffset = baseline + 2;
890900 }
891  pt->drawLineForTextChecking(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
 901 pt->drawLineForTextChecking(IntPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
892902}
893903
894 void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font)
 904void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font)
895905{
896906 // Use same y positioning and height as for selection, so that when the selection and this highlight are on
897907 // the same word there are no pieces sticking out.
898  int y = selectionTop();
899  int h = selectionHeight();
900 
 908 int deltaY = logicalTop() - selectionTop();
 909 int selHeight = selectionHeight();
 910
901911 int sPos = max(marker.startOffset - m_start, (unsigned)0);
902912 int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
903913 TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
904914
905915 // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
906  IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, y), h, sPos, ePos));
 916 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, selectionTop()), selHeight, sPos, ePos));
907917 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
908918 renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
909919

@@void InlineTextBox::paintTextMatchMarker
914924 renderer()->theme()->platformInactiveTextSearchHighlightColor();
915925 pt->save();
916926 updateGraphicsContext(pt, color, color, 0, style->colorSpace()); // Don't draw text at all!
917  pt->clip(IntRect(tx + m_x, ty + y, m_logicalWidth, h));
918  pt->drawHighlightForText(font, run, IntPoint(m_x + tx, y + ty), h, color, style->colorSpace(), sPos, ePos);
 927 pt->clip(IntRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
 928 pt->drawHighlightForText(font, run, IntPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos);
919929 pt->restore();
920930 }
921931}
922932
923 void InlineTextBox::computeRectForReplacementMarker(int /*tx*/, int /*ty*/, const DocumentMarker& marker, RenderStyle* style, const Font& font)
 933void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker, RenderStyle* style, const Font& font)
924934{
925935 // Replacement markers are not actually drawn, but their rects need to be computed for hit testing.
926936 int y = selectionTop();

@@void InlineTextBox::computeRectForReplac
937947 renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
938948}
939949
940 void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, RenderStyle* style, const Font& font, bool background)
 950void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
941951{
942952 if (!renderer()->node())
943953 return;

@@void InlineTextBox::paintDocumentMarkers
981991 // marker intersects this run. Paint it.
982992 switch (marker.type) {
983993 case DocumentMarker::Spelling:
984  paintSpellingOrGrammarMarker(pt, tx, ty, marker, style, font, false);
 994 paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, false);
985995 break;
986996 case DocumentMarker::Grammar:
987  paintSpellingOrGrammarMarker(pt, tx, ty, marker, style, font, true);
 997 paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, true);
988998 break;
989999 case DocumentMarker::TextMatch:
990  paintTextMatchMarker(pt, tx, ty, marker, style, font);
 1000 paintTextMatchMarker(pt, boxOrigin, marker, style, font);
9911001 break;
9921002 case DocumentMarker::CorrectionIndicator:
993  computeRectForReplacementMarker(tx, ty, marker, style, font);
994  paintSpellingOrGrammarMarker(pt, tx, ty, marker, style, font, false);
 1003 computeRectForReplacementMarker(marker, style, font);
 1004 paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, false);
9951005 break;
9961006 case DocumentMarker::Replacement:
9971007 case DocumentMarker::RejectedCorrection:

@@void InlineTextBox::paintDocumentMarkers
10041014}
10051015
10061016
1007 void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int ty, const CompositionUnderline& underline)
 1017void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoint& boxOrigin, const CompositionUnderline& underline)
10081018{
1009  tx += m_x;
1010  ty += m_y;
1011 
10121019 if (m_truncation == cFullTruncation)
10131020 return;
10141021

@@void InlineTextBox::paintCompositionUnde
10491056
10501057 ctx->setStrokeColor(underline.color, renderer()->style()->colorSpace());
10511058 ctx->setStrokeThickness(lineThickness);
1052  ctx->drawLineForText(IntPoint(tx + start, ty + logicalHeight() - lineThickness), width, textRenderer()->document()->printing());
 1059 ctx->drawLineForText(IntPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document()->printing());
10531060}
10541061
10551062int InlineTextBox::caretMinOffset() const
70456

WebCore/rendering/InlineTextBox.h

@@private:
140140 // denote no truncation (the whole run paints) and full truncation (nothing paints at all).
141141
142142protected:
143  void paintCompositionBackground(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&, int startPos, int endPos);
144  void paintDocumentMarkers(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&, bool background);
145  void paintCompositionUnderline(GraphicsContext*, int tx, int ty, const CompositionUnderline&);
 143 void paintCompositionBackground(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
 144 void paintDocumentMarkers(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, bool background);
 145 void paintCompositionUnderline(GraphicsContext*, const IntPoint& boxOrigin, const CompositionUnderline&);
146146#if PLATFORM(MAC)
147147 void paintCustomHighlight(int tx, int ty, const AtomicString& type);
148148#endif
149149
150150private:
151  void paintDecoration(GraphicsContext*, int tx, int ty, int decoration, const ShadowData*);
152  void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&);
153  void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
154  void paintTextMatchMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
155  void computeRectForReplacementMarker(int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
 151 void paintDecoration(GraphicsContext*, const IntPoint& boxOrigin, int decoration, const ShadowData*);
 152 void paintSelection(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&);
 153 void paintSpellingOrGrammarMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
 154 void paintTextMatchMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&);
 155 void computeRectForReplacementMarker(const DocumentMarker&, RenderStyle*, const Font&);
156156};
157157
158158inline RenderText* InlineTextBox::textRenderer() const
70263

WebCore/rendering/RenderBlock.cpp

@@void RenderBlock::paintChildren(PaintInf
22692269 }
22702270 }
22712271
 2272 int childTX = tx;
 2273 int childTY = ty;
 2274 adjustForFlippedBlocksWritingMode(child, childTX, childTY);
22722275 if (!child->hasSelfPaintingLayer() && !child->isFloating())
2273  child->paint(info, tx, ty);
 2276 child->paint(info, childTX, childTY);
22742277
22752278 // Check for page-break-after: always, and if it's set, break and bail.
22762279 bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);

@@void RenderBlock::paintFloats(PaintInfo&
24032406 if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
24042407 PaintInfo currentPaintInfo(paintInfo);
24052408 currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
2406  int currentTX = tx + r->left() - r->m_renderer->x() + r->m_renderer->marginLeft();
2407  int currentTY = ty + r->top() - r->m_renderer->y() + r->m_renderer->marginTop();
 2409 int currentTX = tx + r->left() + r->m_renderer->marginLeft() - r->m_renderer->x();
 2410 int currentTY = ty + r->top() + r->m_renderer->marginTop() - r->m_renderer->y();
 2411 adjustForFlippedBlocksWritingMode(r->m_renderer, currentTX, currentTY);
24082412 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
24092413 if (!preservePhase) {
24102414 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
70260

WebCore/rendering/RenderBox.cpp

@@void RenderBox::blockDirectionOverflow(b
31883188 }
31893189}
31903190
 3191void RenderBox::adjustForFlippedBlocksWritingMode(RenderBox* child, int& tx, int& ty)
 3192{
 3193 if (!style()->isFlippedBlocksWritingMode())
 3194 return;
 3195
 3196 // The child is going to add in its x() and y(), so we have to make sure it ends up in
 3197 // the right place.
 3198 if (style()->isHorizontalWritingMode())
 3199 ty += (height() - child->height() - child->y()) - child->y();
 3200 else
 3201 tx += (width() - child->width() - child->x()) - child->x();
 3202}
 3203
31913204} // namespace WebCore
70356

WebCore/rendering/RenderBox.h

@@public:
377377 virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
378378 virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
379379
 380 void adjustForFlippedBlocksWritingMode(RenderBox* child, int& tx, int& ty);
 381
380382protected:
381383 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
382384 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
70356

WebCore/rendering/style/RenderStyle.h

@@public:
754754 WritingMode writingMode() const { return static_cast<WritingMode>(inherited_flags.m_writingMode); }
755755 bool isHorizontalWritingMode() const { return writingMode() == TopToBottomWritingMode || writingMode() == BottomToTopWritingMode; }
756756 bool isFlippedLinesWritingMode() const { return writingMode() == LeftToRightWritingMode || writingMode() == BottomToTopWritingMode; }
 757 bool isFlippedBlocksWritingMode() const { return writingMode() == RightToLeftWritingMode || writingMode() == BottomToTopWritingMode; }
757758
758759 ESpeak speak() { return static_cast<ESpeak>(rareInheritedData->speak); }
759760
70330

LayoutTests/ChangeLog

 12010-10-25 David Hyatt <hyatt@apple.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 https://bugs.webkit.org/show_bug.cgi?id=48257
 6
 7 Make "rl" and "bt" writing-modes work for blocks and lines. InlineTextBox is refactored to compute the correct
 8 top left corner and left baseline edge once so that can be passed down to all the painting functions instead of
 9 tx and ty.
 10
 11 adjustment helpers have been added that can be called before painting children or lines and that fix up
 12 the coordinates from flipped to physical.
 13
 14 Added fast/blockflow/english-rl-text.html and fast/blockflow/english-bt-text.html
 15 * fast/blockflow/english-bt-text.html: Added.
 16 * fast/blockflow/english-rl-text.html: Added.
 17 * platform/mac/fast/blockflow/english-bt-text-expected.checksum: Added.
 18 * platform/mac/fast/blockflow/english-bt-text-expected.png: Added.
 19 * platform/mac/fast/blockflow/english-bt-text-expected.txt: Added.
 20 * platform/mac/fast/blockflow/english-rl-text-expected.checksum: Added.
 21 * platform/mac/fast/blockflow/english-rl-text-expected.png: Added.
 22 * platform/mac/fast/blockflow/english-rl-text-expected.txt: Added.
 23
1242010-10-25 Dimitri Glazkov <dglazkov@chromium.org>
225
326 Add a flaky test to expectations.
70471

LayoutTests/fast/blockflow/english-bt-text.html

 1<html style="-webkit-writing-mode: horizontal-bt"><body style="border:2px solid black; height:500px">
 2<div style="margin-bottom:1em; height:200px;border:2px solid maroon"><div style="float:right;width:100px;height:100px;background-color:lime"></div>
 3Here is some text in a horizontal-bt block flow. The block direction is bottom-to-top.<br>This line should also be horizontal.</div></body></html>
0

LayoutTests/fast/blockflow/english-rl-text.html

 1<html style="-webkit-writing-mode: vertical-rl"><body style="border:2px solid black; width:500px">
 2<div style="margin-right:1em; width:200px;border:2px solid maroon"><div style="float:right;width:100px;height:100px;background-color:lime"></div>
 3Here is some text in a vertical-rl block flow. The block direction is right-to-left.<br>This line should also be vertical.</div></body></html>
0

LayoutTests/platform/mac/fast/blockflow/english-bt-text-expected.checksum

 10b31200048273801e17725c5f5114ce9
02\ No newline at end of file
0

LayoutTests/platform/mac/fast/blockflow/english-bt-text-expected.txt

 1layer at (0,0) size 800x600
 2 RenderView at (0,0) size 800x600
 3layer at (0,0) size 800x600
 4 RenderBlock {HTML} at (0,0) size 800x600
 5 RenderBody {BODY} at (8,8) size 784x504 [border: (2px solid #000000)]
 6 RenderBlock {DIV} at (2,18) size 780x204 [border: (2px solid #800000)]
 7 RenderBlock (floating) {DIV} at (678,2) size 100x100 [bgcolor=#00FF00]
 8 RenderText {#text} at (2,2) size 531x18
 9 text run at (2,2) width 300: "Here is some text in a horizontal-bt block flow. "
 10 text run at (302,2) width 231: "The block direction is bottom-to-top."
 11 RenderBR {BR} at (533,6) size 0x0
 12 RenderText {#text} at (2,20) size 220x18
 13 text run at (2,20) width 220: "This line should also be horizontal."
0

LayoutTests/platform/mac/fast/blockflow/english-rl-text-expected.checksum

 1e9095147b3c2912dacfcd47d274b9688
02\ No newline at end of file
0

LayoutTests/platform/mac/fast/blockflow/english-rl-text-expected.txt

 1layer at (0,0) size 800x600
 2 RenderView at (0,0) size 800x600
 3layer at (0,0) size 785x600
 4 RenderBlock {HTML} at (0,0) size 785x600
 5 RenderBody {BODY} at (8,8) size 504x584 [border: (2px solid #000000)]
 6 RenderBlock {DIV} at (18,2) size 204x580 [border: (2px solid #800000)]
 7 RenderBlock (floating) {DIV} at (2,478) size 100x100 [bgcolor=#00FF00]
 8 RenderText {#text} at (2,2) size 417x18
 9 text run at (2,2) width 417: "Here is some text in a vertical-rl block flow. "
 10 text run at (2,419) width 34: "The"
 11 text run at (20,2) width 318: "block direction is right-to-left."
 12 RenderBR {BR} at (34,320) size 0x0
 13 RenderText {#text} at (38,2) size 324x18
 14 text run at (38,2) width 324: "This line should also be vertical."
0

LayoutTests/platform/mac/fast/blockflow/english-bt-text-expected.png

INVALID: Image lacks a checksum. This will fail with a MISSING error in run-webkit-tests. Always generate new png files using run-webkit-tests.

LayoutTests/platform/mac/fast/blockflow/english-rl-text-expected.png

INVALID: Image lacks a checksum. This will fail with a MISSING error in run-webkit-tests. Always generate new png files using run-webkit-tests.