summaryrefslogtreecommitdiff
path: root/libs/minikin/Layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/minikin/Layout.cpp')
-rw-r--r--libs/minikin/Layout.cpp85
1 files changed, 53 insertions, 32 deletions
diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp
index e7d41c8..6369109 100644
--- a/libs/minikin/Layout.cpp
+++ b/libs/minikin/Layout.cpp
@@ -18,12 +18,6 @@
#include "minikin/Layout.h"
-#include <cmath>
-#include <iostream>
-#include <mutex>
-#include <string>
-#include <vector>
-
#include <hb-icu.h>
#include <hb-ot.h>
#include <log/log.h>
@@ -31,18 +25,22 @@
#include <unicode/utf16.h>
#include <utils/LruCache.h>
-#include "minikin/Emoji.h"
-#include "minikin/HbUtils.h"
-#include "minikin/LayoutCache.h"
-#include "minikin/LayoutPieces.h"
-#include "minikin/Macros.h"
+#include <cmath>
+#include <iostream>
+#include <mutex>
+#include <string>
+#include <vector>
#include "BidiUtils.h"
#include "LayoutSplitter.h"
#include "LayoutUtils.h"
#include "LocaleListCache.h"
#include "MinikinInternal.h"
-
+#include "minikin/Emoji.h"
+#include "minikin/HbUtils.h"
+#include "minikin/LayoutCache.h"
+#include "minikin/LayoutPieces.h"
+#include "minikin/Macros.h"
namespace minikin {
void Layout::doLayout(const U16StringPiece& textBuf, const Range& range, Bidi bidiFlags,
@@ -53,19 +51,27 @@ void Layout::doLayout(const U16StringPiece& textBuf, const Range& range, Bidi bi
mGlyphs.reserve(count);
for (const BidiText::RunInfo& runInfo : BidiText(textBuf, range, bidiFlags)) {
doLayoutRunCached(textBuf, runInfo.range, runInfo.isRtl, paint, range.getStart(),
- startHyphen, endHyphen, this, nullptr);
+ startHyphen, endHyphen, this, nullptr, nullptr);
}
}
float Layout::measureText(const U16StringPiece& textBuf, const Range& range, Bidi bidiFlags,
const MinikinPaint& paint, StartHyphenEdit startHyphen,
- EndHyphenEdit endHyphen, float* advances) {
+ EndHyphenEdit endHyphen, float* advances, MinikinRect* bounds) {
float advance = 0;
+
+ MinikinRect tmpBounds;
for (const BidiText::RunInfo& runInfo : BidiText(textBuf, range, bidiFlags)) {
const size_t offset = range.toRangeOffset(runInfo.range.getStart());
float* advancesForRun = advances ? advances + offset : nullptr;
- advance += doLayoutRunCached(textBuf, runInfo.range, runInfo.isRtl, paint, 0, startHyphen,
- endHyphen, nullptr, advancesForRun);
+ tmpBounds.setEmpty();
+ float run_advance = doLayoutRunCached(textBuf, runInfo.range, runInfo.isRtl, paint, 0,
+ startHyphen, endHyphen, nullptr, advancesForRun,
+ bounds ? &tmpBounds : nullptr);
+ if (bounds) {
+ bounds->join(tmpBounds, advance, 0);
+ }
+ advance += run_advance;
}
return advance;
}
@@ -73,11 +79,12 @@ float Layout::measureText(const U16StringPiece& textBuf, const Range& range, Bid
float Layout::doLayoutRunCached(const U16StringPiece& textBuf, const Range& range, bool isRtl,
const MinikinPaint& paint, size_t dstStart,
StartHyphenEdit startHyphen, EndHyphenEdit endHyphen,
- Layout* layout, float* advances) {
+ Layout* layout, float* advances, MinikinRect* bounds) {
if (!range.isValid()) {
return 0.0f; // ICU failed to retrieve the bidi run?
}
float advance = 0;
+ MinikinRect tmpBounds;
for (const auto[context, piece] : LayoutSplitter(textBuf, range, isRtl)) {
// Hyphenation only applies to the start/end of run.
const StartHyphenEdit pieceStartHyphen =
@@ -86,25 +93,32 @@ float Layout::doLayoutRunCached(const U16StringPiece& textBuf, const Range& rang
(piece.getEnd() == range.getEnd()) ? endHyphen : EndHyphenEdit::NO_EDIT;
float* advancesForRun =
advances ? advances + (piece.getStart() - range.getStart()) : nullptr;
- advance += doLayoutWord(textBuf.data() + context.getStart(),
- piece.getStart() - context.getStart(), piece.getLength(),
- context.getLength(), isRtl, paint, piece.getStart() - dstStart,
- pieceStartHyphen, pieceEndHyphen, layout, advancesForRun);
+ tmpBounds.setEmpty();
+ float word_advance = doLayoutWord(
+ textBuf.data() + context.getStart(), piece.getStart() - context.getStart(),
+ piece.getLength(), context.getLength(), isRtl, paint, piece.getStart() - dstStart,
+ pieceStartHyphen, pieceEndHyphen, layout, advancesForRun,
+ bounds ? &tmpBounds : nullptr);
+ if (bounds) {
+ bounds->join(tmpBounds, advance, 0);
+ }
+ advance += word_advance;
}
return advance;
}
class LayoutAppendFunctor {
public:
- LayoutAppendFunctor(Layout* layout, float* advances, float* totalAdvance, uint32_t outOffset,
- float wordSpacing)
+ LayoutAppendFunctor(Layout* layout, float* advances, uint32_t outOffset, float wordSpacing,
+ MinikinRect* bounds)
: mLayout(layout),
mAdvances(advances),
- mTotalAdvance(totalAdvance),
mOutOffset(outOffset),
- mWordSpacing(wordSpacing) {}
+ mWordSpacing(wordSpacing),
+ mBounds(bounds) {}
- void operator()(const LayoutPiece& layoutPiece, const MinikinPaint& /* paint */) {
+ void operator()(const LayoutPiece& layoutPiece, const MinikinPaint& /* paint */,
+ const MinikinRect& bounds) {
if (mLayout) {
mLayout->appendLayout(layoutPiece, mOutOffset, mWordSpacing);
}
@@ -112,30 +126,37 @@ public:
const std::vector<float>& advances = layoutPiece.advances();
std::copy(advances.begin(), advances.end(), mAdvances);
}
- if (mTotalAdvance) {
- *mTotalAdvance = layoutPiece.advance();
+ if (mBounds) {
+ mBounds->join(bounds, mTotalAdvance, 0);
}
+ mTotalAdvance += layoutPiece.advance();
}
+ float getTotalAdvance() { return mTotalAdvance; }
+
private:
Layout* mLayout;
float* mAdvances;
- float* mTotalAdvance;
+ float mTotalAdvance{0};
const uint32_t mOutOffset;
const float mWordSpacing;
+ MinikinRect* mBounds;
};
float Layout::doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
bool isRtl, const MinikinPaint& paint, size_t bufStart,
StartHyphenEdit startHyphen, EndHyphenEdit endHyphen, Layout* layout,
- float* advances) {
+ float* advances, MinikinRect* bounds) {
float wordSpacing = count == 1 && isWordSpace(buf[start]) ? paint.wordSpacing : 0;
float totalAdvance = 0;
+ const bool boundsCalculation = bounds != nullptr;
const U16StringPiece textBuf(buf, bufSize);
const Range range(start, start + count);
- LayoutAppendFunctor f(layout, advances, &totalAdvance, bufStart, wordSpacing);
- LayoutCache::getInstance().getOrCreate(textBuf, range, paint, isRtl, startHyphen, endHyphen, f);
+ LayoutAppendFunctor f(layout, advances, bufStart, wordSpacing, bounds);
+ LayoutCache::getInstance().getOrCreate(textBuf, range, paint, isRtl, startHyphen, endHyphen,
+ boundsCalculation, f);
+ totalAdvance = f.getTotalAdvance();
if (wordSpacing != 0) {
totalAdvance += wordSpacing;