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 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, | 826 InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, |
827 const BidiStatus& cleanLineBidiStatus) | 827 const BidiStatus& cleanLineBidiStatus) |
828 { | 828 { |
829 const ComputedStyle& styleToUse = styleRef(); | 829 const ComputedStyle& styleToUse = styleRef(); |
830 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated
(); | 830 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated
(); |
831 LineMidpointState& lineMidpointState = resolver.midpointState(); | 831 LineMidpointState& lineMidpointState = resolver.midpointState(); |
832 InlineIterator endOfLine = resolver.position(); | 832 InlineIterator endOfLine = resolver.position(); |
833 LayoutTextInfo layoutTextInfo; | 833 LayoutTextInfo layoutTextInfo; |
834 VerticalPositionCache verticalPositionCache; | 834 VerticalPositionCache verticalPositionCache; |
835 | 835 |
| 836 // Pagination may require us to delete and re-create a line due to floats. W
hen this happens, |
| 837 // we need to store the pagination strut in the meantime. |
| 838 LayoutUnit paginationStrutFromDeletedLine; |
| 839 |
836 LineBreaker lineBreaker(LineLayoutBlockFlow(this)); | 840 LineBreaker lineBreaker(LineLayoutBlockFlow(this)); |
837 | 841 |
838 while (!endOfLine.atEnd()) { | 842 while (!endOfLine.atEnd()) { |
839 bool logicalWidthIsAvailable = false; | |
840 | |
841 // The runs from the previous line should have been cleaned up. | 843 // The runs from the previous line should have been cleaned up. |
842 ASSERT(!resolver.runs().runCount()); | 844 ASSERT(!resolver.runs().runCount()); |
843 | 845 |
844 // FIXME: Is this check necessary before the first iteration or can it b
e moved to the end? | 846 // FIXME: Is this check necessary before the first iteration or can it b
e moved to the end? |
845 if (layoutState.endLine()) { | 847 if (layoutState.endLine()) { |
846 layoutState.setEndLineMatched(layoutState.endLineMatched() || matche
dEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus)); | 848 layoutState.setEndLineMatched(layoutState.endLineMatched() || matche
dEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus)); |
847 if (layoutState.endLineMatched()) { | 849 if (layoutState.endLineMatched()) { |
848 resolver.setPosition(InlineIterator(resolver.position().root(),
0, 0), 0); | 850 resolver.setPosition(InlineIterator(resolver.position().root(),
0, 0), 0); |
849 break; | 851 break; |
850 } | 852 } |
(...skipping 17 matching lines...) Expand all Loading... |
868 resolver.runs().deleteRuns(); | 870 resolver.runs().deleteRuns(); |
869 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). | 871 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). |
870 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0
), 0); | 872 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0
), 0); |
871 break; | 873 break; |
872 } | 874 } |
873 | 875 |
874 ASSERT(endOfLine != resolver.position()); | 876 ASSERT(endOfLine != resolver.position()); |
875 | 877 |
876 // This is a short-cut for empty lines. | 878 // This is a short-cut for empty lines. |
877 if (layoutState.lineInfo().isEmpty()) { | 879 if (layoutState.lineInfo().isEmpty()) { |
| 880 ASSERT(!paginationStrutFromDeletedLine); |
878 if (lastRootBox()) | 881 if (lastRootBox()) |
879 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), e
ndOfLine.offset(), resolver.status()); | 882 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), e
ndOfLine.offset(), resolver.status()); |
880 resolver.runs().deleteRuns(); | 883 resolver.runs().deleteRuns(); |
881 } else { | 884 } else { |
882 VisualDirectionOverride override = (styleToUse.rtlOrdering() == Visu
alOrder ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride : VisualRig
htToLeftOverride) : NoVisualOverride); | 885 VisualDirectionOverride override = (styleToUse.rtlOrdering() == Visu
alOrder ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride : VisualRig
htToLeftOverride) : NoVisualOverride); |
883 if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext && !r
esolver.context()->parent()) { | 886 if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext && !r
esolver.context()->parent()) { |
884 TextDirection direction = determinePlaintextDirectionality(resol
ver.position().root(), resolver.position().getLineLayoutItem(), resolver.positio
n().offset()); | 887 TextDirection direction = determinePlaintextDirectionality(resol
ver.position().root(), resolver.position().getLineLayoutItem(), resolver.positio
n().offset()); |
885 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse.u
nicodeBidi()))); | 888 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse.u
nicodeBidi()))); |
886 } | 889 } |
887 // FIXME: This ownership is reversed. We should own the BidiRunList
and pass it to createBidiRunsForLine. | 890 // FIXME: This ownership is reversed. We should own the BidiRunList
and pass it to createBidiRunsForLine. |
888 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); | 891 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); |
889 constructBidiRunsForLine(resolver, bidiRuns, endOfLine, override, la
youtState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph); | 892 constructBidiRunsForLine(resolver, bidiRuns, endOfLine, override, la
youtState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph); |
890 ASSERT(resolver.position() == endOfLine); | 893 ASSERT(resolver.position() == endOfLine); |
891 | 894 |
892 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun(); | 895 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun(); |
893 | 896 |
894 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) | 897 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) |
895 bidiRuns.logicallyLastRun()->m_hasHyphen = true; | 898 bidiRuns.logicallyLastRun()->m_hasHyphen = true; |
896 | 899 |
897 // Now that the runs have been ordered, we create the line boxes. | 900 // Now that the runs have been ordered, we create the line boxes. |
898 // At the same time we figure out where border/padding/margin should
be applied for | 901 // At the same time we figure out where border/padding/margin should
be applied for |
899 // inline flow boxes. | 902 // inline flow boxes. |
900 | 903 |
901 LayoutUnit oldLogicalHeight = logicalHeight(); | 904 LayoutUnit oldLogicalHeight = logicalHeight(); |
902 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status
().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositi
onCache, trailingSpaceRun, wordMeasurements); | 905 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status
().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositi
onCache, trailingSpaceRun, wordMeasurements); |
903 | 906 |
904 bidiRuns.deleteRuns(); | 907 bidiRuns.deleteRuns(); |
905 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). | 908 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). |
906 | 909 |
| 910 // If we decided to re-create the line due to pagination, we better
have a new line now. |
| 911 ASSERT(lineBox || !paginationStrutFromDeletedLine); |
| 912 |
907 if (lineBox) { | 913 if (lineBox) { |
908 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLi
ne.offset(), resolver.status()); | 914 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLi
ne.offset(), resolver.status()); |
909 if (layoutState.usesPaintInvalidationBounds()) | 915 if (layoutState.usesPaintInvalidationBounds()) |
910 layoutState.updatePaintInvalidationRangeFromBox(lineBox); | 916 layoutState.updatePaintInvalidationRangeFromBox(lineBox); |
911 | 917 |
912 if (paginated) { | 918 if (paginated) { |
913 LayoutUnit adjustment; | 919 if (paginationStrutFromDeletedLine) { |
914 adjustLinePositionForPagination(*lineBox, adjustment); | 920 // This is a line that got re-created because it got pus
hed to the next fragmentainer, and there |
915 if (adjustment) { | 921 // were floats in the vicinity that affected the availab
le width. Restore the pagination info |
916 LayoutUnit oldLineWidth = availableLogicalWidthForLine(o
ldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIndent
Text); | 922 // for this line. |
917 lineBox->moveInBlockDirection(adjustment); | 923 lineBox->setIsFirstAfterPageBreak(true); |
918 if (layoutState.usesPaintInvalidationBounds()) | 924 lineBox->setPaginationStrut(paginationStrutFromDeletedLi
ne); |
919 layoutState.updatePaintInvalidationRangeFromBox(line
Box); | 925 paginationStrutFromDeletedLine = LayoutUnit(); |
| 926 } else { |
| 927 LayoutUnit adjustment; |
| 928 adjustLinePositionForPagination(*lineBox, adjustment); |
| 929 if (adjustment) { |
| 930 LayoutUnit oldLineWidth = availableLogicalWidthForLi
ne(oldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIn
dentText); |
| 931 lineBox->moveInBlockDirection(adjustment); |
| 932 if (layoutState.usesPaintInvalidationBounds()) |
| 933 layoutState.updatePaintInvalidationRangeFromBox(
lineBox); |
920 | 934 |
921 if (availableLogicalWidthForLine(oldLogicalHeight + adju
stment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText) != o
ldLineWidth) { | 935 if (availableLogicalWidthForLine(oldLogicalHeight +
adjustment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText)
!= oldLineWidth) { |
922 // We have to delete this line, remove all floats th
at got added, and let line layout re-run. | 936 // We have to delete this line, remove all float
s that got added, and let line layout |
923 lineBox->deleteLine(); | 937 // re-run. We had just calculated the pagination
strut for this line, and we need to |
924 endOfLine = restartLayoutRunsAndFloatsInRange(oldLog
icalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver,
previousEndofLine); | 938 // stow it away, so that we can re-apply it when
the new line has been created. |
925 logicalWidthIsAvailable = true; | 939 paginationStrutFromDeletedLine = lineBox->pagina
tionStrut(); |
926 } else { | 940 ASSERT(paginationStrutFromDeletedLine); |
927 setLogicalHeight(lineBox->lineBottomWithLeading()); | 941 // We're also going to assume that we're right a
fter a page break when re-creating this |
| 942 // line, so it better be so. |
| 943 ASSERT(lineBox->isFirstAfterPageBreak()); |
| 944 lineBox->deleteLine(); |
| 945 endOfLine = restartLayoutRunsAndFloatsInRange(ol
dLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolv
er, previousEndofLine); |
| 946 } else { |
| 947 setLogicalHeight(lineBox->lineBottomWithLeading(
)); |
| 948 } |
928 } | 949 } |
929 } | 950 } |
930 } | 951 } |
931 } | 952 } |
932 } | 953 } |
933 | 954 |
934 if (!logicalWidthIsAvailable) { | 955 if (!paginationStrutFromDeletedLine) { |
935 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i) | 956 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i) |
936 setStaticPositions(LineLayoutBlockFlow(this), LineLayoutBox(line
Breaker.positionedObjects()[i]), DoNotIndentText); | 957 setStaticPositions(LineLayoutBlockFlow(this), LineLayoutBox(line
Breaker.positionedObjects()[i]), DoNotIndentText); |
937 | 958 |
938 if (!layoutState.lineInfo().isEmpty()) | 959 if (!layoutState.lineInfo().isEmpty()) |
939 layoutState.lineInfo().setFirstLine(false); | 960 layoutState.lineInfo().setFirstLine(false); |
940 clearFloats(lineBreaker.clear()); | 961 clearFloats(lineBreaker.clear()); |
941 | 962 |
942 if (m_floatingObjects && lastRootBox()) { | 963 if (m_floatingObjects && lastRootBox()) { |
943 InlineBidiResolver endOfLineResolver; | 964 InlineBidiResolver endOfLineResolver; |
944 endOfLineResolver.setPosition(endOfLine, numberOfIsolateAncestor
s(endOfLine)); | 965 endOfLineResolver.setPosition(endOfLine, numberOfIsolateAncestor
s(endOfLine)); |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2057 if (!line || !line->isFirstLineStyle()) | 2078 if (!line || !line->isFirstLineStyle()) |
2058 return reason; | 2079 return reason; |
2059 // It's the RootInlineBox that paints the ::first-line background. Note that
since it may be | 2080 // It's the RootInlineBox that paints the ::first-line background. Note that
since it may be |
2060 // expensive to figure out if the first line is affected by any ::first-line
selectors at all, | 2081 // expensive to figure out if the first line is affected by any ::first-line
selectors at all, |
2061 // we just invalidate it unconditionally, since that's typically cheaper. | 2082 // we just invalidate it unconditionally, since that's typically cheaper. |
2062 invalidateDisplayItemClient(*line); | 2083 invalidateDisplayItemClient(*line); |
2063 return reason; | 2084 return reason; |
2064 } | 2085 } |
2065 | 2086 |
2066 } // namespace blink | 2087 } // namespace blink |
OLD | NEW |