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:
parent
0938befe5d
commit
e20a875170
@ -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',
|
||||
|
@ -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',
|
||||
],
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user