16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 1999-2008, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * file name: GDIFontInstance.cpp 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * created on: 08/09/2000 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * created by: Eric R. Mader 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <windows.h> 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "layout/LETypes.h" 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "layout/LESwaps.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "layout/LEFontInstance.h" 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "GDIFontInstance.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "sfnt.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmaps.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgGDISurface::GDISurface(HDC theHDC) 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : fHdc(theHDC), fCurrentFont(NULL) 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // nothing else to do 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgGDISurface::~GDISurface() 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // nothing to do 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid GDISurface::setHDC(HDC theHDC) 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fHdc = theHDC; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fCurrentFont = NULL; 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid GDISurface::setFont(const GDIFontInstance *font) 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fCurrentFont != font) { 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fCurrentFont = font; 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SelectObject(fHdc, font->getFont()); 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SelectObject(fHdc, font->getFont()); 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid GDISurface::drawGlyphs(const LEFontInstance *font, const LEGlyphID *glyphs, le_int32 count, const float *positions, 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org le_int32 x, le_int32 y, le_int32 width, le_int32 height) 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TTGlyphID *ttGlyphs = LE_NEW_ARRAY(TTGlyphID, count); 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org le_int32 *dx = LE_NEW_ARRAY(le_int32, count); 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org float *ps = LE_NEW_ARRAY(float, count * 2 + 2); 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org le_int32 out = 0; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RECT clip; 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clip.top = 0; 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clip.left = 0; 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clip.bottom = height; 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clip.right = width; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (le_int32 g = 0; g < count; g += 1) { 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphs[g]); 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ttGlyph < 0xFFFE) { 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ttGlyphs[out] = ttGlyph; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dx[out] = (le_int32) (positions[g * 2 + 2] - positions[g * 2]); 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ps[out * 2] = positions[g * 2]; 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ps[out * 2 + 1] = positions[g * 2 + 1]; 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org out += 1; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org le_int32 dyStart, dyEnd; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setFont((GDIFontInstance *) font); 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dyStart = dyEnd = 0; 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (dyEnd < out) { 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org float yOffset = ps[dyStart * 2 + 1]; 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org float xOffset = ps[dyStart * 2]; 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (dyEnd < out && yOffset == ps[dyEnd * 2 + 1]) { 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dyEnd += 1; 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ExtTextOut(fHdc, x + (le_int32) xOffset, y + (le_int32) yOffset - font->getAscent(), ETO_CLIPPED | ETO_GLYPH_INDEX, &clip, 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (LPCWSTR) &ttGlyphs[dyStart], dyEnd - dyStart, (INT *) &dx[dyStart]); 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dyStart = dyEnd; 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LE_DELETE_ARRAY(ps); 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LE_DELETE_ARRAY(dx); 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LE_DELETE_ARRAY(ttGlyphs); 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgGDIFontInstance::GDIFontInstance(GDISurface *surface, TCHAR *faceName, le_int16 pointSize, LEErrorCode &status) 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : FontTableCache(), fSurface(surface), fFont(NULL), 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0), 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL) 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LOGFONT lf; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FLOAT dpiX, dpiY; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org POINT pt; 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org OUTLINETEXTMETRIC otm; 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org HDC hdc = surface->getHDC(); 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (LE_FAILURE(status)) { 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SaveDC(hdc); 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SetGraphicsMode(hdc, GM_ADVANCED); 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SetViewportOrgEx(hdc, 0, 0, NULL); 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SetWindowOrgEx(hdc, 0, 0, NULL); 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dpiX = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSX); 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dpiY = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSY); 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 1 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pt.x = (int) (pointSize * dpiX / 72); 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pt.y = (int) (pointSize * dpiY / 72); 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DPtoLP(hdc, &pt, 1); 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pt.x = pt.y = pointSize; 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfHeight = - pt.y; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfWidth = 0; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfEscapement = 0; 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfOrientation = 0; 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfWeight = 0; 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfItalic = 0; 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfUnderline = 0; 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfStrikeOut = 0; 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfCharSet = DEFAULT_CHARSET; 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfOutPrecision = 0; 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfClipPrecision = 0; 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfQuality = 0; 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfPitchAndFamily = 0; 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lstrcpy(lf.lfFaceName, faceName); 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fFont = CreateFontIndirect(&lf); 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fFont == NULL) { 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = LE_FONT_FILE_NOT_FOUND_ERROR; 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SelectObject(hdc, fFont); 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UINT ret = GetOutlineTextMetrics(hdc, sizeof otm, &otm); 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ret == 0) { 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = LE_MISSING_FONT_TABLE_ERROR; 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto restore; 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fUnitsPerEM = otm.otmEMSquare; 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fAscent = otm.otmTextMetrics.tmAscent; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDescent = otm.otmTextMetrics.tmDescent; 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLeading = otm.otmTextMetrics.tmExternalLeading; 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = initMapper(); 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (LE_FAILURE(status)) { 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto restore; 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = initFontTableCache(); 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgrestore: 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RestoreDC(hdc, -1); 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgGDIFontInstance::GDIFontInstance(GDISurface *surface, const char *faceName, le_int16 pointSize, LEErrorCode &status) 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : FontTableCache(), fSurface(surface), fFont(NULL), 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0), 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL) 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LOGFONTA lf; 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FLOAT dpiX, dpiY; 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org POINT pt; 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org OUTLINETEXTMETRIC otm; 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org HDC hdc = surface->getHDC(); 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (LE_FAILURE(status)) { 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SaveDC(hdc); 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SetGraphicsMode(hdc, GM_ADVANCED); 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SetViewportOrgEx(hdc, 0, 0, NULL); 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SetWindowOrgEx(hdc, 0, 0, NULL); 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dpiX = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSX); 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dpiY = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSY); 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDeviceScaleX = dpiX / 72; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDeviceScaleY = dpiY / 72; 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 1 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pt.x = (int) (pointSize * fDeviceScaleX); 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pt.y = (int) (pointSize * fDeviceScaleY); 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DPtoLP(hdc, &pt, 1); 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pt.x = pt.y = pointSize; 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfHeight = - pt.y; 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfWidth = 0; 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfEscapement = 0; 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfOrientation = 0; 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfWeight = 0; 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfItalic = 0; 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfUnderline = 0; 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfStrikeOut = 0; 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfCharSet = DEFAULT_CHARSET; 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfOutPrecision = 0; 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfClipPrecision = 0; 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfQuality = 0; 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lf.lfPitchAndFamily = 0; 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org strcpy(lf.lfFaceName, faceName); 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fFont = CreateFontIndirectA(&lf); 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fFont == NULL) { 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = LE_FONT_FILE_NOT_FOUND_ERROR; 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SelectObject(hdc, fFont); 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UINT ret = GetOutlineTextMetrics(hdc, sizeof otm, &otm); 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ret != 0) { 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fUnitsPerEM = otm.otmEMSquare; 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fAscent = otm.otmTextMetrics.tmAscent; 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDescent = otm.otmTextMetrics.tmDescent; 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLeading = otm.otmTextMetrics.tmExternalLeading; 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const HEADTable *headTable = NULL; 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const HHEATable *hheaTable = NULL; 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // read unitsPerEm from 'head' table 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org headTable = (const HEADTable *) readFontTable(LE_HEAD_TABLE_TAG); 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (headTable == NULL) { 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = LE_MISSING_FONT_TABLE_ERROR; 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto restore; 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fUnitsPerEM = SWAPW(headTable->unitsPerEm); 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org freeFontTable((const void *)headTable); 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hheaTable = (HHEATable *) readFontTable(LE_HHEA_TABLE_TAG); 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (hheaTable == NULL) { 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = LE_MISSING_FONT_TABLE_ERROR; 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto restore; 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent)); 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent)); 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap)); 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org freeFontTable((const void *) hheaTable); 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = initMapper(); 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (LE_FAILURE(status)) { 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto restore; 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = initFontTableCache(); 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgrestore: 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RestoreDC(hdc, -1); 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgGDIFontInstance::~GDIFontInstance() 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flushFontTableCache(); 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete[] fTableCache; 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fFont != NULL) { 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // FIXME: call RemoveObject first? 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DeleteObject(fFont); 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fMapper; 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMapper = NULL; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgLEErrorCode GDIFontInstance::initMapper() 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LETag cmapTag = LE_CMAP_TABLE_TAG; 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const CMAPTable *cmap = (const CMAPTable *) readFontTable(cmapTag); 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cmap == NULL) { 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return LE_MISSING_FONT_TABLE_ERROR; 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMapper = CMAPMapper::createUnicodeMapper(cmap); 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fMapper == NULL) { 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return LE_MISSING_FONT_TABLE_ERROR; 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return LE_NO_ERROR; 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst void *GDIFontInstance::getFontTable(LETag tableTag) const 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FontTableCache::find(tableTag); 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst void *GDIFontInstance::readFontTable(LETag tableTag) const 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fSurface->setFont(this); 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org HDC hdc = fSurface->getHDC(); 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DWORD stag = SWAPL(tableTag); 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DWORD len = GetFontData(hdc, stag, 0, NULL, 0); 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void *result = NULL; 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len != GDI_ERROR) { 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = LE_NEW_ARRAY(char, len); 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org GetFontData(hdc, stag, 0, result, len); 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid GDIFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org advance.fX = 0; 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org advance.fY = 0; 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (glyph == 0xFFFE || glyph == 0xFFFF) { 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org GLYPHMETRICS metrics; 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DWORD result; 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org HDC hdc = fSurface->getHDC(); 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fSurface->setFont(this); 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_METRICS, &metrics, 0, NULL, &identity); 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result == GDI_ERROR) { 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org advance.fX = metrics.gmCellIncX; 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgle_bool GDIFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hsFixedPoint2 pt; 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org le_bool result; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = fFontInstance->getGlyphPoint(glyph, pointNumber, pt); 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result) { 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org point.fX = xUnitsToPoints(pt.fX); 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org point.fY = yUnitsToPoints(pt.fY); 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 403