Closed
Bug 1063857
Opened 9 years ago
Closed 9 years ago
Spaces between characters are not equal for "text-align-last: justify"
Categories
(Core :: Layout: Text and Fonts, defect)
Core
Layout: Text and Fonts
Tracking
()
RESOLVED
FIXED
mozilla36
People
(Reporter: xidorn, Assigned: xidorn)
References
Details
Attachments
(8 files, 22 obsolete files)
190.08 KB,
image/png
|
Details | |
1.23 KB,
text/html
|
Details | |
3.14 KB,
patch
|
masayuki
:
review-
|
Details | Diff | Splinter Review |
5.10 KB,
patch
|
xidorn
:
review+
|
Details | Diff | Splinter Review |
45.33 KB,
patch
|
xidorn
:
review+
|
Details | Diff | Splinter Review |
9.11 KB,
image/png
|
Details | |
1.66 KB,
text/html
|
Details | |
9.27 KB,
patch
|
roc
:
review+
|
Details | Diff | Splinter Review |
Test code: data:text/html;charset=utf-8,<p style="-moz-text-align-last: justify;">お早うございます</p> In this case, the spaces between the characters are not equal. More precisely, there is no spacing surrounding the first and last character. I guess it is in fact a duplicate of bug 424667.
Assignee | ||
Comment 1•9 years ago
|
||
Difference between Firefox and Chrome. It is obvious that the effect in Chrome is more preferable. Note: it is necessary to enable experimental web platform features to test it in Chrome.
Assignee: nobody → quanxunzhen
Status: NEW → ASSIGNED
Assignee | ||
Comment 2•9 years ago
|
||
This patch uses a behavior similar to Chrome, which, in my opinion, is more preferable.
Attachment #8489671 -
Flags: review?(masayuki)
Assignee | ||
Comment 3•9 years ago
|
||
This patch has passed all tests in Linux x64 opt: https://tbpl.mozilla.org/?tree=Try&rev=fcd273ee4491
Assignee | ||
Updated•9 years ago
|
Component: Layout → Layout: Text
Comment 4•9 years ago
|
||
For users with builds in locales other than Chinese or Japanese, you'll need the testcase to be: data:text/html;charset=utf-8,<html lang="ja"><p style="-moz-text-align-last: justify;">お早うございます</p> since we do justification differently depending on content language (see IsJustifiableCharacter in nsTextFrame.cpp, and its aLangIsCJ argument (which callers misname as isCJK)).
Assignee | ||
Comment 5•9 years ago
|
||
(In reply to David Baron [:dbaron] (UTC-7) (needinfo? for questions) from comment #4) > For users with builds in locales other than Chinese or Japanese, you'll need > the testcase to be: > > data:text/html;charset=utf-8,<html lang="ja"><p style="-moz-text-align-last: > justify;">お早うございます</p> > > since we do justification differently depending on content language (see > IsJustifiableCharacter in nsTextFrame.cpp, and its aLangIsCJ argument (which > callers misname as isCJK)). Oh, I see, if the lang is set to en, there is no longer any space between the characters. Then I have a question that why do we make justification locale-aware? It seems justification in Chrome is not affected by locale. In the other hand, I guess Korean characters should also be processed like Chinese and Japanese characters as well, since they are similar.
Assignee | ||
Comment 6•9 years ago
|
||
(In reply to Xidorn Quan (UTC+10) from comment #5) > In the other hand, I guess Korean characters should also be processed like > Chinese and Japanese characters as well, since they are similar. Well, that's false. I opened the Korean Wikipedia and found that words are separated by spaces in Korean...
Comment 7•9 years ago
|
||
(In reply to Xidorn Quan (UTC+10) from comment #5) > Then I have a question that why do we make justification > locale-aware? It seems justification in Chrome is not affected by locale. because CJ characters may be appear in English or something other languages whose words are separated by spaces. E.g., "good morning is おはよう." In this case, the Japanese characters shouldn't cause additional spaces between each character. They should be displayed as a word in space-separated language's context.
Comment 8•9 years ago
|
||
Note that the reason why the first and last character's space are half of the others is, they shouldn't have spaces outside of them (i.e., at the line edges). Therefore, they are ignored from target characters which should be appended extra space. See also bug 288439 comment 16. Note that the bug was discussed with old text API (Gecko 1.8 and earlier).
Assignee | ||
Comment 9•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, JST) from comment #8) > Note that the reason why the first and last character's space are half of > the others is, they shouldn't have spaces outside of them (i.e., at the line > edges). Therefore, they are ignored from target characters which should be > appended extra space. See also bug 288439 comment 16. Note that the bug was > discussed with old text API (Gecko 1.8 and earlier). I still do not understand clearly why those two characters should not have spaces around. Anyway, I'd like to implement the algorithm described in bug 288439 comment 16 which identifies the points and distributes characters accordingly, so that all the spaces could be equal. If it is necessary to avoid appending space on first and last characters, I'll conform. Does it make sense?
Comment 10•9 years ago
|
||
(In reply to Xidorn Quan (UTC+10) from comment #9) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, > JST) from comment #8) > > Note that the reason why the first and last character's space are half of > > the others is, they shouldn't have spaces outside of them (i.e., at the line > > edges). Therefore, they are ignored from target characters which should be > > appended extra space. See also bug 288439 comment 16. Note that the bug was > > discussed with old text API (Gecko 1.8 and earlier). > > I still do not understand clearly why those two characters should not have > spaces around. Not appending extra space for them is a bug. It was a remaining bug at switching new nsTextFrame in Gecko 1.9. > Anyway, I'd like to implement the algorithm described in bug 288439 comment > 16 which identifies the points and distributes characters accordingly, so > that all the spaces could be equal. Great! > If it is necessary to avoid appending > space on first and last characters, I'll conform. Does it make sense? Yeah, I'll check the behavior when you attach new patch!
Comment 11•9 years ago
|
||
Comment on attachment 8489671 [details] [diff] [review] patch Waiting next patch.
Attachment #8489671 -
Flags: review?(masayuki)
Assignee | ||
Comment 12•9 years ago
|
||
The new patch.
Attachment #8489671 -
Attachment is obsolete: true
Attachment #8492512 -
Flags: review?(masayuki)
Assignee | ||
Comment 13•9 years ago
|
||
Some justification testcases.
Comment 14•9 years ago
|
||
Sorry, I cannot review it soon. Please wait until Wed.
Assignee | ||
Comment 15•9 years ago
|
||
Fix a reftest failure and some other cases. I'm going to work on some tests for the new algorithm.
Attachment #8492512 -
Attachment is obsolete: true
Attachment #8492512 -
Flags: review?(masayuki)
Attachment #8492582 -
Flags: review?(masayuki)
Assignee | ||
Comment 16•9 years ago
|
||
BTW, the latest patch passed all tests in Linux x64 Opt build: https://tbpl.mozilla.org/?tree=Try&rev=eb4dbb93670d
Assignee | ||
Comment 17•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, JST) from comment #14) > Sorry, I cannot review it soon. Please wait until Wed. No worry, I'll wait. And I also need time to write some tests.
Assignee | ||
Comment 18•9 years ago
|
||
Attachment #8492739 -
Flags: review?(masayuki)
Comment 19•9 years ago
|
||
Comment on attachment 8492582 [details] [diff] [review] patch You changes the position of nsTextFrame for appending extra spaces before or after the frame. However, nsTextFrame width is very important, so, you shouldn't do that: 1. Select the text, then, you can see non-selected spaces between nsTextFrames. 2. Test underline across two or more nsTextFrames. Your patch causes underline is not painted between nsTextFrames. FYI: When you define struct, first |{| should be in next line, i.e., struct foo { bar mBazz; }; > - mTextJustificationNumSpaces = 0; > - mTextJustificationNumLetters = 0; > + mTextJustificationNumPoints = 0; > + mTextStartJustifiable = false; > + mTextEndJustifiable = false; Like this, when you need to define a lot of variables for same purpose, you should define a simple struct. Then, the names become simpler and easy to copy and pass to methods.
Attachment #8492582 -
Flags: review?(masayuki) → review-
Comment 20•9 years ago
|
||
Comment on attachment 8492739 [details] [diff] [review] patch for test You should test underlines too (specify it to the <p> elements) And also, if underline is specified only <span>, the underline might not be painted before nor after the nsTextFrame, I guess. We need to check the spec.
Attachment #8492739 -
Flags: review?(masayuki) → review-
Assignee | ||
Comment 21•9 years ago
|
||
I changed the algorithm so that text frames are expanded as expected. Now underline is continuous in a whole line, and there is no non-selected spacing anymore. The tradeoff is that, spans area cannot tightly wrap the text inside. As this matches the current behavior of both Gecko and WebKit, I think it's fine.
Attachment #8492582 -
Attachment is obsolete: true
Attachment #8495249 -
Flags: review?(masayuki)
Assignee | ||
Comment 22•9 years ago
|
||
Fix a crash when there is any trimmed spaces.
Attachment #8495249 -
Attachment is obsolete: true
Attachment #8495249 -
Flags: review?(masayuki)
Attachment #8495606 -
Flags: review?(masayuki)
Comment 23•9 years ago
|
||
(In reply to Xidorn Quan (UTC+10) from comment #21) > Created attachment 8495249 [details] [diff] [review] > patch > > I changed the algorithm so that text frames are expanded as expected. Now > underline is continuous in a whole line, and there is no non-selected > spacing anymore. Looks almost good to me. > The tradeoff is that, spans area cannot tightly wrap the > text inside. As this matches the current behavior of both Gecko and WebKit, > I think it's fine. IE too. However, this doesn't match with letter-spacing examples. I'm not sure what's the best for justificaiton spaces, though. http://www.w3.org/TR/css3-text/#letter-spacing-property fantasai, how about you? On the other hand, at least for now, it's okay to me because the behavior is similar to the other browsers.
Flags: needinfo?(fantasai.bugs)
Assignee | ||
Comment 24•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, JST) from comment #23) > However, this doesn't match with letter-spacing examples. I'm not sure > what's the best for justificaiton spaces, though. > http://www.w3.org/TR/css3-text/#letter-spacing-property As it is an existing problem that the behavior doesn't match the spec, it might be better to track that in some other bug instead of this.
Comment 25•9 years ago
|
||
Comment on attachment 8495606 [details] [diff] [review] patch >+ const JustificationInfo emptyJustification = { >+ 0, false, false, >+ false, false, false, false >+ }; >+ mJustification = emptyJustification; Why don't you create default constructor which clears all members with 0 or false. If doing it makes damage to the performance, I think the struct should have Clear() or something similar method. >@@ -2342,27 +2344,36 @@ nsLineLayout::TrimTrailingWhiteSpaceIn(P > #ifdef NOISY_TRIM > nsFrame::ListTag(stdout, (psd == mRootSpan > ? mBlockReflowState->frame > : psd->mFrame->mFrame)); > printf(": trim of "); > nsFrame::ListTag(stdout, pfd->mFrame); > printf(" returned %d\n", trimOutput.mDeltaWidth); > #endif >- if (trimOutput.mLastCharIsJustifiable && pfd->mJustificationNumSpaces > 0) { >- pfd->mJustificationNumSpaces--; >- } >- >+ > if (trimOutput.mChanged) { > pfd->SetFlag(PFD_RECOMPUTEOVERFLOW, true); > } > > if (trimOutput.mDeltaWidth) { > pfd->mBounds.ISize(lineWM) -= trimOutput.mDeltaWidth; > >+ if (!pfd->mNext) { >+ // If any trailing space is trimmed in the last frame in a line, >+ // the justification point generated by the space should be >+ // removed as well. >+ JustificationInfo& justification = pfd->mJustification; >+ if (justification.mInnerPoints > 0) { >+ justification.mInnerPoints--; >+ } else if (justification.mStartJustifiable) { >+ justification.mStartJustifiable = false; >+ } >+ } Well, I don't understand this well, though. Why do you need to move the code and change the condition? > void > nsLineLayout::ComputeJustificationWeights(PerSpanData* aPSD, >- int32_t* aNumSpaces, >- int32_t* aNumLetters) >+ int32_t& aInnerPoints) Why don't you use the result instead of out param? If it is the reason why aPSD is modified too, it's okay. But I guess there could be better method name. InitializeJustificationInfo() or something? > for (PerFrameData* pfd = aPSD->mFirstFrame; pfd != nullptr; pfd = pfd->mNext) { >+ JustificationInfo& justification = pfd->mJustification; > >- if (true == pfd->GetFlag(PFD_ISTEXTFRAME)) { >- numSpaces += pfd->mJustificationNumSpaces; >- numLetters += pfd->mJustificationNumLetters; >+ if (pfd->GetFlag(PFD_ISTEXTFRAME)) { >+ aInnerPoints += justification.mInnerPoints; >+ } else if (pfd->mSpan != nullptr) { } else if (pfd->mSpan) { >+ PerSpanData* span = pfd->mSpan; >+ ComputeJustificationWeights(span, aInnerPoints); >+ justification.mStartJustifiable = span->mFirstFrame && >+ span->mFirstFrame->mJustification.mStartJustifiable; >+ justification.mEndJustifiable = span->mLastFrame && >+ span->mLastFrame->mJustification.mEndJustifiable; How about to add utility method IsStartJustifiable() and IsEndJustificable() in PerSpanData? Then, here will be easier to read. >+ if (justification.mStartJustifiable && pfd->mPrev) { >+ justification.mSpaceAtStart = true; >+ if (pfd->mPrev->mJustification.mEndJustifiable) { >+ pfd->mPrev->mJustification.mExtraSpaceAtEnd = false; >+ } else { >+ justification.mExtraSpaceAtStart = true; >+ aInnerPoints++; Hmm, I don't like aInnerPointer is both in/out param. I think that it should be just result and callers increment the result themselves. It's clearer for other developers what this method does. So, the method could be: int32_t GetJustificatificationInnerPointsAndInitSpanData(PerSpanData* aPSD)? > nscoord > nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD, FrameJustificationState* aState) > { > NS_ASSERTION(aPSD, "null arg"); > NS_ASSERTION(aState, "null arg"); > >+ if (aPSD->mFrame) { >+ JustificationInfo& frameJustification = aPSD->mFrame->mJustification; >+ if (aPSD->mFirstFrame) { >+ JustificationInfo& justification = aPSD->mFirstFrame->mJustification; firstFrameJustification? Or JustificationInfo should have AssignStartData(const JustificationInfor&)? >+ justification.mSpaceAtStart = frameJustification.mSpaceAtStart; >+ justification.mExtraSpaceAtStart = frameJustification.mExtraSpaceAtStart; >+ } >+ if (aPSD->mLastFrame) { >+ JustificationInfo& justification = aPSD->mLastFrame->mJustification; lastFrameJustification? Or JustificationInfo should have AssignEndData(const JustificationInfor&)? >- nscoord newAllocatedWidthForSpaces = >- (aState->mTotalWidthForSpaces*aState->mNumSpacesProcessed) >- /aState->mTotalNumSpaces; >- >- dw += newAllocatedWidthForSpaces - aState->mWidthForSpacesProcessed; >+ int32_t halves = justification.mInnerPoints * 2; >+ if (justification.mSpaceAtStart) { >+ halves++; >+ flags |= JUSTIFICATION_FLAG_BEFORE; >+ if (justification.mExtraSpaceAtStart) { >+ halves++; >+ flags |= JUSTIFICATION_FLAG_BEFORE_EXTRA; >+ } >+ } >+ if (justification.mSpaceAtEnd) { >+ halves++; >+ flags |= JUSTIFICATION_FLAG_AFTER; >+ if (justification.mExtraSpaceAtEnd) { >+ halves++; >+ flags |= JUSTIFICATION_FLAG_AFTER_EXTRA; >+ } >+ } Looks like that this can be two methods of JustificationInfo like GetNumberOfHalfSpaces() and GetJustificationFlags(). >+ static_cast<nsTextFrame*>(pfd->mFrame)->SetJustificationFlags(flags); > >- aState->mWidthForSpacesProcessed = newAllocatedWidthForSpaces; >+ aState->mNumPointHalvesProcessed += halves; >+ nscoord newAllocated = >+ (aState->mTotalWidthAvailable * aState->mNumPointHalvesProcessed) / >+ aState->mTotalNumPointHalves; And also this can be a method like FrameJustificationState::GetAllocatedSpaceWidth()? Anyway, separating computation between struct members helps us to understand what your patch does. > else { > if (nullptr != pfd->mSpan) { >- dw += ApplyFrameJustification(pfd->mSpan, aState); >+ dw = ApplyFrameJustification(pfd->mSpan, aState); > } > } Could you sort out this here? } else if (pfd->mSpan) { dw = ApplyFrameJustification(pfd->mSpan, aState); } >- if (numSpaces > 0) { >- FrameJustificationState state = >- { numSpaces, numLetters, remainingISize, 0, 0, 0, 0, 0 }; >+ if (innerPoints > 0) { Hmm, numInsertionPoints might be better... >+ FrameJustificationState state = { >+ innerPoints * 2, // mTotalNumPointHalves >+ remainingISize, // mTotalWidthAvailable >+ 0, // mNumPointHalvesProcessed >+ 0, // mWidthProcessed >+ }; I think that you should create default constructor or Clear() method for this too. >+ >+ NS_ASSERTION( >+ state.mNumPointHalvesProcessed == state.mTotalNumPointHalves, >+ "Unprocessed justification points"); >+ NS_ASSERTION(state.mWidthProcessed == state.mTotalWidthAvailable, >+ "Unprocessed justification width"); If you assume that they never occur, use MOZ_ASSERT(). Otherwise, NS_ASSERTION() is okay. >@@ -106,19 +107,22 @@ public: > * Handle all the relative positioning in the line, compute the > * combined area (== overflow area) for the line, and handle view > * sizing/positioning and the setting of the overflow rect. > */ > void RelativePositionFrames(nsOverflowAreas& aOverflowAreas); > > // Support methods for word-wrapping during line reflow > >- void SetTextJustificationWeights(int32_t aNumSpaces, int32_t aNumLetters) { >- mTextJustificationNumSpaces = aNumSpaces; >- mTextJustificationNumLetters = aNumLetters; >+ void SetTextJustificationWeights(int32_t aInnerPoints, >+ bool aStartJustifiable, >+ bool aEndJustifiable) { nit: |{| should be next line. >+ mJustification.mInnerPoints = aInnerPoints; >+ mJustification.mStartJustifiable = aStartJustifiable; >+ mJustification.mEndJustifiable = aEndJustifiable; Hmm, it's better if they are an independent struct... >@@ -341,16 +345,40 @@ protected: > > // XXX remove this when landing bug 154892 (splitting absolute positioned frames) > friend class nsInlineFrame; > > nsBlockReflowState* mBlockRS;/* XXX hack! */ > > nsLineList::iterator mLineBox; > >+ // The justification process has two stages, which are done by >+ // ComputeJustificationWeights and ApplyFrameJustification >+ // respectively. >+ struct JustificationInfo >+ { >+ // The following three fields include the information required >+ // in the first stage. For text frames, they are filled in >+ // ReflowFrame, while for other frames, they are filled >+ // recursively during the first stage. >+ int32_t mInnerPoints; mNumInsertionPoints? >+ bool mStartJustifiable : 1; Starting with mIs is clearer for bool members. >+ bool mEndJustifiable : 1; >+ // The following four fields include the information required >+ // in the second stage. Except m[Extra]SpaceAtStart of first >+ // frame of each span, and m[Extra]SpaceAtEnd of end frame of >+ // each span, all of them will be computed in the first stage. >+ // The exceptions will be figured out in the second stage >+ // recursively. >+ bool mSpaceAtStart : 1; >+ bool mExtraSpaceAtStart : 1; >+ bool mSpaceAtEnd : 1; >+ bool mExtraSpaceAtEnd : 1; >+ }; So, cannot separate first tree members and the others are different stcuts? I feel odd a struct have different stage's data. >+ struct FrameJustificationState >+ { >+ int32_t mTotalNumPointHalves; >+ nscoord mTotalWidthAvailable; >+ int32_t mNumPointHalvesProcessed; >+ nscoord mWidthProcessed; > }; Could you explain each members what mean. >+ void SetTextJustificationWeights(nsLineLayout& aLineLayout) const { nit: |{| should be next line. And could you add a comment to explain what this method does. >+ aLineLayout.SetTextJustificationWeights( >+ mInnerJustificationPoints, mStartJustifiable, mEndJustifiable); nit: Indentation in nsLineLayout should be 2 white spaces. >@@ -2925,41 +2930,30 @@ protected: > // How far we've done tab-width calculation; this is ONLY valid when > // mTabWidths is nullptr (otherwise rely on mTabWidths->mLimit instead). > // It's a DOM offset relative to the current frame's offset. > uint32_t mTabWidthsAnalyzedLimit; > > int32_t mLength; // DOM string length, may be INT32_MAX > gfxFloat mWordSpacing; // space for each whitespace char > gfxFloat mLetterSpacing; // space for each letter >- gfxFloat mJustificationSpacing; > gfxFloat mHyphenWidth; > gfxFloat mOffsetFromBlockOriginForTabs; > bool mReflowing; > nsTextFrame::TextRunType mWhichTextRun; >+ >+ gfxFloat mHalfJustificationSpacing; >+ uint32_t mInnerJustificationPoints; >+ uint32_t mJustificationBaseStart; >+ uint32_t mJustificationBaseEnd; >+ nsTArray<uint8_t> mJustificationFlags; >+ bool mStartJustifiable; >+ bool mEndJustifiable; You should explain each member with comment. And all bool members should be defined at the end of members including bool mReflowing. In this case, mReflowing wastes the memory space. Sorry, I don't have much time today to review the TextFrame part. I hope you should create some utility methods to each struct. If it's possible in TextFrame too. Separating to small code to a method is easier to read since the method name can be self-document. So, you should do that as far as possible. I'll be back on next Monday for the remaining part.
Attachment #8495606 -
Flags: review?(masayuki)
Comment 26•9 years ago
|
||
FYI: Your patch causes characters may not be center of the space including its glyph and additional space. Therefore, in some cases, it's difficult to select a character by mouse. I think that it's okay to separate this issue to another bug, tough.
Comment 27•9 years ago
|
||
(In reply to Xidorn Quan (UTC+10) from comment #24) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, > JST) from comment #23) > > However, this doesn't match with letter-spacing examples. I'm not sure > > what's the best for justificaiton spaces, though. > > http://www.w3.org/TR/css3-text/#letter-spacing-property > > As it is an existing problem that the behavior doesn't match the spec, it > might be better to track that in some other bug instead of this. Yes, of course. But the case of justification should be defined by the spec explicitly.
Assignee | ||
Comment 28•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, JST) from comment #26) > FYI: Your patch causes characters may not be center of the space including > its glyph and additional space. Therefore, in some cases, it's difficult to > select a character by mouse. I think that it's okay to separate this issue > to another bug, tough. If you think it is better to make non-justifiable character have spacing around so that most justifiable character could be centered, I could do so as well. But I prefer the current method. Considering the difficulty of selecting characters, moving to the method WebKits uses may help as well. In most case, they append the spacing after characters. But I think that is not preferable as well. I guess a better way for this problem is to improve the selecting logic instead of justification?
Comment 29•9 years ago
|
||
(In reply to Xidorn Quan (UTC+10) from comment #28) > I guess a better way for this problem is to improve the selecting logic > instead of justification? I think so but I have no actual idea.
Assignee | ||
Comment 30•9 years ago
|
||
The patch to improve selecting. I wonder this patch should be applied independently or with the previous patch.
Attachment #8496367 -
Flags: feedback?(masayuki)
Comment 31•9 years ago
|
||
FYI: Looks like your patch causes bustage on B2G ICS. https://tbpl.mozilla.org/?tree=Try&usebuildbot=1&rev=bc9a9f298448
Comment 32•9 years ago
|
||
I'm not sure what's the best behavior, but I imagine it's easiest to implement letter-spacing and justification spacing behaving the same way.
Flags: needinfo?(fantasai.bugs)
Assignee | ||
Comment 33•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) (away: 9/20 - 9/23, JST) from comment #31) > FYI: Looks like your patch causes bustage on B2G ICS. > https://tbpl.mozilla.org/?tree=Try&usebuildbot=1&rev=bc9a9f298448 That's trivial problem. Simply moving the local type out of the function can solve. Or we may ask the build team to investigate using some new version of gcc: the latest android-ndk is using 4.8 instead of 4.4, and both clang and msvc have supported that feature.
Comment 34•9 years ago
|
||
(In reply to fantasai from comment #32) > I'm not sure what's the best behavior, but I imagine it's easiest to > implement letter-spacing and justification spacing behaving the same way. I agree. Could you mention it in the draft? # Anyway, we won't do that at least in this bug because our letter-spacing behavior still doesn't conform to the draft's example.
Flags: needinfo?(fantasai.bugs)
Comment 35•9 years ago
|
||
Comment on attachment 8496367 [details] [diff] [review] patch for improving selecting Oh, this is great! Looks and works fine to me!
Attachment #8496367 -
Flags: feedback?(masayuki) → feedback+
Assignee | ||
Comment 36•9 years ago
|
||
This patch simplifies some code by introducing util structures.
Attachment #8495606 -
Attachment is obsolete: true
Attachment #8500975 -
Flags: review?(masayuki)
Assignee | ||
Updated•9 years ago
|
Attachment #8496367 -
Flags: review?(ehsan.akhgari)
Comment 37•9 years ago
|
||
Comment on attachment 8496367 [details] [diff] [review] patch for improving selecting Review of attachment 8496367 [details] [diff] [review]: ----------------------------------------------------------------- I'm sorry, I don't know this code very well, and don't feel comfortable reviewing it.
Attachment #8496367 -
Flags: review?(ehsan.akhgari)
Assignee | ||
Updated•9 years ago
|
Attachment #8496367 -
Flags: review?(roc)
Comment 38•9 years ago
|
||
Comment on attachment 8500975 [details] [diff] [review] patch >+struct JustificationCount >+{ >+ // Number of insert points inside a given range of clusters. It does >+ // not include any points before or after the range of clusters. >+ int32_t mInnerPoints; >+ // Whether it is possible that there are insert points before or >+ // after the range of clusters. >+ bool mIsStartJustifiable; >+ bool mIsEndJustifiable; nit: Please use only a white space between type and member name because if a member whose type name is too long will be added, this indent doesn't make sense with the new member. If we change indent of all members, it makes hg annotation messy. So, not aligning the member names to same column is better for the future. >+struct JustificationFlags >+{ >+ bool mSpaceAtStart : 1; >+ bool mExtraSpaceAtStart : 1; >+ bool mSpaceAtEnd : 1; >+ bool mExtraSpaceAtEnd : 1; IIRC, bool should be 1 byte. Why do you need to use ": 1" here? If they are not necessary, please remove them. >+ int32_t SpacesNumberAtStart() const >+ { >+ return !mSpaceAtStart ? 0 : (!mExtraSpaceAtStart ? 1 : 2); >+ } nit: NumberOfSpacesAtStart() or CountOfSpacesAtStart() ? >+ int32_t SpacesNumberAtEnd() const >+ { >+ return !mSpaceAtEnd ? 0 : (!mExtraSpaceAtEnd ? 1 : 2); >+ } ditto. >+ int32_t SpacesNumber() const >+ { >+ return SpacesNumberAtStart() + SpacesNumberAtEnd(); >+ } ditto. >+ void CopySpacesAtStart(const JustificationFlags& aCopy) >+ { >+ mSpaceAtStart = aCopy.mSpaceAtStart; >+ mExtraSpaceAtStart = aCopy.mExtraSpaceAtStart; >+ } nit: We're usually using aOther like this method. >+ void CopySpacesAtEnd(const JustificationFlags& aCopy) >+ { >+ mSpaceAtEnd = aCopy.mSpaceAtEnd; >+ mExtraSpaceAtEnd = aCopy.mExtraSpaceAtEnd; >+ } ditto. >+ void SetBothSpacesAtEnd(bool aSet) >+ { >+ mSpaceAtEnd = aSet; >+ mExtraSpaceAtEnd = aSet; >+ } "Both" is unclear to me. Perhaps, SetExtraSpaceAtEnd()? And why don't you create for AtStart too? >+ if (!pfd->mNext) { >+ // If any trailing space is trimmed in the last frame in a line, >+ // the justification point generated by the space should be >+ // removed as well. Well, I don't understand this comment and following logic... Would you explain by the comment why the struct already includes unnecessary space? >+ JustificationCount& count = pfd->mJustificationCount; Although, this is not used in wide range, but justificationCount is better. >+ if (count.mInnerPoints > 0) { >+ count.mInnerPoints--; >+ } else if (count.mIsStartJustifiable) { >+ count.mIsStartJustifiable = false; >+ } Very odd here to me. If the frame is the last frame of a line, here should adjust mIsEndJustificable, isn't it? >+int32_t >+nsLineLayout::CountInnerJustifiablePoints(PerSpanData* aPSD) > { > NS_ASSERTION(aPSD, "null arg"); >+ int32_t result = 0; > > for (PerFrameData* pfd = aPSD->mFirstFrame; pfd != nullptr; pfd = pfd->mNext) { >+ JustificationCount& count = pfd->mJustificationCount; nit: justificationCount >+ if (pfd->GetFlag(PFD_ISTEXTFRAME)) { >+ result += count.mInnerPoints; >+ } else if (pfd->mSpan != nullptr) { >+ PerSpanData* span = pfd->mSpan; >+ result += CountInnerJustifiablePoints(span); >+ count.mIsStartJustifiable = span->mFirstFrame && >+ span->mFirstFrame->IsStartJustifiable(); nit: justificableCount.mIsStartJustifiable = span->mFirstFrame && span->mFirstFrame->IsStartJustifiable(); is better if it's less than 80 characters. >+ count.mIsEndJustifiable = span->mLastFrame && >+ span->mLastFrame->IsEndJustifiable(); ditto. >+ } > >+ JustificationFlags& flags = pfd->mJustificationFlags; nit: justificationFlags >+ flags = JustificationFlags(); >+ if (count.mIsStartJustifiable && pfd->mPrev) { >+ flags.mSpaceAtStart = true; >+ if (pfd->mPrev->IsEndJustifiable()) { >+ pfd->mPrev->mJustificationFlags.mExtraSpaceAtEnd = false; >+ } else { >+ flags.mExtraSpaceAtStart = true; >+ result++; Sounds odd. CountInnerJustifiablePoints() includes the space of each side?? >+ } How about move this (except result++) to JustificationFlags::SetSpaceAtStart(JustificationFlags& aPreviousJustificationFlags)? > } >+ if (count.mIsEndJustifiable && pfd->mNext) { >+ flags.mSpaceAtEnd = true; >+ flags.mExtraSpaceAtEnd = true; Setting extra space flag here feels odd to me. It's necessary only when following frame doesn't have justificatable character at first of the frame. So, I think that false is normal case for extra space. If you agree with this and it doesn't make the code complicated, would you do so? (I guess you need to change only above block). > nscoord > nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD, FrameJustificationState* aState) > { > NS_ASSERTION(aPSD, "null arg"); > NS_ASSERTION(aState, "null arg"); > > nscoord deltaICoord = 0; > for (PerFrameData* pfd = aPSD->mFirstFrame; pfd != nullptr; pfd = pfd->mNext) { > // Don't reposition bullets (and other frames that occur out of X-order?) > if (!pfd->GetFlag(PFD_ISBULLET)) { > nscoord dw = 0; > WritingMode lineWM = mRootSpan->mWritingMode; >+ JustificationFlags flags = pfd->mJustificationFlags; nit: justificationFlags >+ aState->mNumPointHalvesProcessed += >+ pfd->mJustificationCount.mInnerPoints * 2 + flags.SpacesNumber(); How about to create JustificationCount::CountOfSpaces(const JustificationFlags& aJustificationFlags)? >+ } else if (pfd->mSpan && pfd->mSpan->mFirstFrame) { >+ PerSpanData* span = pfd->mSpan; >+ span->mFirstFrame->mJustificationFlags.CopySpacesAtStart(flags); >+ span->mLastFrame->mJustificationFlags.CopySpacesAtEnd(flags); >+ dw = ApplyFrameJustification(span, aState); > } > > pfd->mBounds.ISize(lineWM) += dw; > > deltaICoord += dw; > pfd->mFrame->SetRect(lineWM, pfd->mBounds, mContainerWidth); > } > } >@@ -2545,34 +2548,43 @@ nsLineLayout::TextAlignLine(nsLineBox* a >+ case NS_STYLE_TEXT_ALIGN_JUSTIFY: { >+ int32_t innerPoints = CountInnerJustifiablePoints(psd); So, this variable name must be wrong. It may includes space at start and/or end. >+ if (innerPoints > 0) { >+ FrameJustificationState state = { >+ innerPoints * 2, // mTotalNumPointHalves >+ remainingISize, // mTotalWidthAvailable >+ 0, // mNumPointHalvesProcessed >+ 0, // mWidthProcessed >+ }; > > // Apply the justification, and make sure to update our linebox > // width to account for it. > aLine->ExpandBy(ApplyFrameJustification(psd, &state), > mContainerWidth); >+ >+ printf("point halves: %d, processed: %d\n", >+ state.mTotalNumPointHalves, state.mNumPointHalvesProcessed); Please don't include printf() at requesting review. >+ NS_ASSERTION( >+ state.mNumPointHalvesProcessed == state.mTotalNumPointHalves, >+ "Unprocessed justification points"); >+ NS_ASSERTION(state.mWidthProcessed == state.mTotalWidthAvailable, >+ "Unprocessed justification width"); If you want to make debug build crashed, you can use MOZ_ASSERT(). Then, you can detect regressions without reftests only on debug build. >diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h >+ void SetJustificationCount(mozilla::JustificationCount aCount) |const mozilla::JustificationCount&|? >+ { >+ mJustificationCount = aCount; > } >+ struct FrameJustificationState >+ { >+ int32_t mTotalNumPointHalves; How about mCountOfHalfSpaces? "Point" in layout sounds like a point represented by x and y. >+ nscoord mTotalWidthAvailable; How about mAvaialbleWidth? "Total" sounds redundant to me. >+ int32_t mNumPointHalvesProcessed; How about mCountOfHalfSpacesProcessed? >+ nscoord mWidthProcessed; > }; >diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp >--- a/layout/generic/nsTextFrame.cpp >+++ b/layout/generic/nsTextFrame.cpp >@@ -2932,41 +2931,29 @@ protected: >+ gfxFloat mHalfJustificationSpacing; >+ JustificationCount mJustificationCount; >+ uint32_t mJustificationBaseStart; >+ uint32_t mJustificationBaseEnd; What do "Base"s mean? Anyway, would you explain each member with comments? >+ nsTArray<JustificationFlags> mJustificationFlags; Hmm, I worry about memory fragmentation caused by this. I'll check the users of this. I'll keep reviewing this after lunch.
Comment 39•9 years ago
|
||
Comment on attachment 8500975 [details] [diff] [review] patch >+ nsTArray<JustificationFlags> mJustificationFlags; The type name is JustificationFlag"s". So, the member name should be mJustificationFlagsArray. >+void >+PropertyProvider::ComputeJustification(int32_t aOffset, int32_t aLength) >+{ >+ bool isCJ = IsChineseOrJapanese(mFrame); >+ nsSkipCharsRunIterator >+ run(mStart, nsSkipCharsRunIterator::LENGTH_INCLUDES_SKIPPED, aLength); >+ run.SetOriginalOffset(aOffset); >+ mJustificationBaseStart = run.GetSkippedOffset(); >+ >+ mJustificationFlags.ClearAndRetainStorage(); >+ while (run.NextRun()) { >+ uint32_t originalOffset = run.GetOriginalOffset(); >+ uint32_t skippedOffset = run.GetSkippedOffset(); >+ uint32_t length = run.GetRunLength(); >+ mJustificationFlags.SetLength( >+ skippedOffset + length - mJustificationBaseStart); Wow, this looks reallocating a lot of time! Cannot you guess enough length out of while loop? And if you use nsAutoTArray for it, you can allocate array in the stack at constructing the PropertyProvider. When it's not enough and needs to reallocate, it uses the heap. >+ gfxSkipCharsIterator iter = run.GetPos(); >+ for (uint32_t i = 0; i < length; ++i) { >+ uint32_t offset = originalOffset + i; >+ if (IsJustifiableCharacter(mFrag, offset, isCJ)) { if (!IsJustifiableCharacter(...)) { continue; } reduces an indent level. >+ iter.SetOriginalOffset(offset); >+ >+ FindClusterStart(mTextRun, originalOffset, &iter); >+ uint32_t firstChar = iter.GetSkippedOffset() - mJustificationBaseStart; Could you test if |iter.GetSkippedOffset() - mJustificationBaseStart| is negative? I think that if it were so, should be crashed safely because it might cause random crash which is hard to find the cause. Use MOZ_RELEASE_ASSERT() for that. I.e., MOZ_RELEASE_ASSERT(iter.GetSkippedOffset() >= mJustificationBaseStart, "Something message here"); >+ if (firstChar == 0) { >+ mJustificationCount.mIsStartJustifiable = true; >+ } else { >+ mJustificationFlags[firstChar].mSpaceAtStart = true; >+ if (mJustificationFlags[firstChar - 1].mSpaceAtEnd) { >+ mJustificationFlags[firstChar - 1].mExtraSpaceAtEnd = false; >+ } else { >+ mJustificationCount.mInnerPoints++; >+ mJustificationFlags[firstChar].mExtraSpaceAtStart = true; >+ } >+ } Hmm, this is difficult to understand. Could you explain what each case means by comments? >+ FindClusterEnd(mTextRun, originalOffset + length, &iter); >+ uint32_t lastChar = iter.GetSkippedOffset() - mJustificationBaseStart; >+ mJustificationCount.mInnerPoints++; >+ mJustificationFlags[lastChar].SetBothSpacesAtEnd(true); ditto. And I also feel odd to set extra space to the end here. >+ >+ // Skip the whole cluster >+ i = iter.GetOriginalOffset() - originalOffset; >+ } >+ } >+ } >+ mJustificationBaseEnd = >+ mJustificationBaseStart + mJustificationFlags.Length(); >+ >+ if (mJustificationBaseEnd > mJustificationBaseStart && |!mJustificationFlags.IsEmpty()|? Then, mJustificationBaseEnd is really necessary yet? Looks like it's enough to be a method. >+ mJustificationFlags.LastElement().mSpaceAtEnd) { >+ mJustificationCount.mInnerPoints--; I feel odd. Why mInnerPoints already includes the space at the end as an inner space? >+ mJustificationCount.mIsEndJustifiable = true; >+ mJustificationFlags.LastElement().SetBothSpacesAtEnd(false); I don't like setting odd value and corrects it later except when it's the only possible way or it's better for performance. >@@ -3070,45 +3115,28 @@ PropertyProvider::GetSpacingInternal(uin > // Now add in justification spacing >+ if (mHalfJustificationSpacing) { >+ // If there is any spaces trimmed at the end, aStart + aLength may >+ // be larger than the flags array. When that happens, we can simply >+ // ignore those spaces. >+ auto end = std::min(aStart + aLength, mJustificationBaseEnd); >+ for (auto i = aStart; i < end; i++) { I'm not sure if using "auto" is allowed... >+ const JustificationFlags flags = const JustificationFlags&? >+ mJustificationFlags[i - mJustificationBaseStart]; >+ aSpacing[i - aStart].mBefore += >+ mHalfJustificationSpacing * flags.SpacesNumberAtStart(); >+ aSpacing[i - aStart].mAfter += >+ mHalfJustificationSpacing * flags.SpacesNumberAtEnd(); > } > } Looks like that you make this method stateful. mJustification* depends on the argument of previous call of ComputeJustification(). Even if it's okay, if the range of this argument includes out of range from the range of ComputJustification(), you should do something. MOZ_ASSERT()? I'm not sure if this is okay. We should ask additional review to roc later, anyway. >@@ -8326,30 +8326,23 @@ nsTextFrame::ReflowText(nsLineLayout& aL >- // Compute space and letter counts for justification, if required Why do you remove this comment? > if (!textStyle->WhiteSpaceIsSignificant() && > (lineContainer->StyleText()->mTextAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY || > lineContainer->StyleText()->mTextAlignLast == NS_STYLE_TEXT_ALIGN_JUSTIFY) && > !lineContainer->IsSVGText()) { >+ void SetJustificationFlags(mozilla::JustificationFlags aFlags) >+ { >+ mJustificationFlags = aFlags; >+ } The argument should be: const mozilla::JustificationFlags& aJustificationFlags >+ mozilla::JustificationFlags GetJustificationFlags() const >+ { >+ return mJustificationFlags; >+ } How about: const mozilla::JustificationFlags& JustificationFlags() const { return mJustificationFlags; } I think that the caller shouldn't change the value and "Get" isn't necessary if this never return nullptr. >+ mozilla::JustificationFlags mJustificationFlags; I'm afraid you are adding a member to nsTextFrame because nsTextFrame is created tons of times. Although, this might be necessary and enough small... But you should retry to think that if we can avoid to add this to nsTextFrame. Could you add a warning comment in JustificationUtils.h. Something like: "Be aware! JustificationFlags is a member of nsTextFrame. Therefore, increasing size of this struct may make damage to the footprint.". But of course, this should be check by roc too. I still don't understand your patch completely. So, if my review is wrong, let me know. However, I worry about some points: 1. You use "point" in the patches, but "point" is not good word in layout because there is another "point" which is represented with x and y. 2. You add some justification data as members of PropertyProvider and nsTextFrame. The former makes the class stateful. And The latter increases the memory. Therefore, our current implementation uses hacky way to compute and set the information to nsTextFrame. (Like TrimTrailingWhiteSpace()) If you can avoid to add a member to nsTextFrame, please try it. 3. Justification code is very complicated. Therefore, even we have already touched it, we need to recall it. So, explaining each code what does is very helpful for everyone. Please add comments or create and use utility methods a lot.
Comment 40•9 years ago
|
||
And I guess that when you write such big patch, you write a patch step by step for each purpose. If so, separating each step to a smaller patch makes review easier and you might find bugs. For example, you might need to redesign current code before changing the logic. Then, the work should be separated to some patches and actually fixing this bug part should be other patches. If you do so, reviews can focus if changing logic is intentional or not.
Comment 41•9 years ago
|
||
See bug 960871 for an example of separating patches.
Assignee | ||
Comment 42•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #39) > >+ mJustificationFlags[i - mJustificationBaseStart]; > >+ aSpacing[i - aStart].mBefore += > >+ mHalfJustificationSpacing * flags.SpacesNumberAtStart(); > >+ aSpacing[i - aStart].mAfter += > >+ mHalfJustificationSpacing * flags.SpacesNumberAtEnd(); > > } > > } > > Looks like that you make this method stateful. mJustification* depends on > the argument of previous call of ComputeJustification(). This class has been stateful before: GetSpacingInternal depends on mJustificationSpacing which is set in SetupJustificationSpacing. Although the former did not depend on ComputeJustification before, I think it's fine since ComputeJustification is only called in one place outside the class. Maybe it is better to rename ComputeJustification to make it clear that it affects the state of the instance? > >+ void SetJustificationFlags(mozilla::JustificationFlags aFlags) > >+ { > >+ mJustificationFlags = aFlags; > >+ } > > The argument should be: const mozilla::JustificationFlags& > aJustificationFlags > > >+ mozilla::JustificationFlags GetJustificationFlags() const > >+ { > >+ return mJustificationFlags; > >+ } > > How about: > > const mozilla::JustificationFlags& JustificationFlags() const > { > return mJustificationFlags; > } Since JustificationFlags is only 1 byte in my patch (and would be 4 byte if you insist that the flags should be plain bool type instead of bit fields), it is more efficient to transfer it by value instead of reference. > I think that the caller shouldn't change the value and "Get" isn't necessary > if this never return nullptr. > > >+ mozilla::JustificationFlags mJustificationFlags; > > I'm afraid you are adding a member to nsTextFrame because nsTextFrame is > created tons of times. Although, this might be necessary and enough small... > But you should retry to think that if we can avoid to add this to > nsTextFrame. That's why I make all bools an one-bit field, so that the whole flags could be only 1 byte. It is possible to remove the member: we can use 4 state bits instead. Do you think it is a better idea?
Assignee | ||
Comment 43•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #38) > >+struct JustificationFlags > >+{ > >+ bool mSpaceAtStart : 1; > >+ bool mExtraSpaceAtStart : 1; > >+ bool mSpaceAtEnd : 1; > >+ bool mExtraSpaceAtEnd : 1; > > IIRC, bool should be 1 byte. Why do you need to use ": 1" here? If they are > not necessary, please remove them. It is useful to reduce the size of the structure. By making them bit fields, the whole structure uses only 1 byte instead of 4 bytes. > >+ JustificationCount& count = pfd->mJustificationCount; > > Although, this is not used in wide range, but justificationCount is better. > > >+ if (count.mInnerPoints > 0) { > >+ count.mInnerPoints--; > >+ } else if (count.mIsStartJustifiable) { > >+ count.mIsStartJustifiable = false; > >+ } > > Very odd here to me. If the frame is the last frame of a line, here should > adjust mIsEndJustificable, isn't it? In this case, there is no inner points (count.mInnerPoints == 0) which means the whole frame contains only a single space which is trimmed. We don't want to count any justification point before this frame because of the trimmed space, hence mIsStartJustifiable is cleared. Since it is at the end of a line, and mIsEndJustifiable is never made its effect, it is not necessary to clear it. > >@@ -2545,34 +2548,43 @@ nsLineLayout::TextAlignLine(nsLineBox* a > >+ case NS_STYLE_TEXT_ALIGN_JUSTIFY: { > >+ int32_t innerPoints = CountInnerJustifiablePoints(psd); > > So, this variable name must be wrong. It may includes space at start and/or > end. It's not wrong. It includes inner points in the context of the given span. It does not include any space before the start or after the end of the span. > > >+ if (innerPoints > 0) { > >+ FrameJustificationState state = { > >+ innerPoints * 2, // mTotalNumPointHalves > >+ remainingISize, // mTotalWidthAvailable > >+ 0, // mNumPointHalvesProcessed > >+ 0, // mWidthProcessed > >+ }; > > > > // Apply the justification, and make sure to update our linebox > > // width to account for it. > > aLine->ExpandBy(ApplyFrameJustification(psd, &state), > > mContainerWidth); > >+ > >+ printf("point halves: %d, processed: %d\n", > >+ state.mTotalNumPointHalves, state.mNumPointHalvesProcessed); > > Please don't include printf() at requesting review. Sorry, I forgot to remove it before submitting. > >diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h > >+ void SetJustificationCount(mozilla::JustificationCount aCount) > > |const mozilla::JustificationCount&|? > > >+ { > >+ mJustificationCount = aCount; > > } > > >+ struct FrameJustificationState > >+ { > >+ int32_t mTotalNumPointHalves; > > How about mCountOfHalfSpaces? "Point" in layout sounds like a point > represented by x and y. But "Space" sounds like a space character to me. Maybe it is better to call it justifiable position, hence "Pos" here?
Assignee | ||
Comment 44•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #40) > And I guess that when you write such big patch, you write a patch step by > step for each purpose. If so, separating each step to a smaller patch makes > review easier and you might find bugs. I think I write the patch by its whole, and I found it hard to separate it into smaller patches since they are coupling tightly. The logic is completely different. The former method bases on justifiable characters, but in this patch it bases on justifiable positions, which makes every place different. Hence it is hard to change some places in one patch and others in another.
Comment 45•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #42) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #39) > > >+ mJustificationFlags[i - mJustificationBaseStart]; > > >+ aSpacing[i - aStart].mBefore += > > >+ mHalfJustificationSpacing * flags.SpacesNumberAtStart(); > > >+ aSpacing[i - aStart].mAfter += > > >+ mHalfJustificationSpacing * flags.SpacesNumberAtEnd(); > > > } > > > } > > > > Looks like that you make this method stateful. mJustification* depends on > > the argument of previous call of ComputeJustification(). > > This class has been stateful before: GetSpacingInternal depends on > mJustificationSpacing which is set in SetupJustificationSpacing. Although > the former did not depend on ComputeJustification before, I think it's fine > since ComputeJustification is only called in one place outside the class. Okay. > Maybe it is better to rename ComputeJustification to make it clear that it > affects the state of the instance? Yeah, I think so. And should be checked with MOZ_ASSERT(). > > const mozilla::JustificationFlags& JustificationFlags() const > > { > > return mJustificationFlags; > > } > > Since JustificationFlags is only 1 byte in my patch (and would be 4 byte if > you insist that the flags should be plain bool type instead of bit fields), > it is more efficient to transfer it by value instead of reference. I don't think that copying 4 byte is slower than 1 byte, but not 100% sure. Either is okay but if you don't use reference, I'd like you to add check the size with static_assert() at build time. > > I think that the caller shouldn't change the value and "Get" isn't necessary > > if this never return nullptr. > > > > >+ mozilla::JustificationFlags mJustificationFlags; > > > > I'm afraid you are adding a member to nsTextFrame because nsTextFrame is > > created tons of times. Although, this might be necessary and enough small... > > But you should retry to think that if we can avoid to add this to > > nsTextFrame. > > That's why I make all bools an one-bit field, so that the whole flags could > be only 1 byte. It is possible to remove the member: we can use 4 state bits > instead. Do you think it is a better idea? I think that using bit field is better as you think. However, when it's used as a member of a class, it might use 4 or 8 byte (32bit OS / 64bit OS). (If there are some bool members around it, it could be merged, though) So, if you can remove it, it's the best. (In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #43) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #38) > > >+struct JustificationFlags > > >+{ > > >+ bool mSpaceAtStart : 1; > > >+ bool mExtraSpaceAtStart : 1; > > >+ bool mSpaceAtEnd : 1; > > >+ bool mExtraSpaceAtEnd : 1; > > > > IIRC, bool should be 1 byte. Why do you need to use ": 1" here? If they are > > not necessary, please remove them. > > It is useful to reduce the size of the structure. By making them bit fields, > the whole structure uses only 1 byte instead of 4 bytes. Ah, okay. I misunderstood. Keep going. > > How about mCountOfHalfSpaces? "Point" in layout sounds like a point > > represented by x and y. > > But "Space" sounds like a space character to me. Maybe it is better to call > it justifiable position, hence "Pos" here? Hmm, I don't like "Pos" too... In the spec, the points which are inserted spaces between characters are called, "expansion opportunity". http://www.w3.org/TR/css3-text/#expanding-text But it's too long and probably there is only one expansion opportunity between two justifiable characters... Instead, can we call of each side of a justifiable character as "expandable sides" or "justifiable sides"? Then, could be as: struct FrameJustificationState { struct { int32_t mCount; int32_t mHandled; } mExpandableSides; struct { nscoord mAvailable; nscoord mConsumed; } mExpandableWidth; } ? (In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #44) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #40) > > And I guess that when you write such big patch, you write a patch step by > > step for each purpose. If so, separating each step to a smaller patch makes > > review easier and you might find bugs. > > I think I write the patch by its whole, and I found it hard to separate it > into smaller patches since they are coupling tightly. Yeah, I can imagine... > The logic is completely different. The former method bases on justifiable characters, but > in this patch it bases on justifiable positions, which makes every place > different. Hence it is hard to change some places in one patch and others in > another. Looks like that your patch changes handling flow too. If this is correct, can you separate the flow change part and logic change part? But anyway, it's optional.
Comment 46•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #43) > > >+ if (count.mInnerPoints > 0) { > > >+ count.mInnerPoints--; > > >+ } else if (count.mIsStartJustifiable) { > > >+ count.mIsStartJustifiable = false; > > >+ } > > > > Very odd here to me. If the frame is the last frame of a line, here should > > adjust mIsEndJustificable, isn't it? > > In this case, there is no inner points (count.mInnerPoints == 0) which means > the whole frame contains only a single space which is trimmed. For example, a text frame "abc" also has 0 inner points, isn't it? I understand the value of JustificationCount::mInnterPoints for "abc 文字" is: a b c ' ' 文 字 ^ ^ ^ ^ ^ Then, 5. Or if "abc文字" then, a b c 文 字 ^ ^ ^ ^ the value must be 4. Is this correct? Therefore, I don't understand why you decrease mInnerPoints from the last frame. Additionally, "文<span>字</span>" is there, I guess that both mInnerPoints values are 0 and mIsEndJustifiable of the former is true, mIsStartJustifiable of the latter is true. Therefore, I don't understand the second case (clearing mIsStartJustifiable). > > >@@ -2545,34 +2548,43 @@ nsLineLayout::TextAlignLine(nsLineBox* a > > >+ case NS_STYLE_TEXT_ALIGN_JUSTIFY: { > > >+ int32_t innerPoints = CountInnerJustifiablePoints(psd); > > > > So, this variable name must be wrong. It may includes space at start and/or > > end. > > It's not wrong. It includes inner points in the context of the given span. > It does not include any space before the start or after the end of the span. Ah, understood. You're right.
Assignee | ||
Comment 47•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #45) > > But "Space" sounds like a space character to me. Maybe it is better to call > > it justifiable position, hence "Pos" here? > > Hmm, I don't like "Pos" too... > > In the spec, the points which are inserted spaces between characters are > called, "expansion opportunity". > http://www.w3.org/TR/css3-text/#expanding-text > > But it's too long and probably there is only one expansion opportunity > between two justifiable characters... Yes, the opportunity seems to be the exact expression. And there is another phase called "break opportunity" which in our current code is called "OptionalBreakPosition". That's why I proposed "Pos". So maybe "oppty"/"oppties" with some comments here? > Instead, can we call of each side of a justifiable character as "expandable > sides" or "justifiable sides"? > > Then, could be as: > > struct FrameJustificationState > { > struct > { > int32_t mCount; > int32_t mHandled; > } mExpandableSides; > struct > { > nscoord mAvailable; > nscoord mConsumed; > } mExpandableWidth; > } > > ? This looks good to me. So we can replace "halves" with "sides". But what do you think about "points"? (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #46) > (In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #43) > > > >+ if (count.mInnerPoints > 0) { > > > >+ count.mInnerPoints--; > > > >+ } else if (count.mIsStartJustifiable) { > > > >+ count.mIsStartJustifiable = false; > > > >+ } > > > > > > Very odd here to me. If the frame is the last frame of a line, here should > > > adjust mIsEndJustificable, isn't it? > > > > In this case, there is no inner points (count.mInnerPoints == 0) which means > > the whole frame contains only a single space which is trimmed. > > For example, a text frame "abc" also has 0 inner points, isn't it? > > I understand the value of JustificationCount::mInnterPoints for "abc 文字" is: > > a b c ' ' 文 字 > ^ ^ ^ ^ ^ Hmmm... I think it's 3: a b c ' ' 文 字 ^ ^ ^ > Then, 5. Or if "abc文字" then, > > a b c 文 字 > ^ ^ ^ ^ > the value must be 4. Is this correct? It's 2. > Therefore, I don't understand why you decrease mInnerPoints from the last > frame. > > Additionally, "文<span>字</span>" is there, I guess that both mInnerPoints > values are 0 and mIsEndJustifiable of the former is true, > mIsStartJustifiable of the latter is true. Therefore, I don't understand the > second case (clearing mIsStartJustifiable). In your case, there is no space be trimmed, hence the condition "trimOutput.mDeltaWidth" is not true. When trimOutput.mDeltaWidth is not zero, the last frame should contains a tailing space which has been trimmed. That frame could either have other characters (so that inner points > 0), or only the space itself (so that mIsStartJustifiable == mIsEndJustifiable == true). In either case, we need to remove the effect of the space because it is trimmed. This, in the current code, happens to be done via suppressing the justification of the last character in a line. However in my new code, the justification is no longer suppressed, thus it is necessary to remove the justification opportunity introducing by the trimmed space in this way.
Comment 48•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #47) > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #45) > > > But "Space" sounds like a space character to me. Maybe it is better to call > > > it justifiable position, hence "Pos" here? > > > > Hmm, I don't like "Pos" too... > > > > In the spec, the points which are inserted spaces between characters are > > called, "expansion opportunity". > > http://www.w3.org/TR/css3-text/#expanding-text > > > > But it's too long and probably there is only one expansion opportunity > > between two justifiable characters... > > Yes, the opportunity seems to be the exact expression. And there is another > phase called "break opportunity" which in our current code is called > "OptionalBreakPosition". That's why I proposed "Pos". So maybe > "oppty"/"oppties" with some comments here? No, if we'll use "opportunity", it should be abbreviated. > > struct FrameJustificationState > > { > > struct > > { > > int32_t mCount; > > int32_t mHandled; > > } mExpandableSides; > > struct > > { > > nscoord mAvailable; > > nscoord mConsumed; > > } mExpandableWidth; > > } > > > > ? > > This looks good to me. So we can replace "halves" with "sides". But what do > you think about "points"? I don't like "points". So, I like "sides" better. Although, "sides" are used in CSS border rendering code. > (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #46) > > (In reply to Xidorn Quan [:xidorn] (UTC-7) from comment #43) > > > > >+ if (count.mInnerPoints > 0) { > > > > >+ count.mInnerPoints--; > > > > >+ } else if (count.mIsStartJustifiable) { > > > > >+ count.mIsStartJustifiable = false; > > > > >+ } > > > > > > > > Very odd here to me. If the frame is the last frame of a line, here should > > > > adjust mIsEndJustificable, isn't it? > > > > > > In this case, there is no inner points (count.mInnerPoints == 0) which means > > > the whole frame contains only a single space which is trimmed. > > > > For example, a text frame "abc" also has 0 inner points, isn't it? > > > > I understand the value of JustificationCount::mInnterPoints for "abc 文字" is: > > > > a b c ' ' 文 字 > > ^ ^ ^ ^ ^ > > Hmmm... I think it's 3: > > a b c ' ' 文 字 > ^ ^ ^ > > > Then, 5. Or if "abc文字" then, > > > > a b c 文 字 > > ^ ^ ^ ^ > > the value must be 4. Is this correct? > > It's 2. Oh, okay. Then, mInnerPoints could be mInnerOpportunities? Anyway, I'll retry to understand your patch with this information. > > Therefore, I don't understand why you decrease mInnerPoints from the last > > frame. > > > > Additionally, "文<span>字</span>" is there, I guess that both mInnerPoints > > values are 0 and mIsEndJustifiable of the former is true, > > mIsStartJustifiable of the latter is true. Therefore, I don't understand the > > second case (clearing mIsStartJustifiable). > > In your case, there is no space be trimmed, hence the condition > "trimOutput.mDeltaWidth" is not true. Oh, I see. > When trimOutput.mDeltaWidth is not zero, the last frame should contains a > tailing space which has been trimmed. That frame could either have other > characters (so that inner points > 0), or only the space itself (so that > mIsStartJustifiable == mIsEndJustifiable == true). In either case, we need > to remove the effect of the space because it is trimmed. Thanks for your explanation. I understood.
Assignee | ||
Comment 49•9 years ago
|
||
Attachment #8500975 -
Attachment is obsolete: true
Attachment #8500975 -
Flags: review?(masayuki)
Attachment #8502299 -
Flags: review?(masayuki)
Comment on attachment 8496367 [details] [diff] [review] patch for improving selecting Review of attachment 8496367 [details] [diff] [review]: ----------------------------------------------------------------- ::: gfx/thebes/gfxTextRun.h @@ +269,5 @@ > * Uses GetSpacing from aBreakProvider. > */ > gfxFloat GetAdvanceWidth(uint32_t aStart, uint32_t aLength, > + PropertyProvider *aProvider, > + PropertyProvider::Spacing* aSpacing = nullptr); Document what is returned in aSpacing.
Attachment #8496367 -
Flags: review?(roc) → review+
Attachment #8502299 -
Flags: review?(roc)
Comment on attachment 8502299 [details] [diff] [review] patch Review of attachment 8502299 [details] [diff] [review]: ----------------------------------------------------------------- Actually, just request review from me once Masayuki is done :-)
Attachment #8502299 -
Flags: review?(roc)
Assignee | ||
Comment 52•9 years ago
|
||
I'm not very sure about my wording on the comment. Do you think that is ok?
Attachment #8496367 -
Attachment is obsolete: true
Attachment #8502831 -
Flags: review+
Flags: needinfo?(roc)
Comment on attachment 8502831 [details] [diff] [review] patch 2 - improve selecting, r=roc Review of attachment 8502831 [details] [diff] [review]: ----------------------------------------------------------------- That's fine, thanks!!
Comment 54•9 years ago
|
||
Comment on attachment 8502299 [details] [diff] [review] patch nit: Could you create a class JustificationUtils which has only static methods you defined/implemented below. (Enough to implement them in the class definition) Then, you can remove "Justification" from their names. >+// The two functions below are the common part of processing >+// justification flags of two adjacent parts. >+ >+static inline void >+SetJustificationSpaceAtStart(JustificationFlags& aFlags, >+ JustificationFlags& aPrevFlags, >+ int32_t& aCount) How about to use result (bool or additional count of spaces?) instead of aCount? If you think that it's harder to understand at reading the callers, keep this style. >+static inline void >+SetJustificationSpaceAtEnd(JustificationFlags& aFlags, int32_t& aCount) >+{ >+ // There is an expansion opportunity after the given part. >+ aCount++; And also here. >+static inline int32_t >+CountExpansionSpaces(const JustificationCount& aCount, >+ const JustificationFlags& aFlags) >+{ >+ return aCount.mInnerOpportunities * 2 + aFlags.CountOfSpaces(); >+} I think that you should explain what the result means with comment. >+// -- Jusitification bits ----------------------------------------------------- >+ >+// These state bits are used to inform the text frame how it should add spaces >+// at its sides for justification. >+// See nsLineLayout::ApplyFrameJustification and JustificationUtils.h. >+FRAME_STATE_BIT(Text, 33, TEXT_JUSTIFICATION_SPACE_AT_START) >+FRAME_STATE_BIT(Text, 34, TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START) >+FRAME_STATE_BIT(Text, 35, TEXT_JUSTIFICATION_SPACE_AT_END) >+FRAME_STATE_BIT(Text, 36, TEXT_JUSTIFICATION_EXTRA_SPACE_AT_END) Hmm, I cannot review this. Roc or dbaron needs to check when you add new flags. >@@ -2342,27 +2340,36 @@ nsLineLayout::TrimTrailingWhiteSpaceIn(P > #ifdef NOISY_TRIM > nsFrame::ListTag(stdout, (psd == mRootSpan > ? mBlockReflowState->frame > : psd->mFrame->mFrame)); > printf(": trim of "); > nsFrame::ListTag(stdout, pfd->mFrame); > printf(" returned %d\n", trimOutput.mDeltaWidth); > #endif >- if (trimOutput.mLastCharIsJustifiable && pfd->mJustificationNumSpaces > 0) { >- pfd->mJustificationNumSpaces--; >- } >- >+ > if (trimOutput.mChanged) { > pfd->SetFlag(PFD_RECOMPUTEOVERFLOW, true); > } > > if (trimOutput.mDeltaWidth) { Could you add comment above this if statement for explaining this means that the frame has trimmed space? > pfd->mBounds.ISize(lineWM) -= trimOutput.mDeltaWidth; > >+ if (!pfd->mNext) { >+ // If any trailing space is trimmed in the last frame in a line, >+ // the justification point generated by the space should be >+ // removed as well. >+ JustificationCount& justificationCount = pfd->mJustificationCount; >+ if (justificationCount.mInnerOpportunities > 0) { >+ justificationCount.mInnerOpportunities--; >+ } else if (justificationCount.mIsStartJustifiable) { >+ justificationCount.mIsStartJustifiable = false; >+ } So, could be JustificationCound::CancelOpportunityForTrimmedSpace() or something? >+int32_t >+nsLineLayout::CountInnerExpansionOpportunities(PerSpanData* aPSD) Ideally, "Justification" should be included into the name, but I have no idea... >+ for (PerFrameData* pfd = aPSD->mFirstFrame; pfd; pfd = pfd->mNext) { >+ JustificationCount& count = pfd->mJustificationCount; >+ if (pfd->GetFlag(PFD_ISTEXTFRAME)) { >+ result += count.mInnerOpportunities; >+ } else if (pfd->mSpan) { >+ PerSpanData* span = pfd->mSpan; >+ result += CountInnerExpansionOpportunities(span); >+ count.mIsStartJustifiable = >+ span->mFirstFrame && span->mFirstFrame->IsStartJustifiable(); >+ count.mIsEndJustifiable = >+ span->mLastFrame && span->mLastFrame->IsEndJustifiable(); Thanks! It's very clear what this code does!! >+ JustificationFlags& flags = pfd->mJustificationFlags; >+ flags = JustificationFlags(); >+ if (count.mIsStartJustifiable && pfd->mPrev) { >+ SetJustificationSpaceAtStart( >+ flags, pfd->mPrev->mJustificationFlags, result); "Adjust" might be better? (instead of "Set") > nscoord > nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD, FrameJustificationState* aState) >+ if (aState->mSpaces.mCount > 0 && >+ aState->mWidth.mAvailable > 0) { Could be FrameJustificationState::IsJustifiable() or something? >+ aState->mSpaces.mHandled += CountExpansionSpaces(count, flags); >+ nscoord newAllocated = >+ (aState->mWidth.mAvailable * aState->mSpaces.mHandled) / >+ aState->mSpaces.mCount; >+ dw = newAllocated - aState->mWidth.mConsumed; >+ aState->mWidth.mConsumed = newAllocated; I guess that this can be FrameJustificationState::Consume(const JustificationCount& aCount, const JustificationFlags& aFlags). And return the dw value as its result. >+ } else if (pfd->mSpan && pfd->mSpan->mFirstFrame) { >+ PerSpanData* span = pfd->mSpan; >+ span->mFirstFrame->mJustificationFlags.CopySpacesAtStart(flags); >+ span->mLastFrame->mJustificationFlags.CopySpacesAtEnd(flags); >+ dw = ApplyFrameJustification(span, aState); > } Could you explain why you copy the flags with comment? And do you need to check if mFirstFrame is not nullptr? It was not checked. Does this work fine with empty <span></span>? >diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h >@@ -567,28 +578,28 @@ protected: > void PlaceTopBottomFrames(PerSpanData* psd, > nscoord aDistanceFromStart, > nscoord aLineBSize); > > void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas); > > bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize); > >- void ComputeJustificationWeights(PerSpanData* psd, int32_t* numSpaces, int32_t* numLetters); >- >- struct FrameJustificationState { >- int32_t mTotalNumSpaces; >- int32_t mTotalNumLetters; >- nscoord mTotalWidthForSpaces; >- nscoord mTotalWidthForLetters; >- int32_t mNumSpacesProcessed; >- int32_t mNumLettersProcessed; >- nscoord mWidthForSpacesProcessed; >- nscoord mWidthForLettersProcessed; >+ struct FrameJustificationState >+ { >+ struct { nit: put the |{| to the next line below the "s". >+ int32_t mCount; >+ int32_t mHandled; >+ } mSpaces; >+ struct { ditto. >+ nscoord mAvailable; >+ nscoord mConsumed; >+ } mWidth; > }; >diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp >+ if (!mJustificationFlagsArray.IsEmpty() && >+ mJustificationFlagsArray.LastElement().mSpaceAtEnd) { >+ // We counted the expansion opportunity after the last character, >+ // but it is not an inner opportunity. >+ mJustificationCount.mInnerOpportunities--; Could you add MOZ_ASSERT(mJustificationCount.mInnerOpportunities > 0) before this line? >+ mJustificationCount.mIsEndJustifiable = true; >+ mJustificationFlagsArray.LastElement().mSpaceAtEnd = false; >+ mJustificationFlagsArray.LastElement().mExtraSpaceAtEnd = false; Setting mIsEndJustifiable true, but setting mSpaceAtEnd and mExtraSpaceAtEnd false may make developers confused. Please add a comment here. >@@ -3071,44 +3120,30 @@ PropertyProvider::GetSpacingInternal(uin > // Now add in justification spacing > if (mJustificationSpacing) { >+ // If there is any spaces trimmed at the end, aStart + aLength may >+ // be larger than the flags array. When that happens, we can simply >+ // ignore those spaces. >+ auto end = std::min(aStart + aLength, >+ mJustificationArrayStart + >+ uint32_t(mJustificationFlagsArray.Length())); nit: add more 2 spaces into the indent of the last line because it's a part of previous line. Looks much simpler than previos patches to me! Thank you. Let me check the new patch, then, perhaps, I'll give r+ and request additional review to roc. And when you request next review, could you post tryserver to create a Windows build? I'd like to check the actual behavior before giving r+. # Sorry for the delay to review due to national holiday of Japan.
Attachment #8502299 -
Flags: review?(masayuki)
Comment 55•9 years ago
|
||
Comment on attachment 8492739 [details] [diff] [review] patch for test And could you test with empty spans? E.g., おは<span></span>よう<span><span></span>ござ<span></span></span>います
Assignee | ||
Comment 56•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #54) > > >+ } else if (pfd->mSpan && pfd->mSpan->mFirstFrame) { > >+ PerSpanData* span = pfd->mSpan; > >+ span->mFirstFrame->mJustificationFlags.CopySpacesAtStart(flags); > >+ span->mLastFrame->mJustificationFlags.CopySpacesAtEnd(flags); > >+ dw = ApplyFrameJustification(span, aState); > > } > > Could you explain why you copy the flags with comment? > > And do you need to check if mFirstFrame is not nullptr? It was not checked. > Does this work fine with empty <span></span>? In the previous code, if it is an empty span, ApplyFrameJustifcation just skips the whole loop and returns 0, hence for this case, the two versions are effectively equal. It processes empty spans just like what is done before. > >+ mJustificationCount.mIsEndJustifiable = true; > >+ mJustificationFlagsArray.LastElement().mSpaceAtEnd = false; > >+ mJustificationFlagsArray.LastElement().mExtraSpaceAtEnd = false; > > Setting mIsEndJustifiable true, but setting mSpaceAtEnd and mExtraSpaceAtEnd > false may make developers confused. Please add a comment here. I'd like to get rid of the confusing code directly, since the flags of last element would be set again in SetupJustificationSpacing according to flags of the text frame. > Looks much simpler than previos patches to me! Thank you. Let me check the > new patch, then, perhaps, I'll give r+ and request additional review to roc. > And when you request next review, could you post tryserver to create a > Windows build? I'd like to check the actual behavior before giving r+. Thanks for your reviewing. > # Sorry for the delay to review due to national holiday of Japan. No worries.
Flags: needinfo?(roc)
Assignee | ||
Comment 57•9 years ago
|
||
try: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=3854e5831244 builds: https://ftp-ssl.mozilla.org/pub/mozilla.org/firefox/try-builds/quanxunzhen@gmail.com-3854e5831244
Attachment #8502299 -
Attachment is obsolete: true
Attachment #8505867 -
Flags: review?(masayuki)
Assignee | ||
Comment 58•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #57) > Created attachment 8505867 [details] [diff] [review] > patch > > try: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=3854e5831244 > builds: > https://ftp-ssl.mozilla.org/pub/mozilla.org/firefox/try-builds/ > quanxunzhen@gmail.com-3854e5831244 Oops... Some compile error because of debug-only variables in my previous patches... new one's here: try: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=5a9d199b21d6 builds: https://ftp-ssl.mozilla.org/pub/mozilla.org/firefox/try-builds/quanxunzhen@gmail.com-5a9d199b21d6
Assignee | ||
Comment 59•9 years ago
|
||
Fix the uninitialised value revealed by valgrind test. https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=b72df8522720
Attachment #8505867 -
Attachment is obsolete: true
Attachment #8505867 -
Flags: review?(masayuki)
Attachment #8506545 -
Flags: review?(masayuki)
Comment 60•9 years ago
|
||
Comment on attachment 8506545 [details] [diff] [review] patch I've not checked the patch yet, but I tested your tryserver build. However, it has some bugs: http://jsfiddle.net/jfzvyywv/5/ 1. With <li> elements? Or with the indent of <li>? Each last character isn't aligned to the end of its line. 2. Empty <span> element causes extra space. This shouldn't be. (#2, #10, #15)
Attachment #8506545 -
Flags: review?(masayuki) → review-
Assignee | ||
Comment 61•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #60) > Comment on attachment 8506545 [details] [diff] [review] > patch > > I've not checked the patch yet, but I tested your tryserver build. However, > it has some bugs: > http://jsfiddle.net/jfzvyywv/5/ > > 1. With <li> elements? Or with the indent of <li>? Each last character isn't > aligned to the end of its line. I'll check this. > 2. Empty <span> element causes extra space. This shouldn't be. (#2, #10, #15) This is a known issue, and I don't think we should solve it for now. On the one hand, it is a rare case in normal use, but for dealing with this, the algorithm would be much more complex. On the other hand, WebKit and Blink have the same effect, and the spec doesn't have specific requirements on this. If we really want to solve it, I think it would be better to open a follow-up bug after this bug being solved.
Assignee | ||
Comment 62•9 years ago
|
||
BTW, do you think we should apply justification between the bullet and the item text? Chrome does so but we don't.
Flags: needinfo?(masayuki)
Assignee | ||
Comment 63•9 years ago
|
||
OK, I solve the both problems together. try: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=46e4d4eb0142
Attachment #8506545 -
Attachment is obsolete: true
Attachment #8507286 -
Flags: review?(masayuki)
Comment 64•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #62) > BTW, do you think we should apply justification between the bullet and the > item text? Chrome does so but we don't. I don't think so. Bullets are not a part of each line. I believe that other browsers should fix it. fantasai, how about you?
Flags: needinfo?(masayuki)
Comment 65•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #63) > Created attachment 8507286 [details] [diff] [review] > patch > > OK, I solve the both problems together. > > try: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=46e4d4eb0142 Looks fine! Great. (FYI: The empty span issue was a regression of your patch. It's not reproduced with current Nightly)
Comment 66•9 years ago
|
||
No, we should not adjust spacing between the bullet and the main text. Please make sure that test ends up in the w3c export directory. :)
Flags: needinfo?(fantasai.bugs)
Assignee | ||
Comment 67•9 years ago
|
||
Attachment #8507286 -
Attachment is obsolete: true
Attachment #8507286 -
Flags: review?(masayuki)
Attachment #8507580 -
Flags: review?(masayuki)
Assignee | ||
Updated•9 years ago
|
Blocks: ruby-align
Comment 68•9 years ago
|
||
(In reply to fantasai from comment #66) > No, we should not adjust spacing between the bullet and the main text. Thanks. > Please make sure that test ends up in the w3c export directory. :) Hmm, about the text-align-last: justify; isn't rendered as the test described both on patched build and Nightly :-( It must be another bug of us or the test... http://test.csswg.org/suites/css3-text/nightly-unstable/html/text-align-last-006.htm
Assignee | ||
Comment 69•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #68) > (In reply to fantasai from comment #66) > > No, we should not adjust spacing between the bullet and the main text. > > Thanks. > > > Please make sure that test ends up in the w3c export directory. :) > > Hmm, about the text-align-last: justify; isn't rendered as the test > described both on patched build and Nightly :-( It must be another bug of us > or the test... > http://test.csswg.org/suites/css3-text/nightly-unstable/html/text-align-last- > 006.htm It is only because that the test doesn't use -moz- prefix. We haven't yet unprefixed it.
Comment 70•9 years ago
|
||
Comment on attachment 8507580 [details] [diff] [review] patch > nscoord > nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD, FrameJustificationState* aState) > { > NS_ASSERTION(aPSD, "null arg"); > NS_ASSERTION(aState, "null arg"); > > nscoord deltaICoord = 0; > for (PerFrameData* pfd = aPSD->mFirstFrame; pfd != nullptr; pfd = pfd->mNext) { > // Don't reposition bullets (and other frames that occur out of X-order?) > if (!pfd->GetFlag(PFD_ISBULLET)) { > nscoord dw = 0; > WritingMode lineWM = mRootSpan->mWritingMode; >+ const JustificationFlags& flags = pfd->mJustificationFlags; >+ const JustificationCount& count = pfd->mJustificationCount; > > pfd->mBounds.IStart(lineWM) += deltaICoord; > > if (true == pfd->GetFlag(PFD_ISTEXTFRAME)) { >+ if (aState->mSpaces.mCount > 0 && >+ aState->mWidth.mAvailable > 0) { IsJustifiable()? >+ // Set corresponding state bits here, so that the text frame >+ // knows how it should add spaces at its sides. >+ nsIFrame* frame = pfd->mFrame; >+ frame->RemoveStateBits(TEXT_JUSTIFICATION_SPACE_AT_START | >+ TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START | >+ TEXT_JUSTIFICATION_SPACE_AT_END | >+ TEXT_JUSTIFICATION_EXTRA_SPACE_AT_END); >+ if (flags.mSpaceAtStart) { >+ frame->AddStateBits(TEXT_JUSTIFICATION_SPACE_AT_START); >+ if (flags.mExtraSpaceAtStart) { >+ frame->AddStateBits(TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START); >+ } >+ } >+ if (flags.mSpaceAtEnd) { >+ frame->AddStateBits(TEXT_JUSTIFICATION_SPACE_AT_END); >+ if (flags.mExtraSpaceAtEnd) { >+ frame->AddStateBits(TEXT_JUSTIFICATION_EXTRA_SPACE_AT_END); >+ } >+ } Could be a method of nsTextFrame which takes JustificationFlags as an argument? E.g., static_cast<nsTextFrame*>(pfd->mFlame)->SetJustificationStateBits(flags); >@@ -389,39 +391,41 @@ protected: > nsOverflowAreas mOverflowAreas; > > // From reflow-state > mozilla::LogicalMargin mMargin; > mozilla::LogicalMargin mBorderPadding; > mozilla::LogicalMargin mOffsets; > > // state for text justification >+ mozilla::JustificationCount mJustificationCount; >+ mozilla::JustificationFlags mJustificationFlags; > > // PerFrameData flags > #define PFD_RELATIVEPOS 0x00000001 > #define PFD_ISTEXTFRAME 0x00000002 > #define PFD_ISNONEMPTYTEXTFRAME 0x00000004 > #define PFD_ISNONWHITESPACETEXTFRAME 0x00000008 > #define PFD_ISLETTERFRAME 0x00000010 > #define PFD_RECOMPUTEOVERFLOW 0x00000020 > #define PFD_ISBULLET 0x00000040 > #define PFD_SKIPWHENTRIMMINGWHITESPACE 0x00000080 >+#define PFD_ISEMPTY 0x00000100 >+#define PFD_LASTFLAG PFD_ISEMPTY > >+ // Other state we use >+ uint16_t mFlags; Although, this isn't a scope of this bug, perhaps, this should be bool flags instead of hacky bit fields... >+void >+PropertyProvider::ComputeJustification(int32_t aOffset, int32_t aLength) >+{ >+ bool isCJ = IsChineseOrJapanese(mFrame); According to the document of text-justiy: auto;, we should include some South Asian Scripts. http://dev.w3.org/csswg/css-text-3/#valdef-text-justify-auto Of course, it's not a scope of this bug. >+ nsSkipCharsRunIterator >+ run(mStart, nsSkipCharsRunIterator::LENGTH_INCLUDES_SKIPPED, aLength); >+ run.SetOriginalOffset(aOffset); >+ mJustificationArrayStart = run.GetSkippedOffset(); >+ >+ MOZ_ASSERT(mJustificationFlagsArray.IsEmpty()); >+ mJustificationFlagsArray.SetCapacity(aLength); >+ while (run.NextRun()) { >+ uint32_t originalOffset = run.GetOriginalOffset(); >+ uint32_t skippedOffset = run.GetSkippedOffset(); >+ uint32_t length = run.GetRunLength(); >+ mJustificationFlagsArray.SetLength( >+ skippedOffset + length - mJustificationArrayStart); nit: indent should be 2 spaces. >+ >+ gfxSkipCharsIterator iter = run.GetPos(); >+ for (uint32_t i = 0; i < length; ++i) { >+ uint32_t offset = originalOffset + i; >+ if (!IsJustifiableCharacter(mFrag, offset, isCJ)) { >+ continue; >+ } >+ >+ iter.SetOriginalOffset(offset); >+ >+ FindClusterStart(mTextRun, originalOffset, &iter); >+ uint32_t firstCharOffset = iter.GetSkippedOffset(); >+ uint32_t firstChar = firstCharOffset > mJustificationArrayStart ? >+ firstCharOffset - mJustificationArrayStart : 0; >+ if (firstChar == 0) { nit: !firstChar >+ mJustificationCount.mIsStartJustifiable = true; >+ } else { >+ JustificationUtils::AdjustSpaceAtStart( >+ mJustificationFlagsArray[firstChar], >+ mJustificationFlagsArray[firstChar - 1], >+ mJustificationCount.mInnerOpportunities); nit: indent should be 2 spaces. >+ } >+ >+ FindClusterEnd(mTextRun, originalOffset + length, &iter); >+ uint32_t lastChar = iter.GetSkippedOffset() - mJustificationArrayStart; >+ JustificationUtils::SetSpaceAtEnd( >+ mJustificationFlagsArray[lastChar], >+ mJustificationCount.mInnerOpportunities); ditto >@@ -3072,44 +3122,30 @@ PropertyProvider::GetSpacingInternal(uin > if (mTabWidths) { > mTabWidths->ApplySpacing(aSpacing, > aStart - mStart.GetSkippedOffset(), aLength); > } > } > > // Now add in justification spacing > if (mJustificationSpacing) { >+ // If there is any spaces trimmed at the end, aStart + aLength may >+ // be larger than the flags array. When that happens, we can simply >+ // ignore those spaces. >+ auto end = std::min(aStart + aLength, >+ mJustificationArrayStart + >+ uint32_t(mJustificationFlagsArray.Length())); nit: use static_cast. > PropertyProvider::SetupJustificationSpacing(bool aPostReflow) > { > NS_PRECONDITION(mLength != INT32_MAX, "Can't call this with undefined length"); > > if (!(mFrame->GetStateBits() & TEXT_JUSTIFICATION_ENABLED)) > return; > > gfxSkipCharsIterator start(mStart), end(mStart); > // We can't just use our mLength here; when InitializeForDisplay is > // called with false for aTrimAfter, we still shouldn't be assigning > // justification space to any trailing whitespace. > nsTextFrame::TrimmedOffsets trimmed = > mFrame->GetTrimmedOffsets(mFrag, true, aPostReflow); > end.AdvanceOriginal(trimmed.mLength); > gfxSkipCharsIterator realEnd(end); >+ ComputeJustification(start.GetOriginalOffset(), >+ end.GetOriginalOffset() - start.GetOriginalOffset()); >+ >+ JustificationFlags flags; >+ nsFrameState stateBits = mFrame->GetStateBits(); >+ if (stateBits & TEXT_JUSTIFICATION_SPACE_AT_START) { >+ flags.mSpaceAtStart = true; >+ if (stateBits & TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START) { >+ flags.mExtraSpaceAtStart = true; >+ } >+ } >+ if (stateBits & TEXT_JUSTIFICATION_SPACE_AT_END) { >+ flags.mSpaceAtEnd = true; >+ if (stateBits & TEXT_JUSTIFICATION_EXTRA_SPACE_AT_END) { >+ flags.mExtraSpaceAtEnd = true; >+ } >+ } >+ >+ int32_t spaces = >+ JustificationUtils::CountExpansionSpaces(mJustificationCount, flags); >+ if (spaces == 0 || mJustificationFlagsArray.IsEmpty()) { nit: !spaces >@@ -544,16 +541,18 @@ protected: > // This does *not* indicate the length of text currently mapped by the frame; > // instead it's a hint saying that this frame *wants* to map this much text > // so if we create a new continuation, this is where that continuation should > // start. > int32_t mContentLengthHint; > nscoord mAscent; > gfxTextRun* mTextRun; > >+ mozilla::JustificationFlags mJustificationFlags; >+ Don't you forget to remove this? Otherwise, looks okay to me. Please ask additional review to roc with new patch. Thank you very much for your great work!!
Attachment #8507580 -
Flags: review?(masayuki) → review+
Assignee | ||
Comment 71•9 years ago
|
||
I think the most critical part in the patch need to have additional review is the added state bits for text frames.
Attachment #8507580 -
Attachment is obsolete: true
Attachment #8507676 -
Flags: review?(roc)
Comment on attachment 8507676 [details] [diff] [review] patch, r=masayuki Review of attachment 8507676 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/generic/JustificationUtils.h @@ +27,5 @@ > +struct JustificationCount > +{ > + // Number of expansion opportunities inside a given range of clusters. > + // It does not include any points before or after the range of clusters. > + int32_t mInnerOpportunities; Needs a bit more explanation, maybe with some examples. A JustificationCount will be associated with a range of clusters, right? If that range of clusters includes a trailing space character, does that space count as an inner opportunity? @@ +31,5 @@ > + int32_t mInnerOpportunities; > + // Whether it is possible that there are insert points before or > + // after the range of clusters. > + bool mIsStartJustifiable; > + bool mIsEndJustifiable; What do these mean, more precisely? Can you give some examples? @@ +41,5 @@ > + { > + } > + > + // Claim that the last opportunity should be cancelled > + // because the tailing space just gets trimmed. trailing ::: layout/generic/nsFrameStateBits.h @@ +416,5 @@ > +// See nsLineLayout::ApplyFrameJustification and JustificationUtils.h. > +FRAME_STATE_BIT(Text, 33, TEXT_JUSTIFICATION_SPACE_AT_START) > +FRAME_STATE_BIT(Text, 34, TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START) > +FRAME_STATE_BIT(Text, 35, TEXT_JUSTIFICATION_SPACE_AT_END) > +FRAME_STATE_BIT(Text, 36, TEXT_JUSTIFICATION_EXTRA_SPACE_AT_END) These bits conflict with Generic bits NS_FRAME_DRAWING_AS_PAINTSERVER and NS_FRAME_UPDATE_LAYER_TREE :-( I don't think we have any implementation-reserved bits available for textframes. Since justification doesn't need to be super-well optimized maybe we can use a FrameProperty to hold the bits for justification. ::: layout/generic/nsLineLayout.h @@ +447,5 @@ > + { > + return mJustificationCount.mIsEndJustifiable; > + } > + > + bool ParticipatesJustification() const ParticipatesInJustification
Attachment #8507676 -
Flags: review?(roc) → review-
Assignee | ||
Comment 73•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #72) > Comment on attachment 8507676 [details] [diff] [review] > patch, r=masayuki > > ::: layout/generic/nsFrameStateBits.h > @@ +416,5 @@ > > +// See nsLineLayout::ApplyFrameJustification and JustificationUtils.h. > > +FRAME_STATE_BIT(Text, 33, TEXT_JUSTIFICATION_SPACE_AT_START) > > +FRAME_STATE_BIT(Text, 34, TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START) > > +FRAME_STATE_BIT(Text, 35, TEXT_JUSTIFICATION_SPACE_AT_END) > > +FRAME_STATE_BIT(Text, 36, TEXT_JUSTIFICATION_EXTRA_SPACE_AT_END) > > These bits conflict with Generic bits NS_FRAME_DRAWING_AS_PAINTSERVER and > NS_FRAME_UPDATE_LAYER_TREE :-( > > I don't think we have any implementation-reserved bits available for > textframes. Since justification doesn't need to be super-well optimized > maybe we can use a FrameProperty to hold the bits for justification. Yes, that's great! I was looking for something like this to hold the data instead of the state bits, since I might soon need more data to be stored with text frames.
Assignee | ||
Comment 74•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #70) > Comment on attachment 8507580 [details] [diff] [review] > patch > > >@@ -389,39 +391,41 @@ protected: > > nsOverflowAreas mOverflowAreas; > > > > // From reflow-state > > mozilla::LogicalMargin mMargin; > > mozilla::LogicalMargin mBorderPadding; > > mozilla::LogicalMargin mOffsets; > > > > // state for text justification > >+ mozilla::JustificationCount mJustificationCount; > >+ mozilla::JustificationFlags mJustificationFlags; > > > > // PerFrameData flags > > #define PFD_RELATIVEPOS 0x00000001 > > #define PFD_ISTEXTFRAME 0x00000002 > > #define PFD_ISNONEMPTYTEXTFRAME 0x00000004 > > #define PFD_ISNONWHITESPACETEXTFRAME 0x00000008 > > #define PFD_ISLETTERFRAME 0x00000010 > > #define PFD_RECOMPUTEOVERFLOW 0x00000020 > > #define PFD_ISBULLET 0x00000040 > > #define PFD_SKIPWHENTRIMMINGWHITESPACE 0x00000080 > >+#define PFD_ISEMPTY 0x00000100 > >+#define PFD_LASTFLAG PFD_ISEMPTY > > > >+ // Other state we use > >+ uint16_t mFlags; > > Although, this isn't a scope of this bug, perhaps, this should be bool flags > instead of hacky bit fields... Should we have a new bug for this? I guess it would be painful to make them bool flags and init them manually.
Assignee | ||
Comment 75•9 years ago
|
||
Attachment #8507676 -
Attachment is obsolete: true
Attachment #8508438 -
Flags: review?(roc)
Comment on attachment 8508438 [details] [diff] [review] patch, r=masayuki Review of attachment 8508438 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/generic/JustificationUtils.h @@ +41,5 @@ > + // Number of expansion opportunities inside a given range of > + // clusters. It does not include any opportunities before or after > + // the range of clusters. > + int32_t mInnerOpportunities; > + // Whether it is possible that there are expansion opportunities I think you should remove "it is possible that" @@ +70,5 @@ > + } > + } > +}; > + > +struct JustificationFlags Need comments explaining what this is for and what the flags mean. @@ +122,5 @@ > + // justification flags of two adjacent parts. > + > + static void AdjustSpaceAtStart(JustificationFlags& aFlags, > + JustificationFlags& aPrevFlags, > + int32_t& aCount) Please add comments explaining what these functions mean. Would it make sense to make these member functions of JustificationFlags?
Attachment #8508438 -
Flags: review?(roc) → review-
Assignee | ||
Comment 77•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #76) > Comment on attachment 8508438 [details] [diff] [review] > patch, r=masayuki > > Review of attachment 8508438 [details] [diff] [review]: > ----------------------------------------------------------------- > > ::: layout/generic/JustificationUtils.h > @@ +41,5 @@ > > + // Number of expansion opportunities inside a given range of > > + // clusters. It does not include any opportunities before or after > > + // the range of clusters. > > + int32_t mInnerOpportunities; > > + // Whether it is possible that there are expansion opportunities > > I think you should remove "it is possible that" I don't think so. There is not always an expansion opportunity when the given side is justifiable. The most obvious case is the line start and line end.
Assignee | ||
Comment 78•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #76) > Comment on attachment 8508438 [details] [diff] [review] > patch, r=masayuki > > Review of attachment 8508438 [details] [diff] [review]: > ----------------------------------------------------------------- > > @@ +70,5 @@ > > + } > > + } > > +}; > > + > > +struct JustificationFlags > > Need comments explaining what this is for and what the flags mean. Isn't it obvious enough with the names and the explaination of the algorithm above? I feel additional comments here are redundant. > > @@ +122,5 @@ > > + // justification flags of two adjacent parts. > > + > > + static void AdjustSpaceAtStart(JustificationFlags& aFlags, > > + JustificationFlags& aPrevFlags, > > + int32_t& aCount) > > Please add comments explaining what these functions mean. I feel it's hard to explain their function individually. But they are short enough and properly commented in the code. I don't think we need more comments on them. > Would it make sense to make these member functions of JustificationFlags? It might make sense, but I prefer keeping them where they are now, because they not only change the flags, but also participate in the algorithm and count the expansion opportunities for their caller. They were inlined in the callers directly in former patches, and be separated out as functions because they are common parts in two places.
Assignee | ||
Comment 79•9 years ago
|
||
Adjust some comments.
Attachment #8508438 -
Attachment is obsolete: true
Attachment #8511741 -
Flags: review?(roc)
Comment on attachment 8511741 [details] [diff] [review] patch, r=masayuki Review of attachment 8511741 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/generic/JustificationUtils.h @@ +26,5 @@ > + * In the following examples, we use "A" to represent justifiable > + * clusters, and "a" for non-justifiable ones. > + * > + * If we have a string "aaAA", the inner expansion opportunites (marked > + * as stars) would be "a a*A*A". In addition to the inner expansion Should this be aa*A*A ? @@ +35,5 @@ > + * If a line is "AaaAA", the final result would be "A>>aa<<A><A", where > + * ">" means a space expanded from the cluster before, and "<" means one > + * from the cluster after. Note that, although the string of this line > + * is justifiable in both sides according to the rule above, there are > + * no expansion opportunities, because they are line ends. You use * for expansion opportunities in the previous paragraph and >> and < in this paragraph. Can you be consistent and use >> and < in the previous paragraph instead of *? @@ +74,5 @@ > + } > +}; > + > +struct JustificationFlags > +{ This still needs documentation. I had to read far ahead in the patch to realize that these flags are actually per-(non-collapsed-)character! That, at least, should be documented here. @@ +76,5 @@ > + > +struct JustificationFlags > +{ > + bool mSpaceAtStart : 1; > + bool mExtraSpaceAtStart : 1; It's not clear what mExtraSpaceAtStart means, even after reading the explanation at the start of the file. Also, these record expansion opportunities, not actual 0x20 space characters, right? If so we should change the names. @@ +130,5 @@ > + // flags according to the flags of the previous adjacent part, and > + // increase the count if it is a new opportunity. > + static void AdjustSpaceAtStart(JustificationFlags& aFlags, > + JustificationFlags& aPrevFlags, > + int32_t& aCount) It's still not very clear what this function does. It seems like we're combining justification data from a previous text run with justification data for the next text run? I'm sorry to be picky about the comments here but making this code easy to understand now will save us a lot of time and effort in the future. It would probably help if the explanation of the algorithm above referenced the actual types and fields that store data used by the algorithm. ::: layout/generic/nsLineLayout.cpp @@ +2484,5 @@ > + struct > + { > + nscoord mAvailable; > + nscoord mConsumed; > + } mWidth; These need documentation too.
Attachment #8511741 -
Flags: review?(roc) → review-
Assignee | ||
Comment 81•9 years ago
|
||
Attachment #8511741 -
Attachment is obsolete: true
Attachment #8513122 -
Flags: review?(roc)
Comment on attachment 8513122 [details] [diff] [review] patch, r=masayuki Review of attachment 8513122 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/generic/JustificationUtils.h @@ +50,5 @@ > + * case is similar for its end side. The first and the last justifi- > + * cation units of a span inherit the justification spaces at start and > + * end respectively from the span. All justification spaces are finally > + * applied to clusters, where they take their effect. The struct > + * JustificationFlags is used to track the information in this phase. Are we doing this because, given the text "a b c", we want selection of "b" to include half the space between "a" and "b" and on the other side half the space between "b" and "c"? If so, please say so. I still find this whole patch very hard to understand. The first phase makes sense. The second phase is very confusing. Here are some suggestions: -- I think we should rename JustificationCount to JustificationOpportunities, since it's not just a count. -- I think we should have a method that just does "phase one", i.e. it gets called for each span and does nothing but compute the JustificationDataForSpan for that span, calling itself recursively to walk over the children. -- I think we should rename JustificationFlags to JustificationAssignment. I think it should include the number of inner opportunities actually assigned (an integer), and the number of half-opportunities assigned to each end; it would be clearest if the latter fields are floats. -- I think we should have a specific method for phase two, that gets called for each span and computes for each span (and ultimately each frame) its JustificationAssignment. -- I think we should attach the JustificationAssignment to the frame as a FrameProperty, just dynamically allocated as a struct. How does that sound? @@ +60,5 @@ > + // any opportunities between this span and the one before or after. > + int32_t mInnerOpportunities; > + // The justifiability of the start and end sides of the span. > + bool mIsStartJustifiable; > + bool mIsEndJustifiable; Somewhere I would expect to see a method that takes two JustificationCounts, one for each part of a consecutive run of text, and merges them, but I don't see it anywhere :-(. @@ +150,5 @@ > + // it forms a new opportunity. > + static void AdjustSpaceAtStart(JustificationFlags& aFlags, > + JustificationFlags& aPrevFlags, > + int32_t& aCount) > + { I still find these methods hard to understand :-(.
Attachment #8513122 -
Flags: review?(roc) → review-
Assignee | ||
Comment 83•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #82) > Comment on attachment 8513122 [details] [diff] [review] > patch, r=masayuki > > Review of attachment 8513122 [details] [diff] [review]: > ----------------------------------------------------------------- > > I still find this whole patch very hard to understand. The first phase makes > sense. The second phase is very confusing. Here are some suggestions: > > -- I think we should rename JustificationCount to > JustificationOpportunities, since it's not just a count. > > -- I think we should have a method that just does "phase one", i.e. it gets > called for each span and does nothing but compute the > JustificationDataForSpan for that span, calling itself recursively to walk > over the children. I think completely separate the two phases may complexify the code. > -- I think we should rename JustificationFlags to JustificationAssignment. I > think it should include the number of inner opportunities actually assigned > (an integer), I don't think including number of inner opportunities is useful, since we always have to recaculate it inside text frames when computing the assignment for clusters. > and the number of half-opportunities assigned to each end; it > would be clearest if the latter fields are floats. We can store sufficient information in 4 bits, why should we store it in 2 floats? I cannot agree with this suggestion. > -- I think we should attach the JustificationAssignment to the frame as a > FrameProperty, just dynamically allocated as a struct. I don't think so. 4 bits are enough for that information. Dynamically allocating has no sense other than adding the code complexity and reducing the performance.
Assignee | ||
Comment 84•9 years ago
|
||
I'd prefer make the comment more clear before changing the code. Would the folloing comment make more sense to you? /** * Jutification Algorithm * * The justification algorithm is based on expansion opportunities * between justifiable clusters. By this algorithm, there is one * expansion opportunity at each side of a justifiable cluster, and * at most one opportunity between two clusters. For example, if there * is a line in a Chinese document is: "你好世界hello world", then * the expansion opportunities would be: * * 你 好 世 界 hello ' ' world * ^ ^ ^ ^ ^ ^ * The spacing left in a line will then be distributed equally to each * opportunities. Because we want that, only justifiable clusters get * expanded, and the split point between two justifiable clusters would * be at the center of them, each expansion opportunities will be filled * by two justification space. The example above would be: * * 你 | 好 | 世 | 界 |hello| ' ' |world * * For a flatten sequence of clusters, this algorithm could be completed * in one pass. It checks whether a cluster is justifiable, and assigns * justification spaces to them. Since it is unknown whether the cluster * after is justifiable or not, every time when a justifiable is found, * the two justification spaces of the expansion opportunity after it * are both assigned to it. When a new justifiable cluster is found, it * will be checked whether the cluster before is also justifiable, and * then the assigned space would be adjusted. This procedure is done by * JustificationUtils::SetSpaceAtEnd and AdjustSpaceAtStart. * * It becomes more complex when lines consist of nested spans instead of * a flatten sequence. To process spans, the algorithm is divided into * two phases. Since spans and clusters play similar roles in many * places in this algorithm, we call them justification units below. * * In the first phase, the algorithm for flatten sequences described * above is applied to each span. After that, justification spaces of * opportunities between units inside a same span get assigned. Then * in the second phase, justification spaces assigned to a span are * recursively assigned to the first and last units inside the span. * The space assignment is recoreded in structure JustificationFlags. * * In the practical code of the algorithm, there are some extra works * in the two phases. In the first phase, expansion opportunities are * counted for calculating the size of each justification space. And in * the second phase, spans are expanded accordingly. */
Flags: needinfo?(roc)
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #84) > * 你 好 世 界 hello ' ' world > * ^ ^ ^ ^ ^ ^ Unfortunately this is difficult to read because in various renderings (Firefox, eclipse, gedit) the ^ characters end up misaligned because the Chinese characters are not truly monospace :-(. Either use inline marks like you had before, or use Latin characters in place of the Chinese characters.
Flags: needinfo?(roc)
Assignee | ||
Comment 86•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #85) > (In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #84) > > * 你 好 世 界 hello ' ' world > > * ^ ^ ^ ^ ^ ^ > > Unfortunately this is difficult to read because in various renderings > (Firefox, eclipse, gedit) the ^ characters end up misaligned because the > Chinese characters are not truly monospace :-(. Either use inline marks like > you had before, or use Latin characters in place of the Chinese characters. OK, so I use inline marks now: /** * Jutification Algorithm * * The justification algorithm is based on expansion opportunities * between justifiable clusters. By this algorithm, there is one * expansion opportunity at each side of a justifiable cluster, and * at most one opportunity between two clusters. For example, if there * is a line in a Chinese document is: "你好世界hello world", then * the expansion opportunities (marked as '*') would be: * * 你*好*世*界*hello*' '*world * * The spacing left in a line will then be distributed equally to each * opportunities. Because we want that, only justifiable clusters get * expanded, and the split point between two justifiable clusters would * be at the center of them, each expansion opportunities will be filled * by two justification space. The example above would be: * * 你 | 好 | 世 | 界 |hello| ' ' |world * * For a flatten sequence of clusters, this algorithm could be completed * in one pass. It checks whether a cluster is justifiable, and assigns * justification spaces to them. Since it is unknown whether the cluster * after is justifiable or not, every time when a justifiable is found, * the two justification spaces of the expansion opportunity after it * are both assigned to it. When a new justifiable cluster is found, it * will be checked whether the cluster before is also justifiable, and * then the assigned space would be adjusted. This procedure is done by * JustificationUtils::SetSpaceAtEnd and AdjustSpaceAtStart. * * It becomes more complex when lines consist of nested spans instead of * a flatten sequence. To process spans, the algorithm is divided into * two phases. Since spans and clusters play similar roles in many * places in this algorithm, we call them justification units below. * * In the first phase, the algorithm for flatten sequences described * above is applied to each span. After that, justification spaces of * opportunities between units inside a same span get assigned. Then * in the second phase, justification spaces assigned to a span are * recursively assigned to the first and last units inside the span. * The space assignment is recoreded in structure JustificationFlags. * * In the practical code of the algorithm, there are some extra works * in the two phases. In the first phase, expansion opportunities are * counted for calculating the size of each justification space. And in * the second phase, spans are expanded accordingly. */
Flags: needinfo?(roc)
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #84) > * Then > * in the second phase, justification spaces assigned to a span are > * recursively assigned to the first and last units inside the span. > * The space assignment is recoreded in structure JustificationFlags. This isn't as clear as the rest of the comment. When you say "justification spaces assigned to a span", you don't mean all the spaces assigned to the span, you just mean the spaces assigned to its ends, right? The way you've described the algorithm here suggests an alternative implementation that might be easier to understand: walk the spans recursively and keep track of the previous text frame's PFD. When you see the next PFD, you can find out what the next cluster after the previous text frame is (if there isn't one), and then you can assign justification space to the previous text frame. That way you should be able to make the code look very much like the one-pass algorithm for the flattened sequence of clusters. Does that make sense?
Assignee | ||
Comment 88•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #87) > (In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #84) > > * Then > > * in the second phase, justification spaces assigned to a span are > > * recursively assigned to the first and last units inside the span. > > * The space assignment is recoreded in structure JustificationFlags. > > This isn't as clear as the rest of the comment. When you say "justification > spaces assigned to a span", you don't mean all the spaces assigned to the > span, you just mean the spaces assigned to its ends, right? Right. > The way you've described the algorithm here suggests an alternative > implementation that might be easier to understand: walk the spans > recursively and keep track of the previous text frame's PFD. When you see > the next PFD, you can find out what the next cluster after the previous text > frame is (if there isn't one), and then you can assign justification space > to the previous text frame. That way you should be able to make the code > look very much like the one-pass algorithm for the flattened sequence of > clusters. Does that make sense? Yes, that makes sense to me.
Assignee | ||
Comment 89•9 years ago
|
||
Attachment #8513122 -
Attachment is obsolete: true
Attachment #8514023 -
Flags: review?(roc)
Assignee | ||
Updated•9 years ago
|
Flags: needinfo?(roc)
Comment on attachment 8514023 [details] [diff] [review] patch Review of attachment 8514023 [details] [diff] [review]: ----------------------------------------------------------------- ::: layout/generic/JustificationUtils.h @@ +90,5 @@ > +{ > + bool mSpaceAtStart : 1; > + bool mExtraSpaceAtStart : 1; > + bool mSpaceAtEnd : 1; > + bool mExtraSpaceAtEnd : 1; I still think it's going to be clearer to call this JustificationAssignment and use two uint8_ts (mSpacesAtStart, mSpacesAtEnd) instead of 4 bools. See below. Also I think using the word "space" here is confusing since we use the word "space" for other things in text, especially actual space characters. Maybe "slots"? So "mSlotsAtStart"? ::: layout/generic/nsLineLayout.cpp @@ +2432,5 @@ > +}; > + > +int32_t > +nsLineLayout::ComputeFrameJustification(PerSpanData* aPSD, > + JustificationComputationState& aState) Somewhere you need to document what the return value of this function means. @@ +2455,5 @@ > > + JustificationFlags& flags = pfd->mJustificationFlags; > + if (count.mIsStartJustifiable && aState.mLastParticipant) { > + JustificationUtils::AdjustSpaceAtStart( > + flags, aState.mLastParticipant->mJustificationFlags, result); Right now we set some flags for a pfd and then when we reach the next pfd, we overwrite the flags for the previous pfd. I think it would be clearer to set the correct final values for mLastParticipant's end and this pfd's start here. When we reach the end of the line, set the last mParticipant's end-gap-count correctly. The important thing is to set the computed flags/gap-count for each end of the frane only once. ::: layout/generic/nsTextFrame.cpp @@ +8874,5 @@ > + flags |= TEXT_JUSTIFICATION_SPACE_AT_START; > + if (aFlags.mExtraSpaceAtStart) { > + flags |= TEXT_JUSTIFICATION_EXTRA_SPACE_AT_START; > + } > + } This (and other code) would be simpler if instead of having JustificationFlags include 2 bools for each end, it included a single uint8_t for each end (whose value is 0, 1 or 2).
Attachment #8514023 -
Flags: review?(roc) → review-
Assignee | ||
Comment 91•9 years ago
|
||
Attachment #8514023 -
Attachment is obsolete: true
Attachment #8514767 -
Flags: review?(roc)
Comment on attachment 8514767 [details] [diff] [review] patch Review of attachment 8514767 [details] [diff] [review]: ----------------------------------------------------------------- This is much much better, thank you! ::: layout/generic/nsLineLayout.cpp @@ +613,5 @@ > pfd->mBorderPadding = LogicalMargin(frameWM); > pfd->mOffsets = LogicalMargin(frameWM); > > + pfd->mJustificationInfo = JustificationInfo(); > + pfd->mJustificationAssignment = JustificationAssignment(); We don't need these I think. @@ +2367,4 @@ > if (trimOutput.mDeltaWidth) { > pfd->mBounds.ISize(lineWM) -= trimOutput.mDeltaWidth; > > + if (!pfd->mNext) { Why are you checking pfd->mNext here? I think there could be multiple textframes all being trimmed. ::: layout/generic/nsTextFrame.cpp @@ +3148,5 @@ > + mJustificationAssignments[i - mJustificationArrayStart]; > + aSpacing[i - aStart].mBefore += > + mJustificationSpacing * assign.mGapsAtStart; > + aSpacing[i - aStart].mAfter += > + mJustificationSpacing * assign.mGapsAtEnd; I'm worried that the total spacing added will not add up to the total justification spacing for the frame due to rounding errors. I think you need to do what you do in nsLineLayout and keep a running total of how many gaps we've allocated, and compute the rounded-to-nscoord next/prev amount consumed and set the width of each gap to the difference between those values.
Attachment #8514767 -
Flags: review?(roc) → review-
Assignee | ||
Comment 93•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #92) > Comment on attachment 8514767 [details] [diff] [review] > patch > > Review of attachment 8514767 [details] [diff] [review]: > ----------------------------------------------------------------- > > This is much much better, thank you! > > ::: layout/generic/nsLineLayout.cpp > @@ +613,5 @@ > > pfd->mBorderPadding = LogicalMargin(frameWM); > > pfd->mOffsets = LogicalMargin(frameWM); > > > > + pfd->mJustificationInfo = JustificationInfo(); > > + pfd->mJustificationAssignment = JustificationAssignment(); > > We don't need these I think. I didn't think so either until I saw an unexpected failure on valgrind test. You can find the result here: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=5a9d199b21d6 Anyway, I think it is safer to do so. > ::: layout/generic/nsTextFrame.cpp > @@ +3148,5 @@ > > + mJustificationAssignments[i - mJustificationArrayStart]; > > + aSpacing[i - aStart].mBefore += > > + mJustificationSpacing * assign.mGapsAtStart; > > + aSpacing[i - aStart].mAfter += > > + mJustificationSpacing * assign.mGapsAtEnd; > > I'm worried that the total spacing added will not add up to the total > justification spacing for the frame due to rounding errors. > > I think you need to do what you do in nsLineLayout and keep a running total > of how many gaps we've allocated, and compute the rounded-to-nscoord > next/prev amount consumed and set the width of each gap to the difference > between those values. I'm just using what method was used in those places. I'm fine with changing it, though.
Assignee | ||
Comment 94•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #93) > (In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #92) > > Comment on attachment 8514767 [details] [diff] [review] > > patch > > > > Review of attachment 8514767 [details] [diff] [review]: > > ----------------------------------------------------------------- > > > ::: layout/generic/nsTextFrame.cpp > > @@ +3148,5 @@ > > > + mJustificationAssignments[i - mJustificationArrayStart]; > > > + aSpacing[i - aStart].mBefore += > > > + mJustificationSpacing * assign.mGapsAtStart; > > > + aSpacing[i - aStart].mAfter += > > > + mJustificationSpacing * assign.mGapsAtEnd; > > > > I'm worried that the total spacing added will not add up to the total > > justification spacing for the frame due to rounding errors. > > > > I think you need to do what you do in nsLineLayout and keep a running total > > of how many gaps we've allocated, and compute the rounded-to-nscoord > > next/prev amount consumed and set the width of each gap to the difference > > between those values. > > I'm just using what method was used in those places. I'm fine with changing > it, though. Well, mBefore and mAfter in Spacing are also gfxFloat, why do we need to use the running total method? I think the graphics part can process that cases correctly.
Flags: needinfo?(roc)
Spacing values should be rounded to the nearest nscoord. See definition of Spacing in gfxFont.h. That rounding introduces error and accumulated errors could lead to the total spacing added being different from the justification width allocated to the frame.
Assignee | ||
Comment 96•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #95) > Spacing values should be rounded to the nearest nscoord. See definition of > Spacing in gfxFont.h. That rounding introduces error and accumulated errors > could lead to the total spacing added being different from the justification > width allocated to the frame. OK, I'll fix it.
Flags: needinfo?(roc)
Assignee | ||
Comment 97•9 years ago
|
||
Attachment #8514767 -
Attachment is obsolete: true
Attachment #8514847 -
Flags: review?(roc)
Comment on attachment 8514847 [details] [diff] [review] patch Review of attachment 8514847 [details] [diff] [review]: ----------------------------------------------------------------- Great!
Attachment #8514847 -
Flags: review?(roc) → review+
Assignee | ||
Comment 99•9 years ago
|
||
Finally got the review granted, then I learn that the unrestricted union is not allowed in our code, so sad...
Assignee | ||
Comment 100•9 years ago
|
||
Should be good now: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=8d687b714a70 roc, you may want to check the code I change in this patch, but I think the changes should be fine.
Attachment #8514847 -
Attachment is obsolete: true
Attachment #8515303 -
Flags: feedback?(roc)
Attachment #8515303 -
Flags: feedback?(roc) → feedback+
Assignee | ||
Updated•9 years ago
|
Attachment #8515303 -
Flags: review+
Assignee | ||
Updated•9 years ago
|
Keywords: checkin-needed
Assignee | ||
Comment 101•9 years ago
|
||
I guess we can move the JustificationApplicationState to MFBT, but I don't have a good idea about the name.
Assignee | ||
Comment 102•9 years ago
|
||
rebase to the latest m-c
Attachment #8515303 -
Attachment is obsolete: true
Attachment #8515695 -
Flags: review+
Comment 103•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/53d51e7fbb9e
Keywords: checkin-needed
Comment 104•9 years ago
|
||
sorry had to back this out for test failures like https://treeherder.mozilla.org/ui/logviewer.html#?job_id=3563495&repo=mozilla-inbound
Assignee | ||
Comment 105•9 years ago
|
||
For justification-cjk-extension, in systems where the fonts lack the support of the Plane 2 characters, the two strings have different original width (see this attachment), hence the result is different. I don't know why it works fine previously, but the its current result is acceptable. How can we fix this reftest? Is there any font covers all characters with a fixed width? Any idea?
Flags: needinfo?(jfkthame)
Assignee | ||
Comment 106•9 years ago
|
||
I have no idea about this regression on Android platform. Any suggestion, roc?
Flags: needinfo?(roc)
No. You probably should set up an Android debugging environment, it'll be worth it in the long run.
Flags: needinfo?(roc)
Comment 108•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #105) > Created attachment 8517762 [details] > comparison for justification-cjk-extension > > For justification-cjk-extension, in systems where the fonts lack the support > of the Plane 2 characters, the two strings have different original width > (see this attachment), hence the result is different. I don't know why it > works fine previously, but the its current result is acceptable. > > How can we fix this reftest? Is there any font covers all characters with a > fixed width? Any idea? Not sure what range of characters you need to be fixed width, but http://sourceforge.net/adobe/csso9ntestfonts/wiki/Home/ might be of use.
Assignee | ||
Comment 109•9 years ago
|
||
(In reply to fantasai from comment #108) > Not sure what range of characters you need to be fixed width, but > http://sourceforge.net/adobe/csso9ntestfonts/wiki/Home/ might be of use. Oh that's great! I found there is another font named Adobe Blank which should be enough in this case.
Flags: needinfo?(jfkthame)
Assignee | ||
Comment 110•9 years ago
|
||
This patch fixes the reftests. But I'm not quite sure whether the changes are valid. try server: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=20180cb3d3db
Attachment #8517937 -
Flags: review?(roc)
Gerv, is it OK for us to land in mozilla-central (for testing only) the Adobe font+license in https://bugzilla.mozilla.org/attachment.cgi?id=8517937 ?
Flags: needinfo?(gerv)
Comment on attachment 8517937 [details] [diff] [review] patch for fixing reftests Review of attachment 8517937 [details] [diff] [review]: ----------------------------------------------------------------- It seems to me we might be best served by having our own test font (or modifying one of our existing test fonts) to have the same glyphs and metrics for a few Chinese characters, including the plane-2 characters, and having this test use that font and those characters. That would be simple and avoid any licensing issues. ::: layout/reftests/bugs/503399.html @@ +5,5 @@ > <style type="text/css"> > > html,body { > color:black; background-color:white; font-size:16px; > + font-family: serif; Do you know why this change is needed?
Attachment #8517937 -
Flags: review?(roc)
Assignee | ||
Comment 113•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #112) > Comment on attachment 8517937 [details] [diff] [review] > patch for fixing reftests > > Review of attachment 8517937 [details] [diff] [review]: > ----------------------------------------------------------------- > > It seems to me we might be best served by having our own test font (or > modifying one of our existing test fonts) to have the same glyphs and > metrics for a few Chinese characters, including the plane-2 characters, and > having this test use that font and those characters. That would be simple > and avoid any licensing issues. > > ::: layout/reftests/bugs/503399.html > @@ +5,5 @@ > > <style type="text/css"> > > > > html,body { > > color:black; background-color:white; font-size:16px; > > + font-family: serif; > > Do you know why this change is needed? TBH, I didn't know. But after you asked, I realize that it is a wrong fix which just simply make it skip the justification procedure for this test. The reason of the failure on this test seems to be the minor difference of the distribution of the spacing. In fact, this minor difference exists in all our current version, even in all platform which the test passes. If you open attachment 8517789 [details] and zoom in, you can always observe the difference. It seems that the new algorithm slightly enlarges the difference in some platform in this testcase, which causes the failure. I have no idea how to fix it... Maybe we can try different position, and see if there is a place matches exactly in the two pages?
Comment 114•9 years ago
|
||
SIL OFL 1.1 is no problem at all. Go right ahead. If it's just test code, no need to adjust about:license. Gerv
Flags: needinfo?(gerv)
Comment 115•9 years ago
|
||
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #105) > Created attachment 8517762 [details] > comparison for justification-cjk-extension > > For justification-cjk-extension, in systems where the fonts lack the support > of the Plane 2 characters, the two strings have different original width > (see this attachment), hence the result is different. I don't know why it > works fine previously, but the its current result is acceptable. > > How can we fix this reftest? Is there any font covers all characters with a > fixed width? Any idea? Maybe you could use the small test font we already have in layout/reftest/fonts/gw432047.ttf? I believe this includes a CJK character in Plane 2 as well as a BMP one, so provided you use those specific characters in the test, it should avoid fallback/.notdef issues.
(In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #113) > The reason of the failure on this test seems to be the minor difference of > the distribution of the spacing. In fact, this minor difference exists in > all our current version, even in all platform which the test passes. If you > open attachment 8517789 [details] and zoom in, you can always observe the > difference. It seems that the new algorithm slightly enlarges the difference > in some platform in this testcase, which causes the failure. I have no idea > how to fix it... Maybe we can try different position, and see if there is a > place matches exactly in the two pages? If you use a test font where the characters are just solid boxes, maybe we can fuzz the test results to account for small alignment differences.
Assignee | ||
Comment 117•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #116) > (In reply to Xidorn Quan [:xidorn] (UTC+11) from comment #113) > > The reason of the failure on this test seems to be the minor difference of > > the distribution of the spacing. In fact, this minor difference exists in > > all our current version, even in all platform which the test passes. If you > > open attachment 8517789 [details] and zoom in, you can always observe the > > difference. It seems that the new algorithm slightly enlarges the difference > > in some platform in this testcase, which causes the failure. I have no idea > > how to fix it... Maybe we can try different position, and see if there is a > > place matches exactly in the two pages? > > If you use a test font where the characters are just solid boxes, maybe we > can fuzz the test results to account for small alignment differences. But the problem is that, in this test, we are checking the position of the caret. Using solid boxes and fuzzing it simply makes the test meaningless again, like my fix before.
Assignee | ||
Comment 118•9 years ago
|
||
Should be good now: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=aab42943095e
Attachment #8517937 -
Attachment is obsolete: true
Attachment #8518653 -
Flags: review?(roc)
Assignee | ||
Comment 119•9 years ago
|
||
Comment on attachment 8518653 [details] [diff] [review] patch for fixing reftests Well, not so good. The failure for b2g is trivial which I can fix immediately. But it seems that the test for 503399 never makes effect on Windows, which now cause a unexpected failure. Should we simply skip it on windows?
Attachment #8518653 -
Flags: review?(roc)
Maybe you should add 503399 to test_reftests_with_caret.html?
Assignee | ||
Comment 121•9 years ago
|
||
OK I'll try.
Assignee | ||
Comment 122•9 years ago
|
||
Should be fine now: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=6bf79646ee59 But it worth to mention that, in some of the platforms, test_reftests_with_caret is simply skipped. I'm not sure whether they can pass the tests once it is no longer skipped.
Attachment #8518653 -
Attachment is obsolete: true
Attachment #8519619 -
Flags: review?(roc)
Attachment #8519619 -
Flags: review?(roc) → review+
Assignee | ||
Comment 123•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/b36d7a550777 https://hg.mozilla.org/integration/mozilla-inbound/rev/5233176d1af1 https://hg.mozilla.org/integration/mozilla-inbound/rev/8fd4e3a06f17 I found I forgot to add r= flag for the reftest-fixing patch... Hope that won't be a big problem...
Comment 124•9 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/b36d7a550777 https://hg.mozilla.org/mozilla-central/rev/5233176d1af1 https://hg.mozilla.org/mozilla-central/rev/8fd4e3a06f17
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla36
You need to log in
before you can comment on or make changes to this bug.
Description
•