18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SimpleFontData.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Font.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontCache.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FloatRect.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontDescription.h"
362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <mlang.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <unicode/uchar.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <unicode/unorm.h>
392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <winsock2.h>
402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/MathExtras.h>
410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CG)
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <ApplicationServices/ApplicationServices.h>
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebKitSystemInterface/WebKitSystemInterface.h>
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing std::max;
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst float cSmallCapsFontSizeMultiplier = 0.7f;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool g_shouldApplyMacAscentHack;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SimpleFontData::setShouldApplyMacAscentHack(bool b)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    g_shouldApplyMacAscentHack = b;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SimpleFontData::shouldApplyMacAscentHack()
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return g_shouldApplyMacAscentHack;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SimpleFontData::initGDIFont()
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!m_platformData.size()) {
682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_fontMetrics.reset();
696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        m_avgCharWidth = 0;
706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        m_maxCharWidth = 0;
716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return;
726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     HDC hdc = GetDC(0);
755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian     HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     OUTLINETEXTMETRIC metrics;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     float ascent = textMetrics.tmAscent;
802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     float descent = textMetrics.tmDescent;
812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     float lineGap = textMetrics.tmExternalLeading;
822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     m_fontMetrics.setAscent(ascent);
832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     m_fontMetrics.setDescent(descent);
842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     m_fontMetrics.setLineGap(lineGap);
852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian     m_avgCharWidth = textMetrics.tmAveCharWidth;
875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian     m_maxCharWidth = textMetrics.tmMaxCharWidth;
882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     float xHeight = ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     GLYPHMETRICS gm;
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     MAT2 mat = { 1, 0, 0, 1 };
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block         xHeight = gm.gmptGlyphOrigin.y;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     m_fontMetrics.setXHeight(xHeight);
972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block     m_fontMetrics.setUnitsPerEm(metrics.otmEMSquare);
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     SelectObject(hdc, oldFont);
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     ReleaseDC(0, hdc);
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     return;
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid SimpleFontData::platformDestroy()
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ScriptFreeCache(&m_scriptCache);
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete m_scriptFontProperties;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
111f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
113f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        float scaledSize = scaleFactor * m_platformData.size();
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isCustomFont()) {
115f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            FontPlatformData scaledFont(m_platformData);
116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            scaledFont.setSize(scaledSize);
117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return new SimpleFontData(scaledFont, true, false);
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
119f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
120f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        LOGFONT winfont;
121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont);
122f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        winfont.lfHeight = -lroundf(scaledSize * (m_platformData.useGDI() ? 1 : 32));
123f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        HFONT hfont = CreateFontIndirect(&winfont);
124f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return new SimpleFontData(FontPlatformData(hfont, scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false);
125f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
126f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
127f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
129f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_derivedFontData)
130f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_derivedFontData = DerivedFontData::create(isCustomFont());
131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_derivedFontData->smallCaps)
132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_derivedFontData->smallCaps = scaledFontData(fontDescription, cSmallCapsFontSizeMultiplier);
133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return m_derivedFontData->smallCaps.get();
135f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
136f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
137f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_derivedFontData)
140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_derivedFontData = DerivedFontData::create(isCustomFont());
141f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_derivedFontData->emphasisMark)
142f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
143f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return m_derivedFontData->emphasisMark.get();
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SimpleFontData::containsCharacters(const UChar* characters, int length) const
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Support custom fonts.
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isCustomFont())
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // merely by testing code page intersection.  This seems suspect though.  Can't a font only partially
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // cover a given code page?
156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface();
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!langFontLink)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HDC dc = GetDC(0);
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD acpCodePages;
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD fontCodePages;
1665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    langFontLink->GetFontCodePages(dc, m_platformData.hfont(), &fontCodePages);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD actualCodePages;
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long numCharactersProcessed;
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long offset = 0;
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (offset < length) {
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed);
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((actualCodePages & fontCodePages) == 0)
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        offset += numCharactersProcessed;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ReleaseDC(0, dc);
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SimpleFontData::determinePitch()
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isCustomFont()) {
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_treatAsFixedPitch = false;
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // TEXTMETRICS have this.  Set m_treatAsFixedPitch based off that.
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HDC dc = GetDC(0);
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SaveDC(dc);
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectObject(dc, m_platformData.hfont());
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Yes, this looks backwards, but the fixed pitch bit is actually set if the font
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // is *not* fixed pitch.  Unbelievable but true.
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TEXTMETRIC tm;
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GetTextMetrics(dc, &tm);
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_treatAsFixedPitch = ((tm.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0);
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RestoreDC(dc, -1);
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ReleaseDC(0, dc);
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20521939df44de1705786c545cd1bf519d47250322dBen MurdochFloatRect SimpleFontData::boundsForGDIGlyph(Glyph glyph) const
20621939df44de1705786c545cd1bf519d47250322dBen Murdoch{
20721939df44de1705786c545cd1bf519d47250322dBen Murdoch    HDC hdc = GetDC(0);
20821939df44de1705786c545cd1bf519d47250322dBen Murdoch    SetGraphicsMode(hdc, GM_ADVANCED);
20921939df44de1705786c545cd1bf519d47250322dBen Murdoch    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
21021939df44de1705786c545cd1bf519d47250322dBen Murdoch
21121939df44de1705786c545cd1bf519d47250322dBen Murdoch    GLYPHMETRICS gdiMetrics;
21221939df44de1705786c545cd1bf519d47250322dBen Murdoch    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
21321939df44de1705786c545cd1bf519d47250322dBen Murdoch    GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity);
21421939df44de1705786c545cd1bf519d47250322dBen Murdoch
21521939df44de1705786c545cd1bf519d47250322dBen Murdoch    SelectObject(hdc, oldFont);
21621939df44de1705786c545cd1bf519d47250322dBen Murdoch    ReleaseDC(0, hdc);
21721939df44de1705786c545cd1bf519d47250322dBen Murdoch
21821939df44de1705786c545cd1bf519d47250322dBen Murdoch    return FloatRect(gdiMetrics.gmptGlyphOrigin.x, -gdiMetrics.gmptGlyphOrigin.y,
21921939df44de1705786c545cd1bf519d47250322dBen Murdoch        gdiMetrics.gmBlackBoxX + m_syntheticBoldOffset, gdiMetrics.gmBlackBoxY);
22021939df44de1705786c545cd1bf519d47250322dBen Murdoch}
22121939df44de1705786c545cd1bf519d47250322dBen Murdoch
22221939df44de1705786c545cd1bf519d47250322dBen Murdochfloat SimpleFontData::widthForGDIGlyph(Glyph glyph) const
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HDC hdc = GetDC(0);
225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    SetGraphicsMode(hdc, GM_ADVANCED);
2265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
227dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
228dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    GLYPHMETRICS gdiMetrics;
229dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
230dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity);
231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SelectObject(hdc, oldFont);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ReleaseDC(0, hdc);
234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
23521939df44de1705786c545cd1bf519d47250322dBen Murdoch    return gdiMetrics.gmCellIncX + m_syntheticBoldOffset;
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_scriptFontProperties) {
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_scriptFontProperties = new SCRIPT_FONTPROPERTIES;
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memset(m_scriptFontProperties, 0, sizeof(SCRIPT_FONTPROPERTIES));
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_scriptFontProperties->cBytes = sizeof(SCRIPT_FONTPROPERTIES);
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HRESULT result = ScriptGetFontProperties(0, scriptCache(), m_scriptFontProperties);
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result == E_PENDING) {
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HDC dc = GetDC(0);
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SaveDC(dc);
2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            SelectObject(dc, m_platformData.hfont());
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ScriptGetFontProperties(dc, scriptCache(), m_scriptFontProperties);
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RestoreDC(dc, -1);
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ReleaseDC(0, dc);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_scriptFontProperties;
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
258