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

Unified Diff: Source/core/rendering/line/LineBreaker.cpp

Issue 142323003: Separate LineBreaker from RenderBlockLineLayout (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/line/LineBreaker.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/line/LineBreaker.cpp
diff --git a/Source/core/rendering/line/LineBreaker.cpp b/Source/core/rendering/line/LineBreaker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f6c50cb9835a27a27f36d8a22d96d6d4bd910b97
--- /dev/null
+++ b/Source/core/rendering/line/LineBreaker.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/rendering/line/LineBreaker.h"
+
+#include "core/rendering/line/BreakingContextInlineHeaders.h"
+
+namespace WebCore {
+
+void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
+ FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
+{
+ while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
+ RenderObject* object = resolver.position().object();
+ if (object->isOutOfFlowPositioned()) {
+ setStaticPositions(m_block, toRenderBox(object));
+ if (object->style()->isOriginalDisplayInlineType()) {
+ resolver.runs().addRun(createRun(0, 1, object, resolver));
+ lineInfo.incrementRunsFromLeadingWhitespace();
+ }
+ } else if (object->isFloating()) {
+ m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, lineInfo, width);
+ } else if (object->isText() && object->style()->hasTextCombine() && object->isCombineText() && !toRenderCombineText(object)->isCombined()) {
+ toRenderCombineText(object)->combineText();
+ if (toRenderCombineText(object)->isCombined())
+ continue;
+ }
+ resolver.position().increment(&resolver);
+ }
+ resolver.commitExplicitEmbedding();
+}
+
+void LineBreaker::reset()
+{
+ m_positionedObjects.clear();
+ m_hyphenated = false;
+ m_clear = CNONE;
+}
+
+InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
+{
+ ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo();
+
+ if (!shapeInsideInfo || !shapeInsideInfo->lineOverlapsShapeBounds())
+ return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
+
+ InlineIterator end = resolver.position();
+ InlineIterator oldEnd = end;
+
+ if (!shapeInsideInfo->hasSegments()) {
+ end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
+ resolver.setPositionIgnoringNestedIsolates(oldEnd);
+ return oldEnd;
+ }
+
+ const SegmentList& segments = shapeInsideInfo->segments();
+ SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
+
+ for (unsigned i = 0; i < segments.size() && !end.atEnd(); i++) {
+ const InlineIterator segmentStart = resolver.position();
+ end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
+
+ ASSERT(segmentRanges.size() == i);
+ if (resolver.position().atEnd()) {
+ segmentRanges.append(LineSegmentRange(segmentStart, end));
+ break;
+ }
+ if (resolver.position() == end) {
+ // Nothing fit this segment
+ end = segmentStart;
+ segmentRanges.append(LineSegmentRange(segmentStart, segmentStart));
+ resolver.setPositionIgnoringNestedIsolates(segmentStart);
+ } else {
+ // Note that resolver.position is already skipping some of the white space at the beginning of the line,
+ // so that's why segmentStart might be different than resolver.position().
+ LineSegmentRange range(resolver.position(), end);
+ segmentRanges.append(range);
+ resolver.setPosition(end, numberOfIsolateAncestors(end));
+
+ if (lineInfo.previousLineBrokeCleanly()) {
+ // If we hit a new line break, just stop adding anything to this line.
+ break;
+ }
+ }
+ }
+ resolver.setPositionIgnoringNestedIsolates(oldEnd);
+ return end;
+}
+
+InlineIterator LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
+{
+ reset();
+
+ ASSERT(resolver.position().root() == m_block);
+
+ bool appliedStartWidth = resolver.position().offset() > 0;
+
+ LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style()));
+
+ skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width);
+
+ if (resolver.position().atEnd())
+ return resolver.position();
+
+ BreakingContext context(resolver, lineInfo, width, renderTextInfo, lastFloatFromPreviousLine, appliedStartWidth, m_block);
+
+ while (context.currentObject()) {
+ context.initializeForCurrentObject();
+ if (context.currentObject()->isBR()) {
+ context.handleBR(m_clear);
+ } else if (context.currentObject()->isOutOfFlowPositioned()) {
+ context.handleOutOfFlowPositioned(m_positionedObjects);
+ } else if (context.currentObject()->isFloating()) {
+ context.handleFloat();
+ } else if (context.currentObject()->isRenderInline()) {
+ context.handleEmptyInline();
+ } else if (context.currentObject()->isReplaced()) {
+ context.handleReplaced();
+ } else if (context.currentObject()->isText()) {
+ if (context.handleText(wordMeasurements, m_hyphenated)) {
+ // We've hit a hard text line break. Our line break iterator is updated, so go ahead and early return.
+ return context.lineBreak();
+ }
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+
+ if (context.atEnd())
+ return context.handleEndOfLine();
+
+ context.commitAndUpdateLineBreakIfNeeded();
+
+ if (context.atEnd())
+ return context.handleEndOfLine();
+
+ context.increment();
+ }
+
+ context.clearLineBreakIfFitsOnLine();
+
+ return context.handleEndOfLine();
+}
+
+}
« no previous file with comments | « Source/core/rendering/line/LineBreaker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698