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 return floor(widthSoFar / mTabWidth + 1) * mTabWidth; 66 } 67 68 private: 69 const float* mStops; 70 size_t mStopsSize; 71 float 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 88 struct LineBreakResult { 89 public: 90 LineBreakResult() = default; 91 92 // Following five vectors have the same length. 93 // TODO: Introduce individual line info struct if copy cost in JNI is negligible. 94 std::vector<int> breakPoints; 95 std::vector<float> widths; 96 std::vector<float> ascents; 97 std::vector<float> descents; 98 std::vector<int> flags; 99 100 LineBreakResult(LineBreakResult&&) = default; 101 LineBreakResult& operator=(LineBreakResult&&) = default; 102 reverseLineBreakResult103 void reverse() { 104 std::reverse(breakPoints.begin(), breakPoints.end()); 105 std::reverse(widths.begin(), widths.end()); 106 std::reverse(ascents.begin(), ascents.end()); 107 std::reverse(descents.begin(), descents.end()); 108 std::reverse(flags.begin(), flags.end()); 109 } 110 111 private: 112 MINIKIN_PREVENT_COPY_AND_ASSIGN(LineBreakResult); 113 }; 114 115 LineBreakResult breakIntoLines(const U16StringPiece& textBuffer, BreakStrategy strategy, 116 HyphenationFrequency frequency, bool justified, 117 const MeasuredText& measuredText, const LineWidth& lineWidth, 118 const TabStops& tabStops); 119 120 } // namespace minikin 121 122 #endif // MINIKIN_LINE_BREAKER_H 123