Changeset 105393 in webkit


Ignore:
Timestamp:
Jan 19, 2012 1:08:12 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[Chromium] Random characters got rendered as empty boxes or with incorrect glyphs even when a font is present
https://bugs.webkit.org/show_bug.cgi?id=76508

Patch by Kazuhiro Inaba <kinaba@chromium.org> on 2012-01-19
Reviewed by Kent Tamura.

Wrapped GetGlyphIndices() API calls so that when they failed we trigger font
loading outside the sandbox and retry the call.

No new auto tests since the bug involves the system's occasional cache behavior
and thus there's no reliable way to reproduce and test the situation.

  • platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp:

(WebCore::getGlyphIndices):
GDI call wrapper ensuring fonts to be loaded.
(WebCore::initSpaceGlyph):
Changed to use the wrapper function.
(WebCore::fillBMPGlyphs):
Changed to use the wrapper function.
Introduced scoped HDC management by HWndDC.
(WebCore::GlyphPage::fill):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r105391 r105393  
     12012-01-19  Kazuhiro Inaba  <kinaba@chromium.org>
     2
     3        [Chromium] Random characters got rendered as empty boxes or with incorrect glyphs even when a font is present
     4        https://bugs.webkit.org/show_bug.cgi?id=76508
     5
     6        Reviewed by Kent Tamura.
     7
     8        Wrapped GetGlyphIndices() API calls so that when they failed we trigger font
     9        loading outside the sandbox and retry the call.
     10
     11        No new auto tests since the bug involves the system's occasional cache behavior
     12        and thus there's no reliable way to reproduce and test the situation.
     13
     14        * platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp:
     15        (WebCore::getGlyphIndices):
     16        GDI call wrapper ensuring fonts to be loaded.
     17        (WebCore::initSpaceGlyph):
     18        Changed to use the wrapper function.
     19        (WebCore::fillBMPGlyphs):
     20        Changed to use the wrapper function.
     21        Introduced scoped HDC management by HWndDC.
     22        (WebCore::GlyphPage::fill):
     23
    1242012-01-19  Adam Barth  <abarth@webkit.org>
    225
  • trunk/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp

    r95901 r105393  
    11/*
    2  * Copyright (c) 2008, 2009 Google Inc. All rights reserved.
     2 * Copyright (c) 2008, 2009, 2012 Google Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535#include "Font.h"
    3636#include "GlyphPageTreeNode.h"
     37#include "HWndDC.h"
    3738#include "PlatformSupport.h"
    3839#include "SimpleFontData.h"
     
    5051}
    5152
    52 // Lazily initializes space glyph
    53 static Glyph initSpaceGlyph(HDC dc, Glyph* spaceGlyph)
    54 {
    55     if (*spaceGlyph)
    56         return *spaceGlyph;
    57 
     53// Convert characters to glyph ids by GetGlyphIndices(), during which, we
     54// ensure the font is loaded in memory to make it work in a sandboxed process.
     55static bool getGlyphIndices(HFONT font, HDC dc, const UChar* characters, unsigned charactersLength, WORD* glyphBuffer, DWORD flag)
     56{
     57    if (GetGlyphIndices(dc, characters, charactersLength, glyphBuffer, flag) != GDI_ERROR)
     58        return true;
     59    if (PlatformSupport::ensureFontLoaded(font)) {
     60        if (GetGlyphIndices(dc, characters, charactersLength, glyphBuffer, flag) != GDI_ERROR)
     61            return true;
     62        // FIXME: Handle gracefully the error if this call also fails.
     63        // See http://crbug.com/6401
     64        LOG_ERROR("Unable to get the glyph indices after second attempt");
     65    }
     66    return false;
     67}
     68
     69// Initializes space glyph
     70static bool initSpaceGlyph(HFONT font, HDC dc, Glyph* spaceGlyph)
     71{
    5872    static wchar_t space = ' ';
    59     GetGlyphIndices(dc, &space, 1, spaceGlyph, 0);
    60     return *spaceGlyph;
     73    return getGlyphIndices(font, dc, &space, 1, spaceGlyph, 0);
    6174}
    6275
     
    6982                          UChar* buffer,
    7083                          GlyphPage* page,
    71                           const SimpleFontData* fontData,
    72                           bool recurse)
    73 {
    74     HDC dc = GetDC((HWND)0);
     84                          const SimpleFontData* fontData)
     85{
     86    HWndDC dc((HWND)0);
    7587    HGDIOBJ oldFont = SelectObject(dc, fontData->platformData().hfont());
    7688
    7789    TEXTMETRIC tm = {0};
    7890    if (!GetTextMetrics(dc, &tm)) {
    79         SelectObject(dc, oldFont);
    80         ReleaseDC(0, dc);
    81 
    82         if (recurse) {
    83             if (PlatformSupport::ensureFontLoaded(fontData->platformData().hfont()))
    84                 return fillBMPGlyphs(offset, length, buffer, page, fontData, false);
    85 
    86             fillEmptyGlyphs(page);
    87             return false;
     91        if (PlatformSupport::ensureFontLoaded(fontData->platformData().hfont())) {
     92            if (!GetTextMetrics(dc, &tm)) {
     93                // FIXME: Handle gracefully the error if this call also fails.
     94                // See http://crbug.com/6401
     95                LOG_ERROR("Unable to get the text metrics after second attempt");
     96
     97                SelectObject(dc, oldFont);
     98                fillEmptyGlyphs(page);
     99                return false;
     100            }
    88101        } else {
    89             // FIXME: Handle gracefully the error if this call also fails.
    90             // See http://crbug.com/6401
    91             LOG_ERROR("Unable to get the text metrics after second attempt");
     102            SelectObject(dc, oldFont);
    92103            fillEmptyGlyphs(page);
    93104            return false;
     
    129140    // we treat turetype and raster Font as different way when windows version
    130141    // is less than Vista.
    131     GetGlyphIndices(dc, buffer, length, localGlyphBuffer, GGI_MARK_NONEXISTING_GLYPHS);
     142    if (!getGlyphIndices(fontData->platformData().hfont(), dc, buffer, length, localGlyphBuffer, GGI_MARK_NONEXISTING_GLYPHS)) {
     143        SelectObject(dc, oldFont);
     144        fillEmptyGlyphs(page);
     145        return false;
     146    }
    132147
    133148    // Copy the output to the GlyphPage
     
    139154
    140155    Glyph spaceGlyph = 0;  // Glyph for a space. Lazily filled.
     156    bool spaceGlyphInitialized = false;
    141157
    142158    for (unsigned i = 0; i < length; i++) {
     
    150166            // Hard code the glyph indices for characters that should be
    151167            // treated like spaces.
    152             glyph = initSpaceGlyph(dc, &spaceGlyph);
     168            if (!spaceGlyphInitialized) {
     169                // If initSpaceGlyph fails, spaceGlyph stays 0 (= glyph is not present).
     170                initSpaceGlyph(fontData->platformData().hfont(), dc, &spaceGlyph);
     171                spaceGlyphInitialized = true;
     172            }
     173            glyph = spaceGlyph;
    153174        } else if (glyph == invalidGlyph) {
    154175            // WebKit expects both the glyph index and FontData
     
    162183
    163184    SelectObject(dc, oldFont);
    164     ReleaseDC(0, dc);
    165185    return haveGlyphs;
    166186}
     
    223243    // or entirely in non-BMP.
    224244    if (bufferLength == length)
    225         return fillBMPGlyphs(offset, length, characterBuffer, this, fontData, true);
     245        return fillBMPGlyphs(offset, length, characterBuffer, this, fontData);
    226246
    227247    if (bufferLength == 2 * length) {
Note: See TracChangeset for help on using the changeset viewer.