void FontFallbackList::setPlatformFont(const FontPlatformData& platformData) { m_familyIndex = cAllFamiliesScanned; ASSERT(fontCache()->generation() == m_generation); RefPtr<FontData> fontData = fontCache()->getCachedFontData(&platformData); m_fontList.append(fontData); }
static FontData* fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName) { if (!document || !document->frame()) return 0; const Settings* settings = document->frame()->settings(); if (!settings) return 0; AtomicString genericFamily; if (familyName == "-webkit-serif") genericFamily = settings->serifFontFamily(); else if (familyName == "-webkit-sans-serif") genericFamily = settings->sansSerifFontFamily(); else if (familyName == "-webkit-cursive") genericFamily = settings->cursiveFontFamily(); else if (familyName == "-webkit-fantasy") genericFamily = settings->fantasyFontFamily(); else if (familyName == "-webkit-monospace") genericFamily = settings->fixedFontFamily(); else if (familyName == "-webkit-standard") genericFamily = settings->standardFontFamily(); if (!genericFamily.isEmpty()) return fontCache()->getCachedFontData(fontCache()->getCachedFontPlatformData(fontDescription, genericFamily)); return 0; }
void FontFallbackList::setPlatformFont(const FontPlatformData& platformData) { m_familyIndex = cAllFamiliesScanned; ASSERT(fontCache()->generation() == m_generation); const FontData* fontData = fontCache()->getCachedFontData(&platformData); m_fontList.append(pair<const FontData*, bool>(fontData, fontData->isCustomFont())); }
PassRefPtr<FixedSizeFontData> FixedSizeFontData::create(const AtomicString& family, unsigned weight, bool italic) { FixedSizeFontData* fontData = new FixedSizeFontData(); fontData->m_weight = weight; fontData->m_italic = italic; LOGFONT& winFont = fontData->m_font; // The size here looks unusual. The negative number is intentional. winFont.lfHeight = -72; winFont.lfWidth = 0; winFont.lfEscapement = 0; winFont.lfOrientation = 0; winFont.lfUnderline = false; winFont.lfStrikeOut = false; winFont.lfCharSet = DEFAULT_CHARSET; winFont.lfOutPrecision = OUT_DEFAULT_PRECIS; winFont.lfQuality = CLEARTYPE_QUALITY; //DEFAULT_QUALITY; winFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; winFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; winFont.lfItalic = italic; winFont.lfWeight = FontPlatformData::adjustedGDIFontWeight(weight, family); int len = std::min(family.length(), (unsigned int)LF_FACESIZE - 1); wmemcpy(winFont.lfFaceName, family.characters(), len); winFont.lfFaceName[len] = L'\0'; fontData->m_hfont.set(CreateFontIndirect(&winFont)); HGDIOBJ oldFont = SelectObject(g_screenDC, fontData->m_hfont.get()); GetTextMetrics(g_screenDC, &fontData->m_metrics); #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) if (IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface()) { #else if (IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface()) { #endif langFontLink->GetFontCodePages(g_screenDC, fontData->m_hfont.get(), &fontData->m_codePages); fontData->m_codePages |= FontPlatformData::getKnownFontCodePages(winFont.lfFaceName); } SelectObject(g_screenDC, oldFont); return adoptRef(fontData); } static PassRefPtr<FixedSizeFontData> createFixedSizeFontData(const AtomicString& family, unsigned weight, bool italic) { FixedSizeFontDataKey key(family, weight, italic); pair<FixedSizeFontCache::iterator, bool> result = g_fixedSizeFontCache.add(key, RefPtr<FixedSizeFontData>()); if (result.second) result.first->second = FixedSizeFontData::create(family, weight, italic); return result.first->second; }
FontGlyphs::FontGlyphs(const FontPlatformData& platformData) : m_pageZero(0) , m_cachedPrimarySimpleFontData(0) , m_fontSelector(0) , m_fontSelectorVersion(0) , m_familyIndex(cAllFamiliesScanned) , m_generation(fontCache().generation()) , m_pitch(UnknownPitch) , m_loadingCustomFonts(false) , m_isForPlatformFont(true) { RefPtr<FontData> fontData = fontCache().getCachedFontData(&platformData); m_realizedFontData.append(fontData.release()); }
CSSFontSelector::~CSSFontSelector() { fontCache()->removeClient(this); deleteAllValues(m_fontFaces); deleteAllValues(m_locallyInstalledFontFaces); deleteAllValues(m_fonts); }
static FontData* fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName) { if (!document || !document->frame()) return 0; const Settings* settings = document->frame()->settings(); if (!settings) return 0; AtomicString genericFamily; UScriptCode script = fontDescription.script(); if (familyName == serifFamily) genericFamily = settings->serifFontFamily(script); else if (familyName == sansSerifFamily) genericFamily = settings->sansSerifFontFamily(script); else if (familyName == cursiveFamily) genericFamily = settings->cursiveFontFamily(script); else if (familyName == fantasyFamily) genericFamily = settings->fantasyFontFamily(script); else if (familyName == monospaceFamily) genericFamily = settings->fixedFontFamily(script); else if (familyName == pictographFamily) genericFamily = settings->pictographFontFamily(script); else if (familyName == standardFamily) genericFamily = settings->standardFontFamily(script); if (!genericFamily.isEmpty()) return fontCache()->getCachedFontData(fontDescription, genericFamily); return 0; }
PassRefPtr<OpenTypeVerticalData> FontPlatformData::verticalData() const { #if !PLATFORM(JS) ASSERT(hash()); return fontCache()->getVerticalData(String::number(hash()), *this); #endif }
void clearMemoryCaches() { #if USE(ACCELERATED_COMPOSITING) // Call textureCacheCompositingThread()->prune(0) in UI thread. BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchMessage(BlackBerry::Platform::createFunctionCallMessage(clearMemoryCachesInCompositingThread)); #endif { JSC::JSLock lock(JSC::SilenceAssertionsOnly); // This function also performs a GC. JSC::releaseExecutableMemory(*JSDOMWindow::commonJSGlobalData()); } // Clean caches after JS garbage collection because JS GC can // generate more dead resources. int capacity = pageCache()->capacity(); pageCache()->setCapacity(0); pageCache()->setCapacity(capacity); pageCache()->releaseAutoreleasedPagesNow(); CrossOriginPreflightResultCache::shared().empty(); if (!memoryCache()->disabled()) { // Evict all dead resources and prune live resources. memoryCache()->setCapacities(0, 0, 0); // Update cache capacity based on current memory status. CacheClientBlackBerry::get()->updateCacheCapacity(); } fontCache()->invalidate(); }
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const { if (m_platformData.isDisabled()) return true; // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC // merely by testing code page intersection. This seems suspect though. Can't a font only partially // cover a given code page? // FIXME: in the case that we failed to get the interface, still use the font. IMLangFontLinkType* langFontLink = fontCache()->getFontLinkInterface(); if (!langFontLink) return true; DWORD fontCodePages = m_platformData.codePages(); if (!fontCodePages) return false; DWORD acpCodePages = 0; langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages); DWORD actualCodePages; long numCharactersProcessed; while (length) { langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed); if (actualCodePages && !(actualCodePages & fontCodePages)) return false; length -= numCharactersProcessed; characters += numCharactersProcessed; } return true; }
const FontData* FontFallbackList::fontDataForCharacters(const Font* font, const UChar* characters, int length) const { // This method is only called when the primary font does not contain the characters we need. // Begin our search at position 1. unsigned realizedFontIndex = 1; const FontData* fontData = fontDataAt(font, realizedFontIndex); while (fontData && !fontData->containsCharacters(characters, length)) fontData = fontDataAt(font, ++realizedFontIndex); if (!fontData) { ASSERT(fontCache()->generation() == m_generation); fontData = fontCache()->getFontDataForCharacters(*font, characters, length); } return fontData; }
DWORD codePages() const { if (!m_codePages) { if (IMLangFontLinkType* langFontLink = fontCache()->getFontLinkInterface()) langFontLink->CodePageToCodePages(m_codePage, &m_codePages); } return m_codePages; }
FontFallbackList::FontFallbackList() : m_familyIndex(0) , m_pitch(UnknownPitch) , m_loadingCustomFonts(false) , m_fontSelector(0) , m_generation(fontCache()->generation()) { }
void WebProcess::getWebCoreStatistics(uint64_t callbackID) { StatisticsData data; // Gather JavaScript statistics. { JSLockHolder lock(JSDOMWindow::commonJSGlobalData()); data.statisticsNumbers.set("JavaScriptObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.objectCount()); data.statisticsNumbers.set("JavaScriptGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount()); data.statisticsNumbers.set("JavaScriptProtectedObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount()); data.statisticsNumbers.set("JavaScriptProtectedGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount()); OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts()); fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts); OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts()); fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts); uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size(); data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize); data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize); } WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); data.statisticsNumbers.set("FastMallocReservedVMBytes", fastMallocStatistics.reservedVMBytes); data.statisticsNumbers.set("FastMallocCommittedVMBytes", fastMallocStatistics.committedVMBytes); data.statisticsNumbers.set("FastMallocFreeListBytes", fastMallocStatistics.freeListBytes); // Gather icon statistics. data.statisticsNumbers.set("IconPageURLMappingCount", iconDatabase().pageURLMappingCount()); data.statisticsNumbers.set("IconRetainedPageURLCount", iconDatabase().retainedPageURLCount()); data.statisticsNumbers.set("IconRecordCount", iconDatabase().iconRecordCount()); data.statisticsNumbers.set("IconsWithDataCount", iconDatabase().iconRecordCountWithData()); // Gather font statistics. data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount()); data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount()); // Gather glyph page statistics. data.statisticsNumbers.set("GlyphPageCount", GlyphPageTreeNode::treeGlyphPageCount()); // Get WebCore memory cache statistics getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics); connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0); }
SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const { FontDescription fontDesc(fontDescription); fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize())); fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize())); fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize())); FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family()); return result ? new SimpleFontData(*result) : 0; }
CSSFontSelector::CSSFontSelector(Document* document) : m_document(document) { // FIXME: An old comment used to say there was no need to hold a reference to m_document // because "we are guaranteed to be destroyed before the document". But there does not // seem to be any such guarantee. ASSERT(m_document); fontCache()->addClient(this); }
void FontFallbackList::invalidate(PassRefPtr<FontSelector> fontSelector) { releaseFontData(); m_fontList.clear(); m_familyIndex = 0; m_pitch = UnknownPitch; m_loadingCustomFonts = false; m_fontSelector = fontSelector; m_generation = fontCache()->generation(); }
FontFallbackList::FontFallbackList() : m_pageZero(0) , m_cachedPrimarySimpleFontData(0) , m_fontSelector(0) , m_familyIndex(0) , m_pitch(UnknownPitch) , m_loadingCustomFonts(false) , m_generation(fontCache()->generation()) { }
void FontFallbackList::releaseFontData() { unsigned numFonts = m_fontList.size(); for (unsigned i = 0; i < numFonts; ++i) { if (!m_fontList[i]->isCustomFont()) { ASSERT(!m_fontList[i]->isSegmented()); fontCache()->releaseFontData(static_cast<const SimpleFontData*>(m_fontList[i].get())); } } }
void FontGlyphs::releaseFontData() { unsigned numFonts = m_realizedFontData.size(); for (unsigned i = 0; i < numFonts; ++i) { if (m_realizedFontData[i]->isCustomFont()) continue; ASSERT(!m_realizedFontData[i]->isSegmented()); fontCache().releaseFontData(toSimpleFontData(m_realizedFontData[i])); } }
PassRefPtr<SimpleFontData> SimpleFontData::platformCreateScaledFontData(const FontDescription& fontDescription, float scaleFactor) const { FontDescription fontDesc(fontDescription); fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize())); fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize())); fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize())); FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family()); if (!result) return 0; return SimpleFontData::create(*result); }
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { if (length != bufferLength) return false; if (fontData->platformData().hfont()) { DWORD fontCodePages = fontData->platformData().codePages(); if (fontCodePages) { if (getCharCodePages) { unsigned lastPos = 0; for (unsigned i = 0; i < bufferLength; ++i) { DWORD actualCodePages = getCharCodePages(buffer[i], lastPos); if (!actualCodePages || (actualCodePages & fontCodePages)) setGlyphDataForIndex(offset + i, buffer[i], fontData); else setGlyphDataForIndex(offset + i, buffer[i], 0); } return true; #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) } else if (IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface()) { #else } else if (IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface()) { #endif for (unsigned i = 0; i < bufferLength; ++i) { DWORD actualCodePages; langFontLink->GetCharCodePages(buffer[i], &actualCodePages); if (!actualCodePages || (actualCodePages & fontCodePages)) setGlyphDataForIndex(offset + i, buffer[i], fontData); else setGlyphDataForIndex(offset + i, buffer[i], 0); } return true; } } } for (unsigned i = 0; i < length; ++i) setGlyphDataForIndex(offset + i, buffer[i], fontData); return true; }
void FontFallbackList::releaseFontData() { unsigned numFonts = m_fontList.size(); for (unsigned i = 0; i < numFonts; ++i) { if (m_fontList[i].second) delete m_fontList[i].first; else { ASSERT(!m_fontList[i].first->isSegmented()); fontCache()->releaseFontData(static_cast<const SimpleFontData*>(m_fontList[i].first)); } } }
const FontPlatformData* ComplexTextController::getComplexFontPlatformData() { #if OS(ANDROID) FallbackScripts fallbackScript = kFallbackScriptNumber; // invalid script value. switch (m_item.item.script) { case HB_Script_Arabic: fallbackScript = kArabic_FallbackScript; break; case HB_Script_Armenian: fallbackScript = kArmenian_FallbackScript; break; case HB_Script_Bengali: fallbackScript = kBengali_FallbackScript; break; case HB_Script_Devanagari: fallbackScript = kDevanagari_FallbackScript; break; case HB_Script_Georgian: fallbackScript = kGeorgian_FallbackScript; break; case HB_Script_Hebrew: if (m_font->fontDescription().weight() >= FontWeightBold) fallbackScript = kHebrewBold_FallbackScript; else fallbackScript = kHebrewRegular_FallbackScript; break; case HB_Script_Kannada: fallbackScript = kKannada_FallbackScript; break; case HB_Script_Malayalam: fallbackScript = kMalayalam_FallbackScript; break; case HB_Script_Tamil: if (m_font->fontDescription().weight() >= FontWeightBold) fallbackScript = kTamilBold_FallbackScript; else fallbackScript = kTamilRegular_FallbackScript; break; case HB_Script_Thai: fallbackScript = kThai_FallbackScript; break; case HB_Script_Telugu: fallbackScript = kTelugu_FallbackScript; break; default: return 0; } return fontCache()->getCachedFallbackScriptFontPlatformData(m_font->fontDescription(), SkGetFallbackScriptID(fallbackScript)); #else // Only Android needs the extra logic. return NULL; #endif }
FontGlyphs::FontGlyphs(PassRefPtr<FontSelector> fontSelector) : m_pageZero(0) , m_cachedPrimarySimpleFontData(0) , m_fontSelector(fontSelector) , m_fontSelectorVersion(m_fontSelector ? m_fontSelector->version() : 0) , m_familyIndex(0) , m_generation(fontCache().generation()) , m_pitch(UnknownPitch) , m_loadingCustomFonts(false) , m_isForPlatformFont(false) { }
static const Vector<DWORD, 4>& getCJKCodePageMasks() { // The default order in which we look for a font for a CJK character. If the user's default code page is // one of these, we will use it first. static const UINT CJKCodePages[] = { 932, /* Japanese */ 936, /* Simplified Chinese */ 950, /* Traditional Chinese */ 949 /* Korean */ }; static Vector<DWORD, 4> codePageMasks; static bool initialized; if (!initialized) { initialized = true; #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface(); #else IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface(); #endif if (!langFontLink) return codePageMasks; UINT defaultCodePage; DWORD defaultCodePageMask = 0; if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE, reinterpret_cast<LPWSTR>(&defaultCodePage), sizeof(defaultCodePage))) langFontLink->CodePageToCodePages(defaultCodePage, &defaultCodePageMask); if (defaultCodePage == CJKCodePages[0] || defaultCodePage == CJKCodePages[1] || defaultCodePage == CJKCodePages[2] || defaultCodePage == CJKCodePages[3]) codePageMasks.append(defaultCodePageMask); for (unsigned i = 0; i < 4; ++i) { if (defaultCodePage != CJKCodePages[i]) { DWORD codePageMask; langFontLink->CodePageToCodePages(CJKCodePages[i], &codePageMask); codePageMasks.append(codePageMask); } } } return codePageMasks; }
PassRefPtr<FontData> CSSFontSelector::getFallbackFontData(const FontDescription& fontDescription, size_t index) { ASSERT_UNUSED(index, !index); if (!m_document) return 0; Settings* settings = m_document->settings(); if (!settings || !settings->fontFallbackPrefersPictographs()) return 0; return fontCache()->getCachedFontData(fontDescription, settings->pictographFontFamily()); }
SimpleFontData::~SimpleFontData() { #if ENABLE(SVG_FONTS) if (!m_svgFontData || !m_svgFontData->svgFontFaceElement()) #endif platformDestroy(); if (!isCustomFont()) { if (m_smallCapsFontData) fontCache()->releaseFontData(m_smallCapsFontData); GlyphPageTreeNode::pruneTreeFontData(this); } }
CSSFontSelector::CSSFontSelector(Document* document) : m_document(document) , m_beginLoadingTimer(this, &CSSFontSelector::beginLoadTimerFired) , m_uniqueId(++fontSelectorId) , m_version(0) { // FIXME: An old comment used to say there was no need to hold a reference to m_document // because "we are guaranteed to be destroyed before the document". But there does not // seem to be any such guarantee. ASSERT(m_document); fontCache()->addClient(this); }
void FontFallbackList::invalidate(PassRefPtr<FontSelector> fontSelector) { releaseFontData(); m_fontList.clear(); m_pageZero = 0; m_pages.clear(); m_cachedPrimarySimpleFontData = 0; m_familyIndex = 0; m_pitch = UnknownPitch; m_loadingCustomFonts = false; m_fontSelector = fontSelector; m_fontSelectorVersion = m_fontSelector ? m_fontSelector->version() : 0; m_generation = fontCache()->generation(); }