SkAdvancedTypefaceMetrics: abstract out linked list

+ use SkSinglyLinkedList<T>
+ move SkSinglyLinkedList.h to core
+ remove SkHackyAutoTDelete
+ getAdvanceData() -> setGlyphWidths()
+ finishRange no longer templated
+ remove unused templated functions

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1953153004

Review-Url: https://codereview.chromium.org/1953153004
This commit is contained in:
halcanary 2016-05-08 18:47:16 -07:00 committed by Commit bot
parent 0938befe5d
commit e20a875170
11 changed files with 195 additions and 314 deletions

View File

@ -265,6 +265,7 @@
'<(skia_src_path)/core/SkShader.cpp',
'<(skia_src_path)/core/SkSharedMutex.cpp',
'<(skia_src_path)/core/SkSharedMutex.h',
'<(skia_src_path)/core/SkSinglyLinkedList.h',
'<(skia_src_path)/core/SkSmallAllocator.h',
'<(skia_src_path)/core/SkSpanProcs.cpp',
'<(skia_src_path)/core/SkSpecialImage.cpp',

View File

@ -45,6 +45,5 @@
'<(skia_src_path)/pdf/SkPDFTypes.h',
'<(skia_src_path)/pdf/SkPDFUtils.cpp',
'<(skia_src_path)/pdf/SkPDFUtils.h',
'<(skia_src_path)/pdf/SkSinglyLinkedList.h',
],
}

View File

@ -27,36 +27,13 @@ typedef struct FT_FaceRec_* FT_Face;
#include <CoreFoundation/CoreFoundation.h>
#endif
template <typename Data>
static void unwind(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* ptr) {
while (ptr) {
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* next = ptr->fNext.release();
delete ptr;
ptr = next;
}
}
SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() {
// If the stacks are too deep we could get stack overflow,
// so we manually destruct the linked lists.
unwind(fGlyphWidths.release());
unwind(fVerticalMetrics.release());
}
namespace skia_advanced_typeface_metrics_utils {
SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() {}
const int16_t kInvalidAdvance = SK_MinS16;
const int16_t kDontCareAdvance = SK_MinS16 + 1;
template <typename Data>
void stripUninterestingTrailingAdvancesFromRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
SkASSERT(false);
}
template <>
void stripUninterestingTrailingAdvancesFromRange<int16_t>(
SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
static void stripUninterestingTrailingAdvancesFromRange(
SkAdvancedTypefaceMetrics::WidthRange* range) {
SkASSERT(range);
int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
@ -74,31 +51,7 @@ void stripUninterestingTrailingAdvancesFromRange<int16_t>(
}
}
template <typename Data>
void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
int startId) {
range->fStartId = startId;
range->fAdvance.setCount(0);
}
template <typename Data, template<typename> class AutoTDelete>
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
AutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
int startId) {
nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
resetRange(nextSlot->get(), startId);
return nextSlot->get();
}
template <typename Data>
void zeroWildcardsInRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
SkASSERT(false);
}
template <>
void zeroWildcardsInRange<int16_t>(
SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
static void zeroWildcardsInRange(SkAdvancedTypefaceMetrics::WidthRange* range) {
SkASSERT(range);
if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) {
return;
@ -113,22 +66,19 @@ void zeroWildcardsInRange<int16_t>(
}
}
template <typename Data>
void finishRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
void SkAdvancedTypefaceMetrics::FinishRange(
SkAdvancedTypefaceMetrics::WidthRange* range,
int endId,
typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
type) {
SkAdvancedTypefaceMetrics::WidthRange::MetricType type) {
range->fEndId = endId;
range->fType = type;
stripUninterestingTrailingAdvancesFromRange(range);
int newLength;
if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
if (type == SkAdvancedTypefaceMetrics::WidthRange::kRange) {
newLength = range->fEndId - range->fStartId + 1;
} else {
if (range->fEndId == range->fStartId) {
range->fType =
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange;
range->fType = SkAdvancedTypefaceMetrics::WidthRange::kRange;
}
newLength = 1;
}
@ -137,13 +87,13 @@ void finishRange(
zeroWildcardsInRange(range);
}
template <typename Data, typename FontHandle>
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
template <typename FontHandle>
void SkAdvancedTypefaceMetrics::setGlyphWidths(
FontHandle fontHandle,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
bool (*getAdvance)(FontHandle fontHandle, int gId, int16_t* data)) {
// Assuming that on average, the ASCII representation of an advance plus
// a space is 8 characters and the ASCII representation of a glyph id is 3
// characters, then the following cut offs for using different range types
@ -159,10 +109,8 @@ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
// d. Removing a leading 0/don't cares is a win because it is omitted
// e. Removing 2 repeating advances is a win
SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = nullptr;
Data lastAdvance = kInvalidAdvance;
WidthRange* prevRange = nullptr;
int16_t lastAdvance = kInvalidAdvance;
int repeatedAdvances = 0;
int wildCardsInRun = 0;
int trailingWildCards = 0;
@ -176,10 +124,10 @@ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
lastIndex =
static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
}
curRange = appendRange(&result, firstIndex);
WidthRange curRange(firstIndex);
for (int gId = firstIndex; gId <= lastIndex; gId++) {
Data advance = kInvalidAdvance;
int16_t advance = kInvalidAdvance;
if (gId < lastIndex) {
// Get glyph id only when subset is nullptr, or the id is in subset.
SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength &&
@ -199,16 +147,16 @@ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
} else if (advance == kDontCareAdvance) {
wildCardsInRun++;
trailingWildCards++;
} else if (curRange->fAdvance.count() ==
} else if (curRange.fAdvance.count() ==
repeatedAdvances + 1 + wildCardsInRun) { // All in run.
if (lastAdvance == 0) {
resetRange(curRange, gId);
curRange.fStartId = gId; // reset
curRange.fAdvance.setCount(0);
trailingWildCards = 0;
} else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
finishRange(curRange, gId - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRun);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
FinishRange(&curRange, gId - 1, WidthRange::kRun);
prevRange = fGlyphWidths.emplace_back(std::move(curRange));
curRange = WidthRange(gId);
trailingWildCards = 0;
}
repeatedAdvances = 0;
@ -217,61 +165,57 @@ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
} else {
if (lastAdvance == 0 &&
repeatedAdvances + 1 + wildCardsInRun >= 4) {
finishRange(curRange,
FinishRange(&curRange,
gId - repeatedAdvances - wildCardsInRun - 2,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
WidthRange::kRange);
prevRange = fGlyphWidths.emplace_back(std::move(curRange));
curRange = WidthRange(gId);
trailingWildCards = 0;
} else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
finishRange(curRange,
gId - trailingWildCards - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
FinishRange(&curRange, gId - trailingWildCards - 1,
WidthRange::kRange);
prevRange = fGlyphWidths.emplace_back(std::move(curRange));
curRange = WidthRange(gId);
trailingWildCards = 0;
} else if (lastAdvance != 0 &&
(repeatedAdvances + 1 >= 3 ||
(repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
finishRange(curRange,
FinishRange(&curRange,
gId - repeatedAdvances - wildCardsInRun - 2,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
WidthRange::kRange);
(void)fGlyphWidths.emplace_back(std::move(curRange));
curRange =
appendRange(&curRange->fNext,
gId - repeatedAdvances - wildCardsInRun - 1);
curRange->fAdvance.append(1, &lastAdvance);
finishRange(curRange, gId - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRun);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
WidthRange(gId - repeatedAdvances - wildCardsInRun - 1);
curRange.fAdvance.append(1, &lastAdvance);
FinishRange(&curRange, gId - 1, WidthRange::kRun);
prevRange = fGlyphWidths.emplace_back(std::move(curRange));
curRange = WidthRange(gId);
trailingWildCards = 0;
}
repeatedAdvances = 0;
wildCardsInRun = trailingWildCards;
trailingWildCards = 0;
}
curRange->fAdvance.append(1, &advance);
curRange.fAdvance.append(1, &advance);
if (advance != kDontCareAdvance) {
lastAdvance = advance;
}
}
if (curRange->fStartId == lastIndex) {
if (curRange.fStartId == lastIndex) {
SkASSERT(prevRange);
if (!prevRange) {
return nullptr; // https://crbug.com/567031
fGlyphWidths.reset();
return; // https://crbug.com/567031
}
SkASSERT(prevRange->fNext->fStartId == lastIndex);
prevRange->fNext.reset();
} else {
finishRange(curRange, lastIndex - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
FinishRange(&curRange, lastIndex - 1, WidthRange::kRange);
fGlyphWidths.emplace_back(std::move(curRange));
}
return result.release();
}
// Make AdvanceMetric template functions available for linking with typename
// WidthRange and VerticalAdvanceRange.
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
FT_Face face,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
@ -279,55 +223,30 @@ template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
#if defined(SK_BUILD_FOR_WIN)
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
HDC hdc,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
IDWriteFontFace* fontFace,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data));
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
CTFontRef ctFont,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data));
#endif
template void resetRange(
SkAdvancedTypefaceMetrics::WidthRange* range,
int startId);
template SkAdvancedTypefaceMetrics::WidthRange* appendRange(
SkAutoTDelete<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot,
int startId);
template void finishRange<int16_t>(
SkAdvancedTypefaceMetrics::WidthRange* range,
int endId,
SkAdvancedTypefaceMetrics::WidthRange::MetricType type);
template void resetRange(
SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
int startId);
template SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange(
SkAutoTDelete<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >*
nextSlot,
int startId);
template void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>(
SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
int endId,
SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type);
// additional declaration needed for testing with a face of an unknown type
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
void* fontData,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(void* fontData, int gId, int16_t* data));
} // namespace skia_advanced_typeface_metrics_utils

View File

@ -14,34 +14,7 @@
#include "SkString.h"
#include "SkTDArray.h"
#include "SkTemplates.h"
// Whatever std::unique_ptr Clank's using doesn't seem to work with AdvanceMetric's
// style of forward-declaration. Probably just a bug in an old libc++ / libstdc++.
// For now, hack around it with our own smart pointer. It'd be nice to clean up.
template <typename T>
class SkHackyAutoTDelete : SkNoncopyable {
public:
explicit SkHackyAutoTDelete(T* ptr = nullptr) : fPtr(ptr) {}
~SkHackyAutoTDelete() { delete fPtr; }
T* get() const { return fPtr; }
T* operator->() const { return fPtr; }
void reset(T* ptr = nullptr) {
if (ptr != fPtr) {
delete fPtr;
fPtr = ptr;
}
}
T* release() {
T* ptr = fPtr;
fPtr = nullptr;
return ptr;
}
private:
T* fPtr;
};
#include "SkSinglyLinkedList.h"
/** \class SkAdvancedTypefaceMetrics
@ -68,6 +41,29 @@ public:
~SkAdvancedTypefaceMetrics();
/** Retrieve advance data for glyphs. Used by the PDF backend. It
calls underlying platform dependent API getAdvance to acquire
the data.
@param num_glyphs Total number of glyphs in the given font.
@param glyphIDs For per-glyph info, specify subset of the
font by giving glyph ids. Each integer
represents a glyph id. Passing nullptr
means all glyphs in the font.
@param glyphIDsCount Number of elements in subsetGlyphIds.
Ignored if glyphIDs is nullptr.
@param getAdvance A function that takes a glyph id and
passes back advance data from the
typeface. Returns false on failure.
*/
template <typename FontHandle>
void setGlyphWidths(FontHandle fontHandle,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(FontHandle fontHandle,
int gId,
int16_t* data));
SkString fFontName;
enum FontType {
@ -126,7 +122,22 @@ public:
uint16_t fStartId;
uint16_t fEndId;
SkTDArray<Data> fAdvance;
SkHackyAutoTDelete<AdvanceMetric<Data> > fNext;
AdvanceMetric(uint16_t startId) : fStartId(startId) {}
AdvanceMetric(AdvanceMetric&& other)
: fType(other.fType)
, fStartId(other.fStartId)
, fEndId(other.fEndId) {
fAdvance.swap(other.fAdvance);
}
AdvanceMetric& operator=(AdvanceMetric&& other) {
fType = other.fType;
fStartId = other.fStartId;
fEndId = other.fEndId;
fAdvance.swap(other.fAdvance);
return *this;
}
AdvanceMetric(const AdvanceMetric&) = delete;
AdvanceMetric& operator=(const AdvanceMetric&) = delete;
};
struct VerticalMetric {
@ -138,9 +149,9 @@ public:
typedef AdvanceMetric<VerticalMetric> VerticalAdvanceRange;
// This is indexed by glyph id.
SkAutoTDelete<WidthRange> fGlyphWidths;
SkSinglyLinkedList<WidthRange> fGlyphWidths;
// Only used for Vertical CID fonts.
SkAutoTDelete<VerticalAdvanceRange> fVerticalMetrics;
SkSinglyLinkedList<VerticalAdvanceRange> fVerticalMetrics;
// The names of each glyph, only populated for postscript fonts.
SkAutoTDelete<SkAutoTArray<SkString> > fGlyphNames;
@ -149,45 +160,13 @@ public:
// kToUnicode_PerGlyphInfo is passed to GetAdvancedTypefaceMetrics.
SkTDArray<SkUnichar> fGlyphToUnicode;
static void FinishRange(WidthRange* range,
int endId,
WidthRange::MetricType type);
private:
typedef SkRefCnt INHERITED;
};
namespace skia_advanced_typeface_metrics_utils {
template <typename Data>
void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
int startId);
template <typename Data, template<typename> class AutoTDelete>
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
AutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
int startId);
template <typename Data>
void finishRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
int endId,
typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
type);
/** Retrieve advance data for glyphs. Used by the PDF backend. It calls
underlying platform dependent API getAdvance to acquire the data.
@param num_glyphs Total number of glyphs in the given font.
@param glyphIDs For per-glyph info, specify subset of the font by
giving glyph ids. Each integer represents a glyph
id. Passing nullptr means all glyphs in the font.
@param glyphIDsCount Number of elements in subsetGlyphIds. Ignored if
glyphIDs is nullptr.
*/
template <typename Data, typename FontHandle>
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
FontHandle fontHandle,
int num_glyphs,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount,
bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data));
} // namespace skia_advanced_typeface_metrics_utils
#endif

View File

@ -31,6 +31,7 @@ public:
}
T* back() { return fTail ? &fTail->fData : nullptr; }
T* front() { return fHead ? &fHead->fData : nullptr; }
bool empty() const { return fHead == nullptr; }
#ifdef SK_DEBUG
int count() { // O(n), debug only.
int count = 0;

View File

@ -322,33 +322,36 @@ static void appendVerticalAdvance(
template <typename Data>
SkPDFArray* composeAdvanceData(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo,
const SkSinglyLinkedList<
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>>& advanceInfo,
uint16_t emSize,
void (*appendAdvance)(const Data& advance, uint16_t emSize,
void (*appendAdvance)(const Data& advance,
uint16_t emSize,
SkPDFArray* array),
Data* defaultAdvance) {
SkPDFArray* result = new SkPDFArray();
for (; advanceInfo != nullptr; advanceInfo = advanceInfo->fNext.get()) {
switch (advanceInfo->fType) {
case SkAdvancedTypefaceMetrics::WidthRange::kDefault: {
SkASSERT(advanceInfo->fAdvance.count() == 1);
*defaultAdvance = advanceInfo->fAdvance[0];
for (const SkAdvancedTypefaceMetrics::AdvanceMetric<Data>& range :
advanceInfo) {
switch (range.fType) {
case SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kDefault: {
SkASSERT(range.fAdvance.count() == 1);
*defaultAdvance = range.fAdvance[0];
break;
}
case SkAdvancedTypefaceMetrics::WidthRange::kRange: {
case SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange: {
auto advanceArray = sk_make_sp<SkPDFArray>();
for (int j = 0; j < advanceInfo->fAdvance.count(); j++)
appendAdvance(advanceInfo->fAdvance[j], emSize,
for (int j = 0; j < range.fAdvance.count(); j++)
appendAdvance(range.fAdvance[j], emSize,
advanceArray.get());
result->appendInt(advanceInfo->fStartId);
result->appendInt(range.fStartId);
result->appendObject(std::move(advanceArray));
break;
}
case SkAdvancedTypefaceMetrics::WidthRange::kRun: {
SkASSERT(advanceInfo->fAdvance.count() == 1);
result->appendInt(advanceInfo->fStartId);
result->appendInt(advanceInfo->fEndId);
appendAdvance(advanceInfo->fAdvance[0], emSize, result);
case SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRun: {
SkASSERT(range.fAdvance.count() == 1);
result->appendInt(range.fStartId);
result->appendInt(range.fEndId);
appendAdvance(range.fAdvance[0], emSize, result);
break;
}
}
@ -1146,12 +1149,11 @@ bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
sysInfo->insertInt("Supplement", 0);
this->insertObject("CIDSystemInfo", std::move(sysInfo));
if (fontInfo()->fGlyphWidths.get()) {
if (!fontInfo()->fGlyphWidths.empty()) {
int16_t defaultWidth = 0;
sk_sp<SkPDFArray> widths(
composeAdvanceData(fontInfo()->fGlyphWidths.get(),
fontInfo()->fEmSize, &appendWidth,
&defaultWidth));
sk_sp<SkPDFArray> widths(composeAdvanceData(
fontInfo()->fGlyphWidths, fontInfo()->fEmSize, &appendWidth,
&defaultWidth));
if (widths->size())
this->insertObject("W", std::move(widths));
if (defaultWidth != 0) {
@ -1160,15 +1162,14 @@ bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
scaleFromFontUnits(defaultWidth, fontInfo()->fEmSize));
}
}
if (fontInfo()->fVerticalMetrics.get()) {
if (!fontInfo()->fVerticalMetrics.empty()) {
struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
defaultAdvance.fVerticalAdvance = 0;
defaultAdvance.fOriginXDisp = 0;
defaultAdvance.fOriginYDisp = 0;
sk_sp<SkPDFArray> advances(
composeAdvanceData(fontInfo()->fVerticalMetrics.get(),
fontInfo()->fEmSize, &appendVerticalAdvance,
&defaultAdvance));
sk_sp<SkPDFArray> advances(composeAdvanceData(
fontInfo()->fVerticalMetrics, fontInfo()->fEmSize,
&appendVerticalAdvance, &defaultAdvance));
if (advances->size())
this->insertObject("W2", std::move(advances));
if (defaultAdvance.fVerticalAdvance ||
@ -1237,27 +1238,24 @@ bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
}
bool SkPDFType1Font::populate(int16_t glyphID) {
SkASSERT(!fontInfo()->fVerticalMetrics.get());
SkASSERT(fontInfo()->fGlyphWidths.get());
SkASSERT(fontInfo()->fVerticalMetrics.empty());
SkASSERT(!fontInfo()->fGlyphWidths.empty());
adjustGlyphRangeForSingleByteEncoding(glyphID);
int16_t defaultWidth = 0;
const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = nullptr;
const SkAdvancedTypefaceMetrics::WidthRange* widthEntry;
for (widthEntry = fontInfo()->fGlyphWidths.get();
widthEntry != nullptr;
widthEntry = widthEntry->fNext.get()) {
switch (widthEntry->fType) {
for (const auto& widthEntry : fontInfo()->fGlyphWidths) {
switch (widthEntry.fType) {
case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
defaultWidth = widthEntry->fAdvance[0];
defaultWidth = widthEntry.fAdvance[0];
break;
case SkAdvancedTypefaceMetrics::WidthRange::kRun:
SkASSERT(false);
break;
case SkAdvancedTypefaceMetrics::WidthRange::kRange:
SkASSERT(widthRangeEntry == nullptr);
widthRangeEntry = widthEntry;
widthRangeEntry = &widthEntry;
break;
}
}

View File

@ -58,8 +58,6 @@
//#define SK_FONTHOST_FREETYPE_RUNTIME_VERSION
//#define SK_GAMMA_APPLY_TO_A8
using namespace skia_advanced_typeface_metrics_utils;
static bool isLCD(const SkScalerContext::Rec& rec) {
return SkMask::kLCD16_Format == rec.fMaskFormat;
}
@ -591,13 +589,14 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics(
if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
if (FT_IS_FIXED_WIDTH(face)) {
appendRange(&info->fGlyphWidths, 0);
SkAdvancedTypefaceMetrics::WidthRange range(0);
int16_t advance = face->max_advance_width;
info->fGlyphWidths->fAdvance.append(1, &advance);
finishRange(info->fGlyphWidths.get(), 0,
SkAdvancedTypefaceMetrics::WidthRange::kDefault);
range.fAdvance.append(1, &advance);
SkAdvancedTypefaceMetrics::FinishRange(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else if (!cid) {
appendRange(&info->fGlyphWidths, 0);
SkAdvancedTypefaceMetrics::WidthRange range(0);
// So as to not blow out the stack, get advances in batches.
for (int gID = 0; gID < face->num_glyphs; gID += 128) {
FT_Fixed advances[128];
@ -608,18 +607,16 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics(
FT_Get_Advances(face, gID, advanceCount, FT_LOAD_NO_SCALE, advances);
for (int i = 0; i < advanceCount; i++) {
int16_t advance = advances[i];
info->fGlyphWidths->fAdvance.append(1, &advance);
range.fAdvance.append(1, &advance);
}
}
finishRange(info->fGlyphWidths.get(), face->num_glyphs - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
SkAdvancedTypefaceMetrics::FinishRange(
&range, face->num_glyphs - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->fGlyphWidths.reset(
getAdvanceData(face,
face->num_glyphs,
glyphIDs,
glyphIDsCount,
&getWidthAdvance));
info->setGlyphWidths(face, face->num_glyphs, glyphIDs,
glyphIDsCount, &getWidthAdvance);
}
}

View File

@ -1619,17 +1619,14 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) {
skia_advanced_typeface_metrics_utils::appendRange(&info->fGlyphWidths, 0);
info->fGlyphWidths->fAdvance.append(1, &min_width);
skia_advanced_typeface_metrics_utils::finishRange(info->fGlyphWidths.get(), 0,
SkAdvancedTypefaceMetrics::WidthRange::kDefault);
SkAdvancedTypefaceMetrics::WidthRange range(0);
range.fAdvance.append(1, &min_width);
SkAdvancedTypefaceMetrics::FinishRange(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->fGlyphWidths.reset(
skia_advanced_typeface_metrics_utils::getAdvanceData(ctFont.get(),
SkToInt(glyphCount),
glyphIDs,
glyphIDsCount,
&getWidthAdvance));
info->setGlyphWidths(ctFont.get(), SkToInt(glyphCount), glyphIDs,
glyphIDsCount, &getWidthAdvance);
}
}
return info;

View File

@ -86,8 +86,6 @@ static bool needToRenderWithSkia(const SkScalerContext::Rec& rec) {
return rec.getHinting() == SkPaint::kNo_Hinting || rec.getHinting() == SkPaint::kSlight_Hinting;
}
using namespace skia_advanced_typeface_metrics_utils;
static void tchar_to_skstring(const TCHAR t[], SkString* s) {
#ifdef UNICODE
size_t sSize = WideCharToMultiByte(CP_UTF8, 0, t, -1, nullptr, 0, nullptr, nullptr);
@ -1835,17 +1833,14 @@ SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics(
if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) {
appendRange(&info->fGlyphWidths, 0);
info->fGlyphWidths->fAdvance.append(1, &min_width);
finishRange(info->fGlyphWidths.get(), 0,
SkAdvancedTypefaceMetrics::WidthRange::kDefault);
SkAdvancedTypefaceMetrics::WidthRange range(0);
range.fAdvance.append(1, &min_width);
SkAdvancedTypefaceMetrics::FinishRange(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->fGlyphWidths.reset(
getAdvanceData(hdc,
glyphCount,
glyphIDs,
glyphIDsCount,
&getWidthAdvance));
info->setGlyphWidths(hdc, glyphCount, glyphIDs,
glyphIDsCount, &getWidthAdvance);
}
}

View File

@ -284,8 +284,6 @@ void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
///////////////////////////////////////////////////////////////////////////////
//PDF Support
using namespace skia_advanced_typeface_metrics_utils;
// Construct Glyph to Unicode table.
// Unicode code points that require conjugate pairs in utf16 are not
// supported.
@ -444,19 +442,16 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
if (fixedWidth) {
appendRange(&info->fGlyphWidths, 0);
SkAdvancedTypefaceMetrics::WidthRange range(0);
int16_t advance;
getWidthAdvance(fDWriteFontFace.get(), 1, &advance);
info->fGlyphWidths->fAdvance.append(1, &advance);
finishRange(info->fGlyphWidths.get(), 0,
SkAdvancedTypefaceMetrics::WidthRange::kDefault);
range.fAdvance.append(1, &advance);
SkAdvancedTypefaceMetrics::FinishRange(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->fGlyphWidths.reset(
getAdvanceData(fDWriteFontFace.get(),
glyphCount,
glyphIDs,
glyphIDsCount,
getWidthAdvance));
info->setGlyphWidths(fDWriteFontFace.get(), glyphCount, glyphIDs,
glyphIDsCount, getWidthAdvance);
}
}

View File

@ -10,8 +10,6 @@
// Include the implementation so we can make an appropriate template instance.
#include "SkAdvancedTypefaceMetrics.h"
using namespace skia_advanced_typeface_metrics_utils;
// Negative values and zeros in a range plus trailing zeros.
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
static const int16_t data1[] = {-1, 0, -3, 4, 5, 6, 7, 0, 0, 0, 8, 0, 0, 0, 0};
@ -98,34 +96,35 @@ static const char* expected14 = "0[1] 5[2]";
static const uint32_t subset14[] = {0, 5};
static const char* expectedSubset14 = "0[1] 5[2]";
static SkString stringify_advance_data(SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* data) {
static SkString stringify_advance_data(const SkSinglyLinkedList<
SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>>& list) {
SkString result;
bool leadingSpace = false;
while (data != nullptr) {
if (leadingSpace) {
result.append(" ");
} else {
leadingSpace = true;
}
switch(data->fType) {
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kRun:
result.appendf("%d %d %d", data->fStartId, data->fEndId, data->fAdvance[0]);
break;
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kRange:
result.appendf("%d[", data->fStartId);
for (int i = 0; i < data->fAdvance.count(); ++i) {
if (i > 0) {
result.append(" ");
}
result.appendf("%d", data->fAdvance[i]);
}
result.append("]");
break;
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kDefault:
result.appendf("<Default=%d>", data->fAdvance[0]);
break;
}
data = data->fNext.get();
for (const SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>& data : list) {
if (leadingSpace) {
result.append(" ");
} else {
leadingSpace = true;
}
switch (data.fType) {
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kRun:
result.appendf("%d %d %d", data.fStartId, data.fEndId,
data.fAdvance[0]);
break;
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kRange:
result.appendf("%d[", data.fStartId);
for (int i = 0; i < data.fAdvance.count(); ++i) {
if (i > 0) {
result.append(" ");
}
result.appendf("%d", data.fAdvance[i]);
}
result.append("]");
break;
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kDefault:
result.appendf("<Default=%d>", data.fAdvance[0]);
break;
}
}
return result;
}
@ -161,10 +160,11 @@ class TestWData {
}
void runTest(skiatest::Reporter* reporter) {
SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t> > result;
result.reset(getAdvanceData((void*)this, fAdvancesLen, fSubset, fSubsetLen, getAdvance));
SkAdvancedTypefaceMetrics metrics;
metrics.setGlyphWidths((void*)this, fAdvancesLen, fSubset, fSubsetLen,
getAdvance);
SkString stringResult = stringify_advance_data(result);
SkString stringResult = stringify_advance_data(metrics.fGlyphWidths);
if (!stringResult.equals(fExpected)) {
ERRORF(reporter, "Expected: %s\n Result: %s\n", fExpected, stringResult.c_str());
}