1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/*
2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (c) 2008, 2009 Google Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions are
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * met:
7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     * Redistributions of source code must retain the above copyright
9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer.
10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     * Redistributions in binary form must reproduce the above
11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * copyright notice, this list of conditions and the following disclaimer
12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * in the documentation and/or other materials provided with the
13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * distribution.
14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     * Neither the name of Google Inc. nor the names of its
15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * contributors may be used to endorse or promote products derived from
16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * this software without specific prior written permission.
17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h"
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <windows.h>
33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <vector>
34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Font.h"
36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "GlyphPageTreeNode.h"
37ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "PlatformBridge.h"
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "SimpleFontData.h"
392bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "SystemInfo.h"
40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "UniscribeHelperTextRun.h"
41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WebCore {
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Fills one page of font data pointers with 0 to indicate that there
45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// are no glyphs for the characters.
46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void fillEmptyGlyphs(GlyphPage* page)
47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (int i = 0; i < GlyphPage::size; ++i)
49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        page->setGlyphDataForIndex(i, 0, 0);
50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Lazily initializes space glyph
53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic Glyph initSpaceGlyph(HDC dc, Glyph* spaceGlyph)
54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (*spaceGlyph)
56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return *spaceGlyph;
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    static wchar_t space = ' ';
59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    GetGlyphIndices(dc, &space, 1, spaceGlyph, 0);
60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return *spaceGlyph;
61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
63635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Fills |length| glyphs starting at |offset| in a |page| in the Basic
64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Multilingual Plane (<= U+FFFF). The input buffer size should be the
65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// same as |length|. We can use the standard Windows GDI functions here.
66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Returns true if any glyphs were found.
67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool fillBMPGlyphs(unsigned offset,
68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                          unsigned length,
69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                          UChar* buffer,
70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                          GlyphPage* page,
71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                          const SimpleFontData* fontData,
72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                          bool recurse)
73635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
74635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    HDC dc = GetDC((HWND)0);
755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HGDIOBJ oldFont = SelectObject(dc, fontData->platformData().hfont());
76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    TEXTMETRIC tm = {0};
78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!GetTextMetrics(dc, &tm)) {
79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        SelectObject(dc, oldFont);
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ReleaseDC(0, dc);
81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (recurse) {
83ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            if (PlatformBridge::ensureFontLoaded(fontData->platformData().hfont()))
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return fillBMPGlyphs(offset, length, buffer, page, fontData, false);
85ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
86ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            fillEmptyGlyphs(page);
87ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            return false;
88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else {
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // FIXME: Handle gracefully the error if this call also fails.
90635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // See http://crbug.com/6401
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            LOG_ERROR("Unable to get the text metrics after second attempt");
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            fillEmptyGlyphs(page);
93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return false;
94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: GetGlyphIndices() sets each item of localGlyphBuffer[]
98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // with the one of the values listed below.
99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //  * With the GGI_MARK_NONEXISTING_GLYPHS flag
100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //    + If the font has a glyph available for the character,
101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //      localGlyphBuffer[i] > 0x0.
102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //    + If the font does not have glyphs available for the character,
103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //      localGlyphBuffer[i] = 0x1F (TrueType Collection?) or
104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //                            0xFFFF (OpenType?).
105635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //  * Without the GGI_MARK_NONEXISTING_GLYPHS flag
106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //    + If the font has a glyph available for the character,
107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //      localGlyphBuffer[i] > 0x0.
108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //    + If the font does not have glyphs available for the character,
109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //      localGlyphBuffer[i] = 0x80.
110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //      (Windows automatically assigns the glyph for a box character to
111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    //      prevent ExtTextOut() from returning errors.)
112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // To avoid from hurting the rendering performance, this code just
113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // tells WebKit whether or not the all glyph indices for the given
114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // characters are 0x80 (i.e. a possibly-invalid glyph) and let it
115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // use alternative fonts for the characters.
116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Although this may cause a problem, it seems to work fine as far as I
117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // have tested. (Obviously, I need more tests.)
118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    WORD localGlyphBuffer[GlyphPage::size];
119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: I find some Chinese characters can not be correctly displayed
121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // when call GetGlyphIndices without flag GGI_MARK_NONEXISTING_GLYPHS,
122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // because the corresponding glyph index is set as 0x20 when current font
123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // does not have glyphs available for the character. According a blog post
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // http://blogs.msdn.com/michkap/archive/2006/06/28/649791.aspx
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // I think we should switch to the way about calling GetGlyphIndices with
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // flag GGI_MARK_NONEXISTING_GLYPHS, it should be OK according the
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // description of MSDN.
128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Also according to Jungshik and Hironori's suggestion and modification
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // we treat turetype and raster Font as different way when windows version
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // is less than Vista.
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    GetGlyphIndices(dc, buffer, length, localGlyphBuffer, GGI_MARK_NONEXISTING_GLYPHS);
132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Copy the output to the GlyphPage
134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    bool haveGlyphs = false;
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int invalidGlyph = 0xFFFF;
136692e5dbf12901edacf14812a6fae25462920af42Steve Block    const DWORD cffTableTag = 0x20464643; // 4-byte identifier for OpenType CFF table ('CFF ').
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((windowsVersion() < WindowsVista) && !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR))
138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        invalidGlyph = 0x1F;
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Glyph spaceGlyph = 0;  // Glyph for a space. Lazily filled.
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (unsigned i = 0; i < length; i++) {
143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        UChar c = buffer[i];
144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Glyph glyph = localGlyphBuffer[i];
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        const SimpleFontData* glyphFontData = fontData;
146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // When this character should be a space, we ignore whatever the font
147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // says and use a space. Otherwise, if fonts don't map one of these
148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // space or zero width glyphs, we will get a box.
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (Font::treatAsSpace(c)) {
150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Hard code the glyph indices for characters that should be
151635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // treated like spaces.
152635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            glyph = initSpaceGlyph(dc, &spaceGlyph);
153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else if (glyph == invalidGlyph) {
154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // WebKit expects both the glyph index and FontData
155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // pointer to be 0 if the glyph is not present
156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            glyph = 0;
157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            glyphFontData = 0;
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else
159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            haveGlyphs = true;
160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        page->setGlyphDataForCharacter(offset + i, glyph, glyphFontData);
161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    SelectObject(dc, oldFont);
164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ReleaseDC(0, dc);
165635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return haveGlyphs;
166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// For non-BMP characters, each is two words (UTF-16) and the input buffer
169635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// size is 2 * |length|. Since GDI doesn't know how to handle non-BMP
170635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// characters, we must use Uniscribe to tell us the glyph indices.
171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project//
172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// We don't want to call this in the case of "regular" characters since some
173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// fonts may not have the correct combining rules for accents. See the notes
174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// at the bottom of ScriptGetCMap. We can't use ScriptGetCMap, though, since
175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// it doesn't seem to support UTF-16, despite what this blog post says:
176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project//   http://blogs.msdn.com/michkap/archive/2006/06/29/650680.aspx
177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project//
178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// So we fire up the full Uniscribe doohicky, give it our string, and it will
179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// correctly handle the UTF-16 for us. The hard part is taking this and getting
180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// the glyph indices back out that correspond to the correct input characters,
181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// since they may be missing.
182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project//
183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Returns true if any glyphs were found.
184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool fillNonBMPGlyphs(unsigned offset,
185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                             unsigned length,
186635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                             UChar* buffer,
187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                             GlyphPage* page,
188635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                             const SimpleFontData* fontData)
189635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
190635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    bool haveGlyphs = false;
191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    UniscribeHelperTextRun state(buffer, length * 2, false,
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                                 fontData->platformData().hfont(),
1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                                 fontData->platformData().scriptCache(),
1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                                 fontData->platformData().scriptFontProperties());
196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    state.setInhibitLigate(true);
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    state.setDisableFontFallback(true);
198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    state.init();
199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (unsigned i = 0; i < length; i++) {
201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Each character in this input buffer is a surrogate pair, which
202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // consists of two UChars. So, the offset for its i-th character is
203635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // (i * 2).
204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        WORD glyph = state.firstGlyphForCharacter(i * 2);
205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (glyph) {
206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            haveGlyphs = true;
207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            page->setGlyphDataForIndex(offset + i, glyph, fontData);
208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else
209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Clear both glyph and fontData fields.
210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            page->setGlyphDataForIndex(offset + i, 0, 0);
211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return haveGlyphs;
213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// We're supposed to return true if there are any glyphs in the range
216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// specified by |offset| and |length| in  our font,
217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// false if there are none.
218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool GlyphPage::fill(unsigned offset, unsigned length, UChar* characterBuffer,
219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                     unsigned bufferLength, const SimpleFontData* fontData)
220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // We have to handle BMP and non-BMP characters differently.
222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: Add assertions to make sure that buffer is entirely in BMP
223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // or entirely in non-BMP.
224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (bufferLength == length)
225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return fillBMPGlyphs(offset, length, characterBuffer, this, fontData, true);
226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (bufferLength == 2 * length) {
228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // A non-BMP input buffer will be twice as long as output glyph buffer
229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // because each character in the non-BMP input buffer will be
230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // represented by a surrogate pair (two UChar's).
231635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return fillNonBMPGlyphs(offset, length, characterBuffer, this, fontData);
232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT_NOT_REACHED();
235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}  // namespace WebCore
239