blob: 5d3e75252f4aaa1c53ca3145e350b584b4d1b9bb [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A module for breaking paragraphs into lines, supporting high quality
* hyphenation and justification.
*/
#ifndef MINIKIN_LINE_BREAKER_H
#define MINIKIN_LINE_BREAKER_H
#include <deque>
#include <vector>
#include "minikin/FontCollection.h"
#include "minikin/Layout.h"
#include "minikin/Macros.h"
#include "minikin/MeasuredText.h"
#include "minikin/MinikinFont.h"
#include "minikin/Range.h"
#include "minikin/U16StringPiece.h"
namespace minikin {
enum class BreakStrategy : uint8_t {
Greedy = 0,
HighQuality = 1,
Balanced = 2,
};
enum class HyphenationFrequency : uint8_t {
None = 0,
Normal = 1,
Full = 2,
};
class Hyphenator;
class WordBreaker;
class TabStops {
public:
// Caller must free stops. stops can be nullprt.
TabStops(const float* stops, size_t nStops, float tabWidth)
: mStops(stops), mStopsSize(nStops), mTabWidth(tabWidth) {}
float nextTab(float widthSoFar) const {
for (size_t i = 0; i < mStopsSize; i++) {
if (mStops[i] > widthSoFar) {
return mStops[i];
}
}
if (mTabWidth == 0) {
return 0;
}
return floor(widthSoFar / mTabWidth + 1) * mTabWidth;
}
private:
const float* mStops;
size_t mStopsSize;
float mTabWidth;
};
// Implement this for the additional information during line breaking.
// The functions in this class's interface may be called several times. The implementation
// must return the same value for the same input.
class LineWidth {
public:
virtual ~LineWidth() {}
// Called to find out the width for the line. This must not return negative values.
virtual float getAt(size_t lineNo) const = 0;
// Called to find out the minimum line width. This mut not return negative values.
virtual float getMin() const = 0;
};
struct LineBreakResult {
public:
LineBreakResult() = default;
// Following five vectors have the same length.
// TODO: Introduce individual line info struct if copy cost in JNI is negligible.
std::vector<int> breakPoints;
std::vector<float> widths;
std::vector<float> ascents;
std::vector<float> descents;
std::vector<int> flags;
LineBreakResult(LineBreakResult&&) = default;
LineBreakResult& operator=(LineBreakResult&&) = default;
void reverse() {
std::reverse(breakPoints.begin(), breakPoints.end());
std::reverse(widths.begin(), widths.end());
std::reverse(ascents.begin(), ascents.end());
std::reverse(descents.begin(), descents.end());
std::reverse(flags.begin(), flags.end());
}
private:
MINIKIN_PREVENT_COPY_AND_ASSIGN(LineBreakResult);
};
LineBreakResult breakIntoLines(const U16StringPiece& textBuffer, BreakStrategy strategy,
HyphenationFrequency frequency, bool justified,
const MeasuredText& measuredText, const LineWidth& lineWidth,
const TabStops& tabStops);
} // namespace minikin
#endif // MINIKIN_LINE_BREAKER_H