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 "core/platform/graphics/FloatPoint.h" 35#include "core/platform/graphics/GlyphBuffer.h" 36#include "core/platform/graphics/TextRun.h" 37#include "hb.h" 38#include "wtf/HashSet.h" 39#include "wtf/OwnArrayPtr.h" 40#include "wtf/OwnPtr.h" 41#include "wtf/PassOwnPtr.h" 42#include "wtf/unicode/CharacterNames.h" 43#include "wtf/Vector.h" 44 45namespace WebCore { 46 47class Font; 48class SimpleFontData; 49 50class HarfBuzzShaper { 51public: 52 enum NormalizeMode { 53 DoNotNormalizeMirrorChars, 54 NormalizeMirrorChars 55 }; 56 57 HarfBuzzShaper(const Font*, const TextRun&); 58 virtual ~HarfBuzzShaper(); 59 60 void setDrawRange(int from, int to); 61 bool shape(GlyphBuffer* = 0); 62 FloatPoint adjustStartPoint(const FloatPoint&); 63 float totalWidth() { return m_totalWidth; } 64 int offsetForPosition(float targetX); 65 FloatRect selectionRect(const FloatPoint&, int height, int from, int to); 66 67private: 68 class HarfBuzzRun { 69 public: 70 static PassOwnPtr<HarfBuzzRun> create(const SimpleFontData* fontData, unsigned startIndex, unsigned numCharacters, TextDirection direction, hb_script_t script) 71 { 72 return adoptPtr(new HarfBuzzRun(fontData, startIndex, numCharacters, direction, script)); 73 } 74 75 void applyShapeResult(hb_buffer_t*); 76 void setGlyphAndPositions(unsigned index, uint16_t glyphId, float advance, float offsetX, float offsetY); 77 void setWidth(float width) { m_width = width; } 78 79 int characterIndexForXPosition(float targetX); 80 float xPositionForOffset(unsigned offset); 81 82 const SimpleFontData* fontData() { return m_fontData; } 83 unsigned startIndex() const { return m_startIndex; } 84 unsigned numCharacters() const { return m_numCharacters; } 85 unsigned numGlyphs() const { return m_numGlyphs; } 86 uint16_t* glyphs() { return &m_glyphs[0]; } 87 float* advances() { return &m_advances[0]; } 88 FloatPoint* offsets() { return &m_offsets[0]; } 89 uint16_t* glyphToCharacterIndexes() { return &m_glyphToCharacterIndexes[0]; } 90 float width() { return m_width; } 91 bool rtl() { return m_direction == RTL; } 92 hb_script_t script() { return m_script; } 93 94 private: 95 HarfBuzzRun(const SimpleFontData*, unsigned startIndex, unsigned numCharacters, TextDirection, hb_script_t); 96 97 const SimpleFontData* m_fontData; 98 unsigned m_startIndex; 99 size_t m_numCharacters; 100 unsigned m_numGlyphs; 101 TextDirection m_direction; 102 hb_script_t m_script; 103 Vector<uint16_t, 256> m_glyphs; 104 Vector<float, 256> m_advances; 105 Vector<uint16_t, 256> m_glyphToCharacterIndexes; 106 Vector<FloatPoint, 256> m_offsets; 107 float m_width; 108 }; 109 110 void setNormalizedBuffer(NormalizeMode = DoNotNormalizeMirrorChars); 111 112 bool isWordEnd(unsigned); 113 int determineWordBreakSpacing(); 114 // setPadding sets a number of pixels to be distributed across the TextRun. 115 // WebKit uses this to justify text. 116 void setPadding(int); 117 118 // In complex text word-spacing affects each line-break, space (U+0020) and non-breaking space (U+00A0). 119 static bool isCodepointSpace(UChar c) { return c == ' ' || c == noBreakSpace || c == '\n'; } 120 121 void setFontFeatures(); 122 123 bool collectHarfBuzzRuns(); 124 bool shapeHarfBuzzRuns(bool shouldSetDirection); 125 bool fillGlyphBuffer(GlyphBuffer*); 126 void fillGlyphBufferFromHarfBuzzRun(GlyphBuffer*, HarfBuzzRun*, FloatPoint& firstOffsetOfNextRun); 127 void setGlyphPositionsForHarfBuzzRun(HarfBuzzRun*, hb_buffer_t*); 128 129 GlyphBufferAdvance createGlyphBufferAdvance(float, float); 130 131 const Font* m_font; 132 OwnArrayPtr<UChar> m_normalizedBuffer; 133 unsigned m_normalizedBufferLength; 134 const TextRun& m_run; 135 136 int m_wordSpacingAdjustment; // Delta adjustment (pixels) for each word break. 137 float m_padding; // Pixels to be distributed over the line at word breaks. 138 float m_padPerWordBreak; // Pixels to be added to each word break. 139 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. 140 int m_letterSpacing; // Pixels to be added after each glyph. 141 142 Vector<hb_feature_t, 4> m_features; 143 Vector<OwnPtr<HarfBuzzRun>, 16> m_harfBuzzRuns; 144 145 FloatPoint m_startOffset; 146 147 int m_fromIndex; 148 int m_toIndex; 149 150 float m_totalWidth; 151}; 152 153} // namespace WebCore 154 155#endif // HarfBuzzShaper_h 156