aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkTypeface.h5
-rw-r--r--src/core/SkAdvancedTypefaceMetrics.h10
-rw-r--r--src/core/SkTypeface.cpp4
-rw-r--r--src/core/SkTypeface_remote.h4
-rw-r--r--src/pdf/SkPDFCanon.h1
-rw-r--r--src/pdf/SkPDFDevice.cpp8
-rw-r--r--src/pdf/SkPDFFont.cpp47
-rw-r--r--src/pdf/SkPDFFont.h3
-rw-r--r--src/pdf/SkPDFMakeToUnicodeCmap.cpp10
-rw-r--r--src/pdf/SkPDFMakeToUnicodeCmap.h4
-rw-r--r--src/ports/SkFontHost_FreeType.cpp42
-rw-r--r--src/ports/SkFontHost_FreeType_common.h1
-rw-r--r--src/ports/SkFontHost_mac.cpp26
-rw-r--r--src/ports/SkFontHost_win.cpp30
-rw-r--r--src/ports/SkTypeface_win_dw.cpp30
-rw-r--r--src/ports/SkTypeface_win_dw.h1
-rw-r--r--tests/PDFGlyphsToUnicodeTest.cpp18
-rw-r--r--tests/TypefaceTest.cpp10
-rw-r--r--tools/fonts/SkRandomScalerContext.cpp4
-rw-r--r--tools/fonts/SkRandomScalerContext.h1
-rw-r--r--tools/fonts/SkTestSVGTypeface.cpp16
-rw-r--r--tools/fonts/SkTestSVGTypeface.h1
-rw-r--r--tools/fonts/SkTestTypeface.cpp15
-rw-r--r--tools/fonts/SkTestTypeface.h1
24 files changed, 162 insertions, 130 deletions
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index 37878cc390..665491c3db 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -318,6 +318,11 @@ protected:
// Backends that do not suport type1 fonts should not override.
virtual void getPostScriptGlyphNames(SkString*) const {}
+ // The mapping from glyph to Unicode; array indices are glyph ids.
+ // For each glyph, give the default Unicode value, if it exists.
+ // dstArray is non-null, and points to an array of size this->countGlyphs().
+ virtual void getGlyphToUnicodeMap(SkUnichar* dstArray) const;
+
virtual SkStreamAsset* onOpenStream(int* ttcIndex) const = 0;
// TODO: make pure virtual.
virtual std::unique_ptr<SkFontData> onMakeFontData() const;
diff --git a/src/core/SkAdvancedTypefaceMetrics.h b/src/core/SkAdvancedTypefaceMetrics.h
index 6be3d443bf..e9af831422 100644
--- a/src/core/SkAdvancedTypefaceMetrics.h
+++ b/src/core/SkAdvancedTypefaceMetrics.h
@@ -10,9 +10,7 @@
#include "SkBitmaskEnum.h"
#include "SkRect.h"
-#include "SkRefCnt.h"
#include "SkString.h"
-#include "SkTDArray.h"
/** \class SkAdvancedTypefaceMetrics
@@ -21,11 +19,6 @@
SkTypeface::getAdvancedMetrics.
*/
struct SkAdvancedTypefaceMetrics {
- SkAdvancedTypefaceMetrics() {}
- SkAdvancedTypefaceMetrics(const SkAdvancedTypefaceMetrics&) = delete;
- SkAdvancedTypefaceMetrics& operator=(const SkAdvancedTypefaceMetrics&) = delete;
- ~SkAdvancedTypefaceMetrics() {}
-
// The PostScript name of the font. See `FontName` and `BaseFont` in PDF standard.
SkString fPostScriptName;
SkString fFontName;
@@ -70,9 +63,6 @@ struct SkAdvancedTypefaceMetrics {
int16_t fCapHeight = 0; // Height (from baseline) of top of flat capitals.
SkIRect fBBox = {0, 0, 0, 0}; // The bounding box of all glyphs (in font units).
-
- // The mapping from glyph to Unicode; array indices are glyph ids.
- SkTDArray<SkUnichar> fGlyphToUnicode;
};
namespace skstd {
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index c6337d7852..92c8c09e33 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -291,6 +291,10 @@ void SkTypeface::getFamilyName(SkString* name) const {
this->onGetFamilyName(name);
}
+void SkTypeface::getGlyphToUnicodeMap(SkUnichar* dst) const {
+ sk_bzero(dst, sizeof(SkUnichar) * this->countGlyphs());
+}
+
std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::getAdvancedMetrics() const {
std::unique_ptr<SkAdvancedTypefaceMetrics> result = this->onGetAdvancedMetrics();
if (result && result->fPostScriptName.isEmpty()) {
diff --git a/src/core/SkTypeface_remote.h b/src/core/SkTypeface_remote.h
index 691b124049..ad729aded3 100644
--- a/src/core/SkTypeface_remote.h
+++ b/src/core/SkTypeface_remote.h
@@ -111,6 +111,10 @@ protected:
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override {
SK_ABORT("Should never be called.");
}
+ void getGlyphToUnicodeMap(SkUnichar*) const override {
+ SK_ABORT("Should never be called.");
+ }
+
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
SK_ABORT("Should never be called.");
return nullptr;
diff --git a/src/pdf/SkPDFCanon.h b/src/pdf/SkPDFCanon.h
index 8d0e8f8fed..8e97db05f5 100644
--- a/src/pdf/SkPDFCanon.h
+++ b/src/pdf/SkPDFCanon.h
@@ -42,6 +42,7 @@ public:
SkTHashMap<uint32_t, std::unique_ptr<SkAdvancedTypefaceMetrics>> fTypefaceMetrics;
SkTHashMap<uint32_t, std::vector<SkString>> fType1GlyphNames;
+ SkTHashMap<uint32_t, std::vector<SkUnichar>> fToUnicodeMap;
SkTHashMap<uint32_t, sk_sp<SkPDFDict>> fFontDescriptors;
SkTHashMap<uint64_t, sk_sp<SkPDFFont>> fFontMap;
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 6e36fb3d82..c18219ab0d 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1052,8 +1052,8 @@ private:
};
} // namespace
-static SkUnichar map_glyph(const SkTDArray<SkUnichar>& glyphToUnicode, SkGlyphID glyph) {
- return SkToInt(glyph) < glyphToUnicode.count() ? glyphToUnicode[SkToInt(glyph)] : -1;
+static SkUnichar map_glyph(const std::vector<SkUnichar>& glyphToUnicode, SkGlyphID glyph) {
+ return glyph < glyphToUnicode.size() ? glyphToUnicode[SkToInt(glyph)] : -1;
}
static void update_font(SkWStream* wStream, int fontIndex, SkScalar textSize) {
@@ -1200,6 +1200,9 @@ void SkPDFDevice::internalDrawText(
if (!metrics) {
return;
}
+ const std::vector<SkUnichar>& glyphToUnicode = SkPDFFont::GetUnicodeMap(
+ typeface, fDocument->canon());
+
SkClusterator clusterator(sourceText, sourceByteCount, paint,
clusters, textByteLength, utf8Text);
const SkGlyphID* glyphs = clusterator.glyphs();
@@ -1244,7 +1247,6 @@ void SkPDFDevice::internalDrawText(
return;
}
SkDynamicMemoryWStream* out = content.stream();
- const SkTDArray<SkUnichar>& glyphToUnicode = metrics->fGlyphToUnicode;
out->writeText("BT\n");
SK_AT_SCOPE_EXIT(out->writeText("ET\n"));
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index 9ba411495a..3b89f62cbe 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -186,6 +186,19 @@ const SkAdvancedTypefaceMetrics* SkPDFFont::GetMetrics(SkTypeface* typeface,
return canon->fTypefaceMetrics.set(id, std::move(metrics))->get();
}
+const std::vector<SkUnichar>& SkPDFFont::GetUnicodeMap(const SkTypeface* typeface,
+ SkPDFCanon* canon) {
+ SkASSERT(typeface);
+ SkASSERT(canon);
+ SkFontID id = typeface->uniqueID();
+ if (std::vector<SkUnichar>* ptr = canon->fToUnicodeMap.find(id)) {
+ return *ptr;
+ }
+ std::vector<SkUnichar> buffer(typeface->countGlyphs());
+ typeface->getGlyphToUnicodeMap(buffer.data());
+ return *canon->fToUnicodeMap.set(id, std::move(buffer));
+}
+
SkAdvancedTypefaceMetrics::FontType SkPDFFont::FontType(const SkAdvancedTypefaceMetrics& metrics) {
if (SkToBool(metrics.fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) ||
SkToBool(metrics.fFlags & SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag)) {
@@ -477,14 +490,15 @@ void SkPDFType0Font::getFontSubset(SkPDFCanon* canon) {
descendantFonts->appendObjRef(std::move(newCIDFont));
this->insertObject("DescendantFonts", std::move(descendantFonts));
- if (metrics.fGlyphToUnicode.count() > 0) {
- this->insertObjRef("ToUnicode",
- SkPDFMakeToUnicodeCmap(metrics.fGlyphToUnicode,
- &this->glyphUsage(),
- multiByteGlyphs(),
- firstGlyphID(),
- lastGlyphID()));
- }
+ const std::vector<SkUnichar>& glyphToUnicode =
+ SkPDFFont::GetUnicodeMap(this->typeface(), canon);
+ SkASSERT(SkToSizeT(this->typeface()->countGlyphs()) == glyphToUnicode.size());
+ this->insertObjRef("ToUnicode",
+ SkPDFMakeToUnicodeCmap(glyphToUnicode.data(),
+ &this->glyphUsage(),
+ this->multiByteGlyphs(),
+ this->firstGlyphID(),
+ this->lastGlyphID()));
SkDEBUGCODE(fPopulated = true);
return;
}
@@ -722,14 +736,15 @@ static void add_type3_font_info(SkPDFCanon* canon,
fontBBox->appendInt(bbox.top());
font->insertObject("FontBBox", std::move(fontBBox));
font->insertName("CIDToGIDMap", "Identity");
- if (metrics && metrics->fGlyphToUnicode.count() > 0) {
- font->insertObjRef("ToUnicode",
- SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode,
- &subset,
- false,
- firstGlyphID,
- lastGlyphID));
- }
+
+ const std::vector<SkUnichar>& glyphToUnicode = SkPDFFont::GetUnicodeMap(typeface, canon);
+ SkASSERT(glyphToUnicode.size() == SkToSizeT(typeface->countGlyphs()));
+ font->insertObjRef("ToUnicode",
+ SkPDFMakeToUnicodeCmap(glyphToUnicode.data(),
+ &subset,
+ false,
+ firstGlyphID,
+ lastGlyphID));
auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor");
int32_t fontDescriptorFlags = kPdfSymbolic;
if (metrics) {
diff --git a/src/pdf/SkPDFFont.h b/src/pdf/SkPDFFont.h
index 9dc4655501..1441eedad9 100644
--- a/src/pdf/SkPDFFont.h
+++ b/src/pdf/SkPDFFont.h
@@ -95,6 +95,9 @@ public:
static const SkAdvancedTypefaceMetrics* GetMetrics(SkTypeface* typeface,
SkPDFCanon* canon);
+ static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface* typeface,
+ SkPDFCanon* canon);
+
/** Subset the font based on current usage.
* Must be called before emitObject().
*/
diff --git a/src/pdf/SkPDFMakeToUnicodeCmap.cpp b/src/pdf/SkPDFMakeToUnicodeCmap.cpp
index afe773207d..c93aa6f2c5 100644
--- a/src/pdf/SkPDFMakeToUnicodeCmap.cpp
+++ b/src/pdf/SkPDFMakeToUnicodeCmap.cpp
@@ -147,15 +147,12 @@ static void append_bfrange_section(const SkTDArray<BFRange>& bfrange,
// For the worst case (having 65536 continuous unicode and we use every other
// one of them), the possible savings by aggressive optimization is 416KB
// pre-compressed and does not provide enough motivation for implementation.
-void SkPDFAppendCmapSections(const SkTDArray<SkUnichar>& glyphToUnicode,
+void SkPDFAppendCmapSections(const SkUnichar* glyphToUnicode,
const SkBitSet* subset,
SkDynamicMemoryWStream* cmap,
bool multiByteGlyphs,
SkGlyphID firstGlyphID,
SkGlyphID lastGlyphID) {
- if (glyphToUnicode.isEmpty()) {
- return;
- }
int glyphOffset = 0;
if (!multiByteGlyphs) {
glyphOffset = firstGlyphID - 1;
@@ -166,8 +163,7 @@ void SkPDFAppendCmapSections(const SkTDArray<SkUnichar>& glyphToUnicode,
BFRange currentRangeEntry = {0, 0, 0};
bool rangeEmpty = true;
- const int limit =
- SkMin32(lastGlyphID + 1, glyphToUnicode.count()) - glyphOffset;
+ const int limit = (int)lastGlyphID + 1 - glyphOffset;
for (int i = firstGlyphID - glyphOffset; i < limit + 1; ++i) {
bool inSubset = i < limit &&
@@ -210,7 +206,7 @@ void SkPDFAppendCmapSections(const SkTDArray<SkUnichar>& glyphToUnicode,
}
sk_sp<SkPDFStream> SkPDFMakeToUnicodeCmap(
- const SkTDArray<SkUnichar>& glyphToUnicode,
+ const SkUnichar* glyphToUnicode,
const SkBitSet* subset,
bool multiByteGlyphs,
SkGlyphID firstGlyphID,
diff --git a/src/pdf/SkPDFMakeToUnicodeCmap.h b/src/pdf/SkPDFMakeToUnicodeCmap.h
index 0c4d1c37dd..656af913d0 100644
--- a/src/pdf/SkPDFMakeToUnicodeCmap.h
+++ b/src/pdf/SkPDFMakeToUnicodeCmap.h
@@ -12,14 +12,14 @@
#include "SkStream.h"
sk_sp<SkPDFStream> SkPDFMakeToUnicodeCmap(
- const SkTDArray<SkUnichar>& glyphToUnicode,
+ const SkUnichar* glyphToUnicode,
const SkBitSet* subset,
bool multiByteGlyphs,
SkGlyphID firstGlyphID,
SkGlyphID lastGlyphID);
// Exposed for unit testing.
-void SkPDFAppendCmapSections(const SkTDArray<SkUnichar>& glyphToUnicode,
+void SkPDFAppendCmapSections(const SkUnichar* glyphToUnicode,
const SkBitSet* subset,
SkDynamicMemoryWStream* cmap,
bool multiByteGlyphs,
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index f1c1b555f2..3e8e9576dd 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -511,23 +511,6 @@ static bool canSubset(FT_Face face) {
return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0;
}
-static void populate_glyph_to_unicode(FT_Face& face, SkTDArray<SkUnichar>* glyphToUnicode) {
- FT_Long numGlyphs = face->num_glyphs;
- glyphToUnicode->setCount(SkToInt(numGlyphs));
- sk_bzero(glyphToUnicode->begin(), sizeof((*glyphToUnicode)[0]) * numGlyphs);
-
- FT_UInt glyphIndex;
- SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
- while (glyphIndex) {
- SkASSERT(glyphIndex < SkToUInt(numGlyphs));
- // Use the first character that maps to this glyphID. https://crbug.com/359065
- if (0 == (*glyphToUnicode)[glyphIndex]) {
- (*glyphToUnicode)[glyphIndex] = charCode;
- }
- charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
- }
-}
-
static SkAdvancedTypefaceMetrics::FontType get_font_type(FT_Face face) {
const char* fontType = FT_Get_X11_Font_Format(face);
static struct { const char* s; SkAdvancedTypefaceMetrics::FontType t; } values[] = {
@@ -602,17 +585,26 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_FreeType::onGetAdvancedMet
}
info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
face->bbox.xMax, face->bbox.yMin);
+ return info;
+}
- bool perGlyphInfo = FT_IS_SCALABLE(face);
+void SkTypeface_FreeType::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
+ SkASSERT(dstArray);
+ AutoFTAccess fta(this);
+ FT_Face face = fta.face();
+ FT_Long numGlyphs = face->num_glyphs;
+ sk_bzero(dstArray, sizeof(SkUnichar) * numGlyphs);
- if (perGlyphInfo &&
- info->fType != SkAdvancedTypefaceMetrics::kType1_Font &&
- face->num_charmaps)
- {
- populate_glyph_to_unicode(face, &(info->fGlyphToUnicode));
+ FT_UInt glyphIndex;
+ SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
+ while (glyphIndex) {
+ SkASSERT(glyphIndex < SkToUInt(numGlyphs));
+ // Use the first character that maps to this glyphID. https://crbug.com/359065
+ if (0 == dstArray[glyphIndex]) {
+ dstArray[glyphIndex] = charCode;
+ }
+ charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
}
-
- return info;
}
void SkTypeface_FreeType::getPostScriptGlyphNames(SkString* dstArray) const {
diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h
index 3aabdde250..eacce04ca1 100644
--- a/src/ports/SkFontHost_FreeType_common.h
+++ b/src/ports/SkFontHost_FreeType_common.h
@@ -91,6 +91,7 @@ protected:
virtual SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor*) const override;
void onFilterRec(SkScalerContextRec*) const override;
+ void getGlyphToUnicodeMap(SkUnichar*) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
void getPostScriptGlyphNames(SkString* dstArray) const override;
int onGetUPEM() const override;
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 8047c4352f..3cc51d43f6 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -719,6 +719,7 @@ protected:
const SkDescriptor*) const override;
void onFilterRec(SkScalerContextRec*) const override;
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
+ void getGlyphToUnicodeMap(SkUnichar*) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
int onCharsToGlyphs(const void* chars, Encoding,
uint16_t glyphs[], int glyphCount) const override;
@@ -1605,9 +1606,7 @@ static sk_sp<SkTypeface> create_from_dataProvider(UniqueCFRef<CGDataProviderRef>
// Iterate through the font in this case. The existing caller caches the result,
// so the performance impact isn't too bad.
static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount,
- SkTDArray<SkUnichar>* glyphToUnicode) {
- glyphToUnicode->setCount(SkToInt(glyphCount));
- SkUnichar* out = glyphToUnicode->begin();
+ SkUnichar* out) {
sk_bzero(out, glyphCount * sizeof(SkUnichar));
UniChar unichar = 0;
while (glyphCount > 0) {
@@ -1628,7 +1627,8 @@ static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount,
// Unicode code points that require conjugate pairs in utf16 are not
// supported.
static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
- SkTDArray<SkUnichar>* glyphToUnicode) {
+ SkUnichar* glyphToUnicode) {
+ sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount);
UniqueCFRef<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont));
if (!charSet) {
populate_glyph_to_unicode_slow(ctFont, glyphCount, glyphToUnicode);
@@ -1651,9 +1651,7 @@ static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
length = 8192;
}
const UInt8* bits = CFDataGetBytePtr(bitmap.get());
- glyphToUnicode->setCount(SkToInt(glyphCount));
- SkUnichar* out = glyphToUnicode->begin();
- sk_bzero(out, glyphCount * sizeof(SkUnichar));
+ sk_bzero(glyphToUnicode, glyphCount * sizeof(SkUnichar));
for (int i = 0; i < length; i++) {
int mask = bits[i];
if (!mask) {
@@ -1663,7 +1661,7 @@ static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
CGGlyph glyph;
UniChar unichar = static_cast<UniChar>((i << 3) + j);
if (mask & (1 << j) && CTFontGetGlyphsForCharacters(ctFont, &unichar, &glyph, 1)) {
- out[glyph] = unichar;
+ glyphToUnicode[glyph] = unichar;
}
}
}
@@ -1681,6 +1679,14 @@ static void CFStringToSkString(CFStringRef src, SkString* dst) {
dst->resize(strlen(dst->c_str()));
}
+void SkTypeface_Mac::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
+ AUTO_CG_LOCK();
+ UniqueCFRef<CTFontRef> ctFont =
+ ctfont_create_exact_copy(fFontRef.get(), CTFontGetUnitsPerEm(fFontRef.get()), nullptr);
+ CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get());
+ populate_glyph_to_unicode(ctFont.get(), glyphCount, dstArray);
+}
+
std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics() const {
AUTO_CG_LOCK();
@@ -1710,10 +1716,6 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics(
}
}
- CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get());
-
- populate_glyph_to_unicode(ctFont.get(), glyphCount, &info->fGlyphToUnicode);
-
SkOTTableOS2_V4::Type fsType;
if (sizeof(fsType) == this->getTableData(SkTEndian_SwapBE32(SkOTTableOS2::TAG),
offsetof(SkOTTableOS2_V4, fsType),
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 35a0a74b22..f1da8053f2 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -261,6 +261,7 @@ protected:
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor*) const override;
void onFilterRec(SkScalerContextRec*) const override;
+ void getGlyphToUnicodeMap(SkUnichar*) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
int onCharsToGlyphs(const void* chars, Encoding encoding,
@@ -362,7 +363,8 @@ void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) {
// require parsing the TTF cmap table (platform 4, encoding 12) directly instead
// of calling GetFontUnicodeRange().
static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount,
- SkTDArray<SkUnichar>* glyphToUnicode) {
+ SkUnichar* glyphToUnicode) {
+ sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount);
DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, nullptr);
if (!glyphSetBufferSize) {
return;
@@ -375,8 +377,6 @@ static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount,
return;
}
- glyphToUnicode->setCount(glyphCount);
- memset(glyphToUnicode->begin(), 0, glyphCount * sizeof(SkUnichar));
for (DWORD i = 0; i < glyphSet->cRanges; ++i) {
// There is no guarantee that within a Unicode range, the corresponding
// glyph id in a font file are continuous. So, even if we have ranges,
@@ -399,9 +399,8 @@ static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount,
// unlikely to have collisions since glyph reuse happens mostly for
// different Unicode pages.
for (USHORT j = 0; j < count; ++j) {
- if (glyph[j] != 0xffff && glyph[j] < glyphCount &&
- (*glyphToUnicode)[glyph[j]] == 0) {
- (*glyphToUnicode)[glyph[j]] = chars[j];
+ if (glyph[j] != 0xFFFF && glyph[j] < glyphCount && glyphToUnicode[glyph[j]] == 0) {
+ glyphToUnicode[glyph[j]] = chars[j];
}
}
}
@@ -1707,6 +1706,23 @@ void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
*isLocalStream = this->fSerializeAsStream;
}
+void LogFontTypeface::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
+ HDC hdc = ::CreateCompatibleDC(nullptr);
+ HFONT font = CreateFontIndirect(&fLogFont);
+ HFONT savefont = (HFONT)SelectObject(hdc, font);
+ LOGFONT lf = fLogFont;
+ HFONT designFont = CreateFontIndirect(&lf);
+ SelectObject(hdc, designFont);
+
+ unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
+ populate_glyph_to_unicode(hdc, glyphCount, dstArray);
+
+ SelectObject(hdc, savefont);
+ DeleteObject(designFont);
+ DeleteObject(font);
+ DeleteDC(hdc);
+}
+
std::unique_ptr<SkAdvancedTypefaceMetrics> LogFontTypeface::onGetAdvancedMetrics() const {
LOGFONT lf = fLogFont;
std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr);
@@ -1757,8 +1773,6 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> LogFontTypeface::onGetAdvancedMetrics
}
}
- populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode));
-
if (glyphCount > 0 &&
(otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) {
info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp
index 69bf7ff034..38e68dccca 100644
--- a/src/ports/SkTypeface_win_dw.cpp
+++ b/src/ports/SkTypeface_win_dw.cpp
@@ -288,42 +288,31 @@ void DWriteFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
///////////////////////////////////////////////////////////////////////////////
//PDF Support
-// Construct Glyph to Unicode table.
-// Unicode code points that require conjugate pairs in utf16 are not
-// supported.
-// TODO(bungeman): This never does what anyone wants.
-// What is really wanted is the text to glyphs mapping
-static void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
- const unsigned glyphCount,
- SkTDArray<SkUnichar>* glyphToUnicode) {
- //Do this like free type instead
- SkAutoTMalloc<SkUnichar> glyphToUni(
- (SkUnichar*)sk_calloc_throw(sizeof(SkUnichar) * glyphCount));
+void DWriteFontTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
+ unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
+ sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount);
+ IDWriteFontFace* fontFace = fDWriteFontFace.get();
int maxGlyph = -1;
unsigned remainingGlyphCount = glyphCount;
for (UINT32 c = 0; c < 0x10FFFF && remainingGlyphCount != 0; ++c) {
UINT16 glyph = 0;
- HRVM(fontFace->GetGlyphIndices(&c, 1, &glyph),
- "Failed to get glyph index.");
+ HRVM(fontFace->GetGlyphIndices(&c, 1, &glyph), "Failed to get glyph index.");
// Intermittent DW bug on Windows 10. See crbug.com/470146.
if (glyph >= glyphCount) {
- return;
+ return;
}
- if (0 < glyph && glyphToUni[glyph] == 0) {
+ if (0 < glyph && glyphToUnicode[glyph] == 0) {
maxGlyph = SkTMax(static_cast<int>(glyph), maxGlyph);
- glyphToUni[glyph] = c; // Always use lowest-index unichar.
+ glyphToUnicode[glyph] = c; // Always use lowest-index unichar.
--remainingGlyphCount;
}
}
- SkTDArray<SkUnichar>(glyphToUni, maxGlyph + 1).swap(*glyphToUnicode);
}
std::unique_ptr<SkAdvancedTypefaceMetrics> DWriteFontTypeface::onGetAdvancedMetrics() const {
std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr);
- const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
-
DWRITE_FONT_METRICS dwfm;
fDWriteFontFace->GetMetrics(&dwfm);
@@ -358,9 +347,6 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> DWriteFontTypeface::onGetAdvancedMetr
info->fPostScriptName = info->fFontName;
}
-
- populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
-
DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType();
if (fontType != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
fontType != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h
index 7abbde55aa..75be040fd4 100644
--- a/src/ports/SkTypeface_win_dw.h
+++ b/src/ports/SkTypeface_win_dw.h
@@ -104,6 +104,7 @@ protected:
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor*) const override;
void onFilterRec(SkScalerContextRec*) const override;
+ void getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
int onCharsToGlyphs(const void* chars, Encoding encoding,
diff --git a/tests/PDFGlyphsToUnicodeTest.cpp b/tests/PDFGlyphsToUnicodeTest.cpp
index 332520bfb0..2aeedf0330 100644
--- a/tests/PDFGlyphsToUnicodeTest.cpp
+++ b/tests/PDFGlyphsToUnicodeTest.cpp
@@ -74,9 +74,12 @@ DEF_TEST(SkPDF_ToUnicode, reporter) {
glyphsInSubset.push(0x101);
glyphToUnicode.push(0x1013);
+ SkGlyphID lastGlyphID = SkToU16(glyphToUnicode.count() - 1);
+
SkDynamicMemoryWStream buffer;
subset.setAll(glyphsInSubset.begin(), glyphsInSubset.count());
- SkPDFAppendCmapSections(glyphToUnicode, &subset, &buffer, true, 0, 0xFFFF);
+ SkPDFAppendCmapSections(&glyphToUnicode[0], &subset, &buffer, true, 0,
+ SkTMin<SkGlyphID>(0xFFFF, lastGlyphID));
char expectedResult[] =
"4 beginbfchar\n\
@@ -98,7 +101,8 @@ endbfrange\n";
// Remove characters and ranges.
buffer.reset();
- SkPDFAppendCmapSections(glyphToUnicode, &subset, &buffer, true, 8, 0x00FF);
+ SkPDFAppendCmapSections(&glyphToUnicode[0], &subset, &buffer, true, 8,
+ SkTMin<SkGlyphID>(0x00FF, lastGlyphID));
char expectedResultChop1[] =
"2 beginbfchar\n\
@@ -116,7 +120,8 @@ endbfrange\n";
// Remove characters from range to downdrade it to one char.
buffer.reset();
- SkPDFAppendCmapSections(glyphToUnicode, &subset, &buffer, true, 0x00D, 0x00FE);
+ SkPDFAppendCmapSections(&glyphToUnicode[0], &subset, &buffer, true, 0x00D,
+ SkTMin<SkGlyphID>(0x00FE, lastGlyphID));
char expectedResultChop2[] =
"2 beginbfchar\n\
@@ -129,7 +134,8 @@ endbfchar\n";
buffer.reset();
- SkPDFAppendCmapSections(glyphToUnicode, nullptr, &buffer, false, 0xFC, 0x110);
+ SkPDFAppendCmapSections(&glyphToUnicode[0], nullptr, &buffer, false, 0xFC,
+ SkTMin<SkGlyphID>(0x110, lastGlyphID));
char expectedResultSingleBytes[] =
"2 beginbfchar\n\
@@ -155,6 +161,7 @@ endbfrange\n";
for (SkUnichar i = 0; i < 100; ++i) {
glyphToUnicode.push(i + 29);
}
+ lastGlyphID = SkToU16(glyphToUnicode.count() - 1);
glyphsInSubset.push(0x2C);
glyphsInSubset.push(0x44);
@@ -165,7 +172,8 @@ endbfrange\n";
SkDynamicMemoryWStream buffer2;
subset2.setAll(glyphsInSubset.begin(), glyphsInSubset.count());
- SkPDFAppendCmapSections(glyphToUnicode, &subset2, &buffer2, true, 0, 0xffff);
+ SkPDFAppendCmapSections(&glyphToUnicode[0], &subset2, &buffer2, true, 0,
+ SkTMin<SkGlyphID>(0xFFFF, lastGlyphID));
char expectedResult2[] =
"4 beginbfchar\n\
diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp
index b6b71aeb8c..34fa3575f1 100644
--- a/tests/TypefaceTest.cpp
+++ b/tests/TypefaceTest.cpp
@@ -203,11 +203,11 @@ DEF_TEST(Typeface, reporter) {
namespace {
-class SkEmptyTypeface : public SkTypeface {
+class EmptyTypeface : public SkTypeface {
public:
- static sk_sp<SkTypeface> Create() { return sk_sp<SkTypeface>(new SkEmptyTypeface()); }
+ static sk_sp<SkTypeface> Create() { return sk_sp<SkTypeface>(new EmptyTypeface()); }
protected:
- SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
+ EmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; }
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
@@ -255,12 +255,12 @@ static int count(skiatest::Reporter* reporter, const SkTypefaceCache& cache) {
}
DEF_TEST(TypefaceCache, reporter) {
- sk_sp<SkTypeface> t1(SkEmptyTypeface::Create());
+ sk_sp<SkTypeface> t1(EmptyTypeface::Create());
{
SkTypefaceCache cache;
REPORTER_ASSERT(reporter, count(reporter, cache) == 0);
{
- sk_sp<SkTypeface> t0(SkEmptyTypeface::Create());
+ sk_sp<SkTypeface> t0(EmptyTypeface::Create());
cache.add(t0.get());
REPORTER_ASSERT(reporter, count(reporter, cache) == 1);
cache.add(t1.get());
diff --git a/tools/fonts/SkRandomScalerContext.cpp b/tools/fonts/SkRandomScalerContext.cpp
index 2d472129a1..9379759ff0 100644
--- a/tools/fonts/SkRandomScalerContext.cpp
+++ b/tools/fonts/SkRandomScalerContext.cpp
@@ -164,6 +164,10 @@ void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {
rec->fMaskFormat = SkMask::kARGB32_Format;
}
+void SkRandomTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
+ fProxy->getGlyphToUnicodeMap(glyphToUnicode);
+}
+
std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const {
return fProxy->getAdvancedMetrics();
}
diff --git a/tools/fonts/SkRandomScalerContext.h b/tools/fonts/SkRandomScalerContext.h
index b71689d9e2..5dbdac68b8 100644
--- a/tools/fonts/SkRandomScalerContext.h
+++ b/tools/fonts/SkRandomScalerContext.h
@@ -27,6 +27,7 @@ protected:
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor*) const override;
void onFilterRec(SkScalerContextRec*) const override;
+ void getGlyphToUnicodeMap(SkUnichar*) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
SkStreamAsset* onOpenStream(int* ttcIndex) const override;
void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const override;
diff --git a/tools/fonts/SkTestSVGTypeface.cpp b/tools/fonts/SkTestSVGTypeface.cpp
index ceb523aa72..199c3b5df6 100644
--- a/tools/fonts/SkTestSVGTypeface.cpp
+++ b/tools/fonts/SkTestSVGTypeface.cpp
@@ -100,15 +100,17 @@ void SkTestSVGTypeface::onFilterRec(SkScalerContextRec* rec) const {
rec->setHinting(SkPaint::kNo_Hinting);
}
+void SkTestSVGTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
+ SkDEBUGCODE(unsigned glyphCount = this->countGlyphs());
+ fCMap.foreach([=](const SkUnichar& c, const SkGlyphID& g) {
+ SkASSERT(g < glyphCount);
+ glyphToUnicode[g] = c;
+ });
+}
+
std::unique_ptr<SkAdvancedTypefaceMetrics> SkTestSVGTypeface::onGetAdvancedMetrics() const {
std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics);
- info->fFontName.set(fName);
-
- SkTDArray<SkUnichar>& toUnicode = info->fGlyphToUnicode;
- toUnicode.setCount(fGlyphCount);
- fCMap.foreach([&toUnicode](const SkUnichar& c, const SkGlyphID& g) {
- toUnicode[g] = c;
- });
+ info->fFontName = fName;
return info;
}
diff --git a/tools/fonts/SkTestSVGTypeface.h b/tools/fonts/SkTestSVGTypeface.h
index 0b53245b70..249cd8bfc1 100644
--- a/tools/fonts/SkTestSVGTypeface.h
+++ b/tools/fonts/SkTestSVGTypeface.h
@@ -77,6 +77,7 @@ protected:
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor* desc) const override;
void onFilterRec(SkScalerContextRec* rec) const override;
+ void getGlyphToUnicodeMap(SkUnichar*) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
SkStreamAsset* onOpenStream(int* ttcIndex) const override {
diff --git a/tools/fonts/SkTestTypeface.cpp b/tools/fonts/SkTestTypeface.cpp
index d7caa5a392..bf3a1a3e9e 100644
--- a/tools/fonts/SkTestTypeface.cpp
+++ b/tools/fonts/SkTestTypeface.cpp
@@ -119,17 +119,16 @@ void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
rec->setHinting(SkPaint::kNo_Hinting);
}
+void SkTestTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
+ unsigned glyphCount = fTestFont->fCharCodesCount;
+ for (unsigned gid = 0; gid < glyphCount; ++gid) {
+ glyphToUnicode[gid] = SkTo<SkUnichar>(fTestFont->fCharCodes[gid]);
+ }
+}
+
std::unique_ptr<SkAdvancedTypefaceMetrics> SkTestTypeface::onGetAdvancedMetrics() const { // pdf only
std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics);
info->fFontName.set(fTestFont->fName);
- int glyphCount = this->onCountGlyphs();
-
- SkTDArray<SkUnichar>& toUnicode = info->fGlyphToUnicode;
- toUnicode.setCount(glyphCount);
- SkASSERT(glyphCount == SkToInt(fTestFont->fCharCodesCount));
- for (int gid = 0; gid < glyphCount; ++gid) {
- toUnicode[gid] = SkToS32(fTestFont->fCharCodes[gid]);
- }
return info;
}
diff --git a/tools/fonts/SkTestTypeface.h b/tools/fonts/SkTestTypeface.h
index d3365f972a..205d82c30f 100644
--- a/tools/fonts/SkTestTypeface.h
+++ b/tools/fonts/SkTestTypeface.h
@@ -71,6 +71,7 @@ protected:
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor* desc) const override;
void onFilterRec(SkScalerContextRec* rec) const override;
+ void getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
SkStreamAsset* onOpenStream(int* ttcIndex) const override {