1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * A module for breaking paragraphs into lines, supporting high quality 19 * hyphenation and justification. 20 */ 21 22 #ifndef MINIKIN_LINE_BREAKER_H 23 #define MINIKIN_LINE_BREAKER_H 24 25 #include <deque> 26 #include <vector> 27 28 #include "minikin/FontCollection.h" 29 #include "minikin/Layout.h" 30 #include "minikin/Macros.h" 31 #include "minikin/MeasuredText.h" 32 #include "minikin/MinikinFont.h" 33 #include "minikin/Range.h" 34 #include "minikin/U16StringPiece.h" 35 36 namespace minikin { 37 38 enum class BreakStrategy : uint8_t { 39 Greedy = 0, 40 HighQuality = 1, 41 Balanced = 2, 42 }; 43 44 enum class HyphenationFrequency : uint8_t { 45 None = 0, 46 Normal = 1, 47 Full = 2, 48 }; 49 50 class Hyphenator; 51 class WordBreaker; 52 53 class TabStops { 54 public: 55 // Caller must free stops. stops can be nullprt. TabStops(const int32_t * stops,size_t nStops,int32_t tabWidth)56 TabStops(const int32_t* stops, size_t nStops, int32_t tabWidth) 57 : mStops(stops), mStopsSize(nStops), mTabWidth(tabWidth) {} 58 nextTab(float widthSoFar)59 float nextTab(float widthSoFar) const { 60 for (size_t i = 0; i < mStopsSize; i++) { 61 if (mStops[i] > widthSoFar) { 62 return mStops[i]; 63 } 64 } 65 return floor(widthSoFar / mTabWidth + 1) * mTabWidth; 66 } 67 68 private: 69 const int32_t* mStops; 70 size_t mStopsSize; 71 int32_t mTabWidth; 72 }; 73 74 // Implement this for the additional information during line breaking. 75 // The functions in this class's interface may be called several times. The implementation 76 // must return the same value for the same input. 77 class LineWidth { 78 public: ~LineWidth()79 virtual ~LineWidth() {} 80 81 // Called to find out the width for the line. This must not return negative values. 82 virtual float getAt(size_t lineNo) const = 0; 83 84 // Called to find out the minimum line width. This mut not return negative values. 85 virtual float getMin() const = 0; 86 87 // Called to find out the available left-side padding for the line. 88 virtual float getLeftPaddingAt(size_t lineNo) const = 0; 89 90 // Called to find out the available right-side padding for the line. 91 virtual float getRightPaddingAt(size_t lineNo) const = 0; 92 }; 93 94 struct LineBreakResult { 95 public: 96 LineBreakResult() = default; 97 98 // Following five vectors have the same length. 99 // TODO: Introduce individual line info struct if copy cost in JNI is negligible. 100 std::vector<int> breakPoints; 101 std::vector<float> widths; 102 std::vector<float> ascents; 103 std::vector<float> descents; 104 std::vector<int> flags; 105 106 LineBreakResult(LineBreakResult&&) = default; 107 LineBreakResult& operator=(LineBreakResult&&) = default; 108 reverseLineBreakResult109 void reverse() { 110 std::reverse(breakPoints.begin(), breakPoints.end()); 111 std::reverse(widths.begin(), widths.end()); 112 std::reverse(ascents.begin(), ascents.end()); 113 std::reverse(descents.begin(), descents.end()); 114 std::reverse(flags.begin(), flags.end()); 115 } 116 117 private: 118 MINIKIN_PREVENT_COPY_AND_ASSIGN(LineBreakResult); 119 }; 120 121 LineBreakResult breakIntoLines(const U16StringPiece& textBuffer, BreakStrategy strategy, 122 HyphenationFrequency frequency, bool justified, 123 const MeasuredText& measuredText, const LineWidth& lineWidth, 124 const TabStops& tabStops); 125 126 } // namespace minikin 127 128 #endif // MINIKIN_LINE_BREAKER_H 129