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