1/* 2 * Copyright (c) 2006, 2007, 2008, 2009, 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#include "config.h" 32#include "UniscribeHelperTextRun.h" 33 34#include "Font.h" 35#include "PlatformBridge.h" 36#include "SimpleFontData.h" 37#include "TextRun.h" 38 39namespace WebCore { 40 41UniscribeHelperTextRun::UniscribeHelperTextRun(const TextRun& run, 42 const Font& font) 43 : UniscribeHelper(run.characters(), run.length(), run.rtl(), 44 font.primaryFont()->platformData().hfont(), 45 font.primaryFont()->platformData().scriptCache(), 46 font.primaryFont()->platformData().scriptFontProperties(), 47 font.primaryFont()->spaceGlyph()) 48 , m_font(&font) 49 , m_fontIndex(0) 50{ 51 setDirectionalOverride(run.directionalOverride()); 52 setLetterSpacing(font.letterSpacing()); 53 setSpaceWidth(font.spaceWidth()); 54 setWordSpacing(font.wordSpacing()); 55 setAscent(font.fontMetrics().ascent()); 56 57 init(); 58 59 // Expansion is the amount to add to make justification happen. This 60 // should be done after Init() so all the runs are already measured. 61 if (run.expansion() > 0) 62 justify(run.expansion()); 63} 64 65UniscribeHelperTextRun::UniscribeHelperTextRun( 66 const wchar_t* input, 67 int inputLength, 68 bool isRtl, 69 HFONT hfont, 70 SCRIPT_CACHE* scriptCache, 71 SCRIPT_FONTPROPERTIES* fontProperties) 72 : UniscribeHelper(input, inputLength, isRtl, hfont, 73 scriptCache, fontProperties, 0) 74 , m_font(0) 75 , m_fontIndex(-1) 76{ 77} 78 79void UniscribeHelperTextRun::tryToPreloadFont(HFONT font) 80{ 81 // Ask the browser to get the font metrics for this font. 82 // That will preload the font and it should now be accessible 83 // from the renderer. 84 PlatformBridge::ensureFontLoaded(font); 85} 86 87bool UniscribeHelperTextRun::nextWinFontData( 88 HFONT* hfont, 89 SCRIPT_CACHE** scriptCache, 90 SCRIPT_FONTPROPERTIES** fontProperties, 91 int* ascent) 92{ 93 // This check is necessary because NextWinFontData can be called again 94 // after we already ran out of fonts. fontDataAt behaves in a strange 95 // manner when the difference between param passed and # of fonts stored in 96 // WebKit::Font is larger than one. We can avoid this check by setting 97 // font_index_ to # of elements in hfonts_ when we run out of font. In that 98 // case, we'd have to go through a couple of more checks before returning 99 // false. 100 if (m_fontIndex == -1 || !m_font) 101 return false; 102 103 // If the font data for a fallback font requested is not yet retrieved, add 104 // them to our vectors. Note that '>' rather than '>=' is used to test that 105 // condition. primaryFont is not stored in hfonts_, and friends so that 106 // indices for fontDataAt and our vectors for font data are 1 off from each 107 // other. That is, when fully populated, hfonts_ and friends have one font 108 // fewer than what's contained in font_. 109 if (static_cast<size_t>(++m_fontIndex) > m_hfonts.size()) { 110 const FontData *fontData = m_font->fontDataAt(m_fontIndex); 111 if (!fontData) { 112 // Ran out of fonts. 113 m_fontIndex = -1; 114 return false; 115 } 116 117 // FIXME: this won't work for SegmentedFontData 118 // http://crbug.com/6425 119 const SimpleFontData* simpleFontData = 120 fontData->fontDataForCharacter(' '); 121 122 m_hfonts.append(simpleFontData->platformData().hfont()); 123 m_scriptCaches.append(simpleFontData->platformData().scriptCache()); 124 m_fontProperties.append(simpleFontData->platformData().scriptFontProperties()); 125 m_ascents.append(simpleFontData->fontMetrics().ascent()); 126 } 127 128 *hfont = m_hfonts[m_fontIndex - 1]; 129 *scriptCache = m_scriptCaches[m_fontIndex - 1]; 130 *fontProperties = m_fontProperties[m_fontIndex - 1]; 131 *ascent = m_ascents[m_fontIndex - 1]; 132 return true; 133} 134 135void UniscribeHelperTextRun::resetFontIndex() 136{ 137 m_fontIndex = 0; 138} 139 140} // namespace WebCore 141