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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 | 484 |
485 bool rootHasSelectedChildren = false; | 485 bool rootHasSelectedChildren = false; |
486 InlineFlowBox* parentBox = 0; | 486 InlineFlowBox* parentBox = 0; |
487 int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace(); | 487 int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace(); |
488 for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) { | 488 for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) { |
489 // Create a box for our object. | 489 // Create a box for our object. |
490 bool isOnlyRun = (runCount == 1); | 490 bool isOnlyRun = (runCount == 1); |
491 if (runCount == 2 && !r->m_object->isListMarker()) | 491 if (runCount == 2 && !r->m_object->isListMarker()) |
492 isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun()
: bidiRuns.firstRun())->m_object->isListMarker(); | 492 isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun()
: bidiRuns.firstRun())->m_object->isListMarker(); |
493 | 493 |
| 494 if (lineInfo.isEmpty()) |
| 495 continue; |
| 496 |
494 InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRu
n); | 497 InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRu
n); |
495 r->m_box = box; | 498 r->m_box = box; |
496 | 499 |
497 ASSERT(box); | 500 ASSERT(box); |
498 if (!box) | 501 if (!box) |
499 continue; | 502 continue; |
500 | 503 |
501 if (!rootHasSelectedChildren && box->renderer()->selectionState() != Ren
derObject::SelectionNone) | 504 if (!rootHasSelectedChildren && box->renderer()->selectionState() != Ren
derObject::SelectionNone) |
502 rootHasSelectedChildren = true; | 505 rootHasSelectedChildren = true; |
503 | 506 |
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1817 static inline bool shouldCollapseWhiteSpace(const RenderStyle* style, const Line
Info& lineInfo, WhitespacePosition whitespacePosition) | 1820 static inline bool shouldCollapseWhiteSpace(const RenderStyle* style, const Line
Info& lineInfo, WhitespacePosition whitespacePosition) |
1818 { | 1821 { |
1819 // CSS2 16.6.1 | 1822 // CSS2 16.6.1 |
1820 // If a space (U+0020) at the beginning of a line has 'white-space' set to '
normal', 'nowrap', or 'pre-line', it is removed. | 1823 // If a space (U+0020) at the beginning of a line has 'white-space' set to '
normal', 'nowrap', or 'pre-line', it is removed. |
1821 // If a space (U+0020) at the end of a line has 'white-space' set to 'normal
', 'nowrap', or 'pre-line', it is also removed. | 1824 // If a space (U+0020) at the end of a line has 'white-space' set to 'normal
', 'nowrap', or 'pre-line', it is also removed. |
1822 // If spaces (U+0020) or tabs (U+0009) at the end of a line have 'white-spac
e' set to 'pre-wrap', UAs may visually collapse them. | 1825 // If spaces (U+0020) or tabs (U+0009) at the end of a line have 'white-spac
e' set to 'pre-wrap', UAs may visually collapse them. |
1823 return style->collapseWhiteSpace() | 1826 return style->collapseWhiteSpace() |
1824 || (whitespacePosition == TrailingWhitespace && style->whiteSpace() == P
RE_WRAP && (!lineInfo.isEmpty() || !lineInfo.previousLineBrokeCleanly())); | 1827 || (whitespacePosition == TrailingWhitespace && style->whiteSpace() == P
RE_WRAP && (!lineInfo.isEmpty() || !lineInfo.previousLineBrokeCleanly())); |
1825 } | 1828 } |
1826 | 1829 |
1827 static bool inlineFlowRequiresLineBox(RenderInline* flow, const LineInfo& lineIn
fo) | 1830 static bool requiresLineBoxForContent(RenderInline* flow, const LineInfo& lineIn
fo) |
| 1831 { |
| 1832 RenderObject* parent = flow->parent(); |
| 1833 if (flow->document()->inNoQuirksMode() |
| 1834 && (flow->style(lineInfo.isFirstLine())->lineHeight() != parent->style(l
ineInfo.isFirstLine())->lineHeight() |
| 1835 || flow->style()->verticalAlign() != parent->style()->verticalAlign() |
| 1836 || !parent->style()->font().fontMetrics().hasIdenticalAscentDescentAndLi
neGap(flow->style()->font().fontMetrics()))) |
| 1837 return true; |
| 1838 return false; |
| 1839 } |
| 1840 |
| 1841 static bool alwaysRequiresLineBox(RenderInline* flow, const LineInfo& lineInfo) |
1828 { | 1842 { |
1829 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. | 1843 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. |
1830 // We need to fix this, though, because at the very least, inlines containin
g only | 1844 // We need to fix this, though, because at the very least, inlines containin
g only |
1831 // ignorable whitespace should should also have line boxes. | 1845 // ignorable whitespace should should also have line boxes. |
1832 if (!flow->document()->inQuirksMode() && flow->style(lineInfo.isFirstLine())
->lineHeight() != flow->parent()->style(lineInfo.isFirstLine())->lineHeight()) | |
1833 return true; | |
1834 | |
1835 return !flow->firstChild() && flow->hasInlineDirectionBordersPaddingOrMargin
(); | 1846 return !flow->firstChild() && flow->hasInlineDirectionBordersPaddingOrMargin
(); |
1836 } | 1847 } |
1837 | 1848 |
1838 static bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace) | 1849 static bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace) |
1839 { | 1850 { |
1840 if (it.m_obj->isFloatingOrPositioned()) | 1851 if (it.m_obj->isFloatingOrPositioned()) |
1841 return false; | 1852 return false; |
1842 | 1853 |
1843 if (it.m_obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(
it.m_obj), lineInfo)) | 1854 if (it.m_obj->isRenderInline() && !alwaysRequiresLineBox(toRenderInline(it.m
_obj), lineInfo) && !requiresLineBoxForContent(toRenderInline(it.m_obj), lineInf
o)) |
1844 return false; | 1855 return false; |
1845 | 1856 |
1846 if (!shouldCollapseWhiteSpace(it.m_obj->style(), lineInfo, whitespacePositio
n) || it.m_obj->isBR()) | 1857 if (!shouldCollapseWhiteSpace(it.m_obj->style(), lineInfo, whitespacePositio
n) || it.m_obj->isBR()) |
1847 return true; | 1858 return true; |
1848 | 1859 |
1849 UChar current = it.current(); | 1860 UChar current = it.current(); |
1850 return current != ' ' && current != '\t' && current != softHyphen && (curren
t != '\n' || it.m_obj->preservesNewline()) | 1861 return current != ' ' && current != '\t' && current != softHyphen && (curren
t != '\n' || it.m_obj->preservesNewline()) |
1851 && !skipNonBreakingSpace(it, lineInfo); | 1862 && !skipNonBreakingSpace(it, lineInfo); |
1852 } | 1863 } |
1853 | 1864 |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2221 } else if (current.m_obj->isRenderInline()) { | 2232 } else if (current.m_obj->isRenderInline()) { |
2222 // Right now, we should only encounter empty inlines here. | 2233 // Right now, we should only encounter empty inlines here. |
2223 ASSERT(!current.m_obj->firstChild()); | 2234 ASSERT(!current.m_obj->firstChild()); |
2224 | 2235 |
2225 RenderInline* flowBox = toRenderInline(current.m_obj); | 2236 RenderInline* flowBox = toRenderInline(current.m_obj); |
2226 | 2237 |
2227 // Now that some inline flows have line boxes, if we are already ign
oring spaces, we need | 2238 // Now that some inline flows have line boxes, if we are already ign
oring spaces, we need |
2228 // to make sure that we stop to include this object and then start i
gnoring spaces again. | 2239 // to make sure that we stop to include this object and then start i
gnoring spaces again. |
2229 // If this object is at the start of the line, we need to behave lik
e list markers and | 2240 // If this object is at the start of the line, we need to behave lik
e list markers and |
2230 // start ignoring spaces. | 2241 // start ignoring spaces. |
2231 if (inlineFlowRequiresLineBox(flowBox, lineInfo)) { | 2242 bool requiresLineBox = alwaysRequiresLineBox(flowBox, lineInfo); |
2232 lineInfo.setEmpty(false, m_block, &width); | 2243 if (requiresLineBox || requiresLineBoxForContent(flowBox, lineInfo))
{ |
| 2244 // An empty inline that only has line-height, vertical-align or
font-metrics will only get a |
| 2245 // line box to affect the height of the line if the rest of the
line is not empty. |
| 2246 if (requiresLineBox) |
| 2247 lineInfo.setEmpty(false, m_block, &width); |
2233 if (ignoringSpaces) { | 2248 if (ignoringSpaces) { |
2234 trailingObjects.clear(); | 2249 trailingObjects.clear(); |
2235 addMidpoint(lineMidpointState, InlineIterator(0, current.m_o
bj, 0)); // Stop ignoring spaces. | 2250 addMidpoint(lineMidpointState, InlineIterator(0, current.m_o
bj, 0)); // Stop ignoring spaces. |
2236 addMidpoint(lineMidpointState, InlineIterator(0, current.m_o
bj, 0)); // Start ignoring again. | 2251 addMidpoint(lineMidpointState, InlineIterator(0, current.m_o
bj, 0)); // Start ignoring again. |
2237 } else if (blockStyle->collapseWhiteSpace() && resolver.position
().m_obj == current.m_obj | 2252 } else if (blockStyle->collapseWhiteSpace() && resolver.position
().m_obj == current.m_obj |
2238 && shouldSkipWhitespaceAfterStartObject(m_block, current.m_o
bj, lineMidpointState)) { | 2253 && shouldSkipWhitespaceAfterStartObject(m_block, current.m_o
bj, lineMidpointState)) { |
2239 // Like with list markers, we start ignoring spaces to make
sure that any | 2254 // Like with list markers, we start ignoring spaces to make
sure that any |
2240 // additional spaces we see will be discarded. | 2255 // additional spaces we see will be discarded. |
2241 currentCharacterIsSpace = true; | 2256 currentCharacterIsSpace = true; |
2242 currentCharacterIsWS = true; | 2257 currentCharacterIsWS = true; |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2783 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); | 2798 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); |
2784 | 2799 |
2785 setLineGridBox(lineGridBox); | 2800 setLineGridBox(lineGridBox); |
2786 | 2801 |
2787 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying | 2802 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying |
2788 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping | 2803 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping |
2789 // to this grid. | 2804 // to this grid. |
2790 } | 2805 } |
2791 | 2806 |
2792 } | 2807 } |
OLD | NEW |