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 float * stops,size_t nStops,float tabWidth)56 TabStops(const float* stops, size_t nStops, float 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 if (mTabWidth == 0) { 66 return 0; 67 } 68 return floor(widthSoFar / mTabWidth + 1) * mTabWidth; 69 } 70 71 private: 72 const float* mStops; 73 size_t mStopsSize; 74 float mTabWidth; 75 }; 76 77 // Implement this for the additional information during line breaking. 78 // The functions in this class's interface may be called several times. The implementation 79 // must return the same value for the same input. 80 class LineWidth { 81 public: ~LineWidth()82 virtual ~LineWidth() {} 83 84 // Called to find out the width for the line. This must not return negative values. 85 virtual float getAt(size_t lineNo) const = 0; 86 87 // Called to find out the minimum line width. This mut not return negative values. 88 virtual float getMin() const = 0; 89 }; 90 91 struct LineBreakResult { 92 public: 93 LineBreakResult() = default; 94 95 // Following five vectors have the same length. 96 // TODO: Introduce individual line info struct if copy cost in JNI is negligible. 97 std::vector<int> breakPoints; 98 std::vector<float> widths; 99 std::vector<float> ascents; 100 std::vector<float> descents; 101 std::vector<int> flags; 102 103 LineBreakResult(LineBreakResult&&) = default; 104 LineBreakResult& operator=(LineBreakResult&&) = default; 105 reverseLineBreakResult106 void reverse() { 107 std::reverse(breakPoints.begin(), breakPoints.end()); 108 std::reverse(widths.begin(), widths.end()); 109 std::reverse(ascents.begin(), ascents.end()); 110 std::reverse(descents.begin(), descents.end()); 111 std::reverse(flags.begin(), flags.end()); 112 } 113 114 private: 115 MINIKIN_PREVENT_COPY_AND_ASSIGN(LineBreakResult); 116 }; 117 118 LineBreakResult breakIntoLines(const U16StringPiece& textBuffer, BreakStrategy strategy, 119 HyphenationFrequency frequency, bool justified, 120 const MeasuredText& measuredText, const LineWidth& lineWidth, 121 const TabStops& tabStops); 122 123 } // namespace minikin 124 125 #endif // MINIKIN_LINE_BREAKER_H 126