1 /* 2 * Copyright (C) 2017 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 #ifndef MINIKIN_ANDROID_LINE_BREAKER_HELPERS_H 18 #define MINIKIN_ANDROID_LINE_BREAKER_HELPERS_H 19 20 #include <algorithm> 21 22 #include "minikin/LineBreaker.h" 23 24 namespace minikin { 25 namespace android { 26 27 class AndroidLineWidth : public LineWidth { 28 public: AndroidLineWidth(float firstWidth,int32_t firstLineCount,float restWidth,const std::vector<float> & indents,int32_t indentsOffset)29 AndroidLineWidth(float firstWidth, int32_t firstLineCount, float restWidth, 30 const std::vector<float>& indents, int32_t indentsOffset) 31 : mFirstWidth(firstWidth), 32 mFirstLineCount(firstLineCount), 33 mRestWidth(restWidth), 34 mIndents(indents), 35 mOffset(indentsOffset) {} 36 getAt(size_t lineNo)37 float getAt(size_t lineNo) const override { 38 const float width = ((ssize_t)lineNo < (ssize_t)mFirstLineCount) ? mFirstWidth : mRestWidth; 39 return std::max(0.0f, width - get(mIndents, lineNo)); 40 } 41 getMin()42 float getMin() const override { 43 // A simpler algorithm would have been simply looping until the larger of 44 // mFirstLineCount and mIndents.size()-mOffset, but that does unnecessary calculations 45 // when mFirstLineCount is large. Instead, we measure the first line, all the lines that 46 // have an indent, and the first line after firstWidth ends and restWidth starts. 47 float minWidth = std::min(getAt(0), getAt(mFirstLineCount)); 48 for (size_t lineNo = 1; lineNo + mOffset < mIndents.size(); lineNo++) { 49 minWidth = std::min(minWidth, getAt(lineNo)); 50 } 51 return minWidth; 52 } 53 54 private: get(const std::vector<float> & vec,size_t lineNo)55 float get(const std::vector<float>& vec, size_t lineNo) const { 56 if (vec.empty()) { 57 return 0; 58 } 59 const size_t index = lineNo + mOffset; 60 if (index < vec.size()) { 61 return vec[index]; 62 } else { 63 return vec.back(); 64 } 65 } 66 67 const float mFirstWidth; 68 const int32_t mFirstLineCount; 69 const float mRestWidth; 70 const std::vector<float>& mIndents; 71 const int32_t mOffset; 72 }; 73 74 class StaticLayoutNative { 75 public: StaticLayoutNative(BreakStrategy strategy,HyphenationFrequency frequency,bool isJustified,std::vector<float> && indents)76 StaticLayoutNative(BreakStrategy strategy, HyphenationFrequency frequency, bool isJustified, 77 std::vector<float>&& indents) 78 : mStrategy(strategy), 79 mFrequency(frequency), 80 mIsJustified(isJustified), 81 mIndents(std::move(indents)) {} 82 computeBreaks(const U16StringPiece & textBuf,const MeasuredText & measuredText,float firstWidth,int32_t firstWidthLineCount,float restWidth,int32_t indentsOffset,const float * tabStops,int32_t tabStopSize,float defaultTabStopWidth)83 LineBreakResult computeBreaks(const U16StringPiece& textBuf, const MeasuredText& measuredText, 84 // Line width arguments 85 float firstWidth, int32_t firstWidthLineCount, float restWidth, 86 int32_t indentsOffset, 87 // Tab stop arguments 88 const float* tabStops, int32_t tabStopSize, 89 float defaultTabStopWidth) const { 90 AndroidLineWidth lineWidth(firstWidth, firstWidthLineCount, restWidth, mIndents, 91 indentsOffset); 92 return breakIntoLines(textBuf, mStrategy, mFrequency, mIsJustified, measuredText, lineWidth, 93 TabStops(tabStops, tabStopSize, defaultTabStopWidth)); 94 } 95 getStrategy()96 inline BreakStrategy getStrategy() const { return mStrategy; } getFrequency()97 inline HyphenationFrequency getFrequency() const { return mFrequency; } isJustified()98 inline bool isJustified() const { return mIsJustified; } 99 100 private: 101 const BreakStrategy mStrategy; 102 const HyphenationFrequency mFrequency; 103 const bool mIsJustified; 104 const std::vector<float> mIndents; 105 const std::vector<float> mLeftPaddings; 106 const std::vector<float> mRightPaddings; 107 }; 108 109 } // namespace android 110 } // namespace minikin 111 112 #endif // MINIKIN_ANDROID_LINE_BREAKER_HELPERS_H 113