1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Copyright (C) 1999-2008, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * file name: GDIFontInstance.cpp 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * created on: 08/09/2000 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * created by: Eric R. Mader 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <windows.h> 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LETypes.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LESwaps.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "layout/LEFontInstance.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GDIFontInstance.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "sfnt.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmaps.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGDISurface::GDISurface(HDC theHDC) 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : fHdc(theHDC), fCurrentFont(NULL) 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing else to do 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGDISurface::~GDISurface() 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid GDISurface::setHDC(HDC theHDC) 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fHdc = theHDC; 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fCurrentFont = NULL; 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid GDISurface::setFont(const GDIFontInstance *font) 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fCurrentFont != font) { 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fCurrentFont = font; 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SelectObject(fHdc, font->getFont()); 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SelectObject(fHdc, font->getFont()); 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid GDISurface::drawGlyphs(const LEFontInstance *font, const LEGlyphID *glyphs, le_int32 count, const float *positions, 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 x, le_int32 y, le_int32 width, le_int32 height) 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TTGlyphID *ttGlyphs = LE_NEW_ARRAY(TTGlyphID, count); 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 *dx = LE_NEW_ARRAY(le_int32, count); 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float *ps = LE_NEW_ARRAY(float, count * 2 + 2); 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 out = 0; 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru RECT clip; 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clip.top = 0; 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clip.left = 0; 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clip.bottom = height; 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clip.right = width; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 g = 0; g < count; g += 1) { 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphs[g]); 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ttGlyph < 0xFFFE) { 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ttGlyphs[out] = ttGlyph; 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dx[out] = (le_int32) (positions[g * 2 + 2] - positions[g * 2]); 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ps[out * 2] = positions[g * 2]; 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ps[out * 2 + 1] = positions[g * 2 + 1]; 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru out += 1; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 dyStart, dyEnd; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setFont((GDIFontInstance *) font); 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dyStart = dyEnd = 0; 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (dyEnd < out) { 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float yOffset = ps[dyStart * 2 + 1]; 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float xOffset = ps[dyStart * 2]; 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (dyEnd < out && yOffset == ps[dyEnd * 2 + 1]) { 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dyEnd += 1; 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ExtTextOut(fHdc, x + (le_int32) xOffset, y + (le_int32) yOffset - font->getAscent(), ETO_CLIPPED | ETO_GLYPH_INDEX, &clip, 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (LPCWSTR) &ttGlyphs[dyStart], dyEnd - dyStart, (INT *) &dx[dyStart]); 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dyStart = dyEnd; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(ps); 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(dx); 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(ttGlyphs); 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGDIFontInstance::GDIFontInstance(GDISurface *surface, TCHAR *faceName, le_int16 pointSize, LEErrorCode &status) 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : FontTableCache(), fSurface(surface), fFont(NULL), 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0), 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL) 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LOGFONT lf; 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FLOAT dpiX, dpiY; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru POINT pt; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OUTLINETEXTMETRIC otm; 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru HDC hdc = surface->getHDC(); 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SaveDC(hdc); 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SetGraphicsMode(hdc, GM_ADVANCED); 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SetViewportOrgEx(hdc, 0, 0, NULL); 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SetWindowOrgEx(hdc, 0, 0, NULL); 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dpiX = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSX); 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dpiY = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSY); 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 1 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pt.x = (int) (pointSize * dpiX / 72); 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pt.y = (int) (pointSize * dpiY / 72); 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DPtoLP(hdc, &pt, 1); 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pt.x = pt.y = pointSize; 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfHeight = - pt.y; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfWidth = 0; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfEscapement = 0; 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfOrientation = 0; 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfWeight = 0; 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfItalic = 0; 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfUnderline = 0; 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfStrikeOut = 0; 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfCharSet = DEFAULT_CHARSET; 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfOutPrecision = 0; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfClipPrecision = 0; 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfQuality = 0; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfPitchAndFamily = 0; 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lstrcpy(lf.lfFaceName, faceName); 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFont = CreateFontIndirect(&lf); 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fFont == NULL) { 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = LE_FONT_FILE_NOT_FOUND_ERROR; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SelectObject(hdc, fFont); 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UINT ret = GetOutlineTextMetrics(hdc, sizeof otm, &otm); 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ret == 0) { 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = LE_MISSING_FONT_TABLE_ERROR; 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto restore; 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fUnitsPerEM = otm.otmEMSquare; 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fAscent = otm.otmTextMetrics.tmAscent; 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fDescent = otm.otmTextMetrics.tmDescent; 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fLeading = otm.otmTextMetrics.tmExternalLeading; 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = initMapper(); 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto restore; 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = initFontTableCache(); 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querurestore: 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru RestoreDC(hdc, -1); 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGDIFontInstance::GDIFontInstance(GDISurface *surface, const char *faceName, le_int16 pointSize, LEErrorCode &status) 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : FontTableCache(), fSurface(surface), fFont(NULL), 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0), 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL) 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LOGFONTA lf; 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FLOAT dpiX, dpiY; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru POINT pt; 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OUTLINETEXTMETRIC otm; 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru HDC hdc = surface->getHDC(); 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SaveDC(hdc); 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SetGraphicsMode(hdc, GM_ADVANCED); 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SetViewportOrgEx(hdc, 0, 0, NULL); 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SetWindowOrgEx(hdc, 0, 0, NULL); 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dpiX = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSX); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dpiY = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSY); 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fDeviceScaleX = dpiX / 72; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fDeviceScaleY = dpiY / 72; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 1 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pt.x = (int) (pointSize * fDeviceScaleX); 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pt.y = (int) (pointSize * fDeviceScaleY); 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DPtoLP(hdc, &pt, 1); 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pt.x = pt.y = pointSize; 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfHeight = - pt.y; 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfWidth = 0; 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfEscapement = 0; 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfOrientation = 0; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfWeight = 0; 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfItalic = 0; 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfUnderline = 0; 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfStrikeOut = 0; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfCharSet = DEFAULT_CHARSET; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfOutPrecision = 0; 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfClipPrecision = 0; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfQuality = 0; 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lf.lfPitchAndFamily = 0; 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru strcpy(lf.lfFaceName, faceName); 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFont = CreateFontIndirectA(&lf); 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fFont == NULL) { 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = LE_FONT_FILE_NOT_FOUND_ERROR; 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SelectObject(hdc, fFont); 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UINT ret = GetOutlineTextMetrics(hdc, sizeof otm, &otm); 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (ret != 0) { 25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fUnitsPerEM = otm.otmEMSquare; 25585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fAscent = otm.otmTextMetrics.tmAscent; 25685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fDescent = otm.otmTextMetrics.tmDescent; 25785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fLeading = otm.otmTextMetrics.tmExternalLeading; 25885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 25985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const HEADTable *headTable = NULL; 26085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const HHEATable *hheaTable = NULL; 26185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 26285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // read unitsPerEm from 'head' table 26385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho headTable = (const HEADTable *) readFontTable(LE_HEAD_TABLE_TAG); 26485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 26585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (headTable == NULL) { 26685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho status = LE_MISSING_FONT_TABLE_ERROR; 26785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho goto restore; 26885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fUnitsPerEM = SWAPW(headTable->unitsPerEm); 27185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho freeFontTable((const void *)headTable); 27285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 27385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho hheaTable = (HHEATable *) readFontTable(LE_HHEA_TABLE_TAG); 27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (hheaTable == NULL) { 27685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho status = LE_MISSING_FONT_TABLE_ERROR; 27785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho goto restore; 27885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 27985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 28085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent)); 28185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent)); 28285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap)); 28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 28485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho freeFontTable((const void *) hheaTable); 28585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = initMapper(); 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(status)) { 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto restore; 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = initFontTableCache(); 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querurestore: 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru RestoreDC(hdc, -1); 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGDIFontInstance::~GDIFontInstance() 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru flushFontTableCache(); 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete[] fTableCache; 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fFont != NULL) { 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // FIXME: call RemoveObject first? 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DeleteObject(fFont); 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fMapper; 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fMapper = NULL; 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEErrorCode GDIFontInstance::initMapper() 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LETag cmapTag = LE_CMAP_TABLE_TAG; 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CMAPTable *cmap = (const CMAPTable *) readFontTable(cmapTag); 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cmap == NULL) { 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LE_MISSING_FONT_TABLE_ERROR; 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fMapper = CMAPMapper::createUnicodeMapper(cmap); 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fMapper == NULL) { 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LE_MISSING_FONT_TABLE_ERROR; 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LE_NO_ERROR; 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst void *GDIFontInstance::getFontTable(LETag tableTag) const 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FontTableCache::find(tableTag); 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst void *GDIFontInstance::readFontTable(LETag tableTag) const 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fSurface->setFont(this); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru HDC hdc = fSurface->getHDC(); 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DWORD stag = SWAPL(tableTag); 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DWORD len = GetFontData(hdc, stag, 0, NULL, 0); 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *result = NULL; 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len != GDI_ERROR) { 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = LE_NEW_ARRAY(char, len); 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GetFontData(hdc, stag, 0, result, len); 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid GDIFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru advance.fX = 0; 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru advance.fY = 0; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (glyph == 0xFFFE || glyph == 0xFFFF) { 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GLYPHMETRICS metrics; 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DWORD result; 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru HDC hdc = fSurface->getHDC(); 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fSurface->setFont(this); 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_METRICS, &metrics, 0, NULL, &identity); 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result == GDI_ERROR) { 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru advance.fX = metrics.gmCellIncX; 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_bool GDIFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru hsFixedPoint2 pt; 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_bool result; 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = fFontInstance->getGlyphPoint(glyph, pointNumber, pt); 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result) { 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru point.fX = xUnitsToPoints(pt.fX); 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru point.fY = yUnitsToPoints(pt.fY); 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 403