Changeset 39205 in webkit


Ignore:
Timestamp:
Dec 11, 2008 3:18:46 AM (15 years ago)
Author:
zecke@webkit.org
Message:

2008-12-11 Holger Hans Peter Freyther <zecke@selfish.org>

Reviewed by Darin Adler.

https://bugs.webkit.org/show_bug.cgi?id=20953

Split out the font fast path from Fast.cpp into FontFastPath.cpp. This
will allow the Qt port to share most of WebCore::Font
implementation but the fast path. Qt does not provide the API to get
individual Glyphs making the fast path hard to support.

  • GNUmakefile.am:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • WebCoreSources.bkl:
  • platform/graphics/Font.cpp:
  • platform/graphics/FontFastPath.cpp: Added. (WebCore::Font::glyphDataForCharacter):
Location:
trunk/WebCore
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r39203 r39205  
     12008-12-11  Holger Hans Peter Freyther  <zecke@selfish.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=20953
     6
     7        Split out the font fast path from Fast.cpp into FontFastPath.cpp. This
     8        will allow the Qt port to share most of WebCore::Font
     9        implementation but the fast path. Qt does not provide the API to get
     10        individual Glyphs making the fast path hard to support.
     11
     12
     13        * GNUmakefile.am:
     14        * WebCore.vcproj/WebCore.vcproj:
     15        * WebCore.xcodeproj/project.pbxproj:
     16        * WebCoreSources.bkl:
     17        * platform/graphics/Font.cpp:
     18        * platform/graphics/FontFastPath.cpp: Added.
     19        (WebCore::Font::glyphDataForCharacter):
     20
    1212008-12-11  Robert Carr  <racarr@svn.gnome.org>
    222
  • trunk/WebCore/GNUmakefile.am

    r39194 r39205  
    12771277        WebCore/platform/graphics/FontRenderingMode.h \
    12781278        WebCore/platform/graphics/FontSelector.h \
     1279        WebCore/platform/graphics/FontFastPath.cpp \
    12791280        WebCore/platform/graphics/FontTraitsMask.h \
    12801281        WebCore/platform/graphics/GeneratedImage.cpp \
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r39194 r39205  
    37913791                                <File
    37923792                                        RelativePath="..\platform\graphics\Font.cpp"
    3793                                         >
     3793                                >
     3794                                <File
     3795                                        RelativePath="..\platform\graphics\FontFastPath.cpp"
     3796                                >
    37943797                                        <FileConfiguration
    37953798                                                Name="Debug|Win32"
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r39194 r39205  
    835835                65DF326109D1E199000BE325 /* UserAgentStyleSheetsData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 656581AF09D14EE6000E61D7 /* UserAgentStyleSheetsData.cpp */; };
    836836                65FEA86909833ADE00BED4AB /* Page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FEA86809833ADE00BED4AB /* Page.cpp */; };
     837                72626E020EF022FE00A07E20 /* FontFastPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72626E010EF022FE00A07E20 /* FontFastPath.cpp */; };
    837838                7284ADDD0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7284ADDB0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp */; };
    838839                7284ADDE0E6FEB31002EEFBD /* UserStyleSheetLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 7284ADDC0E6FEB31002EEFBD /* UserStyleSheetLoader.h */; };
     
    57055706                65F80697054D9F86008BF776 /* BlockExceptions.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockExceptions.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    57065707                65FEA86809833ADE00BED4AB /* Page.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Page.cpp; sourceTree = "<group>"; };
     5708                72626E010EF022FE00A07E20 /* FontFastPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFastPath.cpp; sourceTree = "<group>"; };
    57075709                7284ADDB0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserStyleSheetLoader.cpp; sourceTree = "<group>"; };
    57085710                7284ADDC0E6FEB31002EEFBD /* UserStyleSheetLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserStyleSheetLoader.h; sourceTree = "<group>"; };
     
    1284012842                                B2C3DA580D006CD600EF6F26 /* FontFamily.cpp */,
    1284112843                                B2C3DA590D006CD600EF6F26 /* FontFamily.h */,
     12844                                72626E010EF022FE00A07E20 /* FontFastPath.cpp */,
    1284212845                                37ACCE410DA2980F0089E602 /* FontRenderingMode.h */,
    1284312846                                B2C3DA5A0D006CD600EF6F26 /* FontSelector.h */,
     
    1836018363                                E1271A140EEEC80400F61213 /* WorkerNavigator.cpp in Sources */,
    1836118364                                E1271A590EEECDE400F61213 /* JSWorkerNavigator.cpp in Sources */,
     18365                                72626E020EF022FE00A07E20 /* FontFastPath.cpp in Sources */,
    1836218366                        );
    1836318367                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/WebCoreSources.bkl

    r39174 r39205  
    716716        platform/graphics/FontFallbackList.cpp
    717717        platform/graphics/FontFamily.cpp
     718        platform/graphics/FontFastPath.cpp
    718719        platform/graphics/GlyphPageTreeNode.cpp
    719720        platform/graphics/GlyphWidthMap.cpp
  • trunk/WebCore/platform/graphics/Font.cpp

    r38806 r39205  
    2727#include "CharacterNames.h"
    2828#include "FloatRect.h"
    29 #include "FontCache.h"
    3029#include "FontFallbackList.h"
    3130#include "IntPoint.h"
     
    134133}
    135134
    136 const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCaps) const
    137 {
    138     bool useSmallCapsFont = forceSmallCaps;
    139     if (m_fontDescription.smallCaps()) {
    140         UChar32 upperC = Unicode::toUpper(c);
    141         if (upperC != c) {
    142             c = upperC;
    143             useSmallCapsFont = true;
    144         }
    145     }
    146 
    147     if (mirror)
    148         c = mirroredChar(c);
    149 
    150     unsigned pageNumber = (c / GlyphPage::size);
    151 
    152     GlyphPageTreeNode* node = pageNumber ? m_pages.get(pageNumber) : m_pageZero;
    153     if (!node) {
    154         node = GlyphPageTreeNode::getRootChild(fontDataAt(0), pageNumber);
    155         if (pageNumber)
    156             m_pages.set(pageNumber, node);
    157         else
    158             m_pageZero = node;
    159     }
    160 
    161     GlyphPage* page;
    162     if (!useSmallCapsFont) {
    163         // Fastest loop, for the common case (not small caps).
    164         while (true) {
    165             page = node->page();
    166             if (page) {
    167                 const GlyphData& data = page->glyphDataForCharacter(c);
    168                 if (data.fontData)
    169                     return data;
    170                 if (node->isSystemFallback())
    171                     break;
    172             }
    173 
    174             // Proceed with the fallback list.
    175             node = node->getChild(fontDataAt(node->level()), pageNumber);
    176             if (pageNumber)
    177                 m_pages.set(pageNumber, node);
    178             else
    179                 m_pageZero = node;
    180         }
    181     } else {
    182         while (true) {
    183             page = node->page();
    184             if (page) {
    185                 const GlyphData& data = page->glyphDataForCharacter(c);
    186                 if (data.fontData) {
    187                     // The smallCapsFontData function should not normally return 0.
    188                     // But if it does, we will just render the capital letter big.
    189                     const SimpleFontData* smallCapsFontData = data.fontData->smallCapsFontData(m_fontDescription);
    190                     if (!smallCapsFontData)
    191                         return data;
    192 
    193                     GlyphPageTreeNode* smallCapsNode = GlyphPageTreeNode::getRootChild(smallCapsFontData, pageNumber);
    194                     const GlyphPage* smallCapsPage = smallCapsNode->page();
    195                     if (smallCapsPage) {
    196                         const GlyphData& data = smallCapsPage->glyphDataForCharacter(c);
    197                         if (data.fontData)
    198                             return data;
    199                     }
    200 
    201                     // Do not attempt system fallback off the smallCapsFontData. This is the very unlikely case that
    202                     // a font has the lowercase character but the small caps font does not have its uppercase version.
    203                     return smallCapsFontData->missingGlyphData();
    204                 }
    205 
    206                 if (node->isSystemFallback())
    207                     break;
    208             }
    209 
    210             // Proceed with the fallback list.
    211             node = node->getChild(fontDataAt(node->level()), pageNumber);
    212             if (pageNumber)
    213                 m_pages.set(pageNumber, node);
    214             else
    215                 m_pageZero = node;
    216         }
    217     }
    218 
    219     ASSERT(page);
    220     ASSERT(node->isSystemFallback());
    221 
    222     // System fallback is character-dependent. When we get here, we
    223     // know that the character in question isn't in the system fallback
    224     // font's glyph page. Try to lazily create it here.
    225     UChar codeUnits[2];
    226     int codeUnitsLength;
    227     if (c <= 0xFFFF) {
    228         UChar c16 = c;
    229         if (Font::treatAsSpace(c16))
    230             codeUnits[0] = ' ';
    231         else if (Font::treatAsZeroWidthSpace(c16))
    232             codeUnits[0] = zeroWidthSpace;
    233         else
    234             codeUnits[0] = c16;
    235         codeUnitsLength = 1;
    236     } else {
    237         codeUnits[0] = U16_LEAD(c);
    238         codeUnits[1] = U16_TRAIL(c);
    239         codeUnitsLength = 2;
    240     }
    241     const SimpleFontData* characterFontData = FontCache::getFontDataForCharacters(*this, codeUnits, codeUnitsLength);
    242     if (useSmallCapsFont && characterFontData)
    243         characterFontData = characterFontData->smallCapsFontData(m_fontDescription);
    244     if (characterFontData) {
    245         // Got the fallback glyph and font.
    246         GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData, pageNumber)->page();
    247         const GlyphData& data = fallbackPage && fallbackPage->glyphDataForCharacter(c).fontData ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
    248         // Cache it so we don't have to do system fallback again next time.
    249         if (!useSmallCapsFont)
    250             page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    251         return data;
    252     }
    253 
    254     // Even system fallback can fail; use the missing glyph in that case.
    255     // FIXME: It would be nicer to use the missing glyph from the last resort font instead.
    256     const GlyphData& data = primaryFont()->missingGlyphData();
    257     if (!useSmallCapsFont)
    258         page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    259     return data;
    260 }
    261 
    262135void Font::cachePrimaryFont() const
    263136{
     
    340213}
    341214
    342 void Font::setCodePath(CodePath p)
    343 {
    344     s_codePath = p;
    345 }
    346 
    347 Font::CodePath Font::codePath()
    348 {
    349     return s_codePath;
    350 }
    351 
    352 bool Font::canUseGlyphCache(const TextRun& run) const
    353 {
    354     switch (s_codePath) {
    355         case Auto:
    356             break;
    357         case Simple:
    358             return true;
    359         case Complex:
    360             return false;
    361     }
    362    
    363     // Start from 0 since drawing and highlighting also measure the characters before run->from
    364     for (int i = 0; i < run.length(); i++) {
    365         const UChar c = run[i];
    366         if (c < 0x300)      // U+0300 through U+036F Combining diacritical marks
    367             continue;
    368         if (c <= 0x36F)
    369             return false;
    370 
    371         if (c < 0x0591 || c == 0x05BE)     // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha
    372             continue;
    373         if (c <= 0x05CF)
    374             return false;
    375 
    376         if (c < 0x0600)     // U+0600 through U+1059 Arabic, Syriac, Thaana, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar
    377             continue;
    378         if (c <= 0x1059)
    379             return false;
    380 
    381         if (c < 0x1100)     // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose; Modern Korean will be precomposed as a result of step A)
    382             continue;
    383         if (c <= 0x11FF)
    384             return false;
    385 
    386         if (c < 0x1780)     // U+1780 through U+18AF Khmer, Mongolian
    387             continue;
    388         if (c <= 0x18AF)
    389             return false;
    390 
    391         if (c < 0x1900)     // U+1900 through U+194F Limbu (Unicode 4.0)
    392             continue;
    393         if (c <= 0x194F)
    394             return false;
    395 
    396         if (c < 0x20D0)     // U+20D0 through U+20FF Combining marks for symbols
    397             continue;
    398         if (c <= 0x20FF)
    399             return false;
    400 
    401         if (c < 0xFE20)     // U+FE20 through U+FE2F Combining half marks
    402             continue;
    403         if (c <= 0xFE2F)
    404             return false;
    405     }
    406 
    407     return true;
    408 
    409 }
    410 
    411 void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
    412 {
    413     // This glyph buffer holds our glyphs+advances+font data for each glyph.
    414     GlyphBuffer glyphBuffer;
    415 
    416     float startX = point.x();
    417     WidthIterator it(this, run);
    418     it.advance(from);
    419     float beforeWidth = it.m_runWidthSoFar;
    420     it.advance(to, &glyphBuffer);
    421    
    422     // We couldn't generate any glyphs for the run.  Give up.
    423     if (glyphBuffer.isEmpty())
    424         return;
    425    
    426     float afterWidth = it.m_runWidthSoFar;
    427 
    428     if (run.rtl()) {
    429         float finalRoundingWidth = it.m_finalRoundingWidth;
    430         it.advance(run.length());
    431         startX += finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
    432     } else
    433         startX += beforeWidth;
    434 
    435     // Swap the order of the glyphs if right-to-left.
    436     if (run.rtl())
    437         for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
    438             glyphBuffer.swap(i, end);
    439 
    440     // Calculate the starting point of the glyphs to be displayed by adding
    441     // all the advances up to the first glyph.
    442     FloatPoint startPoint(startX, point.y());
    443     drawGlyphBuffer(context, glyphBuffer, run, startPoint);
    444 }
    445 
    446 void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuffer,
    447                            const TextRun& run, const FloatPoint& point) const
    448 {   
    449     // Draw each contiguous run of glyphs that use the same font data.
    450     const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
    451     FloatSize offset = glyphBuffer.offsetAt(0);
    452     FloatPoint startPoint(point);
    453     float nextX = startPoint.x();
    454     int lastFrom = 0;
    455     int nextGlyph = 0;
    456     while (nextGlyph < glyphBuffer.size()) {
    457         const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph);
    458         FloatSize nextOffset = glyphBuffer.offsetAt(nextGlyph);
    459         if (nextFontData != fontData || nextOffset != offset) {
    460             drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
    461 
    462             lastFrom = nextGlyph;
    463             fontData = nextFontData;
    464             offset = nextOffset;
    465             startPoint.setX(nextX);
    466         }
    467         nextX += glyphBuffer.advanceAt(nextGlyph);
    468         nextGlyph++;
    469     }
    470 
    471     drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
    472 }
    473 
    474215void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
    475216{
     
    519260}
    520261
    521 float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer) const
    522 {
    523     WidthIterator it(this, run);
    524     it.advance(run.length(), glyphBuffer);
    525     return it.m_runWidthSoFar;
    526 }
    527 
    528262FloatRect Font::selectionRectForText(const TextRun& run, const IntPoint& point, int h, int from, int to) const
    529263{
     
    539273}
    540274
    541 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const IntPoint& point, int h, int from, int to) const
    542 {
    543     WidthIterator it(this, run);
    544     it.advance(from);
    545     float beforeWidth = it.m_runWidthSoFar;
    546     it.advance(to);
    547     float afterWidth = it.m_runWidthSoFar;
    548 
    549     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
    550     if (run.rtl()) {
    551         it.advance(run.length());
    552         float totalWidth = it.m_runWidthSoFar;
    553         return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h);
    554     } else {
    555         return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
    556     }
    557 }
    558 
    559275int Font::offsetForPosition(const TextRun& run, int x, bool includePartialGlyphs) const
    560276{
     
    567283        return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
    568284    return offsetForPositionForComplexText(run, x, includePartialGlyphs);
    569 }
    570 
    571 int Font::offsetForPositionForSimpleText(const TextRun& run, int x, bool includePartialGlyphs) const
    572 {
    573     float delta = (float)x;
    574 
    575     WidthIterator it(this, run);
    576     GlyphBuffer localGlyphBuffer;
    577     unsigned offset;
    578     if (run.rtl()) {
    579         delta -= floatWidthForSimpleText(run, 0);
    580         while (1) {
    581             offset = it.m_currentCharacter;
    582             float w;
    583             if (!it.advanceOneCharacter(w, &localGlyphBuffer))
    584                 break;
    585             delta += w;
    586             if (includePartialGlyphs) {
    587                 if (delta - w / 2 >= 0)
    588                     break;
    589             } else {
    590                 if (delta >= 0)
    591                     break;
    592             }
    593         }
    594     } else {
    595         while (1) {
    596             offset = it.m_currentCharacter;
    597             float w;
    598             if (!it.advanceOneCharacter(w, &localGlyphBuffer))
    599                 break;
    600             delta -= w;
    601             if (includePartialGlyphs) {
    602                 if (delta + w / 2 <= 0)
    603                     break;
    604             } else {
    605                 if (delta <= 0)
    606                     break;
    607             }
    608         }
    609     }
    610 
    611     return offset;
    612285}
    613286
  • trunk/WebCore/platform/graphics/FontFastPath.cpp

    r39167 r39205  
    1 /*
    2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2006 Apple Inc. All rights reserved.
     1/**
     2 * Copyright (C) 2003, 2006 Apple Computer, Inc.
     3 * Copyright (C) 2008 Holger Hans Peter Freyther
    64 *
    75 * This library is free software; you can redistribute it and/or
     
    2624
    2725#include "CharacterNames.h"
     26#include "FontCache.h"
    2827#include "FloatRect.h"
    29 #include "FontCache.h"
    30 #include "FontFallbackList.h"
     28#include "GlyphBuffer.h"
     29#include "GlyphPageTreeNode.h"
    3130#include "IntPoint.h"
    32 #include "GlyphBuffer.h"
     31#include "SimpleFontData.h"
    3332#include "WidthIterator.h"
     33
     34#include <wtf/unicode/Unicode.h>
    3435#include <wtf/MathExtras.h>
    3536
     
    3839
    3940namespace WebCore {
    40 
    41 const uint8_t Font::gRoundingHackCharacterTable[256] = {
    42     0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    43     1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/,
    44     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    45     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    46     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    47     1 /*no-break space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    48     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    49     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    50 };
    51 
    52 Font::CodePath Font::s_codePath = Auto;
    53 
    54 // ============================================================================================
    55 // Font Implementation (Cross-Platform Portion)
    56 // ============================================================================================
    57 
    58 Font::Font()
    59     : m_pageZero(0)
    60     , m_cachedPrimaryFont(0)
    61     , m_letterSpacing(0)
    62     , m_wordSpacing(0)
    63     , m_isPlatformFont(false)
    64 {
    65 }
    66 
    67 Font::Font(const FontDescription& fd, short letterSpacing, short wordSpacing)
    68     : m_fontDescription(fd)
    69     , m_pageZero(0)
    70     , m_cachedPrimaryFont(0)
    71     , m_letterSpacing(letterSpacing)
    72     , m_wordSpacing(wordSpacing)
    73     , m_isPlatformFont(false)
    74 {
    75 }
    76 
    77 Font::Font(const FontPlatformData& fontData, bool isPrinterFont)
    78     : m_fontList(FontFallbackList::create())
    79     , m_pageZero(0)
    80     , m_cachedPrimaryFont(0)
    81     , m_letterSpacing(0)
    82     , m_wordSpacing(0)
    83     , m_isPlatformFont(true)
    84 {
    85     m_fontDescription.setUsePrinterFont(isPrinterFont);
    86     m_fontList->setPlatformFont(fontData);
    87 }
    88 
    89 Font::Font(const Font& other)
    90     : m_fontDescription(other.m_fontDescription)
    91     , m_fontList(other.m_fontList)
    92     , m_pages(other.m_pages)
    93     , m_pageZero(other.m_pageZero)
    94     , m_cachedPrimaryFont(other.m_cachedPrimaryFont)
    95     , m_letterSpacing(other.m_letterSpacing)
    96     , m_wordSpacing(other.m_wordSpacing)
    97     , m_isPlatformFont(other.m_isPlatformFont)
    98 {
    99 }
    100 
    101 Font& Font::operator=(const Font& other)
    102 {
    103     m_fontDescription = other.m_fontDescription;
    104     m_fontList = other.m_fontList;
    105     m_pages = other.m_pages;
    106     m_pageZero = other.m_pageZero;
    107     m_cachedPrimaryFont = other.m_cachedPrimaryFont;
    108     m_letterSpacing = other.m_letterSpacing;
    109     m_wordSpacing = other.m_wordSpacing;
    110     m_isPlatformFont = other.m_isPlatformFont;
    111     return *this;
    112 }
    113 
    114 Font::~Font()
    115 {
    116 }
    117 
    118 bool Font::operator==(const Font& other) const
    119 {
    120     // Our FontData don't have to be checked, since checking the font description will be fine.
    121     // FIXME: This does not work if the font was made with the FontPlatformData constructor.
    122     if ((m_fontList && m_fontList->loadingCustomFonts()) ||
    123         (other.m_fontList && other.m_fontList->loadingCustomFonts()))
    124         return false;
    125    
    126     FontSelector* first = m_fontList ? m_fontList->fontSelector() : 0;
    127     FontSelector* second = other.m_fontList ? other.m_fontList->fontSelector() : 0;
    128    
    129     return first == second
    130            && m_fontDescription == other.m_fontDescription
    131            && m_letterSpacing == other.m_letterSpacing
    132            && m_wordSpacing == other.m_wordSpacing
    133            && (m_fontList ? m_fontList->generation() : 0) == (other.m_fontList ? other.m_fontList->generation() : 0);
    134 }
    13541
    13642const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCaps) const
     
    260166}
    261167
    262 void Font::cachePrimaryFont() const
    263 {
    264     ASSERT(m_fontList);
    265     ASSERT(!m_cachedPrimaryFont);
    266     m_cachedPrimaryFont = m_fontList->primaryFont(this)->fontDataForCharacter(' ');
    267 }
    268 
    269 const FontData* Font::fontDataAt(unsigned index) const
    270 {
    271     ASSERT(m_fontList);
    272     return m_fontList->fontDataAt(this, index);
    273 }
    274 
    275 const FontData* Font::fontDataForCharacters(const UChar* characters, int length) const
    276 {
    277     ASSERT(m_fontList);
    278     return m_fontList->fontDataForCharacters(this, characters, length);
    279 }
    280 
    281 void Font::update(PassRefPtr<FontSelector> fontSelector) const
    282 {
    283     // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr, but it ends up
    284     // being reasonably safe (because inherited fonts in the render tree pick up the new
    285     // style anyway. Other copies are transient, e.g., the state in the GraphicsContext, and
    286     // won't stick around long enough to get you in trouble). Still, this is pretty disgusting,
    287     // and could eventually be rectified by using RefPtrs for Fonts themselves.
    288     if (!m_fontList)
    289         m_fontList = FontFallbackList::create();
    290     m_fontList->invalidate(fontSelector);
    291     m_cachedPrimaryFont = 0;
    292     m_pageZero = 0;
    293     m_pages.clear();
    294 }
    295 
    296 int Font::width(const TextRun& run) const
    297 {
    298     return lroundf(floatWidth(run));
    299 }
    300 
    301 int Font::ascent() const
    302 {
    303     return primaryFont()->ascent();
    304 }
    305 
    306 int Font::descent() const
    307 {
    308     return primaryFont()->descent();
    309 }
    310 
    311 int Font::lineSpacing() const
    312 {
    313     return primaryFont()->lineSpacing();
    314 }
    315 
    316 int Font::lineGap() const
    317 {
    318     return primaryFont()->lineGap();
    319 }
    320 
    321 float Font::xHeight() const
    322 {
    323     return primaryFont()->xHeight();
    324 }
    325 
    326 unsigned Font::unitsPerEm() const
    327 {
    328     return primaryFont()->unitsPerEm();
    329 }
    330 
    331 int Font::spaceWidth() const
    332 {
    333     return (int)ceilf(primaryFont()->m_adjustedSpaceWidth + m_letterSpacing);
    334 }
    335 
    336 bool Font::isFixedPitch() const
    337 {
    338     ASSERT(m_fontList);
    339     return m_fontList->isFixedPitch(this);
    340 }
    341 
    342168void Font::setCodePath(CodePath p)
    343169{
     
    472298}
    473299
    474 void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
    475 {
    476     // Don't draw anything while we are using custom fonts that are in the process of loading.
    477     if (m_fontList && m_fontList->loadingCustomFonts())
    478         return;
    479    
    480     to = (to == -1 ? run.length() : to);
    481 
    482 #if ENABLE(SVG_FONTS)
    483     if (primaryFont()->isSVGFont()) {
    484         drawTextUsingSVGFont(context, run, point, from, to);
    485         return;
    486     }
    487 #endif
    488 
    489     if (canUseGlyphCache(run))
    490         drawSimpleText(context, run, point, from, to);
    491     else
    492         drawComplexText(context, run, point, from, to);
    493 }
    494 
    495 float Font::floatWidth(const TextRun& run) const
    496 {
    497 #if ENABLE(SVG_FONTS)
    498     if (primaryFont()->isSVGFont())
    499         return floatWidthUsingSVGFont(run);
    500 #endif
    501 
    502     if (canUseGlyphCache(run))
    503         return floatWidthForSimpleText(run, 0);
    504     return floatWidthForComplexText(run);
    505 }
    506 
    507 float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
    508 {
    509 #if ENABLE(SVG_FONTS)
    510     if (primaryFont()->isSVGFont())
    511         return floatWidthUsingSVGFont(run, extraCharsAvailable, charsConsumed, glyphName);
    512 #endif
    513 
    514     charsConsumed = run.length();
    515     glyphName = "";
    516     if (canUseGlyphCache(run))
    517         return floatWidthForSimpleText(run, 0);
    518     return floatWidthForComplexText(run);
    519 }
    520 
    521300float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer) const
    522301{
     
    524303    it.advance(run.length(), glyphBuffer);
    525304    return it.m_runWidthSoFar;
    526 }
    527 
    528 FloatRect Font::selectionRectForText(const TextRun& run, const IntPoint& point, int h, int from, int to) const
    529 {
    530 #if ENABLE(SVG_FONTS)
    531     if (primaryFont()->isSVGFont())
    532         return selectionRectForTextUsingSVGFont(run, point, h, from, to);
    533 #endif
    534 
    535     to = (to == -1 ? run.length() : to);
    536     if (canUseGlyphCache(run))
    537         return selectionRectForSimpleText(run, point, h, from, to);
    538     return selectionRectForComplexText(run, point, h, from, to);
    539305}
    540306
     
    555321        return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
    556322    }
    557 }
    558 
    559 int Font::offsetForPosition(const TextRun& run, int x, bool includePartialGlyphs) const
    560 {
    561 #if ENABLE(SVG_FONTS)
    562     if (primaryFont()->isSVGFont())
    563         return offsetForPositionForTextUsingSVGFont(run, x, includePartialGlyphs);
    564 #endif
    565 
    566     if (canUseGlyphCache(run))
    567         return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
    568     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
    569323}
    570324
     
    612366}
    613367
    614 #if ENABLE(SVG_FONTS)
    615 bool Font::isSVGFont() const
    616 {
    617     return primaryFont()->isSVGFont();
    618 }
    619 #endif
    620 
    621 FontSelector* Font::fontSelector() const
    622 {
    623     return m_fontList ? m_fontList->fontSelector() : 0;
    624 }
    625 
    626 }
     368}
Note: See TracChangeset for help on using the changeset viewer.