/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * A module for breaking paragraphs into lines, supporting high quality * hyphenation and justification. */ #ifndef MINIKIN_LINE_BREAKER_H #define MINIKIN_LINE_BREAKER_H #include #include #include "minikin/FontCollection.h" #include "minikin/Layout.h" #include "minikin/Macros.h" #include "minikin/MeasuredText.h" #include "minikin/MinikinFont.h" #include "minikin/Range.h" #include "minikin/U16StringPiece.h" namespace minikin { enum class BreakStrategy : uint8_t { Greedy = 0, HighQuality = 1, Balanced = 2, }; enum class HyphenationFrequency : uint8_t { None = 0, Normal = 1, Full = 2, }; class Hyphenator; class WordBreaker; class TabStops { public: // Caller must free stops. stops can be nullprt. TabStops(const int32_t* stops, size_t nStops, int32_t tabWidth) : mStops(stops), mStopsSize(nStops), mTabWidth(tabWidth) {} float nextTab(float widthSoFar) const { for (size_t i = 0; i < mStopsSize; i++) { if (mStops[i] > widthSoFar) { return mStops[i]; } } return floor(widthSoFar / mTabWidth + 1) * mTabWidth; } private: const int32_t* mStops; size_t mStopsSize; int32_t mTabWidth; }; // Implement this for the additional information during line breaking. // The functions in this class's interface may be called several times. The implementation // must return the same value for the same input. class LineWidth { public: virtual ~LineWidth() {} // Called to find out the width for the line. This must not return negative values. virtual float getAt(size_t lineNo) const = 0; // Called to find out the minimum line width. This mut not return negative values. virtual float getMin() const = 0; // Called to find out the available left-side padding for the line. virtual float getLeftPaddingAt(size_t lineNo) const = 0; // Called to find out the available right-side padding for the line. virtual float getRightPaddingAt(size_t lineNo) const = 0; }; struct LineBreakResult { public: LineBreakResult() = default; // Following five vectors have the same length. // TODO: Introduce individual line info struct if copy cost in JNI is negligible. std::vector breakPoints; std::vector widths; std::vector ascents; std::vector descents; std::vector flags; LineBreakResult(LineBreakResult&&) = default; LineBreakResult& operator=(LineBreakResult&&) = default; void reverse() { std::reverse(breakPoints.begin(), breakPoints.end()); std::reverse(widths.begin(), widths.end()); std::reverse(ascents.begin(), ascents.end()); std::reverse(descents.begin(), descents.end()); std::reverse(flags.begin(), flags.end()); } private: MINIKIN_PREVENT_COPY_AND_ASSIGN(LineBreakResult); }; LineBreakResult breakIntoLines(const U16StringPiece& textBuffer, BreakStrategy strategy, HyphenationFrequency frequency, bool justified, const MeasuredText& measuredText, const LineWidth& lineWidth, const TabStops& tabStops); } // namespace minikin #endif // MINIKIN_LINE_BREAKER_H