Reland "Simplify SkTypeface::charsToGlyphs API to require UTF32 input"
This is a reland of fde841de44
Original change's description:
> Simplify SkTypeface::charsToGlyphs API to require UTF32 input
>
> Change-Id: I486713c496c40103eef13fa6068ac4d69e32f606
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/207865
> Commit-Queue: Ben Wagner <bungeman@google.com>
> Reviewed-by: Ben Wagner <bungeman@google.com>
Change-Id: I5162c93b3ea6146d09334545744b791d993397b8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/208679
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
This commit is contained in:
parent
105d7c24c9
commit
64670cb1b8
@ -44,7 +44,7 @@ static void charsToGlyphs_proc(const Rec& r) {
|
||||
|
||||
SkTypeface* face = r.fFont.getTypefaceOrDefault();
|
||||
for (int i = 0; i < r.fLoops; ++i) {
|
||||
face->charsToGlyphs(r.fText, SkTypeface::kUTF32_Encoding, glyphs, r.fCount);
|
||||
face->unicharsToGlyphs(r.fText, r.fCount, glyphs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Benchmark.h"
|
||||
#include "SkFontTypes.h"
|
||||
#include "SkFont.h"
|
||||
#include "SkMakeUnique.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "SkUTF.h"
|
||||
@ -238,12 +238,12 @@ protected:
|
||||
}
|
||||
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
SkFont font(fTypeface);
|
||||
// Do more loops to reduce variance.
|
||||
for (int i = 0; i < loops * 3; ++i) {
|
||||
for (auto& line : fLines) {
|
||||
fTypeface->charsToGlyphs(line->utf.data(),
|
||||
(SkTypeface::Encoding)fEncoding, fGlyphIds.data(),
|
||||
line->glyphCount);
|
||||
font.textToGlyphs(line->utf.data(), line->utf.size(), fEncoding,
|
||||
fGlyphIds.data(), line->glyphCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,12 +33,14 @@ static SkScalar draw_string(SkAtlasTextTarget* target, const SkString& text, SkS
|
||||
auto atlas_font = SkAtlasTextFont::Make(typeface, size);
|
||||
int cnt = SkUTF::CountUTF8(text.c_str(), text.size());
|
||||
std::unique_ptr<SkGlyphID[]> glyphs(new SkGlyphID[cnt]);
|
||||
typeface->charsToGlyphs(text.c_str(), SkTypeface::Encoding::kUTF8_Encoding, glyphs.get(), cnt);
|
||||
|
||||
// Using a paint to get the positions for each glyph.
|
||||
SkFont font;
|
||||
font.setSize(size);
|
||||
font.setTypeface(std::move(typeface));
|
||||
|
||||
font.textToGlyphs(text.c_str(), text.size(), SkTextEncoding::kUTF8, glyphs.get(), cnt);
|
||||
|
||||
std::unique_ptr<SkScalar[]> widths(new SkScalar[cnt]);
|
||||
font.getWidths(glyphs.get(), cnt, widths.get());
|
||||
|
||||
|
@ -302,6 +302,8 @@ public:
|
||||
*/
|
||||
SkGlyphID unicharToGlyph(SkUnichar uni) const;
|
||||
|
||||
void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const;
|
||||
|
||||
/** Returns number of glyphs represented by text.
|
||||
|
||||
If encoding is kUTF8_SkTextEncoding, kUTF16_SkTextEncoding, or
|
||||
|
@ -9,8 +9,6 @@
|
||||
#define SkFontTypes_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
// remove me once google3 uses IWYU
|
||||
#include "SkTypeface.h"
|
||||
|
||||
enum class SkTextEncoding {
|
||||
kUTF8, //!< uses bytes to represent UTF-8 or ASCII
|
||||
@ -36,4 +34,7 @@ enum class SkFontHinting {
|
||||
#define kNormal_SkFontHinting SkFontHinting::kNormal
|
||||
#define kFull_SkFontHinting SkFontHinting::kFull
|
||||
|
||||
// remove me once google3 uses IWYU
|
||||
#include "SkTypeface.h"
|
||||
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "SkFontArguments.h"
|
||||
#include "SkFontParameters.h"
|
||||
#include "SkFontStyle.h"
|
||||
#include "SkFontTypes.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkString.h"
|
||||
|
||||
@ -176,36 +177,20 @@ public:
|
||||
*/
|
||||
static sk_sp<SkTypeface> MakeDeserialize(SkStream*);
|
||||
|
||||
enum Encoding : uint8_t {
|
||||
kUTF8_Encoding,
|
||||
kUTF16_Encoding,
|
||||
kUTF32_Encoding
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an array of character codes, of the specified encoding,
|
||||
* optionally return their corresponding glyph IDs (if glyphs is not NULL).
|
||||
* Given an array of UTF32 character codes, return their corresponding glyph IDs.
|
||||
*
|
||||
* @param chars pointer to the array of character codes
|
||||
* @param encoding how the characters are encoded
|
||||
* @param glyphs (optional) returns the corresponding glyph IDs for each
|
||||
* character code, up to glyphCount values. If a character code is
|
||||
* not found in the typeface, the corresponding glyph ID will be 0.
|
||||
* @param glyphCount number of code points in 'chars' to process. If glyphs
|
||||
* is not NULL, then it must point sufficient memory to write
|
||||
* glyphCount values into it.
|
||||
* @return the number of number of continuous non-zero glyph IDs computed
|
||||
* from the beginning of chars. This value is valid, even if the
|
||||
* glyphs parameter is NULL.
|
||||
* @param chars pointer to the array of UTF32 chars
|
||||
* @param number of chars and glyphs
|
||||
* @param glyphs returns the corresponding glyph IDs for each character.
|
||||
*/
|
||||
int charsToGlyphs(const void* chars, Encoding encoding, SkGlyphID glyphs[],
|
||||
int glyphCount) const;
|
||||
void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const;
|
||||
|
||||
/**
|
||||
* Return the glyphID that corresponds to the specified unicode code-point
|
||||
* (in UTF32 encoding). If the unichar is not supported, returns 0.
|
||||
*
|
||||
* This is a short-cut for calling charsToGlyphs() with kUTF32_Encoding for one code-point.
|
||||
* This is a short-cut for calling unicharsToGlyphs().
|
||||
*/
|
||||
SkGlyphID unicharToGlyph(SkUnichar unichar) const;
|
||||
|
||||
@ -393,8 +378,7 @@ protected:
|
||||
|
||||
virtual void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const = 0;
|
||||
|
||||
virtual int onCharsToGlyphs(const void* chars, Encoding, SkGlyphID glyphs[],
|
||||
int glyphCount) const = 0;
|
||||
virtual void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const = 0;
|
||||
virtual int onCountGlyphs() const = 0;
|
||||
|
||||
virtual int onGetUPEM() const = 0;
|
||||
|
@ -170,6 +170,46 @@ SkGlyphID SkFont::unicharToGlyph(SkUnichar uni) const {
|
||||
return this->getTypefaceOrDefault()->unicharToGlyph(uni);
|
||||
}
|
||||
|
||||
void SkFont::unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
|
||||
this->getTypefaceOrDefault()->unicharsToGlyphs(uni, count, glyphs);
|
||||
}
|
||||
|
||||
class SkConvertToUTF32 {
|
||||
public:
|
||||
SkConvertToUTF32() {}
|
||||
|
||||
const SkUnichar* convert(const void* text, size_t byteLength, SkTextEncoding encoding) {
|
||||
const SkUnichar* uni;
|
||||
switch (encoding) {
|
||||
case SkTextEncoding::kUTF8: {
|
||||
uni = fStorage.reset(byteLength);
|
||||
const char* ptr = (const char*)text;
|
||||
const char* end = ptr + byteLength;
|
||||
for (int i = 0; ptr < end; ++i) {
|
||||
fStorage[i] = SkUTF::NextUTF8(&ptr, end);
|
||||
}
|
||||
} break;
|
||||
case SkTextEncoding::kUTF16: {
|
||||
uni = fStorage.reset(byteLength);
|
||||
const uint16_t* ptr = (const uint16_t*)text;
|
||||
const uint16_t* end = ptr + (byteLength >> 1);
|
||||
for (int i = 0; ptr < end; ++i) {
|
||||
fStorage[i] = SkUTF::NextUTF16(&ptr, end);
|
||||
}
|
||||
} break;
|
||||
case SkTextEncoding::kUTF32:
|
||||
uni = (const SkUnichar*)text;
|
||||
break;
|
||||
default:
|
||||
SK_ABORT("unexpected enum");
|
||||
}
|
||||
return uni;
|
||||
}
|
||||
|
||||
private:
|
||||
SkAutoSTMalloc<256, SkUnichar> fStorage;
|
||||
};
|
||||
|
||||
int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
|
||||
SkGlyphID glyphs[], int maxGlyphCount) const {
|
||||
if (0 == byteLength) {
|
||||
@ -183,26 +223,15 @@ int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding enc
|
||||
return count;
|
||||
}
|
||||
|
||||
// TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding
|
||||
SkTypeface::Encoding typefaceEncoding;
|
||||
switch (encoding) {
|
||||
case kUTF8_SkTextEncoding:
|
||||
typefaceEncoding = SkTypeface::kUTF8_Encoding;
|
||||
break;
|
||||
case kUTF16_SkTextEncoding:
|
||||
typefaceEncoding = SkTypeface::kUTF16_Encoding;
|
||||
break;
|
||||
case kUTF32_SkTextEncoding:
|
||||
typefaceEncoding = SkTypeface::kUTF32_Encoding;
|
||||
break;
|
||||
default:
|
||||
SkASSERT(kGlyphID_SkTextEncoding == encoding);
|
||||
// we can early exit, since we already have glyphIDs
|
||||
memcpy(glyphs, text, count << 1);
|
||||
return count;
|
||||
if (encoding == SkTextEncoding::kGlyphID) {
|
||||
memcpy(glyphs, text, count << 1);
|
||||
return count;
|
||||
}
|
||||
|
||||
(void) this->getTypefaceOrDefault()->charsToGlyphs(text, typefaceEncoding, glyphs,count);
|
||||
SkConvertToUTF32 storage;
|
||||
const SkUnichar* uni = storage.convert(text, byteLength, encoding);
|
||||
|
||||
this->getTypefaceOrDefault()->unicharsToGlyphs(uni, count, glyphs);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -57,12 +57,8 @@ protected:
|
||||
return nullptr;
|
||||
}
|
||||
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
|
||||
virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t glyphs[], int glyphCount) const override {
|
||||
if (glyphs && glyphCount > 0) {
|
||||
sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
|
||||
}
|
||||
return 0;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
|
||||
sk_bzero(glyphs, count * sizeof(glyphs[0]));
|
||||
}
|
||||
int onCountGlyphs() const override { return 0; }
|
||||
int onGetUPEM() const override { return 0; }
|
||||
@ -285,23 +281,16 @@ std::unique_ptr<SkFontData> SkTypeface::onMakeFontData() const {
|
||||
return skstd::make_unique<SkFontData>(std::move(stream), index, nullptr, 0);
|
||||
};
|
||||
|
||||
int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t glyphs[], int glyphCount) const {
|
||||
if (glyphCount <= 0) {
|
||||
return 0;
|
||||
void SkTypeface::unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
|
||||
if (count > 0 && glyphs && uni) {
|
||||
this->onCharsToGlyphs(uni, count, glyphs);
|
||||
}
|
||||
if (nullptr == chars || (unsigned)encoding > kUTF32_Encoding) {
|
||||
if (glyphs) {
|
||||
sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount);
|
||||
}
|
||||
|
||||
SkGlyphID SkTypeface::unicharToGlyph(SkUnichar uni) const {
|
||||
SkGlyphID glyphs[1];
|
||||
return this->onCharsToGlyphs(&uni, kUTF32_Encoding, glyphs, 1) == 1 ? glyphs[0] : 0;
|
||||
SkGlyphID glyphs[1] = { 0 };
|
||||
this->onCharsToGlyphs(&uni, 1, glyphs);
|
||||
return glyphs[0];
|
||||
}
|
||||
|
||||
int SkTypeface::countGlyphs() const {
|
||||
|
@ -122,10 +122,8 @@ protected:
|
||||
SK_ABORT("Should never be called.");
|
||||
return nullptr;
|
||||
}
|
||||
int onCharsToGlyphs(const void* chars, Encoding,
|
||||
uint16_t glyphs[], int glyphCount) const override {
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
|
||||
SK_ABORT("Should never be called.");
|
||||
return 0;
|
||||
}
|
||||
int onCountGlyphs() const override {
|
||||
return this->glyphCount();
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define SkUtils_DEFINED
|
||||
|
||||
#include "SkOpts.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "SkFontTypes.h"
|
||||
#include "../utils/SkUTF.h"
|
||||
|
||||
/** Similar to memset(), but it assigns a 16, 32, or 64-bit value into the buffer.
|
||||
@ -42,23 +42,22 @@ static inline bool SkUTF16_IsTrailingSurrogate (uint16_t c) { return ((c) & 0xFC
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int SkUTFN_CountUnichars(SkTypeface::Encoding enc, const void* utfN, size_t bytes) {
|
||||
static inline int SkUTFN_CountUnichars(SkTextEncoding enc, const void* utfN, size_t bytes) {
|
||||
switch (enc) {
|
||||
case SkTypeface::kUTF8_Encoding: return SkUTF::CountUTF8((const char*)utfN, bytes);
|
||||
case SkTypeface::kUTF16_Encoding: return SkUTF::CountUTF16((const uint16_t*)utfN, bytes);
|
||||
case SkTypeface::kUTF32_Encoding: return SkUTF::CountUTF32((const int32_t*)utfN, bytes);
|
||||
case SkTextEncoding::kUTF8: return SkUTF::CountUTF8((const char*)utfN, bytes);
|
||||
case SkTextEncoding::kUTF16: return SkUTF::CountUTF16((const uint16_t*)utfN, bytes);
|
||||
case SkTextEncoding::kUTF32: return SkUTF::CountUTF32((const int32_t*)utfN, bytes);
|
||||
default: SkDEBUGFAIL("unknown text encoding"); return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline SkUnichar SkUTFN_Next(SkTypeface::Encoding enc,
|
||||
const void** ptr, const void* stop) {
|
||||
static inline SkUnichar SkUTFN_Next(SkTextEncoding enc, const void** ptr, const void* stop) {
|
||||
switch (enc) {
|
||||
case SkTypeface::kUTF8_Encoding:
|
||||
case SkTextEncoding::kUTF8:
|
||||
return SkUTF::NextUTF8((const char**)ptr, (const char*)stop);
|
||||
case SkTypeface::kUTF16_Encoding:
|
||||
case SkTextEncoding::kUTF16:
|
||||
return SkUTF::NextUTF16((const uint16_t**)ptr, (const uint16_t*)stop);
|
||||
case SkTypeface::kUTF32_Encoding:
|
||||
case SkTextEncoding::kUTF32:
|
||||
return SkUTF::NextUTF32((const int32_t**)ptr, (const int32_t*)stop);
|
||||
default: SkDEBUGFAIL("unknown text encoding"); return -1;
|
||||
}
|
||||
|
@ -1551,62 +1551,17 @@ void SkScalerContext_FreeType::emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph
|
||||
|
||||
#include "SkUtils.h"
|
||||
|
||||
static SkUnichar next_utf8(const void** chars) {
|
||||
return SkUTF8_NextUnichar((const char**)chars);
|
||||
}
|
||||
|
||||
static SkUnichar next_utf16(const void** chars) {
|
||||
return SkUTF16_NextUnichar((const uint16_t**)chars);
|
||||
}
|
||||
|
||||
static SkUnichar next_utf32(const void** chars) {
|
||||
const SkUnichar** uniChars = (const SkUnichar**)chars;
|
||||
SkUnichar uni = **uniChars;
|
||||
*uniChars += 1;
|
||||
return uni;
|
||||
}
|
||||
|
||||
typedef SkUnichar (*EncodingProc)(const void**);
|
||||
|
||||
static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
|
||||
static const EncodingProc gProcs[] = {
|
||||
next_utf8, next_utf16, next_utf32
|
||||
};
|
||||
SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
|
||||
return gProcs[enc];
|
||||
}
|
||||
|
||||
int SkTypeface_FreeType::onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t glyphs[], int glyphCount) const
|
||||
{
|
||||
void SkTypeface_FreeType::onCharsToGlyphs(const SkUnichar uni[], int count,
|
||||
SkGlyphID glyphs[]) const {
|
||||
AutoFTAccess fta(this);
|
||||
FT_Face face = fta.face();
|
||||
if (!face) {
|
||||
if (glyphs) {
|
||||
sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
|
||||
}
|
||||
return 0;
|
||||
sk_bzero(glyphs, count * sizeof(glyphs[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
EncodingProc next_uni_proc = find_encoding_proc(encoding);
|
||||
|
||||
if (nullptr == glyphs) {
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
if (0 == FT_Get_Char_Index(face, next_uni_proc(&chars))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return glyphCount;
|
||||
} else {
|
||||
int first = glyphCount;
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
unsigned id = FT_Get_Char_Index(face, next_uni_proc(&chars));
|
||||
glyphs[i] = SkToU16(id);
|
||||
if (0 == id && i < first) {
|
||||
first = i;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
glyphs[i] = SkToU16(FT_Get_Char_Index(face, uni[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,7 @@ protected:
|
||||
int onGetUPEM() const override;
|
||||
bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
|
||||
int32_t adjustments[]) const override;
|
||||
int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
|
||||
int glyphCount) const override;
|
||||
void onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const override;
|
||||
int onCountGlyphs() const override;
|
||||
|
||||
LocalizedStrings* onCreateFamilyNameIterator() const override;
|
||||
|
@ -742,8 +742,7 @@ protected:
|
||||
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;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
|
||||
int onCountGlyphs() const override;
|
||||
|
||||
void* onGetCTFontRef() const override { return (void*)fFontRef.get(); }
|
||||
@ -2333,9 +2332,7 @@ void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
|
||||
*isLocalStream = fIsFromStream;
|
||||
}
|
||||
|
||||
int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t glyphs[], int glyphCount) const
|
||||
{
|
||||
void SkTypeface_Mac::onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
|
||||
// Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points:
|
||||
// When a surrogate pair is detected, the glyph index used is the index of the high surrogate.
|
||||
// It is documented that if a mapping is unavailable, the glyph will be set to 0.
|
||||
@ -2343,81 +2340,38 @@ int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
SkAutoSTMalloc<1024, UniChar> charStorage;
|
||||
const UniChar* src; // UniChar is a UTF-16 16-bit code unit.
|
||||
int srcCount;
|
||||
switch (encoding) {
|
||||
case kUTF8_Encoding: {
|
||||
const char* utf8 = reinterpret_cast<const char*>(chars);
|
||||
UniChar* utf16 = charStorage.reset(2 * glyphCount);
|
||||
src = utf16;
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
SkUnichar uni = SkUTF8_NextUnichar(&utf8);
|
||||
utf16 += SkUTF::ToUTF16(uni, utf16);
|
||||
}
|
||||
srcCount = SkToInt(utf16 - src);
|
||||
break;
|
||||
}
|
||||
case kUTF16_Encoding: {
|
||||
src = reinterpret_cast<const UniChar*>(chars);
|
||||
int extra = 0;
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
if (SkUTF16_IsLeadingSurrogate(src[i + extra])) {
|
||||
++extra;
|
||||
}
|
||||
}
|
||||
srcCount = glyphCount + extra;
|
||||
break;
|
||||
}
|
||||
case kUTF32_Encoding: {
|
||||
const SkUnichar* utf32 = reinterpret_cast<const SkUnichar*>(chars);
|
||||
UniChar* utf16 = charStorage.reset(2 * glyphCount);
|
||||
src = utf16;
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
utf16 += SkUTF::ToUTF16(utf32[i], utf16);
|
||||
}
|
||||
srcCount = SkToInt(utf16 - src);
|
||||
break;
|
||||
}
|
||||
const SkUnichar* utf32 = reinterpret_cast<const SkUnichar*>(uni);
|
||||
UniChar* utf16 = charStorage.reset(2 * count);
|
||||
src = utf16;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
utf16 += SkUTF::ToUTF16(utf32[i], utf16);
|
||||
}
|
||||
srcCount = SkToInt(utf16 - src);
|
||||
|
||||
// If glyphs is nullptr, CT still needs glyph storage for finding the first failure.
|
||||
// Also, if there are any non-bmp code points, the provided 'glyphs' storage will be inadequate.
|
||||
// If there are any non-bmp code points, the provided 'glyphs' storage will be inadequate.
|
||||
SkAutoSTMalloc<1024, uint16_t> glyphStorage;
|
||||
uint16_t* macGlyphs = glyphs;
|
||||
if (nullptr == macGlyphs || srcCount > glyphCount) {
|
||||
if (srcCount > count) {
|
||||
macGlyphs = glyphStorage.reset(srcCount);
|
||||
}
|
||||
|
||||
bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef.get(), src, macGlyphs, srcCount);
|
||||
CTFontGetGlyphsForCharacters(fFontRef.get(), src, macGlyphs, srcCount);
|
||||
|
||||
// If there were any non-bmp, then copy and compact.
|
||||
// If 'glyphs' is nullptr, then compact glyphStorage in-place.
|
||||
// If all are bmp and 'glyphs' is non-nullptr, 'glyphs' already contains the compact glyphs.
|
||||
// If some are non-bmp and 'glyphs' is non-nullptr, copy and compact into 'glyphs'.
|
||||
uint16_t* compactedGlyphs = glyphs;
|
||||
if (nullptr == compactedGlyphs) {
|
||||
compactedGlyphs = macGlyphs;
|
||||
}
|
||||
if (srcCount > glyphCount) {
|
||||
// If all are bmp, 'glyphs' already contains the compact glyphs.
|
||||
// If some are non-bmp, copy and compact into 'glyphs'.
|
||||
if (srcCount > count) {
|
||||
SkASSERT(glyphs != macGlyphs);
|
||||
int extra = 0;
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
compactedGlyphs[i] = macGlyphs[i + extra];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
glyphs[i] = macGlyphs[i + extra];
|
||||
if (SkUTF16_IsLeadingSurrogate(src[i + extra])) {
|
||||
++extra;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SkASSERT(glyphs == macGlyphs);
|
||||
}
|
||||
|
||||
if (allEncoded) {
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
// If we got false, then we need to manually look for first failure.
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
if (0 == compactedGlyphs[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// Odd to get here, as we expected CT to have returned true up front.
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
int SkTypeface_Mac::onCountGlyphs() const {
|
||||
|
@ -267,8 +267,7 @@ protected:
|
||||
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,
|
||||
uint16_t glyphs[], int glyphCount) const override;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
|
||||
int onCountGlyphs() const override;
|
||||
int onGetUPEM() const override;
|
||||
void onGetFamilyName(SkString* familyName) const override;
|
||||
@ -1917,8 +1916,8 @@ private:
|
||||
};
|
||||
#define SkAutoHDC(...) SK_REQUIRE_LOCAL_VAR(SkAutoHDC)
|
||||
|
||||
int LogFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t userGlyphs[], int glyphCount) const
|
||||
void LogFontTypeface::onCharsToGlyphs(const SkUnichar uni[], int glyphCount,
|
||||
SkGlyphID glyphs[]) const
|
||||
{
|
||||
SkAutoHDC hdc(fLogFont);
|
||||
|
||||
@ -1931,119 +1930,35 @@ int LogFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
}
|
||||
bool Ox1FHack = !(tm.tmPitchAndFamily & TMPF_VECTOR) /*&& winVer < Vista */;
|
||||
|
||||
SkAutoSTMalloc<256, uint16_t> scratchGlyphs;
|
||||
uint16_t* glyphs;
|
||||
if (userGlyphs != nullptr) {
|
||||
glyphs = userGlyphs;
|
||||
} else {
|
||||
glyphs = scratchGlyphs.reset(glyphCount);
|
||||
}
|
||||
|
||||
SCRIPT_CACHE sc = 0;
|
||||
switch (encoding) {
|
||||
case SkTypeface::kUTF8_Encoding: {
|
||||
static const int scratchCount = 256;
|
||||
WCHAR scratch[scratchCount];
|
||||
int glyphIndex = 0;
|
||||
const char* currentUtf8 = reinterpret_cast<const char*>(chars);
|
||||
SkUnichar currentChar = 0;
|
||||
if (glyphCount) {
|
||||
currentChar = SkUTF8_NextUnichar(¤tUtf8);
|
||||
static const int scratchCount = 256;
|
||||
WCHAR scratch[scratchCount];
|
||||
int glyphIndex = 0;
|
||||
const uint32_t* utf32 = reinterpret_cast<const uint32_t*>(uni);
|
||||
while (glyphIndex < glyphCount) {
|
||||
// Try a run of bmp.
|
||||
int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
|
||||
int runLength = 0;
|
||||
while (runLength < glyphsLeft && utf32[glyphIndex + runLength] <= 0xFFFF) {
|
||||
scratch[runLength] = static_cast<WCHAR>(utf32[glyphIndex + runLength]);
|
||||
++runLength;
|
||||
}
|
||||
if (runLength) {
|
||||
bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], Ox1FHack);
|
||||
glyphIndex += runLength;
|
||||
}
|
||||
while (glyphIndex < glyphCount) {
|
||||
// Try a run of bmp.
|
||||
int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
|
||||
int runLength = 0;
|
||||
while (runLength < glyphsLeft && currentChar <= 0xFFFF) {
|
||||
scratch[runLength] = static_cast<WCHAR>(currentChar);
|
||||
++runLength;
|
||||
if (runLength < glyphsLeft) {
|
||||
currentChar = SkUTF8_NextUnichar(¤tUtf8);
|
||||
}
|
||||
}
|
||||
if (runLength) {
|
||||
bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], Ox1FHack);
|
||||
glyphIndex += runLength;
|
||||
}
|
||||
|
||||
// Try a run of non-bmp.
|
||||
while (glyphIndex < glyphCount && currentChar > 0xFFFF) {
|
||||
SkUTF::ToUTF16(currentChar, reinterpret_cast<uint16_t*>(scratch));
|
||||
glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
|
||||
++glyphIndex;
|
||||
if (glyphIndex < glyphCount) {
|
||||
currentChar = SkUTF8_NextUnichar(¤tUtf8);
|
||||
}
|
||||
}
|
||||
// Try a run of non-bmp.
|
||||
while (glyphIndex < glyphCount && utf32[glyphIndex] > 0xFFFF) {
|
||||
SkUTF::ToUTF16(utf32[glyphIndex], reinterpret_cast<uint16_t*>(scratch));
|
||||
glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
|
||||
++glyphIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SkTypeface::kUTF16_Encoding: {
|
||||
int glyphIndex = 0;
|
||||
const WCHAR* currentUtf16 = reinterpret_cast<const WCHAR*>(chars);
|
||||
while (glyphIndex < glyphCount) {
|
||||
// Try a run of bmp.
|
||||
int glyphsLeft = glyphCount - glyphIndex;
|
||||
int runLength = 0;
|
||||
while (runLength < glyphsLeft && !SkUTF16_IsLeadingSurrogate(currentUtf16[runLength])) {
|
||||
++runLength;
|
||||
}
|
||||
if (runLength) {
|
||||
bmpCharsToGlyphs(hdc, currentUtf16, runLength, &glyphs[glyphIndex], Ox1FHack);
|
||||
glyphIndex += runLength;
|
||||
currentUtf16 += runLength;
|
||||
}
|
||||
|
||||
// Try a run of non-bmp.
|
||||
while (glyphIndex < glyphCount && SkUTF16_IsLeadingSurrogate(*currentUtf16)) {
|
||||
glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, currentUtf16);
|
||||
++glyphIndex;
|
||||
currentUtf16 += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SkTypeface::kUTF32_Encoding: {
|
||||
static const int scratchCount = 256;
|
||||
WCHAR scratch[scratchCount];
|
||||
int glyphIndex = 0;
|
||||
const uint32_t* utf32 = reinterpret_cast<const uint32_t*>(chars);
|
||||
while (glyphIndex < glyphCount) {
|
||||
// Try a run of bmp.
|
||||
int glyphsLeft = SkTMin(glyphCount - glyphIndex, scratchCount);
|
||||
int runLength = 0;
|
||||
while (runLength < glyphsLeft && utf32[glyphIndex + runLength] <= 0xFFFF) {
|
||||
scratch[runLength] = static_cast<WCHAR>(utf32[glyphIndex + runLength]);
|
||||
++runLength;
|
||||
}
|
||||
if (runLength) {
|
||||
bmpCharsToGlyphs(hdc, scratch, runLength, &glyphs[glyphIndex], Ox1FHack);
|
||||
glyphIndex += runLength;
|
||||
}
|
||||
|
||||
// Try a run of non-bmp.
|
||||
while (glyphIndex < glyphCount && utf32[glyphIndex] > 0xFFFF) {
|
||||
SkUTF::ToUTF16(utf32[glyphIndex], reinterpret_cast<uint16_t*>(scratch));
|
||||
glyphs[glyphIndex] = nonBmpCharToGlyph(hdc, &sc, scratch);
|
||||
++glyphIndex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SK_ABORT("Invalid Text Encoding");
|
||||
}
|
||||
|
||||
if (sc) {
|
||||
::ScriptFreeCache(&sc);
|
||||
}
|
||||
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
if (0 == glyphs[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
int LogFontTypeface::onCountGlyphs() const {
|
||||
|
@ -52,78 +52,9 @@ void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
|
||||
*isLocalStream = SkToBool(fDWriteFontFileLoader.get());
|
||||
}
|
||||
|
||||
static SkUnichar next_utf8(const void** chars) {
|
||||
return SkUTF8_NextUnichar((const char**)chars);
|
||||
}
|
||||
|
||||
static SkUnichar next_utf16(const void** chars) {
|
||||
return SkUTF16_NextUnichar((const uint16_t**)chars);
|
||||
}
|
||||
|
||||
static SkUnichar next_utf32(const void** chars) {
|
||||
const SkUnichar** uniChars = (const SkUnichar**)chars;
|
||||
SkUnichar uni = **uniChars;
|
||||
*uniChars += 1;
|
||||
return uni;
|
||||
}
|
||||
|
||||
typedef SkUnichar (*EncodingProc)(const void**);
|
||||
|
||||
static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
|
||||
static const EncodingProc gProcs[] = {
|
||||
next_utf8, next_utf16, next_utf32
|
||||
};
|
||||
SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
|
||||
return gProcs[enc];
|
||||
}
|
||||
|
||||
int DWriteFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t glyphs[], int glyphCount) const
|
||||
{
|
||||
if (nullptr == glyphs) {
|
||||
EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
const SkUnichar c = next_ucs4_proc(&chars);
|
||||
BOOL exists;
|
||||
fDWriteFont->HasCharacter(c, &exists);
|
||||
if (!exists) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
switch (encoding) {
|
||||
case SkTypeface::kUTF8_Encoding:
|
||||
case SkTypeface::kUTF16_Encoding: {
|
||||
static const int scratchCount = 256;
|
||||
UINT32 scratch[scratchCount];
|
||||
EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
|
||||
for (int baseGlyph = 0; baseGlyph < glyphCount; baseGlyph += scratchCount) {
|
||||
int glyphsLeft = glyphCount - baseGlyph;
|
||||
int limit = SkTMin(glyphsLeft, scratchCount);
|
||||
for (int i = 0; i < limit; ++i) {
|
||||
scratch[i] = next_ucs4_proc(&chars);
|
||||
}
|
||||
fDWriteFontFace->GetGlyphIndices(scratch, limit, &glyphs[baseGlyph]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SkTypeface::kUTF32_Encoding: {
|
||||
const UINT32* utf32 = reinterpret_cast<const UINT32*>(chars);
|
||||
fDWriteFontFace->GetGlyphIndices(utf32, glyphCount, glyphs);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SK_ABORT("Invalid Text Encoding");
|
||||
}
|
||||
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
if (0 == glyphs[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return glyphCount;
|
||||
void DWriteFontTypeface::onCharsToGlyphs(const SkUnichar uni[], int count,
|
||||
SkGlyphID glyphs[]) const {
|
||||
fDWriteFontFace->GetGlyphIndices((const UINT32*)uni, count, glyphs);
|
||||
}
|
||||
|
||||
int DWriteFontTypeface::onCountGlyphs() const {
|
||||
|
@ -116,8 +116,7 @@ protected:
|
||||
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,
|
||||
uint16_t glyphs[], int glyphCount) const override;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
|
||||
int onCountGlyphs() const override;
|
||||
int onGetUPEM() const override;
|
||||
void onGetFamilyName(SkString* familyName) const override;
|
||||
|
@ -69,50 +69,6 @@ static void test_countGlyphs(skiatest::Reporter* reporter, const sk_sp<SkTypefac
|
||||
}
|
||||
}
|
||||
|
||||
// The following three are all the same code points in various encodings.
|
||||
// a中Яיו𝄞a𠮟
|
||||
static uint8_t utf8Chars[] = { 0x61, 0xE4,0xB8,0xAD, 0xD0,0xAF, 0xD7,0x99, 0xD7,0x95, 0xF0,0x9D,0x84,0x9E, 0x61, 0xF0,0xA0,0xAE,0x9F };
|
||||
static uint16_t utf16Chars[] = { 0x0061, 0x4E2D, 0x042F, 0x05D9, 0x05D5, 0xD834,0xDD1E, 0x0061, 0xD842,0xDF9F };
|
||||
static uint32_t utf32Chars[] = { 0x00000061, 0x00004E2D, 0x0000042F, 0x000005D9, 0x000005D5, 0x0001D11E, 0x00000061, 0x00020B9F };
|
||||
|
||||
struct CharsToGlyphs_TestData {
|
||||
const void* chars;
|
||||
int charCount;
|
||||
size_t charsByteLength;
|
||||
SkTypeface::Encoding typefaceEncoding;
|
||||
const char* name;
|
||||
} static charsToGlyphs_TestData[] = {
|
||||
{ utf8Chars, 8, sizeof(utf8Chars), SkTypeface::kUTF8_Encoding, "Simple UTF-8" },
|
||||
{ utf16Chars, 8, sizeof(utf16Chars), SkTypeface::kUTF16_Encoding, "Simple UTF-16" },
|
||||
{ utf32Chars, 8, sizeof(utf32Chars), SkTypeface::kUTF32_Encoding, "Simple UTF-32" },
|
||||
};
|
||||
|
||||
// Test that SkPaint::textToGlyphs agrees with SkTypeface::charsToGlyphs.
|
||||
static void test_charsToGlyphs(skiatest::Reporter* reporter, sk_sp<SkTypeface> face) {
|
||||
uint16_t paintGlyphIds[256];
|
||||
uint16_t faceGlyphIds[256];
|
||||
|
||||
for (size_t testIndex = 0; testIndex < SK_ARRAY_COUNT(charsToGlyphs_TestData); ++testIndex) {
|
||||
CharsToGlyphs_TestData& test = charsToGlyphs_TestData[testIndex];
|
||||
SkTextEncoding encoding = static_cast<SkTextEncoding>(test.typefaceEncoding);
|
||||
|
||||
SkFont font(face);
|
||||
font.textToGlyphs(test.chars, test.charsByteLength, encoding,
|
||||
paintGlyphIds, SK_ARRAY_COUNT(paintGlyphIds));
|
||||
|
||||
face->charsToGlyphs(test.chars, test.typefaceEncoding, faceGlyphIds, test.charCount);
|
||||
|
||||
for (int i = 0; i < test.charCount; ++i) {
|
||||
SkString name;
|
||||
face->getFamilyName(&name);
|
||||
SkString a;
|
||||
a.appendf("%s, paintGlyphIds[%d] = %d, faceGlyphIds[%d] = %d, face = %s",
|
||||
test.name, i, (int)paintGlyphIds[i], i, (int)faceGlyphIds[i], name.c_str());
|
||||
REPORTER_ASSERT(reporter, paintGlyphIds[i] == faceGlyphIds[i], a.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_fontstream(skiatest::Reporter* reporter, SkStream* stream, int ttcIndex) {
|
||||
int n = SkFontStream::GetTableTags(stream, ttcIndex, nullptr);
|
||||
SkAutoTArray<SkFontTableTag> array(n);
|
||||
@ -230,7 +186,6 @@ static void test_tables(skiatest::Reporter* reporter) {
|
||||
test_tables(reporter, face);
|
||||
test_unitsPerEm(reporter, face);
|
||||
test_countGlyphs(reporter, face);
|
||||
test_charsToGlyphs(reporter, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,12 +136,8 @@ static void test_matchStyleCSS3(skiatest::Reporter* reporter) {
|
||||
return nullptr;
|
||||
}
|
||||
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
|
||||
virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
|
||||
uint16_t glyphs[], int glyphCount) const override {
|
||||
if (glyphs && glyphCount > 0) {
|
||||
sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
|
||||
}
|
||||
return 0;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
|
||||
sk_bzero(glyphs, count * sizeof(glyphs[0]));
|
||||
}
|
||||
int onCountGlyphs() const override { return 0; }
|
||||
int onGetUPEM() const override { return 0; }
|
||||
|
@ -21,90 +21,6 @@
|
||||
#include "Test.h"
|
||||
#undef ASSERT
|
||||
|
||||
static size_t uni_to_utf8(const SkUnichar src[], void* dst, int count) {
|
||||
char* u8 = (char*)dst;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int n = SkToInt(SkUTF::ToUTF8(src[i], u8));
|
||||
u8 += n;
|
||||
}
|
||||
return u8 - (char*)dst;
|
||||
}
|
||||
|
||||
static size_t uni_to_utf16(const SkUnichar src[], void* dst, int count) {
|
||||
uint16_t* u16 = (uint16_t*)dst;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int n = SkToInt(SkUTF::ToUTF16(src[i], u16));
|
||||
u16 += n;
|
||||
}
|
||||
return (char*)u16 - (char*)dst;
|
||||
}
|
||||
|
||||
static size_t uni_to_utf32(const SkUnichar src[], void* dst, int count) {
|
||||
SkUnichar* u32 = (SkUnichar*)dst;
|
||||
if (src != u32) {
|
||||
memcpy(u32, src, count * sizeof(SkUnichar));
|
||||
}
|
||||
return count * sizeof(SkUnichar);
|
||||
}
|
||||
|
||||
static int find_first_zero(const uint16_t glyphs[], int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (0 == glyphs[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
DEF_TEST(Paint_cmap, reporter) {
|
||||
// need to implement charsToGlyphs on other backends (e.g. linux, win)
|
||||
// before we can run this tests everywhere
|
||||
return;
|
||||
|
||||
static const int NGLYPHS = 64;
|
||||
|
||||
SkUnichar src[NGLYPHS];
|
||||
SkUnichar dst[NGLYPHS]; // used for utf8, utf16, utf32 storage
|
||||
|
||||
static const struct {
|
||||
size_t (*fSeedTextProc)(const SkUnichar[], void* dst, int count);
|
||||
SkTextEncoding fEncoding;
|
||||
} gRec[] = {
|
||||
{ uni_to_utf8, kUTF8_SkTextEncoding },
|
||||
{ uni_to_utf16, kUTF16_SkTextEncoding },
|
||||
{ uni_to_utf32, kUTF32_SkTextEncoding },
|
||||
};
|
||||
|
||||
SkRandom rand;
|
||||
SkFont font;
|
||||
font.setTypeface(SkTypeface::MakeDefault());
|
||||
SkTypeface* face = font.getTypefaceOrDefault();
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
// generate some random text
|
||||
for (int j = 0; j < NGLYPHS; ++j) {
|
||||
src[j] = ' ' + j;
|
||||
}
|
||||
// inject some random chars, to sometimes abort early
|
||||
src[rand.nextU() & 63] = rand.nextU() & 0xFFF;
|
||||
|
||||
for (size_t k = 0; k < SK_ARRAY_COUNT(gRec); ++k) {
|
||||
size_t len = gRec[k].fSeedTextProc(src, dst, NGLYPHS);
|
||||
|
||||
uint16_t glyphs0[NGLYPHS], glyphs1[NGLYPHS];
|
||||
|
||||
int nglyphs = font.textToGlyphs(dst, len, gRec[k].fEncoding, glyphs0, NGLYPHS);
|
||||
int first = face->charsToGlyphs(dst, (SkTypeface::Encoding)gRec[k].fEncoding,
|
||||
glyphs1, NGLYPHS);
|
||||
int index = find_first_zero(glyphs1, NGLYPHS);
|
||||
|
||||
REPORTER_ASSERT(reporter, NGLYPHS == nglyphs);
|
||||
REPORTER_ASSERT(reporter, index == first);
|
||||
REPORTER_ASSERT(reporter, 0 == memcmp(glyphs0, glyphs1, NGLYPHS * sizeof(uint16_t)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// temparary api for bicubic, just be sure we can set/clear it
|
||||
DEF_TEST(Paint_filterQuality, reporter) {
|
||||
SkPaint p0, p1;
|
||||
|
@ -496,7 +496,8 @@ sk_sp<SkTextBlob> make_blob_causing_fallback(
|
||||
SkASSERT(runBuffer.utf8text == nullptr);
|
||||
SkASSERT(runBuffer.clusters == nullptr);
|
||||
|
||||
glyphTf->charsToGlyphs(s, SkTypeface::kUTF8_Encoding, runBuffer.glyphs, runSize);
|
||||
SkFont(sk_ref_sp(glyphTf)).textToGlyphs(s, strlen(s), SkTextEncoding::kUTF8,
|
||||
runBuffer.glyphs, runSize);
|
||||
|
||||
SkRect glyphBounds;
|
||||
font.getWidths(runBuffer.glyphs, 1, nullptr, &glyphBounds);
|
||||
|
@ -182,11 +182,8 @@ void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal
|
||||
fProxy->getFontDescriptor(desc, isLocal);
|
||||
}
|
||||
|
||||
int SkRandomTypeface::onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
uint16_t glyphs[],
|
||||
int glyphCount) const {
|
||||
return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
|
||||
void SkRandomTypeface::onCharsToGlyphs(const SkUnichar* uni, int count, SkGlyphID glyphs[]) const {
|
||||
fProxy->unicharsToGlyphs(uni, count, glyphs);
|
||||
}
|
||||
|
||||
int SkRandomTypeface::onCountGlyphs() const { return fProxy->countGlyphs(); }
|
||||
|
@ -33,10 +33,7 @@ protected:
|
||||
sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override;
|
||||
void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const override;
|
||||
|
||||
int onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
uint16_t glyphs[],
|
||||
int glyphCount) const override;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
|
||||
int onCountGlyphs() const override;
|
||||
int onGetUPEM() const override;
|
||||
|
||||
|
@ -30,14 +30,8 @@ protected:
|
||||
return nullptr;
|
||||
}
|
||||
void onGetFontDescriptor(SkFontDescriptor*, bool*) const override {}
|
||||
virtual int onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
uint16_t glyphs[],
|
||||
int glyphCount) const override {
|
||||
if (glyphs && glyphCount > 0) {
|
||||
sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
|
||||
}
|
||||
return 0;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
|
||||
sk_bzero(glyphs, count * sizeof(glyphs[0]));
|
||||
}
|
||||
int onCountGlyphs() const override { return 0; }
|
||||
int onGetUPEM() const override { return 0; }
|
||||
|
@ -150,27 +150,11 @@ void TestSVGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal)
|
||||
*isLocal = false;
|
||||
}
|
||||
|
||||
int TestSVGTypeface::onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
uint16_t glyphs[],
|
||||
int glyphCount) const {
|
||||
auto utf8 = (const char*)chars;
|
||||
auto utf16 = (const uint16_t*)chars;
|
||||
auto utf32 = (const SkUnichar*)chars;
|
||||
|
||||
for (int i = 0; i < glyphCount; i++) {
|
||||
SkUnichar ch;
|
||||
switch (encoding) {
|
||||
case kUTF8_Encoding: ch = SkUTF8_NextUnichar(&utf8); break;
|
||||
case kUTF16_Encoding: ch = SkUTF16_NextUnichar(&utf16); break;
|
||||
case kUTF32_Encoding: ch = *utf32++; break;
|
||||
}
|
||||
if (glyphs) {
|
||||
SkGlyphID* g = fCMap.find(ch);
|
||||
glyphs[i] = g ? *g : 0;
|
||||
}
|
||||
void TestSVGTypeface::onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
|
||||
for (int i = 0; i < count; i++) {
|
||||
SkGlyphID* g = fCMap.find(uni[i]);
|
||||
glyphs[i] = g ? *g : 0;
|
||||
}
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
void TestSVGTypeface::onGetFamilyName(SkString* familyName) const { *familyName = fName; }
|
||||
|
@ -94,10 +94,7 @@ protected:
|
||||
|
||||
void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
|
||||
|
||||
int onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
uint16_t glyphs[],
|
||||
int glyphCount) const override;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
|
||||
|
||||
int onCountGlyphs() const override { return fGlyphCount; }
|
||||
|
||||
|
@ -132,26 +132,10 @@ void TestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) co
|
||||
*isLocal = false;
|
||||
}
|
||||
|
||||
int TestTypeface::onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
SkGlyphID glyphs[],
|
||||
int glyphCount) const {
|
||||
auto utf8 = (const char*)chars;
|
||||
auto utf16 = (const uint16_t*)chars;
|
||||
auto utf32 = (const SkUnichar*)chars;
|
||||
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
SkUnichar ch;
|
||||
switch (encoding) {
|
||||
case kUTF8_Encoding: ch = SkUTF8_NextUnichar(&utf8); break;
|
||||
case kUTF16_Encoding: ch = SkUTF16_NextUnichar(&utf16); break;
|
||||
case kUTF32_Encoding: ch = *utf32++; break;
|
||||
}
|
||||
if (glyphs) {
|
||||
glyphs[i] = fTestFont->glyphForUnichar(ch);
|
||||
}
|
||||
void TestTypeface::onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
glyphs[i] = fTestFont->glyphForUnichar(uni[i]);
|
||||
}
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
void TestTypeface::onGetFamilyName(SkString* familyName) const { *familyName = fTestFont->fName; }
|
||||
|
@ -83,10 +83,7 @@ protected:
|
||||
|
||||
void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
|
||||
|
||||
int onCharsToGlyphs(const void* chars,
|
||||
Encoding encoding,
|
||||
uint16_t glyphs[],
|
||||
int glyphCount) const override;
|
||||
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
|
||||
|
||||
int onCountGlyphs() const override { return (int)fTestFont->fCharCodesCount; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user