impl SkFont::getPath
Replacement for SkPaint::getTextPath and getPosTextPath - only works with glyphIDs - doesn't try to do positioning - doesn't force caller to consolidate all the glyphs into one giant path Much of the time is spent transforming the path from the cache's size to the callers. Might consider passing the raw path + matrix rather than scaling it for them??? Bug: skia: Change-Id: Ie13015c61ebe410eaec084282d600338cfccb51a Reviewed-on: https://skia-review.googlesource.com/c/170881 Reviewed-by: Ben Wagner <bungeman@google.com> Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
f152130ef9
commit
07f93f2999
@ -8,7 +8,9 @@
|
||||
#include "Benchmark.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkChecksum.h"
|
||||
#include "SkFont.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
@ -139,10 +141,60 @@ protected:
|
||||
private:
|
||||
typedef Benchmark INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_BENCH( return new FontCacheBench(); )
|
||||
|
||||
// undefine this to run the efficiency test
|
||||
//DEF_BENCH( return new FontCacheEfficiency(); )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FontPathBench : public Benchmark {
|
||||
SkFont fFont;
|
||||
uint16_t fGlyphs[100];
|
||||
SkString fName;
|
||||
const bool fOneAtATime;
|
||||
|
||||
public:
|
||||
FontPathBench(bool oneAtATime) : fOneAtATime(oneAtATime) {
|
||||
fName.printf("font-path-%s", oneAtATime ? "loop" : "batch");
|
||||
}
|
||||
|
||||
protected:
|
||||
const char* onGetName() override {
|
||||
return fName.c_str();
|
||||
}
|
||||
|
||||
bool isSuitableFor(Backend backend) override {
|
||||
return backend == kNonRendering_Backend;
|
||||
}
|
||||
|
||||
void onDelayedSetup() override {
|
||||
fFont.setSize(32);
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fGlyphs); ++i) {
|
||||
fGlyphs[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
SkPath path;
|
||||
for (int i = 0; i < loops; ++i) {
|
||||
if (fOneAtATime) {
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fGlyphs); ++i) {
|
||||
fFont.getPath(fGlyphs[i], &path);
|
||||
}
|
||||
} else {
|
||||
fFont.getPaths(fGlyphs, SK_ARRAY_COUNT(fGlyphs),
|
||||
[](uint16_t, const SkPath* src, void* ctx) {
|
||||
if (src) {
|
||||
*static_cast<SkPath*>(ctx) = *src;
|
||||
}
|
||||
}, &path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef Benchmark INHERITED;
|
||||
};
|
||||
DEF_BENCH( return new FontPathBench(true); )
|
||||
DEF_BENCH( return new FontPathBench(false); )
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define SK_SUPPORT_LEGACY_FONT_FLAGS
|
||||
|
||||
class SkPaint;
|
||||
class SkPath;
|
||||
struct SkFontMetrics;
|
||||
|
||||
class SK_API SkFont {
|
||||
@ -152,7 +153,7 @@ public:
|
||||
return fTypeface->unicharToGlyph(uni);
|
||||
}
|
||||
|
||||
int countText(const void* text, size_t byteLength, SkTextEncoding encoding) {
|
||||
int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
|
||||
return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
|
||||
}
|
||||
|
||||
@ -162,6 +163,16 @@ public:
|
||||
void getWidths(const uint16_t glyphs[], int count, SkScalar widths[],
|
||||
SkRect bounds[] = nullptr) const;
|
||||
|
||||
/**
|
||||
* Returns true if the glyph has an outline (even if its empty), and sets the path.
|
||||
* If the glyph does not have an outline (e.g. it is a bitmap), this returns false
|
||||
* and ignores the path parameter.
|
||||
*/
|
||||
bool getPath(uint16_t glyphID, SkPath* path) const;
|
||||
void getPaths(const uint16_t glyphIDs[], int count,
|
||||
void (*GlyphPathProc)(uint16_t glyphID, const SkPath* pathOrNull, void* ctx),
|
||||
void* ctx) const;
|
||||
|
||||
SkScalar getMetrics(SkFontMetrics* metrics) const;
|
||||
SkScalar getSpacing() const { return this->getMetrics(nullptr); }
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "SkFontPriv.h"
|
||||
#include "SkGlyphCache.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkStrikeCache.h"
|
||||
#include "SkTo.h"
|
||||
@ -334,6 +335,48 @@ void SkFont::getWidths(const uint16_t glyphs[], int count, SkScalar widths[], Sk
|
||||
}
|
||||
}
|
||||
|
||||
void SkFont::getPaths(const uint16_t glyphs[], int count,
|
||||
void (*proc)(uint16_t, const SkPath*, void*), void* ctx) const {
|
||||
SkFont font(*this);
|
||||
SkScalar scale = font.setupForAsPaths(nullptr);
|
||||
|
||||
SkAutoDescriptor ad;
|
||||
SkScalerContextEffects effects;
|
||||
auto desc = SkScalerContext::CreateDescriptorAndEffectsUsingDefaultPaint(font,
|
||||
SkSurfaceProps(0, kUnknown_SkPixelGeometry), SkScalerContextFlags::kNone,
|
||||
SkMatrix::I(), &ad, &effects);
|
||||
auto typeface = SkFontPriv::GetTypefaceOrDefault(font);
|
||||
auto exclusive = SkStrikeCache::FindOrCreateStrikeExclusive(*desc, effects, *typeface);
|
||||
auto cache = exclusive.get();
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const SkPath* orig = cache->findPath(cache->getGlyphIDMetrics(glyphs[i]));
|
||||
if (orig && scale) {
|
||||
SkPath tmp;
|
||||
orig->transform(SkMatrix::MakeScale(scale, scale), &tmp);
|
||||
proc(glyphs[i], &tmp, ctx);
|
||||
} else {
|
||||
proc(glyphs[i], orig, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SkFont::getPath(uint16_t glyphID, SkPath* path) const {
|
||||
struct Pair {
|
||||
SkPath* fPath;
|
||||
bool fWasSet;
|
||||
} pair = { path, false };
|
||||
|
||||
this->getPaths(&glyphID, 1, [](uint16_t, const SkPath* orig, void* ctx) {
|
||||
Pair* pair = static_cast<Pair*>(ctx);
|
||||
if (orig) {
|
||||
*pair->fPath = *orig;
|
||||
pair->fWasSet = true;
|
||||
}
|
||||
}, &pair);
|
||||
return pair.fWasSet;
|
||||
}
|
||||
|
||||
SkScalar SkFont::getMetrics(SkFontMetrics* metrics) const {
|
||||
SkCanonicalizeFont canon(*this);
|
||||
const SkFont& font = canon.getFont();
|
||||
|
Loading…
Reference in New Issue
Block a user