Modified: trunk/Source/WebCore/platform/graphics/GlyphPage.h (143600 => 143601)
--- trunk/Source/WebCore/platform/graphics/GlyphPage.h 2013-02-21 15:38:04 UTC (rev 143600)
+++ trunk/Source/WebCore/platform/graphics/GlyphPage.h 2013-02-21 15:44:02 UTC (rev 143601)
@@ -53,6 +53,11 @@
const SimpleFontData* fontData;
};
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
+#endif
+
// A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous
// range of characters in the Unicode code space. GlyphPages are indexed
// starting from 0 and incrementing for each 256 glyphs.
@@ -63,33 +68,33 @@
// to be overriding the parent's node, but provide no additional information.
class GlyphPage : public RefCounted<GlyphPage> {
public:
- static PassRefPtr<GlyphPage> createUninitialized(GlyphPageTreeNode* owner)
+ static PassRefPtr<GlyphPage> createForMixedFontData(GlyphPageTreeNode* owner)
{
- return adoptRef(new GlyphPage(owner, false));
+ void* slot = fastMalloc(sizeof(GlyphPage) + sizeof(SimpleFontData*) * GlyphPage::size);
+ return adoptRef(new (slot) GlyphPage(owner));
}
- static PassRefPtr<GlyphPage> createZeroedSystemFallbackPage(GlyphPageTreeNode* owner)
+ static PassRefPtr<GlyphPage> createForSingleFontData(GlyphPageTreeNode* owner, const SimpleFontData* fontData)
{
- return adoptRef(new GlyphPage(owner, true));
+ ASSERT(fontData);
+ return adoptRef(new GlyphPage(owner, fontData));
}
PassRefPtr<GlyphPage> createCopiedSystemFallbackPage(GlyphPageTreeNode* owner) const
{
- RefPtr<GlyphPage> page = GlyphPage::createUninitialized(owner);
+ RefPtr<GlyphPage> page = GlyphPage::createForMixedFontData(owner);
memcpy(page->m_glyphs, m_glyphs, sizeof(m_glyphs));
- page->m_fontDataForAllGlyphs = m_fontDataForAllGlyphs;
- if (m_perGlyphFontData) {
- page->m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*)));
- memcpy(page->m_perGlyphFontData, m_perGlyphFontData, size * sizeof(SimpleFontData*));
+ if (hasPerGlyphFontData())
+ memcpy(page->m_perGlyphFontData, m_perGlyphFontData, sizeof(SimpleFontData*) * GlyphPage::size);
+ else {
+ for (size_t i = 0; i < GlyphPage::size; ++i) {
+ page->m_perGlyphFontData[i] = m_glyphs[i] ? m_fontDataForAllGlyphs : 0;
+ }
}
return page.release();
}
- ~GlyphPage()
- {
- if (m_perGlyphFontData)
- fastFree(m_perGlyphFontData);
- }
+ ~GlyphPage() { }
static const size_t size = 256; // Covers Latin-1 in a single page.
@@ -103,11 +108,9 @@
{
ASSERT_WITH_SECURITY_IMPLICATION(index < size);
Glyph glyph = m_glyphs[index];
- if (m_perGlyphFontData)
+ if (hasPerGlyphFontData())
return GlyphData(glyph, m_perGlyphFontData[index]);
- if (!glyph)
- return GlyphData(0, 0);
- return GlyphData(glyph, m_fontDataForAllGlyphs);
+ return GlyphData(glyph, glyph ? m_fontDataForAllGlyphs : 0);
}
Glyph glyphAt(unsigned index) const
@@ -119,12 +122,9 @@
const SimpleFontData* fontDataForCharacter(UChar32 c) const
{
unsigned index = indexForCharacter(c);
- if (m_perGlyphFontData)
+ if (hasPerGlyphFontData())
return m_perGlyphFontData[index];
- Glyph glyph = m_glyphs[index];
- if (!glyph)
- return 0;
- return m_fontDataForAllGlyphs;
+ return m_glyphs[index] ? m_fontDataForAllGlyphs : 0;
}
void setGlyphDataForCharacter(UChar32 c, Glyph g, const SimpleFontData* f)
@@ -138,29 +138,13 @@
m_glyphs[index] = glyph;
// GlyphPage getters will always return a null SimpleFontData* for glyph #0 if there's no per-glyph font array.
- if (m_perGlyphFontData) {
+ if (hasPerGlyphFontData()) {
m_perGlyphFontData[index] = glyph ? fontData : 0;
return;
}
- if (!glyph)
- return;
-
- // A glyph index without a font data pointer makes no sense.
- ASSERT(fontData);
-
- if (!m_fontDataForAllGlyphs)
- m_fontDataForAllGlyphs = fontData;
-
- if (m_fontDataForAllGlyphs == fontData)
- return;
-
- // This GlyphPage houses glyphs from multiple fonts, transition to an array of SimpleFontData pointers.
- const SimpleFontData* oldFontData = m_fontDataForAllGlyphs;
- m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*)));
- for (unsigned i = 0; i < size; ++i)
- m_perGlyphFontData[i] = m_glyphs[i] ? oldFontData : 0;
- m_perGlyphFontData[index] = fontData;
+ // A single-font GlyphPage already assigned m_fontDataForAllGlyphs in the constructor.
+ ASSERT(!glyph || fontData == m_fontDataForAllGlyphs);
}
void setGlyphDataForIndex(unsigned index, const GlyphData& glyphData)
@@ -168,15 +152,10 @@
setGlyphDataForIndex(index, glyphData.glyph, glyphData.fontData);
}
- void clearForFontData(const SimpleFontData* fontData)
+ void removeFontDataFromSystemFallbackPage(const SimpleFontData* fontData)
{
- if (!m_perGlyphFontData) {
- if (m_fontDataForAllGlyphs == fontData) {
- memset(m_glyphs, 0, sizeof(m_glyphs));
- m_fontDataForAllGlyphs = 0;
- }
- return;
- }
+ // This method should only be called on the system fallback page, which is never single-font.
+ ASSERT(hasPerGlyphFontData());
for (size_t i = 0; i < size; ++i) {
if (m_perGlyphFontData[i] == fontData) {
m_glyphs[i] = 0;
@@ -191,22 +170,29 @@
bool fill(unsigned offset, unsigned length, UChar* characterBuffer, unsigned bufferLength, const SimpleFontData*);
private:
- GlyphPage(GlyphPageTreeNode* owner, bool clearGlyphs)
- : m_fontDataForAllGlyphs(0)
- , m_perGlyphFontData(0)
+ explicit GlyphPage(GlyphPageTreeNode* owner, const SimpleFontData* fontDataForAllGlyphs = 0)
+ : m_fontDataForAllGlyphs(fontDataForAllGlyphs)
, m_owner(owner)
{
- if (clearGlyphs)
- memset(m_glyphs, 0, sizeof(m_glyphs));
+ memset(m_glyphs, 0, sizeof(m_glyphs));
+ if (hasPerGlyphFontData())
+ memset(m_perGlyphFontData, 0, sizeof(SimpleFontData*) * GlyphPage::size);
}
- const SimpleFontData* m_fontDataForAllGlyphs;
- const SimpleFontData** m_perGlyphFontData;
+ bool hasPerGlyphFontData() const { return !m_fontDataForAllGlyphs; }
+ const SimpleFontData* m_fontDataForAllGlyphs;
GlyphPageTreeNode* m_owner;
Glyph m_glyphs[size];
+
+ // NOTE: This array has (GlyphPage::size) elements if m_fontDataForAllGlyphs is null.
+ const SimpleFontData* m_perGlyphFontData[0];
};
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
} // namespace WebCore
#endif // GlyphPage_h
Modified: trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp (143600 => 143601)
--- trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp 2013-02-21 15:38:04 UTC (rev 143600)
+++ trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp 2013-02-21 15:44:02 UTC (rev 143601)
@@ -201,15 +201,17 @@
}
}
- m_page = GlyphPage::createUninitialized(this);
-
// Now that we have a buffer full of characters, we want to get back an array
// of glyph indices. This part involves calling into the platform-specific
// routine of our glyph map for actually filling in the page with the glyphs.
// Success is not guaranteed. For example, Times fails to fill page 260, giving glyph data
// for only 128 out of 256 characters.
bool haveGlyphs;
- if (fontData->isSegmented()) {
+ if (!fontData->isSegmented()) {
+ m_page = GlyphPage::createForSingleFontData(this, static_cast<const SimpleFontData*>(fontData));
+ haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData));
+ } else {
+ m_page = GlyphPage::createForMixedFontData(this);
haveGlyphs = false;
const SegmentedFontData* segmentedFontData = static_cast<const SegmentedFontData*>(fontData);
@@ -225,7 +227,7 @@
int to = 1 + min(static_cast<int>(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::createUninitialized(this);
+ scratchPage = GlyphPage::createForMixedFontData(this);
pageToFill = scratchPage.get();
}
@@ -246,8 +248,7 @@
}
}
}
- } else
- haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData));
+ }
if (!haveGlyphs)
m_page = 0;
@@ -279,7 +280,7 @@
m_page = parentPage;
} else {
// Combine the parent's glyphs and ours to form a new more complete page.
- m_page = GlyphPage::createUninitialized(this);
+ m_page = GlyphPage::createForMixedFontData(this);
// Overlay the parent page on the fallback page. Check if the fallback font
// has added anything.
@@ -307,7 +308,7 @@
if (parentPage)
m_page = parentPage->createCopiedSystemFallbackPage(this);
else
- m_page = GlyphPage::createZeroedSystemFallbackPage(this);
+ m_page = GlyphPage::createForMixedFontData(this);
}
}
@@ -369,7 +370,7 @@
// Prune fall back child (if any) of this font.
if (m_systemFallbackChild && m_systemFallbackChild->m_page)
- m_systemFallbackChild->m_page->clearForFontData(fontData);
+ m_systemFallbackChild->m_page->removeFontDataFromSystemFallbackPage(fontData);
// Prune any branch that contains this FontData.
if (OwnPtr<GlyphPageTreeNode> node = m_children.take(fontData)) {