101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien/* 201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * Copyright (C) 2015 The Android Open Source Project 301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * 401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * you may not use this file except in compliance with the License. 601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * You may obtain a copy of the License at 701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * 801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * http://www.apache.org/licenses/LICENSE-2.0 901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * 1001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * Unless required by applicable law or agreed to in writing, software 1101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * distributed under the License is distributed on an "AS IS" BASIS, 1201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * See the License for the specific language governing permissions and 1401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * limitations under the License. 1501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien */ 1601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien/** 1801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * A module for breaking paragraphs into lines, supporting high quality 1901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien * hyphenation and justification. 2001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien */ 2101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 2201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#ifndef MINIKIN_LINE_BREAKER_H 2301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#define MINIKIN_LINE_BREAKER_H 2401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 25f6596e3f30ebe2cbe506c144c09d959dada1ae4aRoozbeh Pournader#include <deque> 2601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#include <vector> 271d461589869ee5b7102f96271b0ef0a776ab513cSeigo Nonaka 28728f42cbd5acd0fa8d8dbe07d0302d41475eb95cRoozbeh Pournader#include "minikin/FontCollection.h" 29f58d27e7e10160319fcf58e2d1a5f080a2f59e5eRoozbeh Pournader#include "minikin/Layout.h" 300dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka#include "minikin/Macros.h" 3126ef1697ea9f110d58f99eb64118f15ae9c6f785Seigo Nonaka#include "minikin/MeasuredText.h" 32728f42cbd5acd0fa8d8dbe07d0302d41475eb95cRoozbeh Pournader#include "minikin/MinikinFont.h" 33d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka#include "minikin/Range.h" 34d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka#include "minikin/U16StringPiece.h" 3501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 3614e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonakanamespace minikin { 3701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 380dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonakaenum class BreakStrategy : uint8_t { 390dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka Greedy = 0, 400dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka HighQuality = 1, 410dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka Balanced = 2, 4201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 4301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 440dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonakaenum class HyphenationFrequency : uint8_t { 450dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka None = 0, 460dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka Normal = 1, 470dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka Full = 2, 480dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader}; 490dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader 501d461589869ee5b7102f96271b0ef0a776ab513cSeigo Nonakaclass Hyphenator; 519a5572ee64349a81deddd1d7dd1897920f2b4358Seigo Nonakaclass WordBreaker; 529a5572ee64349a81deddd1d7dd1897920f2b4358Seigo Nonaka 5301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass TabStops { 546c8722e217ff5238f0b849152d7936959a728103Seigo Nonakapublic: 556c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // Caller must free stops. stops can be nullprt. 566c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka TabStops(const int32_t* stops, size_t nStops, int32_t tabWidth) 576c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka : mStops(stops), mStopsSize(nStops), mTabWidth(tabWidth) {} 586c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 596c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka float nextTab(float widthSoFar) const { 606c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka for (size_t i = 0; i < mStopsSize; i++) { 616c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka if (mStops[i] > widthSoFar) { 626c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return mStops[i]; 6301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 6401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 656c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return floor(widthSoFar / mTabWidth + 1) * mTabWidth; 666c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } 676c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka 686c8722e217ff5238f0b849152d7936959a728103Seigo Nonakaprivate: 696c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka const int32_t* mStops; 706c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka size_t mStopsSize; 716c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka int32_t mTabWidth; 7201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 7301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 740dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka// Implement this for the additional information during line breaking. 750dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka// The functions in this class's interface may be called several times. The implementation 760dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka// must return the same value for the same input. 770dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonakaclass LineWidth { 786c8722e217ff5238f0b849152d7936959a728103Seigo Nonakapublic: 796c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka virtual ~LineWidth() {} 8001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 810385197086b0f08a39e7f6c9cee6f178ecb2746fSeigo Nonaka // Called to find out the width for the line. This must not return negative values. 826c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka virtual float getAt(size_t lineNo) const = 0; 8333ead53d74e8c8cb5331d7612d4f26d993a4a88bRoozbeh Pournader 840385197086b0f08a39e7f6c9cee6f178ecb2746fSeigo Nonaka // Called to find out the minimum line width. This mut not return negative values. 856c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka virtual float getMin() const = 0; 86f58d27e7e10160319fcf58e2d1a5f080a2f59e5eRoozbeh Pournader 876c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // Called to find out the available left-side padding for the line. 886c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka virtual float getLeftPaddingAt(size_t lineNo) const = 0; 89c9421a96ac99be65955f47567146411772171cc1Seigo Nonaka 906c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka // Called to find out the available right-side padding for the line. 916c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka virtual float getRightPaddingAt(size_t lineNo) const = 0; 920dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka}; 9301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 940dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonakastruct LineBreakResult { 950dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonakapublic: 960dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka LineBreakResult() = default; 970dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader 980dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka // Following five vectors have the same length. 990dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka // TODO: Introduce individual line info struct if copy cost in JNI is negligible. 1000dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka std::vector<int> breakPoints; 1010dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka std::vector<float> widths; 1020dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka std::vector<float> ascents; 1030dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka std::vector<float> descents; 1040dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka std::vector<int> flags; 10501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1060dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka LineBreakResult(LineBreakResult&&) = default; 1070dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka LineBreakResult& operator=(LineBreakResult&&) = default; 10801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 109366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka void reverse() { 110366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka std::reverse(breakPoints.begin(), breakPoints.end()); 111366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka std::reverse(widths.begin(), widths.end()); 112366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka std::reverse(ascents.begin(), ascents.end()); 113366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka std::reverse(descents.begin(), descents.end()); 114366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka std::reverse(flags.begin(), flags.end()); 115366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka } 116366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka 117366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonakaprivate: 118a22996e31226e3dcbfb0c57d03ca9ac54028fc28Seigo Nonaka MINIKIN_PREVENT_COPY_AND_ASSIGN(LineBreakResult); 1190dcb27d502afcb34f59ac85c886ec13a5fdaa0ddSeigo Nonaka}; 12001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1210948fbb63636111c193365e01dbe952defd700f3Seigo NonakaLineBreakResult breakIntoLines(const U16StringPiece& textBuffer, BreakStrategy strategy, 1220948fbb63636111c193365e01dbe952defd700f3Seigo Nonaka HyphenationFrequency frequency, bool justified, 1230948fbb63636111c193365e01dbe952defd700f3Seigo Nonaka const MeasuredText& measuredText, const LineWidth& lineWidth, 1240948fbb63636111c193365e01dbe952defd700f3Seigo Nonaka const TabStops& tabStops); 12501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 12614e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonaka} // namespace minikin 12701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 12801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#endif // MINIKIN_LINE_BREAKER_H 129