| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, 2009 Google Inc. All rights reserved. | 2 * Copyright (c) 2008, 2009, 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| 11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
| 12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
| (...skipping 29 matching lines...) Expand all Loading... |
| 42 namespace WebCore { | 42 namespace WebCore { |
| 43 | 43 |
| 44 // Fills one page of font data pointers with 0 to indicate that there | 44 // Fills one page of font data pointers with 0 to indicate that there |
| 45 // are no glyphs for the characters. | 45 // are no glyphs for the characters. |
| 46 static void fillEmptyGlyphs(GlyphPage* page) | 46 static void fillEmptyGlyphs(GlyphPage* page) |
| 47 { | 47 { |
| 48 for (int i = 0; i < GlyphPage::size; ++i) | 48 for (int i = 0; i < GlyphPage::size; ++i) |
| 49 page->setGlyphDataForIndex(i, 0, 0); | 49 page->setGlyphDataForIndex(i, 0, 0); |
| 50 } | 50 } |
| 51 | 51 |
| 52 // Lazily initializes space glyph | 52 // Convert characters to glyph ids by GetGlyphIndices(), during which, we |
| 53 static Glyph initSpaceGlyph(HDC dc, Glyph* spaceGlyph) | 53 // ensure the font is loaded in memory to make it work in a sandboxed process. |
| 54 static bool getGlyphIndices(HFONT font, HDC dc, const UChar* characters, unsigne
d charactersLength, WORD* glyphBuffer, DWORD flag) |
| 54 { | 55 { |
| 55 if (*spaceGlyph) | 56 if (GetGlyphIndices(dc, characters, charactersLength, glyphBuffer, flag) !=
GDI_ERROR) |
| 56 return *spaceGlyph; | 57 return true; |
| 58 if (PlatformSupport::ensureFontLoaded(font)) { |
| 59 if (GetGlyphIndices(dc, characters, charactersLength, glyphBuffer, flag)
!= GDI_ERROR) |
| 60 return true; |
| 61 // FIXME: Handle gracefully the error if this call also fails. |
| 62 // See http://crbug.com/6401 |
| 63 LOG_ERROR("Unable to get the glyph indices after second attempt"); |
| 64 } |
| 65 return false; |
| 66 } |
| 57 | 67 |
| 68 // Initializes space glyph |
| 69 static bool initSpaceGlyph(HFONT font, HDC dc, Glyph* spaceGlyph) |
| 70 { |
| 58 static wchar_t space = ' '; | 71 static wchar_t space = ' '; |
| 59 GetGlyphIndices(dc, &space, 1, spaceGlyph, 0); | 72 return getGlyphIndices(font, dc, &space, 1, spaceGlyph, 0); |
| 60 return *spaceGlyph; | |
| 61 } | 73 } |
| 62 | 74 |
| 63 // Fills |length| glyphs starting at |offset| in a |page| in the Basic | 75 // Fills |length| glyphs starting at |offset| in a |page| in the Basic |
| 64 // Multilingual Plane (<= U+FFFF). The input buffer size should be the | 76 // Multilingual Plane (<= U+FFFF). The input buffer size should be the |
| 65 // same as |length|. We can use the standard Windows GDI functions here. | 77 // same as |length|. We can use the standard Windows GDI functions here. |
| 66 // Returns true if any glyphs were found. | 78 // Returns true if any glyphs were found. |
| 67 static bool fillBMPGlyphs(unsigned offset, | 79 static bool fillBMPGlyphs(unsigned offset, |
| 68 unsigned length, | 80 unsigned length, |
| 69 UChar* buffer, | 81 UChar* buffer, |
| 70 GlyphPage* page, | 82 GlyphPage* page, |
| 71 const SimpleFontData* fontData, | 83 const SimpleFontData* fontData) |
| 72 bool recurse) | |
| 73 { | 84 { |
| 74 HDC dc = GetDC((HWND)0); | 85 HDC dc = GetDC((HWND)0); |
| 75 HGDIOBJ oldFont = SelectObject(dc, fontData->platformData().hfont()); | 86 HGDIOBJ oldFont = SelectObject(dc, fontData->platformData().hfont()); |
| 76 | 87 |
| 77 TEXTMETRIC tm = {0}; | 88 TEXTMETRIC tm = {0}; |
| 78 if (!GetTextMetrics(dc, &tm)) { | 89 if (!GetTextMetrics(dc, &tm)) { |
| 79 SelectObject(dc, oldFont); | 90 if (PlatformSupport::ensureFontLoaded(fontData->platformData().hfont()))
{ |
| 80 ReleaseDC(0, dc); | 91 if (!GetTextMetrics(dc, &tm)) { |
| 92 // FIXME: Handle gracefully the error if this call also fails. |
| 93 // See http://crbug.com/6401 |
| 94 LOG_ERROR("Unable to get the text metrics after second attempt")
; |
| 81 | 95 |
| 82 if (recurse) { | 96 SelectObject(dc, oldFont); |
| 83 if (PlatformSupport::ensureFontLoaded(fontData->platformData().hfont
())) | 97 ReleaseDC(0, dc); |
| 84 return fillBMPGlyphs(offset, length, buffer, page, fontData, fal
se); | 98 fillEmptyGlyphs(page); |
| 85 | 99 return false; |
| 86 fillEmptyGlyphs(page); | 100 } |
| 87 return false; | |
| 88 } else { | 101 } else { |
| 89 // FIXME: Handle gracefully the error if this call also fails. | 102 SelectObject(dc, oldFont); |
| 90 // See http://crbug.com/6401 | 103 ReleaseDC(0, dc); |
| 91 LOG_ERROR("Unable to get the text metrics after second attempt"); | |
| 92 fillEmptyGlyphs(page); | 104 fillEmptyGlyphs(page); |
| 93 return false; | 105 return false; |
| 94 } | 106 } |
| 95 } | 107 } |
| 96 | 108 |
| 97 // FIXME: GetGlyphIndices() sets each item of localGlyphBuffer[] | 109 // FIXME: GetGlyphIndices() sets each item of localGlyphBuffer[] |
| 98 // with the one of the values listed below. | 110 // with the one of the values listed below. |
| 99 // * With the GGI_MARK_NONEXISTING_GLYPHS flag | 111 // * With the GGI_MARK_NONEXISTING_GLYPHS flag |
| 100 // + If the font has a glyph available for the character, | 112 // + If the font has a glyph available for the character, |
| 101 // localGlyphBuffer[i] > 0x0. | 113 // localGlyphBuffer[i] > 0x0. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 121 // when call GetGlyphIndices without flag GGI_MARK_NONEXISTING_GLYPHS, | 133 // when call GetGlyphIndices without flag GGI_MARK_NONEXISTING_GLYPHS, |
| 122 // because the corresponding glyph index is set as 0x20 when current font | 134 // because the corresponding glyph index is set as 0x20 when current font |
| 123 // does not have glyphs available for the character. According a blog post | 135 // does not have glyphs available for the character. According a blog post |
| 124 // http://blogs.msdn.com/michkap/archive/2006/06/28/649791.aspx | 136 // http://blogs.msdn.com/michkap/archive/2006/06/28/649791.aspx |
| 125 // I think we should switch to the way about calling GetGlyphIndices with | 137 // I think we should switch to the way about calling GetGlyphIndices with |
| 126 // flag GGI_MARK_NONEXISTING_GLYPHS, it should be OK according the | 138 // flag GGI_MARK_NONEXISTING_GLYPHS, it should be OK according the |
| 127 // description of MSDN. | 139 // description of MSDN. |
| 128 // Also according to Jungshik and Hironori's suggestion and modification | 140 // Also according to Jungshik and Hironori's suggestion and modification |
| 129 // we treat turetype and raster Font as different way when windows version | 141 // we treat turetype and raster Font as different way when windows version |
| 130 // is less than Vista. | 142 // is less than Vista. |
| 131 GetGlyphIndices(dc, buffer, length, localGlyphBuffer, GGI_MARK_NONEXISTING_G
LYPHS); | 143 if (!getGlyphIndices(fontData->platformData().hfont(), dc, buffer, length, l
ocalGlyphBuffer, GGI_MARK_NONEXISTING_GLYPHS)) { |
| 144 SelectObject(dc, oldFont); |
| 145 ReleaseDC(0, dc); |
| 146 fillEmptyGlyphs(page); |
| 147 return false; |
| 148 } |
| 132 | 149 |
| 133 // Copy the output to the GlyphPage | 150 // Copy the output to the GlyphPage |
| 134 bool haveGlyphs = false; | 151 bool haveGlyphs = false; |
| 135 int invalidGlyph = 0xFFFF; | 152 int invalidGlyph = 0xFFFF; |
| 136 const DWORD cffTableTag = 0x20464643; // 4-byte identifier for OpenType CFF
table ('CFF '). | 153 const DWORD cffTableTag = 0x20464643; // 4-byte identifier for OpenType CFF
table ('CFF '). |
| 137 if ((windowsVersion() < WindowsVista) && !(tm.tmPitchAndFamily & TMPF_TRUETY
PE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR)) | 154 if ((windowsVersion() < WindowsVista) && !(tm.tmPitchAndFamily & TMPF_TRUETY
PE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR)) |
| 138 invalidGlyph = 0x1F; | 155 invalidGlyph = 0x1F; |
| 139 | 156 |
| 140 Glyph spaceGlyph = 0; // Glyph for a space. Lazily filled. | 157 Glyph spaceGlyph = 0; // Glyph for a space. Lazily filled. |
| 158 bool spaceGlyphInitialized = false; |
| 141 | 159 |
| 142 for (unsigned i = 0; i < length; i++) { | 160 for (unsigned i = 0; i < length; i++) { |
| 143 UChar c = buffer[i]; | 161 UChar c = buffer[i]; |
| 144 Glyph glyph = localGlyphBuffer[i]; | 162 Glyph glyph = localGlyphBuffer[i]; |
| 145 const SimpleFontData* glyphFontData = fontData; | 163 const SimpleFontData* glyphFontData = fontData; |
| 146 // When this character should be a space, we ignore whatever the font | 164 // When this character should be a space, we ignore whatever the font |
| 147 // says and use a space. Otherwise, if fonts don't map one of these | 165 // says and use a space. Otherwise, if fonts don't map one of these |
| 148 // space or zero width glyphs, we will get a box. | 166 // space or zero width glyphs, we will get a box. |
| 149 if (Font::treatAsSpace(c)) { | 167 if (Font::treatAsSpace(c)) { |
| 150 // Hard code the glyph indices for characters that should be | 168 // Hard code the glyph indices for characters that should be |
| 151 // treated like spaces. | 169 // treated like spaces. |
| 152 glyph = initSpaceGlyph(dc, &spaceGlyph); | 170 if (!spaceGlyphInitialized) { |
| 171 // If initSpaceGlyph fails, spaceGlyph stays 0 (= glyph is not p
resent). |
| 172 initSpaceGlyph(fontData->platformData().hfont(), dc, &spaceGlyph
); |
| 173 spaceGlyphInitialized = true; |
| 174 } |
| 175 glyph = spaceGlyph; |
| 153 } else if (glyph == invalidGlyph) { | 176 } else if (glyph == invalidGlyph) { |
| 154 // WebKit expects both the glyph index and FontData | 177 // WebKit expects both the glyph index and FontData |
| 155 // pointer to be 0 if the glyph is not present | 178 // pointer to be 0 if the glyph is not present |
| 156 glyph = 0; | 179 glyph = 0; |
| 157 glyphFontData = 0; | 180 glyphFontData = 0; |
| 158 } else | 181 } else |
| 159 haveGlyphs = true; | 182 haveGlyphs = true; |
| 160 page->setGlyphDataForCharacter(offset + i, glyph, glyphFontData); | 183 page->setGlyphDataForCharacter(offset + i, glyph, glyphFontData); |
| 161 } | 184 } |
| 162 | 185 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 // We're supposed to return true if there are any glyphs in the range | 238 // We're supposed to return true if there are any glyphs in the range |
| 216 // specified by |offset| and |length| in our font, | 239 // specified by |offset| and |length| in our font, |
| 217 // false if there are none. | 240 // false if there are none. |
| 218 bool GlyphPage::fill(unsigned offset, unsigned length, UChar* characterBuffer, | 241 bool GlyphPage::fill(unsigned offset, unsigned length, UChar* characterBuffer, |
| 219 unsigned bufferLength, const SimpleFontData* fontData) | 242 unsigned bufferLength, const SimpleFontData* fontData) |
| 220 { | 243 { |
| 221 // We have to handle BMP and non-BMP characters differently. | 244 // We have to handle BMP and non-BMP characters differently. |
| 222 // FIXME: Add assertions to make sure that buffer is entirely in BMP | 245 // FIXME: Add assertions to make sure that buffer is entirely in BMP |
| 223 // or entirely in non-BMP. | 246 // or entirely in non-BMP. |
| 224 if (bufferLength == length) | 247 if (bufferLength == length) |
| 225 return fillBMPGlyphs(offset, length, characterBuffer, this, fontData, tr
ue); | 248 return fillBMPGlyphs(offset, length, characterBuffer, this, fontData); |
| 226 | 249 |
| 227 if (bufferLength == 2 * length) { | 250 if (bufferLength == 2 * length) { |
| 228 // A non-BMP input buffer will be twice as long as output glyph buffer | 251 // A non-BMP input buffer will be twice as long as output glyph buffer |
| 229 // because each character in the non-BMP input buffer will be | 252 // because each character in the non-BMP input buffer will be |
| 230 // represented by a surrogate pair (two UChar's). | 253 // represented by a surrogate pair (two UChar's). |
| 231 return fillNonBMPGlyphs(offset, length, characterBuffer, this, fontData)
; | 254 return fillNonBMPGlyphs(offset, length, characterBuffer, this, fontData)
; |
| 232 } | 255 } |
| 233 | 256 |
| 234 ASSERT_NOT_REACHED(); | 257 ASSERT_NOT_REACHED(); |
| 235 return false; | 258 return false; |
| 236 } | 259 } |
| 237 | 260 |
| 238 } // namespace WebCore | 261 } // namespace WebCore |
| OLD | NEW |