SkScalerContext to use smart pointers.

CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-Clang-GCE-CPU-AVX2-x86_64-Debug-ASAN-Trybot;master.client.skia:Test-Ubuntu-Clang-GCE-CPU-AVX2-x86_64-Debug-MSAN-Trybot

Change-Id: I27a714388b8ded7dfc968e322b0a587205f575f1
Reviewed-on: https://skia-review.googlesource.com/3731
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
bungeman 2016-10-20 16:06:52 -04:00 committed by Skia Commit-Bot
parent 050ffa9ad5
commit 7cfd46aebd
19 changed files with 173 additions and 171 deletions

View File

@ -308,8 +308,9 @@ public:
* if allowFailure is true, this returns NULL, else it returns a
* dummy scalercontext that will not crash, but will draw nothing.
*/
SkScalerContext* createScalerContext(const SkScalerContextEffects&, const SkDescriptor*,
bool allowFailure = false) const;
std::unique_ptr<SkScalerContext> createScalerContext(const SkScalerContextEffects&,
const SkDescriptor*,
bool allowFailure = false) const;
/**
* Return a rectangle (scaled to 1-pt) that represents the union of the bounds of all

View File

@ -38,13 +38,12 @@ static SkGlyphCache_Globals& get_globals() {
#define kMinGlyphImageSize (16*2)
#define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphCount)
SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkScalerContext* ctx)
SkGlyphCache::SkGlyphCache(const SkDescriptor* desc, std::unique_ptr<SkScalerContext> ctx)
: fDesc(desc->copy())
, fScalerContext(ctx)
, fScalerContext(std::move(ctx))
, fGlyphAlloc(kMinAllocAmount) {
SkASSERT(typeface);
SkASSERT(desc);
SkASSERT(ctx);
SkASSERT(fScalerContext);
fPrev = fNext = nullptr;
@ -54,11 +53,11 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
}
SkGlyphCache::~SkGlyphCache() {
fGlyphMap.foreach ([](SkGlyph* g) {
fGlyphMap.foreach([](SkGlyph* g) {
if (g->fPathData) {
delete g->fPathData->fPath;
} } );
delete fScalerContext;
}
});
}
SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(PackedUnicharID packedUnicharID) {
@ -528,13 +527,13 @@ SkGlyphCache* SkGlyphCache::VisitCache(SkTypeface* typeface,
{
// pass true the first time, to notice if the scalercontext failed,
// so we can try the purge.
SkScalerContext* ctx = typeface->createScalerContext(effects, desc, true);
std::unique_ptr<SkScalerContext> ctx = typeface->createScalerContext(effects, desc, true);
if (!ctx) {
get_globals().purgeAll();
ctx = typeface->createScalerContext(effects, desc, false);
SkASSERT(ctx);
}
cache = new SkGlyphCache(typeface, desc, ctx);
cache = new SkGlyphCache(desc, std::move(ctx));
}
AutoValidate av(cache);

View File

@ -110,7 +110,7 @@ public:
void dump() const;
SkScalerContext* getScalerContext() const { return fScalerContext; }
SkScalerContext* getScalerContext() const { return fScalerContext.get(); }
/** Find a matching cache entry, and call proc() with it. If none is found create a new one.
If the proc() returns true, detach the cache and return it, otherwise leave it and return
@ -195,8 +195,7 @@ private:
PackedGlyphID fPackedGlyphID;
};
// SkGlyphCache takes ownership of the scalercontext.
SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*);
SkGlyphCache(const SkDescriptor*, std::unique_ptr<SkScalerContext>);
~SkGlyphCache();
// Return the SkGlyph* associated with MakeID. The id parameter is the
@ -233,7 +232,7 @@ private:
SkGlyphCache* fNext;
SkGlyphCache* fPrev;
const std::unique_ptr<SkDescriptor> fDesc;
SkScalerContext* const fScalerContext;
const std::unique_ptr<SkScalerContext> fScalerContext;
SkPaint::FontMetrics fFontMetrics;
// Map from a combined GlyphID and sub-pixel position to a SkGlyph.

View File

@ -12,6 +12,7 @@
#include "SkDescriptor.h"
#include "SkDraw.h"
#include "SkGlyph.h"
#include "SkMakeUnique.h"
#include "SkMaskFilter.h"
#include "SkMaskGamma.h"
#include "SkMatrix22.h"
@ -62,11 +63,11 @@ void SkGlyph::zeroMetrics() {
#define DUMP_RECx
#endif
SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkScalerContextEffects& effects,
SkScalerContext::SkScalerContext(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, nullptr)))
, fTypeface(sk_ref_sp(typeface))
, fTypeface(std::move(typeface))
, fPathEffect(sk_ref_sp(effects.fPathEffect))
, fMaskFilter(sk_ref_sp(effects.fMaskFilter))
, fRasterizer(sk_ref_sp(effects.fRasterizer))
@ -831,9 +832,9 @@ SkAxisAlignment SkScalerContext::computeAxisAlignmentForHText() {
class SkScalerContext_Empty : public SkScalerContext {
public:
SkScalerContext_Empty(SkTypeface* typeface, const SkScalerContextEffects& effects,
SkScalerContext_Empty(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext(typeface, effects, desc) {}
: SkScalerContext(std::move(typeface), effects, desc) {}
protected:
unsigned generateGlyphCount() override {
@ -859,13 +860,13 @@ protected:
extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc);
SkScalerContext* SkTypeface::createScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc,
bool allowFailure) const {
SkScalerContext* c = this->onCreateScalerContext(effects, desc);
std::unique_ptr<SkScalerContext> SkTypeface::createScalerContext(
const SkScalerContextEffects& effects, const SkDescriptor* desc, bool allowFailure) const
{
std::unique_ptr<SkScalerContext> c(this->onCreateScalerContext(effects, desc));
if (!c && !allowFailure) {
c = new SkScalerContext_Empty(const_cast<SkTypeface*>(this), effects, desc);
c = skstd::make_unique<SkScalerContext_Empty>(sk_ref_sp(const_cast<SkTypeface*>(this)),
effects, desc);
}
return c;
}

View File

@ -211,7 +211,7 @@ public:
kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
};
SkScalerContext(SkTypeface*, const SkScalerContextEffects&, const SkDescriptor*);
SkScalerContext(sk_sp<SkTypeface>, const SkScalerContextEffects&, const SkDescriptor*);
virtual ~SkScalerContext();
SkTypeface* getTypeface() const { return fTypeface.get(); }
@ -353,11 +353,6 @@ private:
void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
SkPath* devPath, SkMatrix* fillToDevMatrix);
// returns the right context from our link-list for this char. If no match
// is found it returns nullptr. If a match is found then the glyphID param is
// set to the glyphID that maps to the provided char.
SkScalerContext* getContextFromChar(SkUnichar uni, uint16_t* glyphID);
// SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.
protected:
// Visible to subclasses so that generateImage can apply the pre-blend directly.

View File

@ -346,13 +346,14 @@ bool SkTypeface::onComputeBounds(SkRect* bounds) const {
desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
SkScalerContextEffects noeffects;
SkAutoTDelete<SkScalerContext> ctx(this->createScalerContext(noeffects, desc, true));
if (ctx.get()) {
SkPaint::FontMetrics fm;
ctx->getFontMetrics(&fm);
bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize,
fm.fXMax * invTextSize, fm.fBottom * invTextSize);
return true;
std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, desc, true);
if (!ctx) {
return false;
}
return false;
SkPaint::FontMetrics fm;
ctx->getFontMetrics(&fm);
bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize,
fm.fXMax * invTextSize, fm.fBottom * invTextSize);
return true;
}

View File

@ -5,26 +5,26 @@
* found in the LICENSE file.
*/
#include "SkCanvas.h"
#include "SkDescriptor.h"
#include "SkGScalerContext.h"
#include "SkGlyph.h"
#include "SkPath.h"
#include "SkCanvas.h"
#include "SkMakeUnique.h"
#define STD_SIZE 1
class SkGScalerContext : public SkScalerContext {
public:
SkGScalerContext(SkGTypeface* face, const SkScalerContextEffects& effects,
SkGScalerContext(sk_sp<SkGTypeface> face, const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext(face, effects, desc)
, fFace(face)
: SkScalerContext(std::move(face), effects, desc)
{
size_t descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec);
SkAutoDescriptor ad(descSize);
SkDescriptor* newDesc = ad.getDesc();
newDesc->init();
void* entry = newDesc->addEntry(kRec_SkDescriptorTag,
sizeof(SkScalerContext::Rec), &fRec);
@ -38,15 +38,16 @@ public:
}
SkASSERT(descSize == newDesc->getLength());
newDesc->computeChecksum();
fProxy = face->proxy()->createScalerContext(effects, newDesc);
fProxy = this->getGTypeface()->proxy()->createScalerContext(effects, newDesc);
fRec.getSingleMatrix(&fMatrix);
fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE);
}
virtual ~SkGScalerContext() { delete fProxy; }
protected:
SkGTypeface* getGTypeface() { return static_cast<SkGTypeface*>(this->getTypeface()); }
unsigned generateGlyphCount() override;
uint16_t generateCharToGlyph(SkUnichar) override;
void generateAdvance(SkGlyph*) override;
@ -56,8 +57,7 @@ protected:
void generateFontMetrics(SkPaint::FontMetrics*) override;
private:
SkGTypeface* fFace;
SkScalerContext* fProxy;
std::unique_ptr<SkScalerContext> fProxy;
SkMatrix fMatrix;
};
@ -93,7 +93,7 @@ void SkGScalerContext::generateMetrics(SkGlyph* glyph) {
path.transform(fMatrix);
SkRect storage;
const SkPaint& paint = fFace->paint();
const SkPaint& paint = this->getGTypeface()->paint();
const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
&storage,
SkPaint::kFill_Style);
@ -120,7 +120,7 @@ void SkGScalerContext::generateImage(const SkGlyph& glyph) {
canvas.translate(-SkIntToScalar(glyph.fLeft),
-SkIntToScalar(glyph.fTop));
canvas.concat(fMatrix);
canvas.drawPath(path, fFace->paint());
canvas.drawPath(path, this->getGTypeface()->paint());
} else {
fProxy->getImage(glyph);
}
@ -159,7 +159,7 @@ SkGTypeface::SkGTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint)
SkScalerContext* SkGTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
return new SkGScalerContext(const_cast<SkGTypeface*>(this), effects, desc);
return new SkGScalerContext(sk_ref_sp(const_cast<SkGTypeface*>(this)), effects, desc);
}
void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {

View File

@ -5,17 +5,19 @@
* found in the LICENSE file.
*/
#include "SkRandomScalerContext.h"
#include "SkGlyph.h"
#include "SkPath.h"
#include "SkCanvas.h"
#include "SkGlyph.h"
#include "SkMakeUnique.h"
#include "SkPath.h"
#include "SkRandomScalerContext.h"
#include "SkRasterizer.h"
class SkDescriptor;
class SkRandomScalerContext : public SkScalerContext {
public:
SkRandomScalerContext(SkRandomTypeface*, const SkScalerContextEffects&,
SkRandomScalerContext(sk_sp<SkRandomTypeface>, const SkScalerContextEffects&,
const SkDescriptor*, bool fFakeIt);
virtual ~SkRandomScalerContext();
protected:
unsigned generateGlyphCount() override;
@ -27,27 +29,22 @@ protected:
void generateFontMetrics(SkPaint::FontMetrics*) override;
private:
SkRandomTypeface* fFace;
SkScalerContext* fProxy;
SkRandomTypeface* getRandomTypeface() const {
return static_cast<SkRandomTypeface*>(this->getTypeface());
}
std::unique_ptr<SkScalerContext> fProxy;
bool fFakeIt;
};
#define STD_SIZE 1
#include "SkDescriptor.h"
SkRandomScalerContext::SkRandomScalerContext(SkRandomTypeface* face,
SkRandomScalerContext::SkRandomScalerContext(sk_sp<SkRandomTypeface> face,
const SkScalerContextEffects& effects,
const SkDescriptor* desc,
bool fakeIt)
: SkScalerContext(face, effects, desc)
, fFace(face)
: SkScalerContext(std::move(face), effects, desc)
, fFakeIt(fakeIt) {
fProxy = face->proxy()->createScalerContext(effects, desc);
fProxy = this->getRandomTypeface()->proxy()->createScalerContext(effects, desc);
}
SkRandomScalerContext::~SkRandomScalerContext() { delete fProxy; }
unsigned SkRandomScalerContext::generateGlyphCount() {
return fProxy->getGlyphCount();
}
@ -90,7 +87,7 @@ void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) {
fProxy->getPath(*glyph, &path);
SkRect storage;
const SkPaint& paint = fFace->paint();
const SkPaint& paint = this->getRandomTypeface()->paint();
const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
&storage,
SkPaint::kFill_Style);
@ -167,7 +164,7 @@ void SkRandomScalerContext::generateImage(const SkGlyph& glyph) {
SkCanvas canvas(bm);
canvas.translate(-SkIntToScalar(glyph.fLeft),
-SkIntToScalar(glyph.fTop));
canvas.drawPath(path, fFace->paint());
canvas.drawPath(path, this->getRandomTypeface()->paint());
} else {
fProxy->forceGenerateImageFromPath();
fProxy->getImage(glyph);
@ -198,7 +195,8 @@ SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint
SkScalerContext* SkRandomTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
return new SkRandomScalerContext(const_cast<SkRandomTypeface*>(this), effects, desc, fFakeIt);
return new SkRandomScalerContext(sk_ref_sp(const_cast<SkRandomTypeface*>(this)),
effects, desc, fFakeIt);
}
void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {

View File

@ -11,8 +11,8 @@
#include "SkDescriptor.h"
#include "SkFontDescriptor.h"
#include "SkGlyph.h"
#include "SkMakeUnique.h"
#include "SkMask.h"
// #include "SkOTUtils.h"
#include "SkScalerContext.h"
#include "SkTestScalerContext.h"
#include "SkTypefaceCache.h"
@ -116,9 +116,9 @@ void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
}
}
SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
SkTestTypeface::SkTestTypeface(sk_sp<SkTestFont> testFont, const SkFontStyle& style)
: SkTypeface(style, false)
, fTestFont(testFont) {
, fTestFont(std::move(testFont)) {
}
void SkTestTypeface::getAdvance(SkGlyph* glyph) {
@ -194,31 +194,32 @@ SkASSERT(0); // incomplete
class SkTestScalerContext : public SkScalerContext {
public:
SkTestScalerContext(SkTestTypeface* face, const SkScalerContextEffects& effects,
SkTestScalerContext(sk_sp<SkTestTypeface> face, const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext(face, effects, desc)
, fFace(face)
: SkScalerContext(std::move(face), effects, desc)
{
fRec.getSingleMatrix(&fMatrix);
this->forceGenerateImageFromPath();
}
virtual ~SkTestScalerContext() {
protected:
SkTestTypeface* getTestTypeface() const {
return static_cast<SkTestTypeface*>(this->getTypeface());
}
protected:
unsigned generateGlyphCount() override {
return fFace->onCountGlyphs();
return this->getTestTypeface()->onCountGlyphs();
}
uint16_t generateCharToGlyph(SkUnichar uni) override {
uint16_t glyph;
(void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
(void) this->getTestTypeface()->onCharsToGlyphs((const void *) &uni,
SkTypeface::kUTF16_Encoding, &glyph, 1);
return glyph;
}
void generateAdvance(SkGlyph* glyph) override {
fFace->getAdvance(glyph);
this->getTestTypeface()->getAdvance(glyph);
const SkVector advance = fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX),
SkFloatToScalar(glyph->fAdvanceY));
@ -227,7 +228,7 @@ protected:
}
void generateMetrics(SkGlyph* glyph) override {
fFace->getMetrics(glyph);
this->getTestTypeface()->getMetrics(glyph);
const SkVector advance = fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX),
SkFloatToScalar(glyph->fAdvanceY));
@ -235,7 +236,7 @@ protected:
glyph->fAdvanceY = SkScalarToFloat(advance.fY);
SkPath path;
fFace->getPath(*glyph, &path);
this->getTestTypeface()->getPath(*glyph, &path);
path.transform(fMatrix);
SkRect storage;
@ -253,7 +254,7 @@ protected:
void generateImage(const SkGlyph& glyph) override {
SkPath path;
fFace->getPath(glyph, &path);
this->getTestTypeface()->getPath(glyph, &path);
SkBitmap bm;
bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
@ -270,12 +271,12 @@ protected:
}
void generatePath(const SkGlyph& glyph, SkPath* path) override {
fFace->getPath(glyph, path);
this->getTestTypeface()->getPath(glyph, path);
path->transform(fMatrix);
}
void generateFontMetrics(SkPaint::FontMetrics* metrics) override {
fFace->getFontMetrics(metrics);
this->getTestTypeface()->getFontMetrics(metrics);
if (metrics) {
SkScalar scale = fMatrix.getScaleY();
metrics->fTop = SkScalarMul(metrics->fTop, scale);
@ -291,11 +292,11 @@ protected:
}
private:
SkTestTypeface* fFace;
SkMatrix fMatrix;
};
SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
return new SkTestScalerContext(const_cast<SkTestTypeface*>(this), effects, desc);
SkScalerContext* SkTestTypeface::onCreateScalerContext(
const SkScalerContextEffects& effects, const SkDescriptor* desc) const
{
return new SkTestScalerContext(sk_ref_sp(const_cast<SkTestTypeface*>(this)), effects, desc);
}

View File

@ -26,13 +26,11 @@ struct SkTestFontData {
const SkPaint::FontMetrics& fMetrics;
const char* fName;
SkTypeface::Style fStyle;
SkTestFont* fFontCache;
sk_sp<SkTestFont> fCachedFont;
};
class SkTestFont : public SkRefCnt {
public:
SkTestFont(const SkTestFontData& );
virtual ~SkTestFont();
int codeToIndex(SkUnichar charCode) const;
@ -58,10 +56,7 @@ private:
class SkTestTypeface : public SkTypeface {
public:
SkTestTypeface(SkTestFont*, const SkFontStyle& style);
virtual ~SkTestTypeface() {
SkSafeUnref(fTestFont);
}
SkTestTypeface(sk_sp<SkTestFont>, const SkFontStyle& style);
void getAdvance(SkGlyph* glyph);
void getFontMetrics(SkPaint::FontMetrics* metrics);
void getMetrics(SkGlyph* glyph);
@ -105,7 +100,7 @@ protected:
return 0;
}
private:
SkTestFont* fTestFont;
sk_sp<SkTestFont> fTestFont;
friend class SkTestScalerContext;
};

View File

@ -68,7 +68,7 @@ public:
bool isEqualTo(const SkDescriptor& desc) const override { return *fDesc == desc; }
#endif
private:
const SkAutoTDelete<SkScalerContext> fScalerContext;
const std::unique_ptr<SkScalerContext> fScalerContext;
#ifdef SK_DEBUG
const std::unique_ptr<SkDescriptor> fDesc;
#endif

View File

@ -14,6 +14,7 @@
#include "SkFontDescriptor.h"
#include "SkFontHost_FreeType_common.h"
#include "SkGlyph.h"
#include "SkMakeUnique.h"
#include "SkMask.h"
#include "SkMaskGamma.h"
#include "SkMatrix22.h"
@ -179,7 +180,9 @@ static void unref_ft_library() {
class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base {
public:
SkScalerContext_FreeType(SkTypeface*, const SkScalerContextEffects&, const SkDescriptor* desc);
SkScalerContext_FreeType(sk_sp<SkTypeface>,
const SkScalerContextEffects&,
const SkDescriptor* desc);
virtual ~SkScalerContext_FreeType();
bool success() const {
@ -612,13 +615,12 @@ static bool isAxisAligned(const SkScalerContext::Rec& rec) {
SkScalerContext* SkTypeface_FreeType::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
SkScalerContext_FreeType* c =
new SkScalerContext_FreeType(const_cast<SkTypeface_FreeType*>(this), effects, desc);
auto c = skstd::make_unique<SkScalerContext_FreeType>(
sk_ref_sp(const_cast<SkTypeface_FreeType*>(this)), effects, desc);
if (!c->success()) {
delete c;
c = nullptr;
}
return c;
return c.release();
}
void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
@ -725,10 +727,10 @@ static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) {
return chosenStrikeIndex;
}
SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface,
const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext_FreeType_Base(typeface, effects, desc)
: SkScalerContext_FreeType_Base(std::move(typeface), effects, desc)
, fFace(nullptr)
, fFTSize(nullptr)
, fStrikeIndex(-1)
@ -741,7 +743,8 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
// load the font file
using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face>, unref_ft_face>;
std::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ft_face(typeface));
using FT_FaceRef = skstd::remove_pointer_t<FT_Face>;
std::unique_ptr<FT_FaceRef, UnrefFTFace> ftFace(ref_ft_face(this->getTypeface()));
if (nullptr == ftFace) {
SkDEBUGF(("Could not create FT_Face.\n"));
return;

View File

@ -26,9 +26,9 @@ protected:
// This value was chosen by eyeballing the result in Firefox and trying to match it.
static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
SkScalerContext_FreeType_Base(SkTypeface* typeface, const SkScalerContextEffects& effects,
SkScalerContext_FreeType_Base(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects,
const SkDescriptor *desc)
: INHERITED(typeface, effects, desc)
: INHERITED(std::move(typeface), effects, desc)
{}
void generateGlyphImage(FT_Face face, const SkGlyph& glyph, const SkMatrix& bitmapTransform);
@ -80,17 +80,17 @@ protected:
SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
PerGlyphInfo, const uint32_t*, uint32_t) const override;
int onGetUPEM() const override;
virtual bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
int32_t adjustments[]) const override;
virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
int glyphCount) const override;
bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
int32_t adjustments[]) const override;
int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
int glyphCount) const override;
int onCountGlyphs() const override;
LocalizedStrings* onCreateFamilyNameIterator() const override;
int onGetTableTags(SkFontTableTag tags[]) const override;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const override;
size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const override;
private:
typedef SkTypeface INHERITED;

View File

@ -694,7 +694,7 @@ struct GlyphRect {
class SkScalerContext_Mac : public SkScalerContext {
public:
SkScalerContext_Mac(SkTypeface_Mac*, const SkScalerContextEffects&, const SkDescriptor*);
SkScalerContext_Mac(sk_sp<SkTypeface_Mac>, const SkScalerContextEffects&, const SkDescriptor*);
protected:
unsigned generateGlyphCount(void) override;
@ -802,10 +802,10 @@ static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize,
return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, nullptr);
}
SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface,
const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: INHERITED(typeface, effects, desc)
: INHERITED(std::move(typeface), effects, desc)
, fFBoundingBoxes()
, fFBoundingBoxesGlyphOffset(0)
, fGeneratedFBoundingBoxes(false)
@ -815,7 +815,7 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
{
AUTO_CG_LOCK();
CTFontRef ctFont = typeface->fFontRef.get();
CTFontRef ctFont = static_cast<SkTypeface_Mac*>(this->getTypeface())->fFontRef.get();
CFIndex numGlyphs = CTFontGetGlyphCount(ctFont);
SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF);
fGlyphCount = SkToU16(numGlyphs);
@ -1962,7 +1962,7 @@ size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset,
SkScalerContext* SkTypeface_Mac::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
return new SkScalerContext_Mac(const_cast<SkTypeface_Mac*>(this), effects, desc);
return new SkScalerContext_Mac(sk_ref_sp(const_cast<SkTypeface_Mac*>(this)), effects, desc);
}
void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {

View File

@ -16,6 +16,7 @@
#include "SkFontDescriptor.h"
#include "SkGlyph.h"
#include "SkHRESULT.h"
#include "SkMakeUnique.h"
#include "SkMaskGamma.h"
#include "SkMatrix22.h"
#include "SkOTTable_maxp.h"
@ -530,7 +531,9 @@ const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
class SkScalerContext_GDI : public SkScalerContext {
public:
SkScalerContext_GDI(SkTypeface*, const SkScalerContextEffects&, const SkDescriptor* desc);
SkScalerContext_GDI(sk_sp<LogFontTypeface>,
const SkScalerContextEffects&,
const SkDescriptor* desc);
virtual ~SkScalerContext_GDI();
// Returns true if the constructor was able to complete all of its
@ -600,17 +603,17 @@ static BYTE compute_quality(const SkScalerContext::Rec& rec) {
}
}
SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
SkScalerContext_GDI::SkScalerContext_GDI(sk_sp<LogFontTypeface> rawTypeface,
const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext(rawTypeface, effects, desc)
: SkScalerContext(std::move(rawTypeface), effects, desc)
, fDDC(0)
, fSavefont(0)
, fFont(0)
, fSC(0)
, fGlyphCount(-1)
{
LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface);
LogFontTypeface* typeface = static_cast<LogFontTypeface*>(this->getTypeface());
fDDC = ::CreateCompatibleDC(nullptr);
if (!fDDC) {
@ -2254,13 +2257,12 @@ size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
SkScalerContext_GDI* ctx = new SkScalerContext_GDI(const_cast<LogFontTypeface*>(this),
effects, desc);
auto ctx = skstd::make_unique<SkScalerContext_GDI>(
sk_ref_sp(const_cast<LogFontTypeface*>(this)), effects, desc);
if (!ctx->isValid()) {
delete ctx;
ctx = nullptr;
}
return ctx;
return ctx.release();
}
void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {

View File

@ -204,18 +204,18 @@ static bool is_axis_aligned(const SkScalerContext::Rec& rec) {
both_zero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
}
SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
SkScalerContext_DW::SkScalerContext_DW(sk_sp<DWriteFontTypeface> typefaceRef,
const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext(typeface, effects, desc)
, fTypeface(SkRef(typeface))
: SkScalerContext(std::move(typefaceRef), effects, desc)
, fGlyphCount(-1) {
DWriteFontTypeface* typeface = this->getDWriteTypeface();
#if SK_HAS_DWRITE_2_H
fTypeface->fFactory->QueryInterface<IDWriteFactory2>(&fFactory2);
typeface->fFactory->QueryInterface<IDWriteFactory2>(&fFactory2);
SkTScopedComPtr<IDWriteFontFace2> fontFace2;
fTypeface->fDWriteFontFace->QueryInterface<IDWriteFontFace2>(&fontFace2);
typeface->fDWriteFontFace->QueryInterface<IDWriteFontFace2>(&fontFace2);
fIsColorFont = fFactory2.get() && fontFace2.get() && fontFace2->IsColorFont();
#endif
@ -335,14 +335,15 @@ SkScalerContext_DW::~SkScalerContext_DW() {
unsigned SkScalerContext_DW::generateGlyphCount() {
if (fGlyphCount < 0) {
fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount();
fGlyphCount = this->getDWriteTypeface()->fDWriteFontFace->GetGlyphCount();
}
return fGlyphCount;
}
uint16_t SkScalerContext_DW::generateCharToGlyph(SkUnichar uni) {
uint16_t index = 0;
fTypeface->fDWriteFontFace->GetGlyphIndices(reinterpret_cast<UINT32*>(&uni), 1, &index);
UINT32* uniPtr = reinterpret_cast<UINT32*>(&uni);
this->getDWriteTypeface()->fDWriteFontFace->GetGlyphIndices(uniPtr, 1, &index);
return index;
}
@ -363,7 +364,7 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
{
SkAutoExclusive l(DWriteFactoryMutex);
HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics(
HRVM(this->getDWriteTypeface()->fDWriteFontFace->GetGdiCompatibleGlyphMetrics(
fTextSizeMeasure,
1.0f, // pixelsPerDip
&fGsA,
@ -373,14 +374,14 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
"Could not get gdi compatible glyph metrics.");
} else {
SkAutoExclusive l(DWriteFactoryMutex);
HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm),
HRVM(this->getDWriteTypeface()->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm),
"Could not get design metrics.");
}
DWRITE_FONT_METRICS dwfm;
{
Shared l(DWriteFactoryMutex);
fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
this->getDWriteTypeface()->fDWriteFontFace->GetMetrics(&dwfm);
}
SkScalar advanceX = SkScalarMulDiv(fTextSizeMeasure,
SkIntToScalar(gm.advanceWidth),
@ -422,7 +423,7 @@ HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
DWRITE_GLYPH_RUN run;
run.glyphCount = 1;
run.glyphAdvances = &advance;
run.fontFace = fTypeface->fDWriteFontFace.get();
run.fontFace = this->getDWriteTypeface()->fDWriteFontFace.get();
run.fontEmSize = SkScalarToFloat(fTextSizeRender);
run.bidiLevel = 0;
run.glyphIndices = &glyphId;
@ -432,7 +433,7 @@ HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
{
SkAutoExclusive l(DWriteFactoryMutex);
HRM(fTypeface->fFactory->CreateGlyphRunAnalysis(
HRM(this->getDWriteTypeface()->fFactory->CreateGlyphRunAnalysis(
&run,
1.0f, // pixelsPerDip,
&fXform,
@ -491,7 +492,7 @@ bool SkScalerContext_DW::getColorGlyphRun(const SkGlyph& glyph,
DWRITE_GLYPH_RUN run;
run.glyphCount = 1;
run.glyphAdvances = &advance;
run.fontFace = fTypeface->fDWriteFontFace.get();
run.fontFace = this->getDWriteTypeface()->fDWriteFontFace.get();
run.fontEmSize = SkScalarToFloat(fTextSizeRender);
run.bidiLevel = 0;
run.glyphIndices = &glyphId;
@ -558,13 +559,13 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) {
if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
{
fTypeface->fDWriteFontFace->GetGdiCompatibleMetrics(
this->getDWriteTypeface()->fDWriteFontFace->GetGdiCompatibleMetrics(
fTextSizeRender,
1.0f, // pixelsPerDip
&fXform,
&dwfm);
} else {
fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
this->getDWriteTypeface()->fDWriteFontFace->GetMetrics(&dwfm);
}
SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm);
@ -580,9 +581,9 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) {
metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
#if SK_HAS_DWRITE_1_H
if (fTypeface->fDWriteFontFace1.get()) {
if (this->getDWriteTypeface()->fDWriteFontFace1.get()) {
DWRITE_FONT_METRICS1 dwfm1;
fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1);
this->getDWriteTypeface()->fDWriteFontFace1->GetMetrics(&dwfm1);
metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / upem;
metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom) / upem;
metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / upem;
@ -595,7 +596,7 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) {
# pragma message("No dwrite_1.h is available, font metrics may be affected.")
#endif
AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get());
AutoTDWriteTable<SkOTTableHead> head(this->getDWriteTypeface()->fDWriteFontFace.get());
if (head.fExists &&
head.fSize >= sizeof(SkOTTableHead) &&
head->version == SkOTTableHead::version1)
@ -726,7 +727,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
DWRITE_GLYPH_RUN run;
run.glyphCount = 1;
run.glyphAdvances = &advance;
run.fontFace = fTypeface->fDWriteFontFace.get();
run.fontFace = this->getDWriteTypeface()->fDWriteFontFace.get();
run.fontEmSize = SkScalarToFloat(fTextSizeRender);
run.bidiLevel = 0;
run.glyphIndices = &index;
@ -737,7 +738,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
{
SkAutoExclusive l(DWriteFactoryMutex);
HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
HRNM(this->getDWriteTypeface()->fFactory->CreateGlyphRunAnalysis(&run,
1.0f, // pixelsPerDip,
&fXform,
renderingMode,
@ -899,15 +900,16 @@ void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
SkAutoExclusive l(DWriteFactoryMutex);
//TODO: convert to<->from DIUs? This would make a difference if hinting.
//It may not be needed, it appears that DirectWrite only hints at em size.
HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fTextSizeRender),
&glyphId,
nullptr, //advances
nullptr, //offsets
1, //num glyphs
FALSE, //sideways
FALSE, //rtl
geometryToPath.get()),
"Could not create glyph outline.");
HRVM(this->getDWriteTypeface()->fDWriteFontFace->GetGlyphRunOutline(
SkScalarToFloat(fTextSizeRender),
&glyphId,
nullptr, //advances
nullptr, //offsets
1, //num glyphs
FALSE, //sideways
FALSE, //rtl
geometryToPath.get()),
"Could not create glyph outline.");
}
path->transform(fSkXform);

View File

@ -23,7 +23,9 @@ class SkDescriptor;
class SkScalerContext_DW : public SkScalerContext {
public:
SkScalerContext_DW(DWriteFontTypeface*, const SkScalerContextEffects&, const SkDescriptor*);
SkScalerContext_DW(sk_sp<DWriteFontTypeface>,
const SkScalerContextEffects&,
const SkDescriptor*);
virtual ~SkScalerContext_DW();
protected:
@ -47,6 +49,10 @@ private:
bool isColorGlyph(const SkGlyph& glyph);
DWriteFontTypeface* getDWriteTypeface() {
return static_cast<DWriteFontTypeface*>(this->getTypeface());
}
#if SK_HAS_DWRITE_2_H
bool getColorGlyphRun(const SkGlyph& glyph, IDWriteColorGlyphRunEnumerator** colorGlyph);
@ -70,7 +76,6 @@ private:
SkScalar fTextSizeRender;
/** The text size to measure with. */
SkScalar fTextSizeMeasure;
SkAutoTUnref<DWriteFontTypeface> fTypeface;
int fGlyphCount;
DWRITE_RENDERING_MODE fRenderingMode;
DWRITE_TEXTURE_TYPE fTextureType;

View File

@ -247,7 +247,7 @@ SkStreamAsset* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
const SkDescriptor* desc) const {
return new SkScalerContext_DW(const_cast<DWriteFontTypeface*>(this), effects, desc);
return new SkScalerContext_DW(sk_ref_sp(const_cast<DWriteFontTypeface*>(this)), effects, desc);
}
void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {

View File

@ -23,7 +23,7 @@ namespace sk_tool_utils {
void release_portable_typefaces() {
for (int index = 0; index < gTestFontsCount; ++index) {
SkTestFontData& fontData = gTestFonts[index];
SkSafeUnref(fontData.fFontCache);
fontData.fCachedFont.reset();
}
}
@ -54,19 +54,19 @@ sk_sp<SkTypeface> create_font(const char* name, SkFontStyle style) {
sub = &gSubFonts[gDefaultFontIndex];
fontData = &sub->fFont;
}
SkTestFont* font;
sk_sp<SkTestFont> font;
{
SkAutoMutexAcquire ac(gTestFontMutex);
if (fontData->fFontCache) {
font = SkSafeRef(fontData->fFontCache);
if (fontData->fCachedFont) {
font = fontData->fCachedFont;
} else {
font = new SkTestFont(*fontData);
font = sk_make_sp<SkTestFont>(*fontData);
SkDEBUGCODE(font->fDebugName = sub->fName);
SkDEBUGCODE(font->fDebugStyle = sub->fStyle);
fontData->fFontCache = SkSafeRef(font);
fontData->fCachedFont = font;
}
}
return sk_make_sp<SkTestTypeface>(font, style);
return sk_make_sp<SkTestTypeface>(std::move(font), style);
}
}