From 33c145503253fd65b7a2c0d191a118977438c541 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 13 Jul 2015 09:32:15 +1000 Subject: [PATCH] Bug 1181890 - Center children of ruby content frame if necessary after the bidi reposition. r=jfkthame --HG-- extra : source : db370ccfe5334eae5c4397a8ababab12f0794099 --- layout/base/nsBidiPresUtils.cpp | 58 ++++++++++++++----- layout/base/nsBidiPresUtils.h | 31 ++++++---- .../reftests/css-ruby/bug1181890-notref.html | 9 +++ layout/reftests/css-ruby/bug1181890-ref.html | 9 +++ layout/reftests/css-ruby/bug1181890.html | 10 ++++ layout/reftests/css-ruby/reftest.list | 2 + 6 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 layout/reftests/css-ruby/bug1181890-notref.html create mode 100644 layout/reftests/css-ruby/bug1181890-ref.html create mode 100644 layout/reftests/css-ruby/bug1181890.html diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index dc30bc37b854..cc44898f3aa3 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -1263,7 +1263,7 @@ nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame, aBpd->ResetData(); } -void +/* static */ nscoord nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, int32_t aNumFramesOnLine, WritingMode aLineWM, @@ -1273,16 +1273,17 @@ nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, // If this line consists of a line frame, reorder the line frame's children. if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) { aFirstFrameOnLine = aFirstFrameOnLine->GetFirstPrincipalChild(); - if (!aFirstFrameOnLine) - return; + if (!aFirstFrameOnLine) { + return 0; + } // All children of the line frame are on the first line. Setting aNumFramesOnLine // to -1 makes InitLogicalArrayFromLine look at all of them. aNumFramesOnLine = -1; } BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); - RepositionInlineFrames(&bld, aFirstFrameOnLine, aLineWM, - aContainerSize, aStart); + return RepositionInlineFrames(&bld, aFirstFrameOnLine, aLineWM, + aContainerSize, aStart); } nsIFrame* @@ -1437,6 +1438,41 @@ nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame, } } +/* static */ void +nsBidiPresUtils::RepositionRubyContentFrame( + nsIFrame* aFrame, WritingMode aFrameWM, const LogicalMargin& aBorderPadding) +{ + const nsFrameList& childList = aFrame->PrincipalChildList(); + if (childList.IsEmpty()) { + return; + } + + // Reorder the children. + // XXX It currently doesn't work properly because we do not + // resolve frames inside ruby content frames. + nscoord isize = ReorderFrames(childList.FirstChild(), + childList.GetLength(), + aFrameWM, aFrame->GetSize(), + aBorderPadding.IStart(aFrameWM)); + isize += aBorderPadding.IEnd(aFrameWM); + + if (aFrame->StyleText()->mRubyAlign == NS_STYLE_RUBY_ALIGN_START) { + return; + } + nscoord residualISize = aFrame->ISize(aFrameWM) - isize; + if (residualISize <= 0) { + return; + } + + // When ruby-align is not "start", if the content does not fill this + // frame, we need to center the children. + for (nsIFrame* child : childList) { + LogicalRect rect = child->GetLogicalRect(aFrameWM, 0); + rect.IStart(aFrameWM) += residualISize / 2; + child->SetRect(aFrameWM, rect, 0); + } +} + /* static */ nscoord nsBidiPresUtils::RepositionRubyFrame( nsIFrame* aFrame, @@ -1492,14 +1528,7 @@ nsBidiPresUtils::RepositionRubyFrame( } else { if (frameType == nsGkAtoms::rubyBaseFrame || frameType == nsGkAtoms::rubyTextFrame) { - // Reorder the children. - // XXX It currently doesn't work properly because we do not - // resolve frames inside ruby content frames. - const nsFrameList& childList = aFrame->PrincipalChildList(); - if (childList.NotEmpty()) { - ReorderFrames(childList.FirstChild(), childList.GetLength(), - frameWM, frameSize, aBorderPadding.IStart(frameWM)); - } + RepositionRubyContentFrame(aFrame, frameWM, aBorderPadding); } // Note that, ruby text container is not present in all conditions // above. It is intended, because the children of rtc are reordered @@ -1636,7 +1665,7 @@ nsBidiPresUtils::InitContinuationStates(nsIFrame* aFrame, } } -void +/* static */ nscoord nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld, nsIFrame* aFirstChild, WritingMode aLineWM, @@ -1673,6 +1702,7 @@ nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld, start, &continuationStates, aLineWM, false, aContainerSize); } + return start; } bool diff --git a/layout/base/nsBidiPresUtils.h b/layout/base/nsBidiPresUtils.h index c7a60f8a5b0b..510c6c9107e1 100644 --- a/layout/base/nsBidiPresUtils.h +++ b/layout/base/nsBidiPresUtils.h @@ -159,14 +159,16 @@ public: /** * Reorder this line using Bidi engine. * Update frame array, following the new visual sequence. + * + * @return total inline size * * @lina 05/02/2000 */ - static void ReorderFrames(nsIFrame* aFirstFrameOnLine, - int32_t aNumFramesOnLine, - mozilla::WritingMode aLineWM, - const nsSize& aContainerSize, - nscoord aStart); + static nscoord ReorderFrames(nsIFrame* aFirstFrameOnLine, + int32_t aNumFramesOnLine, + mozilla::WritingMode aLineWM, + const nsSize& aContainerSize, + nscoord aStart); /** * Format Unicode text, taking into account bidi capabilities @@ -397,6 +399,14 @@ private: nsIFrame* aCurrentFrame, BidiParagraphData* aBpd); + /** + * Position ruby content frames (ruby base/text frame). + * Called from RepositionRubyFrame. + */ + static void RepositionRubyContentFrame( + nsIFrame* aFrame, mozilla::WritingMode aFrameWM, + const mozilla::LogicalMargin& aBorderPadding); + /* * Position ruby frames. Called from RepositionFrame. */ @@ -475,14 +485,15 @@ private: * Adjust frame positions following their visual order * * @param aFirstChild the first kid + * @return total inline size * * @lina 04/11/2000 */ - static void RepositionInlineFrames(BidiLineData* aBld, - nsIFrame* aFirstChild, - mozilla::WritingMode aLineWM, - const nsSize& aContainerSize, - nscoord aStart); + static nscoord RepositionInlineFrames(BidiLineData* aBld, + nsIFrame* aFirstChild, + mozilla::WritingMode aLineWM, + const nsSize& aContainerSize, + nscoord aStart); /** * Helper method for Resolve() diff --git a/layout/reftests/css-ruby/bug1181890-notref.html b/layout/reftests/css-ruby/bug1181890-notref.html new file mode 100644 index 000000000000..0e97415a88b6 --- /dev/null +++ b/layout/reftests/css-ruby/bug1181890-notref.html @@ -0,0 +1,9 @@ + +

+ Aaaaaaaaaaaaa + BBBBBb +

+

+ Aaaaaaaaaaaaa + BBBBBb +

diff --git a/layout/reftests/css-ruby/bug1181890-ref.html b/layout/reftests/css-ruby/bug1181890-ref.html new file mode 100644 index 000000000000..41a46d13e377 --- /dev/null +++ b/layout/reftests/css-ruby/bug1181890-ref.html @@ -0,0 +1,9 @@ + +

+ Aaaaaaaaaaaaa + BBBBBb +

+

+ Aaaaaaaaaaaaa + BBBBBb +

diff --git a/layout/reftests/css-ruby/bug1181890.html b/layout/reftests/css-ruby/bug1181890.html new file mode 100644 index 000000000000..3369a7482d6c --- /dev/null +++ b/layout/reftests/css-ruby/bug1181890.html @@ -0,0 +1,10 @@ + +

+ Aaaaaaaaaaaaa + BBBBBb +

+

+ Aaaaaaaaaaaaa + BBBBBb +

+‎ diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index 60a04233205f..c5fdf85fb001 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -53,3 +53,5 @@ pref(layout.css.vertical-text.enabled,true) == ruby-position-vertical-rl.html ru == ruby-span-1.html ruby-span-1-ref.html == ruby-whitespace-1.html ruby-whitespace-1-ref.html == ruby-whitespace-2.html ruby-whitespace-2-ref.html +== bug1181890.html bug1181890-ref.html +!= bug1181890.html bug1181890-notref.html