static FILE* fopen_win(const char* utf8path, const char* perm) { if (is_ascii(utf8path)) { return fopen(utf8path, perm); } const char* ptr = utf8path; const char* end = utf8path + strlen(utf8path); size_t n = 0; while (ptr < end) { SkUnichar u = SkUTF8_NextUnicharWithError(&ptr, end); if (u < 0) { return nullptr; // malformed UTF-8 } n += SkUTF16_FromUnichar(u); } std::vector<uint16_t> wchars(n + 1); uint16_t* out = wchars.data(); for (const char* ptr = utf8path; ptr < end;) { out += SkUTF16_FromUnichar(SkUTF8_NextUnicharWithError(&ptr, end), out); } SkASSERT(out == &wchars[n]); *out = 0; // final null wchar_t wperms[4] = {(wchar_t)perm[0], (wchar_t)perm[1], (wchar_t)perm[2], (wchar_t)perm[3]}; return _wfopen((wchar_t*)wchars.data(), wperms); }
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(SkUTF16_FromUnichar(src[i], u16)); u16 += n; } return (char*)u16 - (char*)dst; }
static hb_bool_t harfbuzzGetGlyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData) { SkPaint* paint = reinterpret_cast<SkPaint*>(fontData); paint->setTextEncoding(SkPaint::kUTF16_TextEncoding); uint16_t text[4]; size_t length = SkUTF16_FromUnichar(unicode, text); uint16_t glyph16; paint->textToGlyphs(text, length, &glyph16); *glyph = glyph16; return !!*glyph; }
static void test_utf16(skiatest::Reporter* reporter) { static const SkUnichar gUni[] = { 0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234 }; uint16_t buf[2]; for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) { size_t count = SkUTF16_FromUnichar(gUni[i], buf); REPORTER_ASSERT(reporter, count == 2); size_t count2 = SkUTF16_CountUnichars(buf, 2); REPORTER_ASSERT(reporter, count2 == 1); const uint16_t* ptr = buf; SkUnichar c = SkUTF16_NextUnichar(&ptr); REPORTER_ASSERT(reporter, c == gUni[i]); REPORTER_ASSERT(reporter, ptr - buf == 2); } }
SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style, const char* bcp47[], int bcp47Count, SkUnichar character) const { const DWriteStyle dwStyle(style); const WCHAR* dwFamilyName = nullptr; SkSMallocWCHAR dwFamilyNameLocal; if (familyName) { HRN(sk_cstring_to_wchar(familyName, &dwFamilyNameLocal)); dwFamilyName = dwFamilyNameLocal; } WCHAR str[16]; UINT32 strLen = static_cast<UINT32>( SkUTF16_FromUnichar(character, reinterpret_cast<uint16_t*>(str))); const SkSMallocWCHAR* dwBcp47; SkSMallocWCHAR dwBcp47Local; if (bcp47Count < 1) { dwBcp47 = &fLocaleName; } else { // TODO: support fallback stack. // TODO: DirectWrite supports 'zh-CN' or 'zh-Hans', but 'zh' misses completely // and may produce a Japanese font. HRN(sk_cstring_to_wchar(bcp47[bcp47Count - 1], &dwBcp47Local)); dwBcp47 = &dwBcp47Local; } if (fFactory2.get()) { SkTScopedComPtr<IDWriteFontFallback> systemFontFallback; IDWriteFontFallback* fontFallback = fFontFallback.get(); if (!fontFallback) { HRNM(fFactory2->GetSystemFontFallback(&systemFontFallback), "Could not get system fallback."); fontFallback = systemFontFallback.get(); } SkTScopedComPtr<IDWriteNumberSubstitution> numberSubstitution; HRNM(fFactory2->CreateNumberSubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, nullptr, TRUE, &numberSubstitution), "Could not create number substitution."); SkTScopedComPtr<FontFallbackSource> fontFallbackSource( new FontFallbackSource(str, strLen, *dwBcp47, numberSubstitution.get())); UINT32 mappedLength; SkTScopedComPtr<IDWriteFont> font; FLOAT scale; HRNM(fontFallback->MapCharacters(fontFallbackSource.get(), 0, // textPosition, strLen, fFontCollection.get(), dwFamilyName, dwStyle.fWeight, dwStyle.fSlant, dwStyle.fWidth, &mappedLength, &font, &scale), "Could not map characters"); if (!font.get()) { return nullptr; } SkTScopedComPtr<IDWriteFontFace> fontFace; HRNM(font->CreateFontFace(&fontFace), "Could not get font face from font."); SkTScopedComPtr<IDWriteFontFamily> fontFamily; HRNM(font->GetFontFamily(&fontFamily), "Could not get family from font."); return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get()); } SkTScopedComPtr<IDWriteTextFormat> fallbackFormat; HRNM(fFactory->CreateTextFormat(dwFamilyName ? dwFamilyName : L"", fFontCollection.get(), dwStyle.fWeight, dwStyle.fSlant, dwStyle.fWidth, 72.0f, *dwBcp47, &fallbackFormat), "Could not create text format."); SkTScopedComPtr<IDWriteTextLayout> fallbackLayout; HRNM(fFactory->CreateTextLayout(str, strLen, fallbackFormat.get(), 200.0f, 200.0f, &fallbackLayout), "Could not create text layout."); SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer( new FontFallbackRenderer(this, character)); HRNM(fallbackLayout->Draw(nullptr, fontFallbackRenderer.get(), 50.0f, 50.0f), "Could not draw layout with renderer."); return fontFallbackRenderer->FallbackTypeface(); }