LineBreaker.h revision dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3f
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" 3001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 3101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Leviennamespace android { 3201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 3301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienenum BreakStrategy { 3401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien kBreakStrategy_Greedy = 0, 3501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien kBreakStrategy_HighQuality = 1, 3601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien kBreakStrategy_Balanced = 2 3701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 3801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 3901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien// TODO: want to generalize to be able to handle array of line widths 4001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass LineWidths { 4101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien public: 4201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setWidths(float firstWidth, int firstWidthLineCount, float restWidth) { 4301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mFirstWidth = firstWidth; 4401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mFirstWidthLineCount = firstWidthLineCount; 4501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mRestWidth = restWidth; 4601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 47dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien void setMargins(const std::vector<float>& margins) { 48dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien mMargins = margins; 49dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } 505cdad92c300a65cab89b172e952186f0c5870657Raph Levien bool isConstant() const { 515cdad92c300a65cab89b172e952186f0c5870657Raph Levien // technically mFirstWidthLineCount == 0 would count too, but doesn't actually happen 52dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien return mRestWidth == mFirstWidth && mMargins.empty(); 535cdad92c300a65cab89b172e952186f0c5870657Raph Levien } 5401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float getLineWidth(int line) const { 55dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien float width = (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth; 56dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien if (!mMargins.empty()) { 57dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien if ((size_t)line < mMargins.size()) { 58dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien width -= mMargins[line]; 59dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } else { 60dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien width -= mMargins.back(); 61dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } 62dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien } 63dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien return width; 6401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 6501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien private: 6601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float mFirstWidth; 6701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien int mFirstWidthLineCount; 6801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float mRestWidth; 69dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien std::vector<float> mMargins; 7001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 7101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 7201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass TabStops { 7301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien public: 7401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void set(const int* stops, size_t nStops, int tabWidth) { 7501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien if (stops != nullptr) { 7601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mStops.assign(stops, stops + nStops); 7701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } else { 7801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mStops.clear(); 7901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 8001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mTabWidth = tabWidth; 8101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 8201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float nextTab(float widthSoFar) const { 8301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien for (size_t i = 0; i < mStops.size(); i++) { 8401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien if (mStops[i] > widthSoFar) { 8501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mStops[i]; 8601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 8701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 8801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return floor(widthSoFar / mTabWidth + 1) * mTabWidth; 8901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 9001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien private: 9101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<int> mStops; 9201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien int mTabWidth; 9301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 9401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 9501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levienclass LineBreaker { 9601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien public: 975cdad92c300a65cab89b172e952186f0c5870657Raph Levien const static int kTab_Shift = 29; // keep synchronized with TAB_MASK in StaticLayout.java 985cdad92c300a65cab89b172e952186f0c5870657Raph Levien 9901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ~LineBreaker() { 10001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien utext_close(&mUText); 10101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien delete mBreakIterator; 10201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 10301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 10401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // Note: Locale persists across multiple invocations (it is not cleaned up by finish()), 10501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // explicitly to avoid the cost of creating ICU BreakIterator objects. It should always 10601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // be set on the first invocation, but callers are encouraged not to call again unless 10701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // locale has actually changed. 10801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // That logic could be here but it's better for performance that it's upstream because of 10901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // the cost of constructing and comparing the ICU Locale object. 1105cdad92c300a65cab89b172e952186f0c5870657Raph Levien // Note: caller is responsible for managing lifetime of hyphenator 1115cdad92c300a65cab89b172e952186f0c5870657Raph Levien void setLocale(const icu::Locale& locale, Hyphenator* hyphenator); 11201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 11301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void resize(size_t size) { 11401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mTextBuf.resize(size); 11501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mCharWidths.resize(size); 11601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 11701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 11801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t size() const { 11901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mTextBuf.size(); 12001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 12101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 12201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien uint16_t* buffer() { 12301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mTextBuf.data(); 12401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 12501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 12601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float* charWidths() { 12701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mCharWidths.data(); 12801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 12901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 13001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // set text to current contents of buffer 13101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setText(); 13201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 13301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setLineWidths(float firstWidth, int firstWidthLineCount, float restWidth); 13401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 135dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien void setMargins(const std::vector<float>& margins); 136dc7bc6e39e1ef6b713b927baf24db8b4f02f1a3fRaph Levien 13701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setTabStops(const int* stops, size_t nStops, int tabWidth) { 13801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien mTabStops.set(stops, nStops, tabWidth); 13901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 14001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 14101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien BreakStrategy getStrategy() const { return mStrategy; } 14201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 14301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void setStrategy(BreakStrategy strategy) { mStrategy = strategy; } 14401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 14501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // TODO: this class is actually fairly close to being general and not tied to using 14601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // Minikin to do the shaping of the strings. The main thing that would need to be changed 14701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // is having some kind of callback (or virtual class, or maybe even template), which could 14801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // easily be instantiated with Minikin's Layout. Future work for when needed. 1495cdad92c300a65cab89b172e952186f0c5870657Raph Levien float addStyleRun(MinikinPaint* paint, const FontCollection* typeface, FontStyle style, 1505cdad92c300a65cab89b172e952186f0c5870657Raph Levien size_t start, size_t end, bool isRtl); 15101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 15201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void addReplacement(size_t start, size_t end, float width); 15301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 15401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t computeBreaks(); 15501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 15601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien const int* getBreaks() const { 15701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mBreaks.data(); 15801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 15901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 16001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien const float* getWidths() const { 16101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mWidths.data(); 16201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 16301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1645cdad92c300a65cab89b172e952186f0c5870657Raph Levien const int* getFlags() const { 16501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien return mFlags.data(); 16601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien } 16701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 16801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void finish(); 16901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 17001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien private: 17101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // ParaWidth is used to hold cumulative width from beginning of paragraph. Note that for 17201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // very large paragraphs, accuracy could degrade using only 32-bit float. Note however 17301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // that float is used extensively on the Java side for this. This is a typedef so that 17401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // we can easily change it based on performance/accuracy tradeoff. 17501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien typedef double ParaWidth; 17601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 17701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // A single candidate break 17801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien struct Candidate { 17901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t offset; // offset to text buffer, in code units 18001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t prev; // index to previous break 18101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth preBreak; 18201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth postBreak; 18301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float penalty; // penalty of this break (for example, hyphen penalty) 18401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float score; // best score found for this break 1855cdad92c300a65cab89b172e952186f0c5870657Raph Levien size_t lineNumber; // only updated for non-constant line widths 1865cdad92c300a65cab89b172e952186f0c5870657Raph Levien uint8_t hyphenEdit; 18701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien }; 18801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 18901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float currentLineWidth() const; 19001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1915cdad92c300a65cab89b172e952186f0c5870657Raph Levien // compute shrink/stretch penalty for line 1925cdad92c300a65cab89b172e952186f0c5870657Raph Levien float computeScore(float delta, bool atEnd); 1935cdad92c300a65cab89b172e952186f0c5870657Raph Levien 1945cdad92c300a65cab89b172e952186f0c5870657Raph Levien void addWordBreak(size_t offset, ParaWidth preBreak, ParaWidth postBreak, float penalty, 1955cdad92c300a65cab89b172e952186f0c5870657Raph Levien uint8_t hyph); 19601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 19701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void addCandidate(Candidate cand); 19801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 1995cdad92c300a65cab89b172e952186f0c5870657Raph Levien // push an actual break to the output. Takes care of setting flags for tab 2005cdad92c300a65cab89b172e952186f0c5870657Raph Levien void pushBreak(int offset, float width, uint8_t hyph); 2015cdad92c300a65cab89b172e952186f0c5870657Raph Levien 20201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien void computeBreaksGreedy(); 20301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 2045cdad92c300a65cab89b172e952186f0c5870657Raph Levien void computeBreaksOptimal(); 2055cdad92c300a65cab89b172e952186f0c5870657Raph Levien 2065cdad92c300a65cab89b172e952186f0c5870657Raph Levien // special case when LineWidth is constant (layout is rectangle) 2075cdad92c300a65cab89b172e952186f0c5870657Raph Levien void computeBreaksOptimalRect(); 2085cdad92c300a65cab89b172e952186f0c5870657Raph Levien 2095cdad92c300a65cab89b172e952186f0c5870657Raph Levien void finishBreaksOptimal(); 21001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 21101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien icu::BreakIterator* mBreakIterator = nullptr; 21201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien UText mUText = UTEXT_INITIALIZER; 21301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<uint16_t>mTextBuf; 21401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<float>mCharWidths; 21501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 2165cdad92c300a65cab89b172e952186f0c5870657Raph Levien Hyphenator* mHyphenator; 2175cdad92c300a65cab89b172e952186f0c5870657Raph Levien std::vector<uint8_t> mHyphBuf; 2185cdad92c300a65cab89b172e952186f0c5870657Raph Levien 21901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // layout parameters 22001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien BreakStrategy mStrategy = kBreakStrategy_Greedy; 22101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien LineWidths mLineWidths; 22201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien TabStops mTabStops; 22301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 22401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // result of line breaking 22501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<int> mBreaks; 22601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<float> mWidths; 2275cdad92c300a65cab89b172e952186f0c5870657Raph Levien std::vector<int> mFlags; 22801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 22901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth mWidth = 0; 23001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien std::vector<Candidate> mCandidates; 23101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 23201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien // the following are state for greedy breaker (updated while adding style runs) 23301f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t mLastBreak; 23401f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien size_t mBestBreak; 23501f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien float mBestScore; 23601f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien ParaWidth mPreBreak; // prebreak of last break 23701f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien int mFirstTabIndex; 23801f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien}; 23901f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 24001f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien} // namespace android 24101f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien 24201f526614431e3a0a6e1a48039e00b8a9b7d6fbfRaph Levien#endif // MINIKIN_LINE_BREAKER_H 243