| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |