From 2004d8c100e015925f388c1f2d77e1d48758c13a Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 8 Jan 2011 23:17:18 +0000 Subject: [PATCH] LayoutGlyphs() was broken in various ways when encountering missing glyphs: * The code used continue to restart the loop when encountering a missing glyph, but in that case the index wouldn't be incremented, meaning the consumers would received the same index for ConsumeEmptyGlphy() and ConsumeGlyph() and at the end there was not necessarily a call for every index, resulting in uninitialized array elements for GetHasGlyphs, GetEdges, GetEscapements and GetBoundingBoxes. * Since the advance values were not reset in case of a missing glyph but still added for the next char, the coordinates the consumers would get were advanced by the advance values of the glyph preceeding the missing glyph(s). This made StringWidth return wrong widths. * The loop end condition was skipped by the continue as well, which would have resulted in overruns when there were problematic chars at the end of a string. Fixes #7075 where the uninitialized array elements caused random truncation errors. The problematic character in this case is a tab, that has no glyph as it is a dynamic spacer. Previously this was resolved to the "missing glyph" (the box) which had a width. I find it highly problematic not to fall back to such a glyph, because there is no real way to see that you're using a font that has missing glyphs. Instead those are simply collapsed to nothing with this change (instead of being random). This whole problem is only brought up by not guaranteeing that there always is a glyph as was the case before where a missing glyph was replaced by the box. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40172 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/GlyphLayoutEngine.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/servers/app/GlyphLayoutEngine.h b/src/servers/app/GlyphLayoutEngine.h index b4cc6f828a..c8150c6ba8 100644 --- a/src/servers/app/GlyphLayoutEngine.h +++ b/src/servers/app/GlyphLayoutEngine.h @@ -55,7 +55,7 @@ public: fCacheEntry->WriteUnlock(); else fCacheEntry->ReadUnlock(); - + FontCache::Default()->Recycle(fCacheEntry); } @@ -275,22 +275,22 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, const GlyphCache* glyph = entry->Glyph(charCode, fallbackEntry); if (glyph == NULL) { - consumer.ConsumeEmptyGlyph(index, charCode, x, y); - continue; + consumer.ConsumeEmptyGlyph(index++, charCode, x, y); + advanceX = 0; + advanceY = 0; } else { - if (!consumer.ConsumeGlyph(index, charCode, glyph, entry, x, y)) { + if (!consumer.ConsumeGlyph(index++, charCode, glyph, entry, x, y)) { advanceX = 0; advanceY = 0; break; } + + // get next increment for pen position + advanceX = glyph->advance_x; + advanceY = glyph->advance_y; } - // get next increment for pen position - advanceX = glyph->advance_x; - advanceY = glyph->advance_y; - lastCharCode = charCode; - index++; if (utf8String - start + 1 > length) break; }