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 |