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