Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: Source/core/rendering/RenderBlockLineLayout.cpp

Issue 24998005: unicode-bidi: plaintext does not work properly when a line wraps (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « LayoutTests/fast/text/international/unicode-bidi-plaintext-line-wrap-expected.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ight reserved. 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ight reserved.
4 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2010 Google Inc. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, RenderObject* root, RenderObject* startObject) 1118 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, RenderObject* root, RenderObject* startObject)
1119 { 1119 {
1120 if (root != startObject) { 1120 if (root != startObject) {
1121 RenderObject* parent = startObject->parent(); 1121 RenderObject* parent = startObject->parent();
1122 setupResolverToResumeInIsolate(resolver, root, parent); 1122 setupResolverToResumeInIsolate(resolver, root, parent);
1123 notifyObserverEnteredObject(&resolver, startObject); 1123 notifyObserverEnteredObject(&resolver, startObject);
1124 } 1124 }
1125 } 1125 }
1126 1126
1127 // FIXME: BidiResolver should have this logic. 1127 // FIXME: BidiResolver should have this logic.
1128 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection Override override, bool previousLineBrokeCleanly) 1128 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection Override override, bool previousLineBrokeCleanly, bool isNewUBAParagraph)
1129 { 1129 {
1130 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead 1130 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
1131 // of the resolver owning the runs. 1131 // of the resolver owning the runs.
1132 ASSERT(&topResolver.runs() == &bidiRuns); 1132 ASSERT(&topResolver.runs() == &bidiRuns);
1133 ASSERT(topResolver.position() != endOfRuns); 1133 ASSERT(topResolver.position() != endOfRuns);
1134 RenderObject* currentRoot = topResolver.position().root(); 1134 RenderObject* currentRoot = topResolver.position().root();
1135 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea nly); 1135 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea nly);
1136 1136
1137 while (!topResolver.isolatedRuns().isEmpty()) { 1137 while (!topResolver.isolatedRuns().isEmpty()) {
1138 // It does not matter which order we resolve the runs as long as we reso lve them all. 1138 // It does not matter which order we resolve the runs as long as we reso lve them all.
1139 BidiRun* isolatedRun = topResolver.isolatedRuns().last(); 1139 BidiRun* isolatedRun = topResolver.isolatedRuns().last();
1140 topResolver.isolatedRuns().removeLast(); 1140 topResolver.isolatedRuns().removeLast();
1141 1141
1142 RenderObject* startObj = isolatedRun->object(); 1142 RenderObject* startObj = isolatedRun->object();
1143 1143
1144 // Only inlines make sense with unicode-bidi: isolate (blocks are alread y isolated). 1144 // Only inlines make sense with unicode-bidi: isolate (blocks are alread y isolated).
1145 // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the 1145 // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
1146 // tree to see which parent inline is the isolate. We could change enter Isolate 1146 // tree to see which parent inline is the isolate. We could change enter Isolate
1147 // to take a RenderObject and do this logic there, but that would be a l ayering 1147 // to take a RenderObject and do this logic there, but that would be a l ayering
1148 // violation for BidiResolver (which knows nothing about RenderObject). 1148 // violation for BidiResolver (which knows nothing about RenderObject).
1149 RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWi thinRoot(startObj, currentRoot)); 1149 RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWi thinRoot(startObj, currentRoot));
1150 ASSERT(isolatedInline); 1150 ASSERT(isolatedInline);
1151 1151
1152 InlineBidiResolver isolatedResolver; 1152 InlineBidiResolver isolatedResolver;
1153 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi(); 1153 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi();
1154 TextDirection direction = isolatedInline->style()->direction(); 1154 TextDirection direction = isolatedInline->style()->direction();
1155 if (unicodeBidi == Plaintext) 1155 if (unicodeBidi == Plaintext) {
1156 direction = determinePlaintextDirectionality(isolatedInline, startOb j); 1156 if (isNewUBAParagraph)
1157 else { 1157 direction = determinePlaintextDirectionality(isolatedInline, sta rtObj);
1158 else
1159 direction = determinePlaintextDirectionality(isolatedInline);
1160 } else {
1158 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride); 1161 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride);
1159 direction = isolatedInline->style()->direction(); 1162 direction = isolatedInline->style()->direction();
1160 } 1163 }
1161 isolatedResolver.setStatus(statusWithDirection(direction, isOverride(uni codeBidi))); 1164 isolatedResolver.setStatus(statusWithDirection(direction, isOverride(uni codeBidi)));
1162 1165
1163 setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, startOb j); 1166 setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, startOb j);
1164 1167
1165 // The starting position is the beginning of the first run within the is olate that was identified 1168 // The starting position is the beginning of the first run within the is olate that was identified
1166 // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the 1169 // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the
1167 // first run within the isolate. 1170 // first run within the isolate.
(...skipping 19 matching lines...) Expand all
1187 currentRoot = isolatedInline; 1190 currentRoot = isolatedInline;
1188 } 1191 }
1189 } 1192 }
1190 } 1193 }
1191 1194
1192 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd) 1195 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd)
1193 { 1196 {
1194 return segmentStart == segmentEnd; 1197 return segmentStart == segmentEnd;
1195 } 1198 }
1196 1199
1197 static inline void constructBidiRunsForLine(const RenderBlock* block, InlineBidi Resolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end OfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly) 1200 static inline void constructBidiRunsForLine(const RenderBlock* block, InlineBidi Resolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end OfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool is NewUBAParagraph)
1198 { 1201 {
1199 ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo(); 1202 ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
1200 if (!shapeInsideInfo || !shapeInsideInfo->hasSegments()) { 1203 if (!shapeInsideInfo || !shapeInsideInfo->hasSegments()) {
1201 constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly); 1204 constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly, isNewUBAParagraph);
1202 return; 1205 return;
1203 } 1206 }
1204 1207
1205 const SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges(); 1208 const SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
1206 ASSERT(segmentRanges.size()); 1209 ASSERT(segmentRanges.size());
1207 1210
1208 for (size_t i = 0; i < segmentRanges.size(); i++) { 1211 for (size_t i = 0; i < segmentRanges.size(); i++) {
1209 LineSegmentIterator iterator = segmentRanges[i].start; 1212 LineSegmentIterator iterator = segmentRanges[i].start;
1210 InlineIterator segmentStart(iterator.root, iterator.object, iterator.off set); 1213 InlineIterator segmentStart(iterator.root, iterator.object, iterator.off set);
1211 iterator = segmentRanges[i].end; 1214 iterator = segmentRanges[i].end;
1212 InlineIterator segmentEnd(iterator.root, iterator.object, iterator.offse t); 1215 InlineIterator segmentEnd(iterator.root, iterator.object, iterator.offse t);
1213 if (i) { 1216 if (i) {
1214 ASSERT(segmentStart.m_obj); 1217 ASSERT(segmentStart.m_obj);
1215 BidiRun* segmentMarker = createRun(segmentStart.m_pos, segmentStart. m_pos, segmentStart.m_obj, topResolver); 1218 BidiRun* segmentMarker = createRun(segmentStart.m_pos, segmentStart. m_pos, segmentStart.m_obj, topResolver);
1216 segmentMarker->m_startsSegment = true; 1219 segmentMarker->m_startsSegment = true;
1217 bidiRuns.addRun(segmentMarker); 1220 bidiRuns.addRun(segmentMarker);
1218 // Do not collapse midpoints between segments 1221 // Do not collapse midpoints between segments
1219 topResolver.midpointState().betweenMidpoints = false; 1222 topResolver.midpointState().betweenMidpoints = false;
1220 } 1223 }
1221 if (!segmentIsEmpty(segmentStart, segmentEnd)) { 1224 if (!segmentIsEmpty(segmentStart, segmentEnd)) {
1222 topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segme ntStart)); 1225 topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segme ntStart));
1223 constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, overr ide, previousLineBrokeCleanly); 1226 constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, overr ide, previousLineBrokeCleanly, isNewUBAParagraph);
1224 } 1227 }
1225 } 1228 }
1226 } 1229 }
1227 1230
1228 // This function constructs line boxes for all of the text runs in the resolver and computes their position. 1231 // This function constructs line boxes for all of the text runs in the resolver and computes their position.
1229 RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(unsigned bidiLevel, Bidi RunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, Verti calPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurem ents& wordMeasurements) 1232 RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(unsigned bidiLevel, Bidi RunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, Verti calPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurem ents& wordMeasurements)
1230 { 1233 {
1231 if (!bidiRuns.runCount()) 1234 if (!bidiRuns.runCount())
1232 return 0; 1235 return 0;
1233 1236
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 lastRootBox()->setLineBreakInfo(end.m_obj, end.m_pos, resolver.s tatus()); 1683 lastRootBox()->setLineBreakInfo(end.m_obj, end.m_pos, resolver.s tatus());
1681 } else { 1684 } else {
1682 VisualDirectionOverride override = (styleToUse->rtlOrdering() == Vis ualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualR ightToLeftOverride) : NoVisualOverride); 1685 VisualDirectionOverride override = (styleToUse->rtlOrdering() == Vis ualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualR ightToLeftOverride) : NoVisualOverride);
1683 1686
1684 if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && ! resolver.context()->parent()) { 1687 if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && ! resolver.context()->parent()) {
1685 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().object(), resolver.position().offset( )); 1688 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().object(), resolver.position().offset( ));
1686 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse-> unicodeBidi()))); 1689 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse-> unicodeBidi())));
1687 } 1690 }
1688 // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine. 1691 // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
1689 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); 1692 BidiRunList<BidiRun>& bidiRuns = resolver.runs();
1690 constructBidiRunsForLine(this, resolver, bidiRuns, end, override, la youtState.lineInfo().previousLineBrokeCleanly()); 1693 constructBidiRunsForLine(this, resolver, bidiRuns, end, override, la youtState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph);
1691 ASSERT(resolver.position() == end); 1694 ASSERT(resolver.position() == end);
1692 1695
1693 BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrok eCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0; 1696 BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrok eCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
1694 1697
1695 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) { 1698 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) {
1696 bidiRuns.logicallyLastRun()->m_hasHyphen = true; 1699 bidiRuns.logicallyLastRun()->m_hasHyphen = true;
1697 consecutiveHyphenatedLines++; 1700 consecutiveHyphenatedLines++;
1698 } else 1701 } else
1699 consecutiveHyphenatedLines = 0; 1702 consecutiveHyphenatedLines = 0;
1700 1703
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver ticalPositionCache); 3363 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver ticalPositionCache);
3361 3364
3362 setLineGridBox(lineGridBox); 3365 setLineGridBox(lineGridBox);
3363 3366
3364 // FIXME: If any of the characteristics of the box change compared to the ol d one, then we need to do a deep dirtying 3367 // FIXME: If any of the characteristics of the box change compared to the ol d one, then we need to do a deep dirtying
3365 // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping 3368 // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping
3366 // to this grid. 3369 // to this grid.
3367 } 3370 }
3368 3371
3369 } 3372 }
OLDNEW
« no previous file with comments | « LayoutTests/fast/text/international/unicode-bidi-plaintext-line-wrap-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698