Home | History | Annotate | Download | only in mac
      1 /*
      2  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23  */
     24 
     25 #ifndef ComplexTextController_h
     26 #define ComplexTextController_h
     27 
     28 #include "GlyphBuffer.h"
     29 #include <wtf/HashSet.h>
     30 #include <wtf/PassRefPtr.h>
     31 #include <wtf/RefCounted.h>
     32 #include <wtf/RetainPtr.h>
     33 #include <wtf/Vector.h>
     34 #include <wtf/unicode/Unicode.h>
     35 
     36 namespace WebCore {
     37 
     38 class Font;
     39 class SimpleFontData;
     40 class TextRun;
     41 
     42 // ComplexTextController is responsible for rendering and measuring glyphs for
     43 // complex scripts on OS X.
     44 // The underlying API can be selected at compile time based on USE(ATSUI) and
     45 // USE(CORE_TEXT).  If both are defined then the Core Text APIs are used for
     46 // OS Versions >= 10.6, ATSUI is used otherwise.
     47 class ComplexTextController {
     48 public:
     49     ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0);
     50 
     51     // Advance and emit glyphs up to the specified character.
     52     void advance(unsigned to, GlyphBuffer* = 0);
     53 
     54     // Compute the character offset for a given x coordinate.
     55     int offsetForPosition(int x, bool includePartialGlyphs);
     56 
     57     // Returns the width of everything we've consumed so far.
     58     float runWidthSoFar() const { return m_runWidthSoFar; }
     59 
     60     float totalWidth() const { return m_totalWidth; }
     61 
     62     // Extra width to the left of the leftmost glyph.
     63     float finalRoundingWidth() const { return m_finalRoundingWidth; }
     64 
     65 private:
     66     class ComplexTextRun : public RefCounted<ComplexTextRun> {
     67     public:
     68 #if USE(CORE_TEXT)
     69         static PassRefPtr<ComplexTextRun> create(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength)
     70         {
     71             return adoptRef(new ComplexTextRun(ctRun, fontData, characters, stringLocation, stringLength));
     72         }
     73 #endif
     74 #if USE(ATSUI)
     75         static PassRefPtr<ComplexTextRun> create(ATSUTextLayout atsuTextLayout, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr, bool directionalOverride)
     76         {
     77             return adoptRef(new ComplexTextRun(atsuTextLayout, fontData, characters, stringLocation, stringLength, ltr, directionalOverride));
     78         }
     79 #endif
     80         static PassRefPtr<ComplexTextRun> create(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
     81         {
     82             return adoptRef(new ComplexTextRun(fontData, characters, stringLocation, stringLength, ltr));
     83         }
     84 
     85         unsigned glyphCount() const { return m_glyphCount; }
     86         const SimpleFontData* fontData() const { return m_fontData; }
     87         const UChar* characters() const { return m_characters; }
     88         unsigned stringLocation() const { return m_stringLocation; }
     89         size_t stringLength() const { return m_stringLength; }
     90         ALWAYS_INLINE CFIndex indexAt(size_t i) const;
     91         CFIndex endOffsetAt(size_t i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; }
     92         const CGGlyph* glyphs() const { return m_glyphs; }
     93         const CGSize* advances() const { return m_advances; }
     94         bool isMonotonic() const { return m_isMonotonic; }
     95         void setIsNonMonotonic();
     96 
     97     private:
     98 #if USE(CORE_TEXT)
     99         ComplexTextRun(CTRunRef, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength);
    100         void createTextRunFromFontDataCoreText(bool ltr);
    101 #endif
    102 #if USE(ATSUI)
    103         ComplexTextRun(ATSUTextLayout, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr, bool directionalOverride);
    104         void createTextRunFromFontDataATSUI(bool ltr);
    105 #endif
    106         ComplexTextRun(const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr);
    107 
    108 #if USE(ATSUI)
    109 #ifdef BUILDING_ON_TIGER
    110         typedef UInt32 URefCon;
    111 #endif
    112         static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector, ATSULineRef, URefCon, void*, ATSULayoutOperationCallbackStatus*);
    113 #endif
    114 
    115 #if USE(CORE_TEXT)
    116         RetainPtr<CTRunRef> m_coreTextRun;
    117 #endif
    118         unsigned m_glyphCount;
    119         const SimpleFontData* m_fontData;
    120         const UChar* m_characters;
    121         unsigned m_stringLocation;
    122         size_t m_stringLength;
    123 #if USE(CORE_TEXT)
    124         RetainPtr<CFMutableDataRef> m_coreTextIndicesData;
    125         const CFIndex* m_coreTextIndices;
    126 #endif
    127 #if USE(ATSUI)
    128         Vector<CFIndex, 64> m_atsuiIndices;
    129 #endif
    130         Vector<CFIndex, 64> m_glyphEndOffsets;
    131         Vector<CGGlyph, 64> m_glyphsVector;
    132         const CGGlyph* m_glyphs;
    133         Vector<CGSize, 64> m_advancesVector;
    134         const CGSize* m_advances;
    135 #if USE(ATSUI)
    136         bool m_directionalOverride;
    137 #endif
    138         bool m_isMonotonic;
    139     };
    140 
    141     void collectComplexTextRuns();
    142 
    143     // collectComplexTextRunsForCharacters() is a stub function that calls through to the ATSUI or Core Text variants based
    144     // on the API in use.
    145     void collectComplexTextRunsForCharacters(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*);
    146     void collectComplexTextRunsForCharactersATSUI(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*);
    147     void collectComplexTextRunsForCharactersCoreText(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*);
    148     void adjustGlyphsAndAdvances();
    149 
    150     const Font& m_font;
    151     const TextRun& m_run;
    152     bool m_mayUseNaturalWritingDirection;
    153 
    154     Vector<UChar, 256> m_smallCapsBuffer;
    155 
    156     Vector<RefPtr<ComplexTextRun>, 16> m_complexTextRuns;
    157     Vector<CGSize, 256> m_adjustedAdvances;
    158     Vector<CGGlyph, 256> m_adjustedGlyphs;
    159 
    160     unsigned m_currentCharacter;
    161     int m_end;
    162 
    163     CGFloat m_totalWidth;
    164 
    165     float m_runWidthSoFar;
    166     unsigned m_numGlyphsSoFar;
    167     size_t m_currentRun;
    168     unsigned m_glyphInCurrentRun;
    169     unsigned m_characterInCurrentGlyph;
    170     float m_finalRoundingWidth;
    171     float m_padding;
    172     float m_padPerSpace;
    173 
    174     HashSet<const SimpleFontData*>* m_fallbackFonts;
    175 
    176     unsigned m_lastRoundingGlyph;
    177 };
    178 
    179 } // namespace WebCore
    180 
    181 #endif // ComplexTextController_h
    182