📄 glyphpagetreenode.cpp
字号:
if (fontData->isSegmented()) { haveGlyphs = false; const SegmentedFontData* segmentedFontData = static_cast<const SegmentedFontData*>(fontData); unsigned numRanges = segmentedFontData->numRanges(); bool zeroFilled = false; RefPtr<GlyphPage> scratchPage; GlyphPage* pageToFill = m_page.get(); for (unsigned i = 0; i < numRanges; i++) { const FontDataRange& range = segmentedFontData->rangeAt(i); int from = max(0, range.from() - static_cast<int>(start)); int to = 1 + min(range.to() - static_cast<int>(start), static_cast<int>(GlyphPage::size) - 1); if (from < static_cast<int>(GlyphPage::size) && to > 0) { if (haveGlyphs && !scratchPage) { scratchPage = GlyphPage::create(this); pageToFill = scratchPage.get(); } if (!zeroFilled) { if (from > 0 || to < static_cast<int>(GlyphPage::size)) { for (unsigned i = 0; i < GlyphPage::size; i++) pageToFill->setGlyphDataForIndex(i, 0, 0); } zeroFilled = true; } haveGlyphs |= pageToFill->fill(from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), range.fontData()); if (scratchPage) { for (int j = from; j < to; j++) { if (!m_page->m_glyphs[j].glyph && pageToFill->m_glyphs[j].glyph) m_page->m_glyphs[j] = pageToFill->m_glyphs[j]; } } } } } else haveGlyphs = m_page->fill(0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData)); if (!haveGlyphs) m_page = 0; } else if (parentPage && parentPage->owner() != m_parent) { // The page we're overriding may not be owned by our parent node. // This happens when our parent node provides no useful overrides // and just copies the pointer to an already-existing page (see // below). // // We want our override to be shared by all nodes that reference // that page to avoid duplication, and so standardize on having the // page's owner collect all the overrides. Call getChild on the // page owner with the desired font data (this will populate // the page) and then reference it. m_page = parentPage->owner()->getChild(fontData, pageNumber)->page(); } else { // Get the pure page for the fallback font (at level 1 with no // overrides). getRootChild will always create a page if one // doesn't exist, but the page doesn't necessarily have glyphs // (this pointer may be 0). GlyphPage* fallbackPage = getRootChild(fontData, pageNumber)->page(); if (!parentPage) { // When the parent has no glyphs for this page, we can easily // override it just by supplying the glyphs from our font. m_page = fallbackPage; } else if (!fallbackPage) { // When our font has no glyphs for this page, we can just reference the // parent page. m_page = parentPage; } else { // Combine the parent's glyphs and ours to form a new more complete page. m_page = GlyphPage::create(this); // Overlay the parent page on the fallback page. Check if the fallback font // has added anything. bool newGlyphs = false; for (unsigned i = 0; i < GlyphPage::size; i++) { if (parentPage->m_glyphs[i].glyph) m_page->m_glyphs[i] = parentPage->m_glyphs[i]; else if (fallbackPage->m_glyphs[i].glyph) { m_page->m_glyphs[i] = fallbackPage->m_glyphs[i]; newGlyphs = true; } else { const GlyphData data = { 0, 0 }; m_page->m_glyphs[i] = data; } } if (!newGlyphs) // We didn't override anything, so our override is just the parent page. m_page = parentPage; } } } else { m_page = GlyphPage::create(this); // System fallback. Initialized with the parent's page here, as individual // entries may use different fonts depending on character. If the Font // ever finds it needs a glyph out of the system fallback page, it will // ask the system for the best font to use and fill that glyph in for us. if (parentPage) memcpy(m_page->m_glyphs, parentPage->m_glyphs, GlyphPage::size * sizeof(m_page->m_glyphs[0])); else { const GlyphData data = { 0, 0 }; for (unsigned i = 0; i < GlyphPage::size; i++) m_page->m_glyphs[i] = data; } }}GlyphPageTreeNode* GlyphPageTreeNode::getChild(const FontData* fontData, unsigned pageNumber){ ASSERT(fontData || !m_isSystemFallback); ASSERT(pageNumber == m_pageNumber); GlyphPageTreeNode* child = fontData ? m_children.get(fontData) : m_systemFallbackChild; if (!child) { child = new GlyphPageTreeNode; child->m_parent = this; child->m_level = m_level + 1; if (fontData && fontData->isCustomFont()) { for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent) curr->m_customFontCount++; }#ifndef NDEBUG child->m_pageNumber = m_pageNumber;#endif if (fontData) { m_children.set(fontData, child); fontData->setMaxGlyphPageTreeLevel(max(fontData->maxGlyphPageTreeLevel(), child->m_level)); } else { m_systemFallbackChild = child; child->m_isSystemFallback = true; } child->initializePage(fontData, pageNumber); } return child;}void GlyphPageTreeNode::pruneCustomFontData(const FontData* fontData){ if (!fontData || !m_customFontCount) return; // Prune any branch that contains this FontData. GlyphPageTreeNode* node = m_children.get(fontData); if (node) { m_children.remove(fontData); unsigned fontCount = node->m_customFontCount + 1; delete node; for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent) curr->m_customFontCount -= fontCount; } // Check any branches that remain that still have custom fonts underneath them. if (!m_customFontCount) return; HashMap<const FontData*, GlyphPageTreeNode*>::iterator end = m_children.end(); for (HashMap<const FontData*, GlyphPageTreeNode*>::iterator it = m_children.begin(); it != end; ++it) it->second->pruneCustomFontData(fontData);}void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, unsigned level){ ASSERT(fontData); if (!fontData) return; // Prune any branch that contains this FontData. HashMap<const FontData*, GlyphPageTreeNode*>::iterator child = m_children.find(fontData); if (child == m_children.end()) { // If there is no level-1 node for fontData, then there is no deeper node for it in this tree. if (!level) return; } else { GlyphPageTreeNode* node = child->second; m_children.remove(fontData); unsigned customFontCount = node->m_customFontCount; delete node; if (customFontCount) { for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent) curr->m_customFontCount -= customFontCount; } } level++; if (level > fontData->maxGlyphPageTreeLevel()) return; HashMap<const FontData*, GlyphPageTreeNode*>::iterator end = m_children.end(); for (HashMap<const FontData*, GlyphPageTreeNode*>::iterator it = m_children.begin(); it != end; ++it) it->second->pruneFontData(fontData, level);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -