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