Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp

Issue 9280004: Merge 105393 - [Chromium] Random characters got rendered as empty boxes or with incorrect glyphs ... (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/963/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698