1b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka/* 2b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * Copyright (C) 2017 The Android Open Source Project 3b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * 4b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License"); 5b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * you may not use this file except in compliance with the License. 6b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * You may obtain a copy of the License at 7b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * 8b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * http://www.apache.org/licenses/LICENSE-2.0 9b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * 10b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * Unless required by applicable law or agreed to in writing, software 11b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS, 12b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * See the License for the specific language governing permissions and 14b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka * limitations under the License. 15b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka */ 16b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 17b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka#ifndef MINIKIN_ANDROID_LINE_BREAKER_HELPERS_H 18b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka#define MINIKIN_ANDROID_LINE_BREAKER_HELPERS_H 19b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 200385197086b0f08a39e7f6c9cee6f178ecb2746fSeigo Nonaka#include <algorithm> 210385197086b0f08a39e7f6c9cee6f178ecb2746fSeigo Nonaka 22b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka#include "minikin/LineBreaker.h" 23b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 24b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonakanamespace minikin { 25b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonakanamespace android { 26b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 270dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonakaclass AndroidLineWidth : public LineWidth { 286c8722e217ff5238f0b849152d7936959a728103Seigo Nonakapublic: 296c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka AndroidLineWidth(float firstWidth, int32_t firstLineCount, float restWidth, 306c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float>& indents, const std::vector<float>& leftPaddings, 316c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float>& rightPaddings, int32_t indentsAndPaddingsOffset) 326c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka : mFirstWidth(firstWidth), 336c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mFirstLineCount(firstLineCount), 346c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mRestWidth(restWidth), 356c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mIndents(indents), 366c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mLeftPaddings(leftPaddings), 376c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mRightPaddings(rightPaddings), 386c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mOffset(indentsAndPaddingsOffset) {} 396c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 406c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float getAt(size_t lineNo) const override { 416c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const float width = ((ssize_t)lineNo < (ssize_t)mFirstLineCount) ? mFirstWidth : mRestWidth; 420385197086b0f08a39e7f6c9cee6f178ecb2746fSeigo Nonaka return std::max(0.0f, width - get(mIndents, lineNo)); 436c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } 446c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 456c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float getMin() const override { 466c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // A simpler algorithm would have been simply looping until the larger of 476c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // mFirstLineCount and mIndents.size()-mOffset, but that does unnecessary calculations 486c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // when mFirstLineCount is large. Instead, we measure the first line, all the lines that 496c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // have an indent, and the first line after firstWidth ends and restWidth starts. 506c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float minWidth = std::min(getAt(0), getAt(mFirstLineCount)); 516c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka for (size_t lineNo = 1; lineNo + mOffset < mIndents.size(); lineNo++) { 526c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka minWidth = std::min(minWidth, getAt(lineNo)); 53b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka } 546c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return minWidth; 556c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } 56b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 576c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float getLeftPaddingAt(size_t lineNo) const override { return get(mLeftPaddings, lineNo); } 58b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 596c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float getRightPaddingAt(size_t lineNo) const override { return get(mRightPaddings, lineNo); } 60b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 616c8722e217ff5238f0b849152d7936959a728103Seigo Nonakaprivate: 626c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float get(const std::vector<float>& vec, size_t lineNo) const { 636c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka if (vec.empty()) { 646c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return 0; 65b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka } 666c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const size_t index = lineNo + mOffset; 676c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka if (index < vec.size()) { 686c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return vec[index]; 696c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } else { 706c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return vec.back(); 71b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka } 726c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } 736c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 746c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const float mFirstWidth; 756c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const int32_t mFirstLineCount; 766c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const float mRestWidth; 776c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float>& mIndents; 786c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float>& mLeftPaddings; 796c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float>& mRightPaddings; 806c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const int32_t mOffset; 81b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka}; 82b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 83b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonakaclass StaticLayoutNative { 846c8722e217ff5238f0b849152d7936959a728103Seigo Nonakapublic: 856c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka StaticLayoutNative(BreakStrategy strategy, HyphenationFrequency frequency, bool isJustified, 866c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka std::vector<float>&& indents, std::vector<float>&& leftPaddings, 876c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka std::vector<float>&& rightPaddings) 886c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka : mStrategy(strategy), 896c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mFrequency(frequency), 906c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mIsJustified(isJustified), 916c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mIndents(std::move(indents)), 926c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mLeftPaddings(std::move(leftPaddings)), 93b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka mRightPaddings(std::move(rightPaddings)) {} 94b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 950948fbb63636111c193365e01dbe952defd700f3Seigo Nonaka LineBreakResult computeBreaks(const U16StringPiece& textBuf, const MeasuredText& measuredText, 966c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // Line width arguments 976c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float firstWidth, int32_t firstWidthLineCount, float restWidth, 986c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka int32_t indentsOffset, 996c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // Tab stop arguments 1006c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const int32_t* tabStops, int32_t tabStopSize, 1016c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka int32_t defaultTabStopWidth) const { 1026c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka AndroidLineWidth lineWidth(firstWidth, firstWidthLineCount, restWidth, mIndents, 1036c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mLeftPaddings, mRightPaddings, indentsOffset); 1040948fbb63636111c193365e01dbe952defd700f3Seigo Nonaka return breakIntoLines(textBuf, mStrategy, mFrequency, mIsJustified, measuredText, lineWidth, 1050948fbb63636111c193365e01dbe952defd700f3Seigo Nonaka TabStops(tabStops, tabStopSize, defaultTabStopWidth)); 1066c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } 1076c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 1086c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline BreakStrategy getStrategy() const { return mStrategy; } 1096c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline HyphenationFrequency getFrequency() const { return mFrequency; } 1106c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline bool isJustified() const { return mIsJustified; } 1116c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 1126c8722e217ff5238f0b849152d7936959a728103Seigo Nonakaprivate: 1136c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const BreakStrategy mStrategy; 1146c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const HyphenationFrequency mFrequency; 1156c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const bool mIsJustified; 1166c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float> mIndents; 1176c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float> mLeftPaddings; 1186c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const std::vector<float> mRightPaddings; 119b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka}; 120b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 121b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka} // namespace android 122b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka} // namespace minikin 123b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka 124b27a39233e1cc2d1230b02fe859969c9811095aaSeigo Nonaka#endif // MINIKIN_ANDROID_LINE_BREAKER_HELPERS_H 125