summaryrefslogtreecommitdiff
path: root/libs/minikin/LayoutCore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/minikin/LayoutCore.cpp')
-rw-r--r--libs/minikin/LayoutCore.cpp84
1 files changed, 33 insertions, 51 deletions
diff --git a/libs/minikin/LayoutCore.cpp b/libs/minikin/LayoutCore.cpp
index 6f33ad7..b079e85 100644
--- a/libs/minikin/LayoutCore.cpp
+++ b/libs/minikin/LayoutCore.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "Minikin"
+#define ATRACE_TAG ATRACE_TAG_VIEW
#include "minikin/LayoutCore.h"
@@ -24,6 +25,7 @@
#include <unicode/ubidi.h>
#include <unicode/utf16.h>
#include <utils/LruCache.h>
+#include <utils/Trace.h>
#include <cmath>
#include <iostream>
@@ -32,11 +34,12 @@
#include <vector>
#include "BidiUtils.h"
-#include "FontFeatureUtils.h"
#include "LayoutUtils.h"
#include "LocaleListCache.h"
#include "MinikinInternal.h"
+#include "ScriptUtils.h"
#include "minikin/Emoji.h"
+#include "minikin/FontFeature.h"
#include "minikin/HbUtils.h"
#include "minikin/LayoutCache.h"
#include "minikin/LayoutPieces.h"
@@ -136,45 +139,6 @@ static bool isColorBitmapFont(const HbFontUniquePtr& font) {
return cbdt;
}
-static hb_codepoint_t decodeUtf16(const uint16_t* chars, size_t len, ssize_t* iter) {
- UChar32 result;
- U16_NEXT(chars, *iter, (ssize_t)len, result);
- if (U_IS_SURROGATE(result)) { // isolated surrogate
- result = 0xFFFDu; // U+FFFD REPLACEMENT CHARACTER
- }
- return (hb_codepoint_t)result;
-}
-
-static hb_script_t getScriptRun(const uint16_t* chars, size_t len, ssize_t* iter) {
- if (size_t(*iter) == len) {
- return HB_SCRIPT_UNKNOWN;
- }
- uint32_t cp = decodeUtf16(chars, len, iter);
- hb_unicode_funcs_t* unicode_func = hb_unicode_funcs_get_default();
- hb_script_t current_script = hb_unicode_script(unicode_func, cp);
- for (;;) {
- if (size_t(*iter) == len) break;
- const ssize_t prev_iter = *iter;
- cp = decodeUtf16(chars, len, iter);
- const hb_script_t script = hb_unicode_script(unicode_func, cp);
- if (script != current_script) {
- if (current_script == HB_SCRIPT_INHERITED || current_script == HB_SCRIPT_COMMON) {
- current_script = script;
- } else if (script == HB_SCRIPT_INHERITED || script == HB_SCRIPT_COMMON) {
- continue;
- } else {
- *iter = prev_iter;
- break;
- }
- }
- }
- if (current_script == HB_SCRIPT_INHERITED) {
- current_script = HB_SCRIPT_COMMON;
- }
-
- return current_script;
-}
-
/**
* Disable certain scripts (mostly those with cursive connection) from having letterspacing
* applied. See https://github.com/behdad/harfbuzz/issues/64 for more details.
@@ -349,7 +313,7 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
double size = paint.size;
double scaleX = paint.scaleX;
- std::unordered_map<const Font*, uint32_t> fontMap;
+ std::unordered_map<const MinikinFont*, uint32_t> fontMap;
float x = 0;
float y = 0;
@@ -358,19 +322,20 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
isRtl ? --run_ix : ++run_ix) {
FontCollection::Run& run = items[run_ix];
FakedFont fakedFont = paint.font->getBestFont(substr, run, paint.fontStyle);
- auto it = fontMap.find(fakedFont.font.get());
+ const std::shared_ptr<MinikinFont>& typeface = fakedFont.typeface();
+ auto it = fontMap.find(typeface.get());
uint8_t font_ix;
if (it == fontMap.end()) {
// First time to see this font.
font_ix = mFonts.size();
mFonts.push_back(fakedFont);
- fontMap.insert(std::make_pair(fakedFont.font.get(), font_ix));
+ fontMap.insert(std::make_pair(typeface.get(), font_ix));
// We override some functions which are not thread safe.
- HbFontUniquePtr font(hb_font_create_sub_font(fakedFont.font->baseFont().get()));
+ HbFontUniquePtr font(hb_font_create_sub_font(fakedFont.hbFont().get()));
hb_font_set_funcs(
font.get(), isColorBitmapFont(font) ? getFontFuncsForEmoji() : getFontFuncs(),
- new SkiaArguments({fakedFont.font->typeface().get(), &paint, fakedFont.fakery}),
+ new SkiaArguments({fakedFont.typeface().get(), &paint, fakedFont.fakery}),
[](void* data) { delete reinterpret_cast<SkiaArguments*>(data); });
hbFonts.push_back(std::move(font));
} else {
@@ -387,7 +352,7 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
}
if (needExtent) {
MinikinExtent verticalExtent;
- fakedFont.font->typeface()->GetFontExtent(&verticalExtent, paint, fakedFont.fakery);
+ typeface->GetFontExtent(&verticalExtent, paint, fakedFont.fakery);
mExtent.extendBy(verticalExtent);
}
@@ -400,11 +365,10 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
// Note: scriptRunStart and scriptRunEnd, as well as run.start and run.end, run between 0
// and count.
- ssize_t scriptRunEnd;
- for (ssize_t scriptRunStart = run.start; scriptRunStart < run.end;
- scriptRunStart = scriptRunEnd) {
- scriptRunEnd = scriptRunStart;
- hb_script_t script = getScriptRun(buf + start, run.end, &scriptRunEnd /* iterator */);
+ for (const auto [range, script] : ScriptText(textBuf, run.start, run.end)) {
+ ssize_t scriptRunStart = range.getStart();
+ ssize_t scriptRunEnd = range.getEnd();
+
// After the last line, scriptRunEnd is guaranteed to have increased, since the only
// time getScriptRun does not increase its iterator is when it has already reached the
// end of the buffer. But that can't happen, since if we have already reached the end
@@ -494,4 +458,22 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
mAdvance = x;
}
+// static
+MinikinRect LayoutPiece::calculateBounds(const LayoutPiece& layout, const MinikinPaint& paint) {
+ ATRACE_CALL();
+ MinikinRect out;
+ for (uint32_t i = 0; i < layout.glyphCount(); ++i) {
+ MinikinRect bounds;
+ uint32_t glyphId = layout.glyphIdAt(i);
+ const FakedFont& fakedFont = layout.fontAt(i);
+ const Point& pos = layout.pointAt(i);
+
+ fakedFont.typeface()->GetBounds(&bounds, glyphId, paint, fakedFont.fakery);
+ out.join(bounds, pos);
+ }
+ return out;
+}
+
+LayoutPiece::~LayoutPiece() {}
+
} // namespace minikin