1 /* 2 * Copyright (C) 2012 Google 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 are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef HarfBuzzShaper_h 32 #define HarfBuzzShaper_h 33 34 #include "hb.h" 35 #include "platform/geometry/FloatBoxExtent.h" 36 #include "platform/geometry/FloatPoint.h" 37 #include "platform/text/TextRun.h" 38 #include "wtf/HashSet.h" 39 #include "wtf/OwnPtr.h" 40 #include "wtf/PassOwnPtr.h" 41 #include "wtf/unicode/CharacterNames.h" 42 #include "wtf/Vector.h" 43 44 #include <unicode/uscript.h> 45 46 namespace WebCore { 47 48 class Font; 49 class GlyphBuffer; 50 class SimpleFontData; 51 52 class HarfBuzzShaper FINAL { 53 public: 54 enum ForTextEmphasisOrNot { 55 NotForTextEmphasis, 56 ForTextEmphasis 57 }; 58 59 HarfBuzzShaper(const Font*, const TextRun&, ForTextEmphasisOrNot = NotForTextEmphasis); 60 61 void setDrawRange(int from, int to); 62 bool shape(GlyphBuffer* = 0); 63 FloatPoint adjustStartPoint(const FloatPoint&); 64 float totalWidth() { return m_totalWidth; } 65 int offsetForPosition(float targetX); 66 FloatRect selectionRect(const FloatPoint&, int height, int from, int to); 67 FloatBoxExtent glyphBoundingBox() const { return m_glyphBoundingBox; } 68 69 private: 70 class HarfBuzzRun { 71 public: 72 HarfBuzzRun(const HarfBuzzRun&); 73 ~HarfBuzzRun(); 74 75 static PassOwnPtr<HarfBuzzRun> create(const SimpleFontData* fontData, unsigned startIndex, unsigned numCharacters, TextDirection direction, hb_script_t script) 76 { 77 return adoptPtr(new HarfBuzzRun(fontData, startIndex, numCharacters, direction, script)); 78 } 79 80 void applyShapeResult(hb_buffer_t*); 81 void copyShapeResultAndGlyphPositions(const HarfBuzzRun&); 82 void setGlyphAndPositions(unsigned index, uint16_t glyphId, float advance, float offsetX, float offsetY); 83 void setWidth(float width) { m_width = width; } 84 85 int characterIndexForXPosition(float targetX); 86 float xPositionForOffset(unsigned offset); 87 88 const SimpleFontData* fontData() { return m_fontData; } 89 unsigned startIndex() const { return m_startIndex; } 90 unsigned numCharacters() const { return m_numCharacters; } 91 unsigned numGlyphs() const { return m_numGlyphs; } 92 uint16_t* glyphs() { return &m_glyphs[0]; } 93 float* advances() { return &m_advances[0]; } 94 FloatPoint* offsets() { return &m_offsets[0]; } 95 bool hasGlyphToCharacterIndexes() const 96 { 97 return m_glyphToCharacterIndexes.size() > 0; 98 } 99 uint16_t* glyphToCharacterIndexes() 100 { 101 return &m_glyphToCharacterIndexes[0]; 102 } 103 float width() { return m_width; } 104 bool rtl() { return m_direction == RTL; } 105 hb_script_t script() { return m_script; } 106 107 private: 108 HarfBuzzRun(const SimpleFontData*, unsigned startIndex, unsigned numCharacters, TextDirection, hb_script_t); 109 110 const SimpleFontData* m_fontData; 111 unsigned m_startIndex; 112 size_t m_numCharacters; 113 unsigned m_numGlyphs; 114 TextDirection m_direction; 115 hb_script_t m_script; 116 Vector<uint16_t, 256> m_glyphs; 117 Vector<float, 256> m_advances; 118 Vector<uint16_t, 256> m_glyphToCharacterIndexes; 119 Vector<FloatPoint, 256> m_offsets; 120 float m_width; 121 }; 122 123 bool isWordEnd(unsigned); 124 int determineWordBreakSpacing(); 125 // setPadding sets a number of pixels to be distributed across the TextRun. 126 // WebKit uses this to justify text. 127 void setPadding(int); 128 129 // In complex text word-spacing affects each line-break, space (U+0020) and non-breaking space (U+00A0). 130 static bool isCodepointSpace(UChar c) { return c == ' ' || c == noBreakSpace || c == '\n'; } 131 132 void setFontFeatures(); 133 134 bool createHarfBuzzRuns(); 135 bool shapeHarfBuzzRuns(); 136 bool fillGlyphBuffer(GlyphBuffer*); 137 void fillGlyphBufferFromHarfBuzzRun(GlyphBuffer*, HarfBuzzRun*, FloatPoint& firstOffsetOfNextRun); 138 void fillGlyphBufferForTextEmphasis(GlyphBuffer*, HarfBuzzRun* currentRun); 139 void setGlyphPositionsForHarfBuzzRun(HarfBuzzRun*, hb_buffer_t*); 140 void addHarfBuzzRun(unsigned startCharacter, unsigned endCharacter, const SimpleFontData*, UScriptCode); 141 142 const Font* m_font; 143 OwnPtr<UChar[]> m_normalizedBuffer; 144 unsigned m_normalizedBufferLength; 145 const TextRun& m_run; 146 147 float m_wordSpacingAdjustment; // Delta adjustment (pixels) for each word break. 148 float m_padding; // Pixels to be distributed over the line at word breaks. 149 float m_padPerWordBreak; // Pixels to be added to each word break. 150 float m_padError; // m_padPerWordBreak might have a fractional component. Since we only add a whole number of padding pixels at each word break we accumulate error. This is the number of pixels that we are behind so far. 151 float m_letterSpacing; // Pixels to be added after each glyph. 152 153 Vector<hb_feature_t, 4> m_features; 154 Vector<OwnPtr<HarfBuzzRun>, 16> m_harfBuzzRuns; 155 156 FloatPoint m_startOffset; 157 158 int m_fromIndex; 159 int m_toIndex; 160 161 ForTextEmphasisOrNot m_forTextEmphasis; 162 163 float m_totalWidth; 164 FloatBoxExtent m_glyphBoundingBox; 165 166 friend struct CachedShapingResults; 167 }; 168 169 } // namespace WebCore 170 171 #endif // HarfBuzzShaper_h 172