1 /* 2 * Copyright (C) 2007, 2008, 2009, 2011 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 typedef unsigned short CGGlyph; 37 38 #if USE(CORE_TEXT) 39 typedef const struct __CTRun * CTRunRef; 40 typedef const struct __CTLine * CTLineRef; 41 #endif 42 #if USE(ATSUI) 43 typedef struct OpaqueATSUTextLayout* ATSUTextLayout; 44 typedef struct ATSGlyphVector* ATSULineRef; 45 typedef UInt32 ATSULayoutOperationSelector; 46 typedef UInt32 ATSULayoutOperationCallbackStatus; 47 #endif 48 49 namespace WebCore { 50 51 class Font; 52 class SimpleFontData; 53 class TextRun; 54 55 // ComplexTextController is responsible for rendering and measuring glyphs for 56 // complex scripts on OS X. 57 // The underlying API can be selected at compile time based on USE(ATSUI) and 58 // USE(CORE_TEXT). If both are defined then the Core Text APIs are used for 59 // OS Versions >= 10.6, ATSUI is used otherwise. 60 class ComplexTextController { 61 public: 62 ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool forTextEmphasis = false); 63 64 // Advance and emit glyphs up to the specified character. 65 void advance(unsigned to, GlyphBuffer* = 0); 66 67 // Compute the character offset for a given x coordinate. 68 int offsetForPosition(float x, bool includePartialGlyphs); 69 70 // Returns the width of everything we've consumed so far. runWidthSoFar()71 float runWidthSoFar() const { return m_runWidthSoFar; } 72 totalWidth()73 float totalWidth() const { return m_totalWidth; } 74 minGlyphBoundingBoxX()75 float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; } maxGlyphBoundingBoxX()76 float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; } minGlyphBoundingBoxY()77 float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; } maxGlyphBoundingBoxY()78 float maxGlyphBoundingBoxY() const { return m_maxGlyphBoundingBoxY; } 79 80 private: 81 class ComplexTextRun : public RefCounted<ComplexTextRun> { 82 public: 83 #if USE(CORE_TEXT) create(CTRunRef ctRun,const SimpleFontData * fontData,const UChar * characters,unsigned stringLocation,size_t stringLength,CFRange runRange)84 static PassRefPtr<ComplexTextRun> create(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange) 85 { 86 return adoptRef(new ComplexTextRun(ctRun, fontData, characters, stringLocation, stringLength, runRange)); 87 } 88 #endif 89 #if USE(ATSUI) create(ATSUTextLayout atsuTextLayout,const SimpleFontData * fontData,const UChar * characters,unsigned stringLocation,size_t stringLength,bool ltr,bool directionalOverride)90 static PassRefPtr<ComplexTextRun> create(ATSUTextLayout atsuTextLayout, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr, bool directionalOverride) 91 { 92 return adoptRef(new ComplexTextRun(atsuTextLayout, fontData, characters, stringLocation, stringLength, ltr, directionalOverride)); 93 } 94 #endif create(const SimpleFontData * fontData,const UChar * characters,unsigned stringLocation,size_t stringLength,bool ltr)95 static PassRefPtr<ComplexTextRun> create(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr) 96 { 97 return adoptRef(new ComplexTextRun(fontData, characters, stringLocation, stringLength, ltr)); 98 } 99 glyphCount()100 unsigned glyphCount() const { return m_glyphCount; } fontData()101 const SimpleFontData* fontData() const { return m_fontData; } characters()102 const UChar* characters() const { return m_characters; } stringLocation()103 unsigned stringLocation() const { return m_stringLocation; } stringLength()104 size_t stringLength() const { return m_stringLength; } 105 ALWAYS_INLINE CFIndex indexAt(size_t i) const; indexEnd()106 CFIndex indexEnd() const { return m_indexEnd; } endOffsetAt(size_t i)107 CFIndex endOffsetAt(size_t i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; } glyphs()108 const CGGlyph* glyphs() const { return m_glyphs; } advances()109 const CGSize* advances() const { return m_advances; } isMonotonic()110 bool isMonotonic() const { return m_isMonotonic; } 111 void setIsNonMonotonic(); 112 113 private: 114 #if USE(CORE_TEXT) 115 ComplexTextRun(CTRunRef, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange); 116 void createTextRunFromFontDataCoreText(bool ltr); 117 #endif 118 #if USE(ATSUI) 119 ComplexTextRun(ATSUTextLayout, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr, bool directionalOverride); 120 void createTextRunFromFontDataATSUI(bool ltr); 121 #endif 122 ComplexTextRun(const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr); 123 124 #if USE(ATSUI) 125 static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector, ATSULineRef, URefCon, void*, ATSULayoutOperationCallbackStatus*); 126 #endif 127 128 unsigned m_glyphCount; 129 const SimpleFontData* m_fontData; 130 const UChar* m_characters; 131 unsigned m_stringLocation; 132 size_t m_stringLength; 133 #if USE(CORE_TEXT) 134 Vector<CFIndex, 64> m_coreTextIndicesVector; 135 const CFIndex* m_coreTextIndices; 136 #endif 137 #if USE(ATSUI) 138 Vector<CFIndex, 64> m_atsuiIndices; 139 #endif 140 CFIndex m_indexEnd; 141 Vector<CFIndex, 64> m_glyphEndOffsets; 142 Vector<CGGlyph, 64> m_glyphsVector; 143 const CGGlyph* m_glyphs; 144 Vector<CGSize, 64> m_advancesVector; 145 const CGSize* m_advances; 146 #if USE(ATSUI) 147 bool m_directionalOverride; 148 #endif 149 bool m_isMonotonic; 150 }; 151 152 void collectComplexTextRuns(); 153 154 // collectComplexTextRunsForCharacters() is a stub function that calls through to the ATSUI or Core Text variants based 155 // on the API in use. 156 void collectComplexTextRunsForCharacters(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*); 157 void collectComplexTextRunsForCharactersATSUI(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*); 158 void collectComplexTextRunsForCharactersCoreText(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*); 159 void adjustGlyphsAndAdvances(); 160 161 const Font& m_font; 162 const TextRun& m_run; 163 bool m_mayUseNaturalWritingDirection; 164 bool m_forTextEmphasis; 165 166 Vector<UChar, 256> m_smallCapsBuffer; 167 168 #if USE(CORE_TEXT) 169 // Retain lines rather than their runs for better performance. 170 Vector<RetainPtr<CTLineRef> > m_coreTextLines; 171 #endif 172 Vector<RefPtr<ComplexTextRun>, 16> m_complexTextRuns; 173 Vector<CGSize, 256> m_adjustedAdvances; 174 Vector<CGGlyph, 256> m_adjustedGlyphs; 175 176 unsigned m_currentCharacter; 177 int m_end; 178 179 CGFloat m_totalWidth; 180 181 float m_runWidthSoFar; 182 unsigned m_numGlyphsSoFar; 183 size_t m_currentRun; 184 unsigned m_glyphInCurrentRun; 185 unsigned m_characterInCurrentGlyph; 186 float m_expansion; 187 float m_expansionPerOpportunity; 188 float m_leadingExpansion; 189 bool m_afterExpansion; 190 191 HashSet<const SimpleFontData*>* m_fallbackFonts; 192 193 float m_minGlyphBoundingBoxX; 194 float m_maxGlyphBoundingBoxX; 195 float m_minGlyphBoundingBoxY; 196 float m_maxGlyphBoundingBoxY; 197 }; 198 199 } // namespace WebCore 200 201 #endif // ComplexTextController_h 202