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 2501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#include "unicode/brkiter.h" 2601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#include "unicode/locid.h" 2701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#include <cmath> 2801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#include <vector> 295cdad92c300a65cab89b172e952186f0c5870657Raph Levien#include "minikin/Hyphenator.h" 3057b6dae9894b9362ef04517ff477fd491f9d433bRaph Levien#include "minikin/WordBreaker.h" 3101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 3201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Leviennamespace android { 3301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 3401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienenum BreakStrategy { 3501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien kBreakStrategy_Greedy = 0, 3601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien kBreakStrategy_HighQuality = 1, 3701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien kBreakStrategy_Balanced = 2 3801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 3901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 400dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournaderenum HyphenationFrequency { 410dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader kHyphenationFrequency_None = 0, 420dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader kHyphenationFrequency_Normal = 1, 430dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader kHyphenationFrequency_Full = 2 440dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader}; 450dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader 4601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien// TODO: want to generalize to be able to handle array of line widths 4701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass LineWidths { 4801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien public: 4901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setWidths(float firstWidth, int firstWidthLineCount, float restWidth) { 5001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mFirstWidth = firstWidth; 5101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mFirstWidthLineCount = firstWidthLineCount; 5201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mRestWidth = restWidth; 5301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 54bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien void setIndents(const std::vector<float>& indents) { 55bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien mIndents = indents; 56dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } 575cdad92c300a65cab89b172e952186f0c5870657Raph Levien bool isConstant() const { 585cdad92c300a65cab89b172e952186f0c5870657Raph Levien // technically mFirstWidthLineCount == 0 would count too, but doesn't actually happen 59bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien return mRestWidth == mFirstWidth && mIndents.empty(); 605cdad92c300a65cab89b172e952186f0c5870657Raph Levien } 6101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float getLineWidth(int line) const { 62dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien float width = (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth; 63bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien if (!mIndents.empty()) { 64bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien if ((size_t)line < mIndents.size()) { 65bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien width -= mIndents[line]; 66dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } else { 67bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien width -= mIndents.back(); 68dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } 69dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } 70dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien return width; 7101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 72879e8a3a479b2cedd05e652f082683a02aa57dcfRaph Levien void clear() { 73879e8a3a479b2cedd05e652f082683a02aa57dcfRaph Levien mIndents.clear(); 74879e8a3a479b2cedd05e652f082683a02aa57dcfRaph Levien } 7501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien private: 7601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float mFirstWidth; 7701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien int mFirstWidthLineCount; 7801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float mRestWidth; 79bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien std::vector<float> mIndents; 8001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 8101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 8201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass TabStops { 8301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien public: 8401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void set(const int* stops, size_t nStops, int tabWidth) { 8501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien if (stops != nullptr) { 8601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mStops.assign(stops, stops + nStops); 8701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } else { 8801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mStops.clear(); 8901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 9001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mTabWidth = tabWidth; 9101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 9201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float nextTab(float widthSoFar) const { 9301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien for (size_t i = 0; i < mStops.size(); i++) { 9401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien if (mStops[i] > widthSoFar) { 9501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mStops[i]; 9601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 9701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 9801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return floor(widthSoFar / mTabWidth + 1) * mTabWidth; 9901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 10001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien private: 10101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<int> mStops; 10201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien int mTabWidth; 10301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 10401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 10501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass LineBreaker { 10601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien public: 1075cdad92c300a65cab89b172e952186f0c5870657Raph Levien const static int kTab_Shift = 29; // keep synchronized with TAB_MASK in StaticLayout.java 1085cdad92c300a65cab89b172e952186f0c5870657Raph Levien 10901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // Note: Locale persists across multiple invocations (it is not cleaned up by finish()), 11001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // explicitly to avoid the cost of creating ICU BreakIterator objects. It should always 11101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // be set on the first invocation, but callers are encouraged not to call again unless 11201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // locale has actually changed. 11301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // That logic could be here but it's better for performance that it's upstream because of 11401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // the cost of constructing and comparing the ICU Locale object. 1155cdad92c300a65cab89b172e952186f0c5870657Raph Levien // Note: caller is responsible for managing lifetime of hyphenator 1165cdad92c300a65cab89b172e952186f0c5870657Raph Levien void setLocale(const icu::Locale& locale, Hyphenator* hyphenator); 11701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 11801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void resize(size_t size) { 11901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mTextBuf.resize(size); 12001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mCharWidths.resize(size); 12101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 12201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 12301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t size() const { 12401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mTextBuf.size(); 12501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 12601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 12701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien uint16_t* buffer() { 12801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mTextBuf.data(); 12901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 13001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 13101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float* charWidths() { 13201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mCharWidths.data(); 13301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 13401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 13501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // set text to current contents of buffer 13601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setText(); 13701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 13801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setLineWidths(float firstWidth, int firstWidthLineCount, float restWidth); 13901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 140bb86b433f97a301c11800806b1ce5331fa227d4aRaph Levien void setIndents(const std::vector<float>& indents); 141dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien 14201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setTabStops(const int* stops, size_t nStops, int tabWidth) { 14301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mTabStops.set(stops, nStops, tabWidth); 14401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 14501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 14601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien BreakStrategy getStrategy() const { return mStrategy; } 14701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 14801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setStrategy(BreakStrategy strategy) { mStrategy = strategy; } 14901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1500dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader HyphenationFrequency getHyphenationFrequency() const { return mHyphenationFrequency; } 1510dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader 1520dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader void setHyphenationFrequency(HyphenationFrequency frequency) { 1530dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader mHyphenationFrequency = frequency; 1540dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader } 1550dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader 15601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // TODO: this class is actually fairly close to being general and not tied to using 15701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // Minikin to do the shaping of the strings. The main thing that would need to be changed 15801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // is having some kind of callback (or virtual class, or maybe even template), which could 15901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // easily be instantiated with Minikin's Layout. Future work for when needed. 1605cdad92c300a65cab89b172e952186f0c5870657Raph Levien float addStyleRun(MinikinPaint* paint, const FontCollection* typeface, FontStyle style, 1615cdad92c300a65cab89b172e952186f0c5870657Raph Levien size_t start, size_t end, bool isRtl); 16201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 16301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void addReplacement(size_t start, size_t end, float width); 16401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 16501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t computeBreaks(); 16601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 16701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien const int* getBreaks() const { 16801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mBreaks.data(); 16901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 17001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 17101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien const float* getWidths() const { 17201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mWidths.data(); 17301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 17401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1755cdad92c300a65cab89b172e952186f0c5870657Raph Levien const int* getFlags() const { 17601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mFlags.data(); 17701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 17801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 17901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void finish(); 18001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 18101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien private: 18201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // ParaWidth is used to hold cumulative width from beginning of paragraph. Note that for 18301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // very large paragraphs, accuracy could degrade using only 32-bit float. Note however 18401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // that float is used extensively on the Java side for this. This is a typedef so that 18501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // we can easily change it based on performance/accuracy tradeoff. 18601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien typedef double ParaWidth; 18701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 18801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // A single candidate break 18901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien struct Candidate { 19001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t offset; // offset to text buffer, in code units 19101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t prev; // index to previous break 19201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth preBreak; 19301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth postBreak; 19401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float penalty; // penalty of this break (for example, hyphen penalty) 19501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float score; // best score found for this break 1965cdad92c300a65cab89b172e952186f0c5870657Raph Levien size_t lineNumber; // only updated for non-constant line widths 1975cdad92c300a65cab89b172e952186f0c5870657Raph Levien uint8_t hyphenEdit; 19801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien }; 19901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 20001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float currentLineWidth() const; 20101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 2025cdad92c300a65cab89b172e952186f0c5870657Raph Levien void addWordBreak(size_t offset, ParaWidth preBreak, ParaWidth postBreak, float penalty, 2035cdad92c300a65cab89b172e952186f0c5870657Raph Levien uint8_t hyph); 20401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 20501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void addCandidate(Candidate cand); 20601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 2075cdad92c300a65cab89b172e952186f0c5870657Raph Levien // push an actual break to the output. Takes care of setting flags for tab 2085cdad92c300a65cab89b172e952186f0c5870657Raph Levien void pushBreak(int offset, float width, uint8_t hyph); 2095cdad92c300a65cab89b172e952186f0c5870657Raph Levien 21001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void computeBreaksGreedy(); 21101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 212abae97a39c26e191e350575932611a90e6b04d06Raph Levien void computeBreaksOptimal(bool isRectangular); 2135cdad92c300a65cab89b172e952186f0c5870657Raph Levien 2145cdad92c300a65cab89b172e952186f0c5870657Raph Levien void finishBreaksOptimal(); 21501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 21657b6dae9894b9362ef04517ff477fd491f9d433bRaph Levien WordBreaker mWordBreaker; 21701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<uint16_t>mTextBuf; 21801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<float>mCharWidths; 21901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 2205cdad92c300a65cab89b172e952186f0c5870657Raph Levien Hyphenator* mHyphenator; 2215cdad92c300a65cab89b172e952186f0c5870657Raph Levien std::vector<uint8_t> mHyphBuf; 2225cdad92c300a65cab89b172e952186f0c5870657Raph Levien 22301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // layout parameters 22401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien BreakStrategy mStrategy = kBreakStrategy_Greedy; 2250dc07c0be325b7c12c50729e04c4b2785a673fd7Roozbeh Pournader HyphenationFrequency mHyphenationFrequency = kHyphenationFrequency_Normal; 22601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien LineWidths mLineWidths; 22701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien TabStops mTabStops; 22801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 22901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // result of line breaking 23001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<int> mBreaks; 23101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<float> mWidths; 2325cdad92c300a65cab89b172e952186f0c5870657Raph Levien std::vector<int> mFlags; 23301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 23401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth mWidth = 0; 23501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<Candidate> mCandidates; 236abae97a39c26e191e350575932611a90e6b04d06Raph Levien float mLinePenalty = 0.0f; 23701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 23801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // the following are state for greedy breaker (updated while adding style runs) 23901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t mLastBreak; 24001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t mBestBreak; 24101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float mBestScore; 24201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth mPreBreak; // prebreak of last break 24301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien int mFirstTabIndex; 24401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 24501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 24601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien} // namespace android 24701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 24801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#endif // MINIKIN_LINE_BREAKER_H 249