Implement UpdateTexture for 2D textures only.
[wine] / objects / font.c
index ecadda5..d0063aa 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 1993 Alexandre Julliard
  *           1997 Alex Korobka
+ * Copyright 2002,2003 Shachar Shemesh
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 #include "winerror.h"
 #include "winnls.h"
+#include "wownt32.h"
+#include "gdi.h"
 #include "wine/unicode.h"
-#include "font.h"
-#include "options.h"
 #include "wine/debug.h"
-#include "gdi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(font);
 WINE_DECLARE_DEBUG_CHANNEL(gdi);
 
+static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
+static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs font_funcs =
+{
+    FONT_SelectObject,  /* pSelectObject */
+    FONT_GetObject16,   /* pGetObject16 */
+    FONT_GetObjectA,    /* pGetObjectA */
+    FONT_GetObjectW,    /* pGetObjectW */
+    NULL,               /* pUnrealizeObject */
+    FONT_DeleteObject   /* pDeleteObject */
+};
+
 #define ENUM_UNICODE   0x00000001
 #define ENUM_CALLED     0x00000002
 
+typedef struct
+{
+    GDIOBJHDR   header;
+    LOGFONTW    logfont;
+} FONTOBJ;
+
 typedef struct
 {
   LPLOGFONT16           lpLogFontParam;
-  FONTENUMPROCEX16      lpEnumFunc;
+  FONTENUMPROC16        lpEnumFunc;
   LPARAM                lpData;
 
   LPNEWTEXTMETRICEX16   lpTextMetric;
   LPENUMLOGFONTEX16     lpLogFont;
   SEGPTR                segTextMetric;
   SEGPTR                segLogFont;
+  DWORD                 dwFlags;
+  HDC                   hdc;
+  DC                   *dc;
+  PHYSDEV               physDev;
 } fontEnum16;
 
 typedef struct
 {
   LPLOGFONTW          lpLogFontParam;
-  FONTENUMPROCEXW     lpEnumFunc;
+  FONTENUMPROCW       lpEnumFunc;
   LPARAM              lpData;
   DWORD               dwFlags;
+  HDC                 hdc;
+  DC                 *dc;
+  PHYSDEV             physDev;
 } fontEnum32;
+
 /*
  *  For TranslateCharsetInfo
  */
@@ -71,6 +103,7 @@ static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
   { HEBREW_CHARSET, 1255, FS(5)},
   { ARABIC_CHARSET, 1256, FS(6)},
   { BALTIC_CHARSET, 1257, FS(7)},
+  { VIETNAMESE_CHARSET, 1258, FS(8)},
   /* reserved by ANSI */
   { DEFAULT_CHARSET, 0, FS(0)},
   { DEFAULT_CHARSET, 0, FS(0)},
@@ -79,14 +112,13 @@ static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
   { DEFAULT_CHARSET, 0, FS(0)},
   { DEFAULT_CHARSET, 0, FS(0)},
   { DEFAULT_CHARSET, 0, FS(0)},
-  { DEFAULT_CHARSET, 0, FS(0)},
   /* ANSI and OEM */
   { THAI_CHARSET,  874,  FS(16)},
   { SHIFTJIS_CHARSET, 932, FS(17)},
   { GB2312_CHARSET, 936, FS(18)},
   { HANGEUL_CHARSET, 949, FS(19)},
   { CHINESEBIG5_CHARSET, 950, FS(20)},
-  { JOHAB_CHARSET, 1361, FS(21)}, 
+  { JOHAB_CHARSET, 1361, FS(21)},
   /* reserved for alternate ANSI and OEM */
   { DEFAULT_CHARSET, 0, FS(0)},
   { DEFAULT_CHARSET, 0, FS(0)},
@@ -98,35 +130,13 @@ static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
   { DEFAULT_CHARSET, 0, FS(0)},
   /* reserved for system */
   { DEFAULT_CHARSET, 0, FS(0)},
-  { DEFAULT_CHARSET, 0, FS(0)},
+  { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
 };
 
-/* ### start build ### */
-extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
-/* ### stop build ### */
-
 /***********************************************************************
  *              LOGFONT conversion functions.
  */
-void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
-{
-    font16->lfHeight = font32->lfHeight;
-    font16->lfWidth = font32->lfWidth;
-    font16->lfEscapement = font32->lfEscapement;
-    font16->lfOrientation = font32->lfOrientation;
-    font16->lfWeight = font32->lfWeight;
-    font16->lfItalic = font32->lfItalic;
-    font16->lfUnderline = font32->lfUnderline;
-    font16->lfStrikeOut = font32->lfStrikeOut;
-    font16->lfCharSet = font32->lfCharSet;
-    font16->lfOutPrecision = font32->lfOutPrecision;
-    font16->lfClipPrecision = font32->lfClipPrecision;
-    font16->lfQuality = font32->lfQuality;
-    font16->lfPitchAndFamily = font32->lfPitchAndFamily;
-    lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
-}
-
-void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
+static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
 {
     font16->lfHeight = font32->lfHeight;
     font16->lfWidth = font32->lfWidth;
@@ -146,25 +156,7 @@ void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
     font16->lfFaceName[LF_FACESIZE-1] = 0;
 }
 
-void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
-{
-    font32->lfHeight = font16->lfHeight;
-    font32->lfWidth = font16->lfWidth;
-    font32->lfEscapement = font16->lfEscapement;
-    font32->lfOrientation = font16->lfOrientation;
-    font32->lfWeight = font16->lfWeight;
-    font32->lfItalic = font16->lfItalic;
-    font32->lfUnderline = font16->lfUnderline;
-    font32->lfStrikeOut = font16->lfStrikeOut;
-    font32->lfCharSet = font16->lfCharSet;
-    font32->lfOutPrecision = font16->lfOutPrecision;
-    font32->lfClipPrecision = font16->lfClipPrecision;
-    font32->lfQuality = font16->lfQuality;
-    font32->lfPitchAndFamily = font16->lfPitchAndFamily;
-    lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
-}
-
-void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
+static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
 {
     font32->lfHeight = font16->lfHeight;
     font32->lfWidth = font16->lfWidth;
@@ -183,41 +175,21 @@ void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
     font32->lfFaceName[LF_FACESIZE-1] = 0;
 }
 
-void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
+static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
 {
     memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
     MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
                        LF_FACESIZE);
 }
 
-void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
+static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
 {
     memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
     WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
                        LF_FACESIZE, NULL, NULL);
 }
 
-void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
-{
-    FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
-    lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
-    lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
-    lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
-}
-
-void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
-{
-    FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
-
-    MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
-    font32->elfFullName[LF_FULLFACESIZE-1] = 0;
-    MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
-    font32->elfStyle[LF_FACESIZE-1] = 0;
-    MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
-    font32->elfScript[LF_FACESIZE-1] = 0;
-}
-
-void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
+static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
 {
     FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
 
@@ -232,7 +204,7 @@ void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 fon
     font16->elfScript[LF_FACESIZE-1] = '\0';
 }
 
-void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
+static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
 {
     FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
 
@@ -250,127 +222,7 @@ void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA
 /***********************************************************************
  *              TEXTMETRIC conversion functions.
  */
-void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
-{
-    ptm16->tmHeight = ptm32->tmHeight;
-    ptm16->tmAscent = ptm32->tmAscent;
-    ptm16->tmDescent = ptm32->tmDescent;
-    ptm16->tmInternalLeading = ptm32->tmInternalLeading;
-    ptm16->tmExternalLeading = ptm32->tmExternalLeading;
-    ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
-    ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
-    ptm16->tmWeight = ptm32->tmWeight;
-    ptm16->tmOverhang = ptm32->tmOverhang;
-    ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
-    ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
-    ptm16->tmFirstChar = ptm32->tmFirstChar;
-    ptm16->tmLastChar = ptm32->tmLastChar;
-    ptm16->tmDefaultChar = ptm32->tmDefaultChar;
-    ptm16->tmBreakChar = ptm32->tmBreakChar;
-    ptm16->tmItalic = ptm32->tmItalic;
-    ptm16->tmUnderlined = ptm32->tmUnderlined;
-    ptm16->tmStruckOut = ptm32->tmStruckOut;
-    ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
-    ptm16->tmCharSet = ptm32->tmCharSet;
-}
-
-void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
-{
-    ptm16->tmHeight = ptm32->tmHeight;
-    ptm16->tmAscent = ptm32->tmAscent;
-    ptm16->tmDescent = ptm32->tmDescent;
-    ptm16->tmInternalLeading = ptm32->tmInternalLeading;
-    ptm16->tmExternalLeading = ptm32->tmExternalLeading;
-    ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
-    ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
-    ptm16->tmWeight = ptm32->tmWeight;
-    ptm16->tmOverhang = ptm32->tmOverhang;
-    ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
-    ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
-    ptm16->tmFirstChar = ptm32->tmFirstChar;
-    ptm16->tmLastChar = ptm32->tmLastChar;
-    ptm16->tmDefaultChar = ptm32->tmDefaultChar;
-    ptm16->tmBreakChar = ptm32->tmBreakChar;
-    ptm16->tmItalic = ptm32->tmItalic;
-    ptm16->tmUnderlined = ptm32->tmUnderlined;
-    ptm16->tmStruckOut = ptm32->tmStruckOut;
-    ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
-    ptm16->tmCharSet = ptm32->tmCharSet;
-}
-
-void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
-{
-    ptm32->tmHeight = ptm16->tmHeight;
-    ptm32->tmAscent = ptm16->tmAscent;
-    ptm32->tmDescent = ptm16->tmDescent;
-    ptm32->tmInternalLeading = ptm16->tmInternalLeading;
-    ptm32->tmExternalLeading = ptm16->tmExternalLeading;
-    ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
-    ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
-    ptm32->tmWeight = ptm16->tmWeight;
-    ptm32->tmOverhang = ptm16->tmOverhang;
-    ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
-    ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
-    ptm32->tmFirstChar = ptm16->tmFirstChar;
-    ptm32->tmLastChar = ptm16->tmLastChar;
-    ptm32->tmDefaultChar = ptm16->tmDefaultChar;
-    ptm32->tmBreakChar = ptm16->tmBreakChar;
-    ptm32->tmItalic = ptm16->tmItalic;
-    ptm32->tmUnderlined = ptm16->tmUnderlined;
-    ptm32->tmStruckOut = ptm16->tmStruckOut;
-    ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
-    ptm32->tmCharSet = ptm16->tmCharSet;
-}
-
-void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
-{
-    ptm32->tmHeight = ptm16->tmHeight;
-    ptm32->tmAscent = ptm16->tmAscent;
-    ptm32->tmDescent = ptm16->tmDescent;
-    ptm32->tmInternalLeading = ptm16->tmInternalLeading;
-    ptm32->tmExternalLeading = ptm16->tmExternalLeading;
-    ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
-    ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
-    ptm32->tmWeight = ptm16->tmWeight;
-    ptm32->tmOverhang = ptm16->tmOverhang;
-    ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
-    ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
-    ptm32->tmFirstChar = ptm16->tmFirstChar;
-    ptm32->tmLastChar = ptm16->tmLastChar;
-    ptm32->tmDefaultChar = ptm16->tmDefaultChar;
-    ptm32->tmBreakChar = ptm16->tmBreakChar;
-    ptm32->tmItalic = ptm16->tmItalic;
-    ptm32->tmUnderlined = ptm16->tmUnderlined;
-    ptm32->tmStruckOut = ptm16->tmStruckOut;
-    ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
-    ptm32->tmCharSet = ptm16->tmCharSet;
-}
-
-void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
-{
-    ptm32W->tmHeight = ptm32A->tmHeight;
-    ptm32W->tmAscent = ptm32A->tmAscent;
-    ptm32W->tmDescent = ptm32A->tmDescent;
-    ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
-    ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
-    ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
-    ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
-    ptm32W->tmWeight = ptm32A->tmWeight;
-    ptm32W->tmOverhang = ptm32A->tmOverhang;
-    ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
-    ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
-    ptm32W->tmFirstChar = ptm32A->tmFirstChar;
-    ptm32W->tmLastChar = ptm32A->tmLastChar;
-    ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
-    ptm32W->tmBreakChar = ptm32A->tmBreakChar;
-    ptm32W->tmItalic = ptm32A->tmItalic;
-    ptm32W->tmUnderlined = ptm32A->tmUnderlined;
-    ptm32W->tmStruckOut = ptm32A->tmStruckOut;
-    ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
-    ptm32W->tmCharSet = ptm32A->tmCharSet;
-}
-
-void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
+static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
 {
     ptmA->tmHeight = ptmW->tmHeight;
     ptmA->tmAscent = ptmW->tmAscent;
@@ -395,9 +247,28 @@ void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
 }
 
 
-void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
-{
-    FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
+static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
+{
+    ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
+    ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
+    ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
+    ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
+    ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
+    ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
+    ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
+    ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
+    ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
+    ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
+    ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
+    ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
+    ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
+    ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
+    ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
+    ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
+    ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
+    ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
+    ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
+    ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
     ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
     ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
     ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
@@ -405,7 +276,7 @@ void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16
     memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
 }
 
-void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
+static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
 {
     FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
     ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
@@ -415,33 +286,6 @@ void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA p
     memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
 }
 
-void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
-{
-    FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
-    ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
-    ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
-    ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
-    ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
-    memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
-}
-
-
-/***********************************************************************
- *           CreateFontIndirect   (GDI.57)
- */
-HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
-{
-    LOGFONTW lfW;
-
-    if(plf16) {
-        FONT_LogFont16ToW( plf16, &lfW );
-       return CreateFontIndirectW( &lfW );
-    } else {
-        return CreateFontIndirectW( NULL );
-    }
-}
-
-
 /***********************************************************************
  *           CreateFontIndirectA   (GDI32.@)
  */
@@ -467,14 +311,17 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
     if (plf)
     {
         FONTOBJ* fontPtr;
-       if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
+       if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
+                                       (HGDIOBJ *)&hFont, &font_funcs )))
        {
            memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
 
-           TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
-                  plf->lfHeight, plf->lfWidth, 
+           TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
+                  plf->lfHeight, plf->lfWidth,
                   plf->lfEscapement, plf->lfOrientation,
                   plf->lfPitchAndFamily,
+                 plf->lfOutPrecision, plf->lfClipPrecision,
+                 plf->lfQuality, plf->lfCharSet,
                   debugstr_w(plf->lfFaceName),
                   plf->lfWeight > 400 ? "Bold" : "",
                   plf->lfItalic ? "Italic" : "", hFont);
@@ -483,7 +330,7 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
              /* this should really depend on whether GM_ADVANCED is set */
              fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
              WARN("orientation angle %f set to "
-                   "escapement angle %f for new font %04x\n", 
+                   "escapement angle %f for new font %p\n",
                    plf->lfOrientation/10., plf->lfEscapement/10., hFont);
            }
            GDI_ReleaseObj( hFont );
@@ -494,39 +341,6 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
     return hFont;
 }
 
-/***********************************************************************
- *           CreateFont    (GDI.56)
- */
-HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
-                            INT16 weight, BYTE italic, BYTE underline,
-                            BYTE strikeout, BYTE charset, BYTE outpres,
-                            BYTE clippres, BYTE quality, BYTE pitch,
-                            LPCSTR name )
-{
-    LOGFONT16 logfont;
-
-    logfont.lfHeight = height;
-    logfont.lfWidth = width;
-    logfont.lfEscapement = esc;
-    logfont.lfOrientation = orient;
-    logfont.lfWeight = weight;
-    logfont.lfItalic = italic;
-    logfont.lfUnderline = underline;
-    logfont.lfStrikeOut = strikeout;
-    logfont.lfCharSet = charset;
-    logfont.lfOutPrecision = outpres;
-    logfont.lfClipPrecision = clippres;
-    logfont.lfQuality = quality;
-    logfont.lfPitchAndFamily = pitch;
-   
-    if (name) 
-       lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
-    else 
-       logfont.lfFaceName[0] = '\0';
-
-    return CreateFontIndirect16( &logfont );
-}
-
 /*************************************************************************
  *           CreateFontA    (GDI32.@)
  */
@@ -551,10 +365,10 @@ HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
     logfont.lfClipPrecision = clippres;
     logfont.lfQuality = quality;
     logfont.lfPitchAndFamily = pitch;
-   
-    if (name) 
+
+    if (name)
        lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
-    else 
+    else
        logfont.lfFaceName[0] = '\0';
 
     return CreateFontIndirectA( &logfont );
@@ -584,22 +398,63 @@ HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
     logfont.lfClipPrecision = clippres;
     logfont.lfQuality = quality;
     logfont.lfPitchAndFamily = pitch;
-   
-    if (name) 
-       lstrcpynW(logfont.lfFaceName, name, 
+
+    if (name)
+       lstrcpynW(logfont.lfFaceName, name,
                  sizeof(logfont.lfFaceName) / sizeof(WCHAR));
-    else 
+    else
        logfont.lfFaceName[0] = '\0';
 
     return CreateFontIndirectW( &logfont );
 }
 
 
+/***********************************************************************
+ *           FONT_SelectObject
+ *
+ * If the driver supports vector fonts we create a gdi font first and
+ * then call the driver to give it a chance to supply its own device
+ * font.  If the driver wants to do this it returns TRUE and we can
+ * delete the gdi font, if the driver wants to use the gdi font it
+ * should return FALSE, to signal an error return GDI_ERROR.  For
+ * drivers that don't support vector fonts they must supply their own
+ * font.
+ */
+static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
+{
+    HGDIOBJ ret = 0;
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (!dc) return 0;
+
+    if (dc->hFont != handle || dc->gdiFont == NULL)
+    {
+        if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
+            dc->gdiFont = WineEngCreateFontInstance(dc, handle);
+    }
+
+    if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
+
+    if (ret && dc->gdiFont) dc->gdiFont = 0;
+
+    if (ret == HGDI_ERROR)
+        ret = 0; /* SelectObject returns 0 on error */
+    else
+    {
+        ret = dc->hFont;
+        dc->hFont = handle;
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
+}
+
+
 /***********************************************************************
  *           FONT_GetObject16
  */
-INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
+static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    FONTOBJ *font = obj;
     LOGFONT16 lf16;
 
     FONT_LogFontWTo16( &font->logfont, &lf16 );
@@ -612,132 +467,190 @@ INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
 /***********************************************************************
  *           FONT_GetObjectA
  */
-INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
+static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    FONTOBJ *font = obj;
     LOGFONTA lfA;
 
     FONT_LogFontWToA( &font->logfont, &lfA );
 
     if (count > sizeof(lfA)) count = sizeof(lfA);
-    memcpy( buffer, &lfA, count );
+    if(buffer)
+        memcpy( buffer, &lfA, count );
     return count;
 }
+
 /***********************************************************************
  *           FONT_GetObjectW
  */
-INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
+static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    FONTOBJ *font = obj;
     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
-    memcpy( buffer, &font->logfont, count );
+    if(buffer)
+        memcpy( buffer, &font->logfont, count );
     return count;
 }
 
 
+/***********************************************************************
+ *           FONT_DeleteObject
+ */
+static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
+{
+    WineEngDestroyFontInstance( handle );
+    return GDI_FreeObject( handle, obj );
+}
+
+
 /***********************************************************************
  *              FONT_EnumInstance16
  *
  * Called by the device driver layer to pass font info
  * down to the application.
  */
-static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
+static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
                                DWORD fType, LPARAM lp )
 {
-#define pfe ((fontEnum16*)lp)
-    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
+    fontEnum16 *pfe = (fontEnum16*)lp;
+    INT ret = 1;
+    DC *dc;
+
+    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
        pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
     {
+        WORD args[7];
+        DWORD result;
+
         FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
        FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
-
-        return FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
-                                        (UINT16)fType, (LPARAM)pfe->lpData );
+        pfe->dwFlags |= ENUM_CALLED;
+        GDI_ReleaseObj( pfe->hdc );  /* release the GDI lock */
+
+        args[6] = SELECTOROF(pfe->segLogFont);
+        args[5] = OFFSETOF(pfe->segLogFont);
+        args[4] = SELECTOROF(pfe->segTextMetric);
+        args[3] = OFFSETOF(pfe->segTextMetric);
+        args[2] = fType;
+        args[1] = HIWORD(pfe->lpData);
+        args[0] = LOWORD(pfe->lpData);
+        WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
+        ret = LOWORD(result);
+
+        /* get the lock again and make sure the DC is still valid */
+        dc = DC_GetDCPtr( pfe->hdc );
+        if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
+        {
+            if (dc) GDI_ReleaseObj( pfe->hdc );
+            pfe->hdc = 0;  /* make sure we don't try to release it later on */
+            ret = 0;
+        }
     }
-#undef pfe
-    return 1;
+    return ret;
 }
 
 /***********************************************************************
  *              FONT_EnumInstance
  */
-static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
+static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
                              DWORD fType, LPARAM lp )
 {
-    /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
+    fontEnum32 *pfe = (fontEnum32*)lp;
+    INT ret = 1;
+    DC *dc;
 
-#define pfe ((fontEnum32*)lp)
-    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
+    /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
+    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
        pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
     {
        /* convert font metrics */
+        ENUMLOGFONTEXA logfont;
+        NEWTEXTMETRICEXA tmA;
 
         pfe->dwFlags |= ENUM_CALLED;
-       if( pfe->dwFlags & ENUM_UNICODE )
-       {
-           return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
-       }
-       else
-       {
-           ENUMLOGFONTEXA logfont;
-           NEWTEXTMETRICEXA tmA;
+        if (!(pfe->dwFlags & ENUM_UNICODE))
+        {
+            FONT_EnumLogFontExWToA( plf, &logfont);
+            FONT_NewTextMetricExWToA( ptm, &tmA );
+            plf = (LPENUMLOGFONTEXW)&logfont;
+            ptm = (NEWTEXTMETRICEXW *)&tmA;
+        }
+        GDI_ReleaseObj( pfe->hdc );  /* release the GDI lock */
 
-           FONT_EnumLogFontExWToA( plf, &logfont);
-           FONT_NewTextMetricExWToA( ptm, &tmA );
+        ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
 
-           return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, 
-                                   (LPNEWTEXTMETRICEXW)&tmA, fType,
-                                   pfe->lpData );
-       }
+        /* get the lock again and make sure the DC is still valid */
+        dc = DC_GetDCPtr( pfe->hdc );
+        if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
+        {
+            if (dc) GDI_ReleaseObj( pfe->hdc );
+            pfe->hdc = 0;  /* make sure we don't try to release it later on */
+            ret = 0;
+        }
     }
-#undef pfe
-    return 1;
+    return ret;
 }
 
 /***********************************************************************
  *              EnumFontFamiliesEx     (GDI.613)
  */
 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
-                                   FONTENUMPROCEX16 efproc, LPARAM lParam,
+                                   FONTENUMPROC16 efproc, LPARAM lParam,
                                    DWORD dwFlags)
 {
-    BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
-    INT16      retVal = 0;
-    DC*        dc = DC_GetDCPtr( hDC );
+    fontEnum16 fe16;
+    INT16      ret = 1, ret2;
+    DC*        dc = DC_GetDCPtr( HDC_32(hDC) );
+    NEWTEXTMETRICEX16 tm16;
+    ENUMLOGFONTEX16 lf16;
+    LOGFONTW lfW;
+    BOOL enum_gdi_fonts;
 
     if (!dc) return 0;
-    enum_func = dc->funcs->pEnumDeviceFonts;
-    GDI_ReleaseObj( hDC );
-
-    if (enum_func)
+    FONT_LogFont16ToW(plf, &lfW);
+
+    fe16.hdc = HDC_32(hDC);
+    fe16.dc = dc;
+    fe16.physDev = dc->physDev;
+    fe16.lpLogFontParam = plf;
+    fe16.lpEnumFunc = efproc;
+    fe16.lpData = lParam;
+    fe16.lpTextMetric = &tm16;
+    fe16.lpLogFont = &lf16;
+    fe16.segTextMetric = MapLS( &tm16 );
+    fe16.segLogFont = MapLS( &lf16 );
+    fe16.dwFlags = 0;
+
+    enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
+
+    if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
     {
-        NEWTEXTMETRICEX16 tm16;
-        ENUMLOGFONTEX16 lf16;
-        fontEnum16 fe16;
-        LOGFONTW lfW;
-        FONT_LogFont16ToW(plf, &lfW);
-
-        fe16.lpLogFontParam = plf;
-        fe16.lpEnumFunc = efproc;
-        fe16.lpData = lParam;
-        fe16.lpTextMetric = &tm16;
-        fe16.lpLogFont = &lf16;
-        fe16.segTextMetric = MapLS( &tm16 );
-        fe16.segLogFont = MapLS( &lf16 );
-
-        retVal = enum_func( hDC, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
-        UnMapLS( fe16.segTextMetric );
-        UnMapLS( fe16.segLogFont );
+        ret = 0;
+        goto done;
+    }
+
+    if (enum_gdi_fonts)
+        ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
+    fe16.dwFlags &= ~ENUM_CALLED;
+    if (ret && dc->funcs->pEnumDeviceFonts) {
+       ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
+       if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
+           ret = ret2;
     }
-    return retVal;
+done:
+    UnMapLS( fe16.segTextMetric );
+    UnMapLS( fe16.segLogFont );
+    if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
+    return ret;
 }
 
 /***********************************************************************
  *             FONT_EnumFontFamiliesEx
  */
 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
-                                   FONTENUMPROCEXW efproc, 
+                                   FONTENUMPROCW efproc,
                                    LPARAM lParam, DWORD dwUnicode)
 {
-    BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
     INT ret = 1, ret2;
     DC *dc = DC_GetDCPtr( hDC );
     fontEnum32 fe32;
@@ -751,21 +664,28 @@ static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
     fe32.lpEnumFunc = efproc;
     fe32.lpData = lParam;
     fe32.dwFlags = dwUnicode;
+    fe32.hdc = hDC;
+    fe32.dc = dc;
+    fe32.physDev = dc->physDev;
 
-    enum_func = dc->funcs->pEnumDeviceFonts;
-    GDI_ReleaseObj( hDC );
     enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
 
-    if (!enum_func && !enum_gdi_fonts) return 0;
-    
+    if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
+    {
+        ret = 0;
+        goto done;
+    }
+
     if (enum_gdi_fonts)
         ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
     fe32.dwFlags &= ~ENUM_CALLED;
-    if (ret && enum_func) {
-       ret2 = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
+    if (ret && dc->funcs->pEnumDeviceFonts) {
+       ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
        if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
            ret = ret2;
     }
+ done:
+    if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
     return ret;
 }
 
@@ -773,7 +693,7 @@ static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
  *              EnumFontFamiliesExW    (GDI32.@)
  */
 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
-                                    FONTENUMPROCEXW efproc, 
+                                    FONTENUMPROCW efproc,
                                     LPARAM lParam, DWORD dwFlags )
 {
     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
@@ -783,14 +703,13 @@ INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
  *              EnumFontFamiliesExA    (GDI32.@)
  */
 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
-                                    FONTENUMPROCEXA efproc, 
+                                    FONTENUMPROCA efproc,
                                     LPARAM lParam, DWORD dwFlags)
 {
     LOGFONTW lfW;
     FONT_LogFontAToW( plf, &lfW );
 
-    return  FONT_EnumFontFamiliesEx( hDC, &lfW,
-                                    (FONTENUMPROCEXW)efproc, lParam, 0);
+    return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
 }
 
 /***********************************************************************
@@ -820,7 +739,7 @@ INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
 
-    return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
+    return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
 }
 
 /***********************************************************************
@@ -835,7 +754,7 @@ INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
     else lf.lfFaceName[0] = 0;
 
-    return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
+    return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
 }
 
 /***********************************************************************
@@ -844,7 +763,7 @@ INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
                           LPARAM lpData )
 {
-    return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
+    return EnumFontFamilies16( hDC, lpName, efproc, lpData );
 }
 
 /***********************************************************************
@@ -866,15 +785,6 @@ INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
 }
 
 
-/***********************************************************************
- *           GetTextCharacterExtra    (GDI.89)
- */
-INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
-{
-    return (INT16)GetTextCharacterExtra( hdc );
-}
-
-
 /***********************************************************************
  *           GetTextCharacterExtra    (GDI32.@)
  */
@@ -882,23 +792,13 @@ INT WINAPI GetTextCharacterExtra( HDC hdc )
 {
     INT ret;
     DC *dc = DC_GetDCPtr( hdc );
-    if (!dc) return 0;
-    ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
-                 / dc->vportExtX );
+    if (!dc) return 0x80000000;
+    ret = dc->charExtra;
     GDI_ReleaseObj( hdc );
     return ret;
 }
 
 
-/***********************************************************************
- *           SetTextCharacterExtra    (GDI.8)
- */
-INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
-{
-    return (INT16)SetTextCharacterExtra( hdc, extra );
-}
-
-
 /***********************************************************************
  *           SetTextCharacterExtra    (GDI32.@)
  */
@@ -906,29 +806,19 @@ INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
 {
     INT prev;
     DC * dc = DC_GetDCPtr( hdc );
-    if (!dc) return 0;
+    if (!dc) return 0x80000000;
     if (dc->funcs->pSetTextCharacterExtra)
         prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
     else
     {
-        extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
-        prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
-        dc->charExtra = abs(extra);
+        prev = dc->charExtra;
+        dc->charExtra = extra;
     }
     GDI_ReleaseObj( hdc );
     return prev;
 }
 
 
-/***********************************************************************
- *           SetTextJustification    (GDI.10)
- */
-INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
-{
-    return SetTextJustification( hdc, extra, breaks );
-}
-
-
 /***********************************************************************
  *           SetTextJustification    (GDI32.@)
  */
@@ -961,14 +851,6 @@ BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
 }
 
 
-/***********************************************************************
- *           GetTextFace    (GDI.92)
- */
-INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
-{
-        return GetTextFaceA(hdc,count,name);
-}
-
 /***********************************************************************
  *           GetTextFaceA    (GDI32.@)
  */
@@ -977,10 +859,13 @@ INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
     INT res = GetTextFaceW(hdc, 0, NULL);
     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
     GetTextFaceW( hdc, res, nameW );
-    
+
     if (name)
-        res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
-                                  NULL, NULL);
+    {
+        if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
+            name[count-1] = 0;
+        res = strlen(name);
+    }
     else
         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
     HeapFree( GetProcessHeap(), 0, nameW );
@@ -998,7 +883,9 @@ INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return 0;
 
-    if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
+    if(dc->gdiFont)
+        ret = WineEngGetTextFace(dc->gdiFont, count, name);
+    else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
     {
         if (name)
         {
@@ -1013,37 +900,6 @@ INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
 }
 
 
-/***********************************************************************
- *           GetTextExtent    (GDI.91)
- */
-DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
-{
-    SIZE16 size;
-    if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
-    return MAKELONG( size.cx, size.cy );
-}
-
-
-/***********************************************************************
- *           GetTextExtentPoint    (GDI.471)
- *
- * FIXME: Should this have a bug for compatibility?
- * Original Windows versions of GetTextExtentPoint{A,W} have documented
- * bugs (-> MSDN KB q147647.txt).
- */
-BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
-                                    LPSIZE16 size )
-{
-    SIZE size32;
-    BOOL ret;
-    TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
-    ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
-    size->cx = size32.cx;
-    size->cy = size32.cy;
-    return (BOOL16)ret;
-}
-
-
 /***********************************************************************
  *           GetTextExtentPoint32A    (GDI32.@)
  */
@@ -1059,7 +915,7 @@ BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
        HeapFree( GetProcessHeap(), 0, p );
     }
 
-    TRACE("(%08x %s %d %p): returning %ld x %ld\n",
+    TRACE("(%p %s %d %p): returning %ld x %ld\n",
           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
     return ret;
 }
@@ -1094,7 +950,7 @@ BOOL WINAPI GetTextExtentPoint32W(
 
     GDI_ReleaseObj( hdc );
 
-    TRACE("(%08x %s %d %p): returning %ld x %ld\n",
+    TRACE("(%p %s %d %p): returning %ld x %ld\n",
           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
     return ret;
 }
@@ -1130,7 +986,7 @@ BOOL WINAPI GetTextExtentPointI(
 
     GDI_ReleaseObj( hdc );
 
-    TRACE("(%08x %p %d %p): returning %ld x %ld\n",
+    TRACE("(%p %p %d %p): returning %ld x %ld\n",
           hdc, indices, count, size, size->cx, size->cy );
     return ret;
 }
@@ -1185,7 +1041,7 @@ BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
  * - kerning? see below
  *
  * Kerning.  Since kerning would be carried out by the rendering code it should
- * be done by the driver.  However they don't support it yet.  Also I am not 
+ * be done by the driver.  However they don't support it yet.  Also I am not
  * yet persuaded that (certainly under Win95) any kerning is actually done.
  *
  * str: According to MSDN this should be null-terminated.  That is not true; a
@@ -1212,7 +1068,7 @@ BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
     SIZE tSize;
     BOOL ret = FALSE;
 
-    TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
+    TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
 
     size->cx = size->cy = nFit = extent = 0;
     for(index = 0; index < count; index++)
@@ -1242,19 +1098,6 @@ done:
     return ret;
 }
 
-/***********************************************************************
- *           GetTextMetrics    (GDI.93)
- */
-BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
-{
-    TEXTMETRICW tm32;
-
-    if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
-    FONT_TextMetricWTo16( &tm32, metrics );
-    return TRUE;
-}
-
-
 /***********************************************************************
  *           GetTextMetricsA    (GDI32.@)
  */
@@ -1287,12 +1130,12 @@ BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
      * therefore we have to convert them to logical */
 
 #define WDPTOLP(x) ((x<0)?                                     \
-               (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
-               (abs((x)*dc->wndExtX/dc->vportExtX)))
+               (-abs(INTERNAL_XDSTOWS(dc, (x)))):              \
+               (abs(INTERNAL_XDSTOWS(dc, (x)))))
 #define HDPTOLP(y) ((y<0)?                                     \
-               (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
-               (abs((y)*dc->wndExtY/dc->vportExtY)))
-       
+               (-abs(INTERNAL_YDSTOWS(dc, (y)))):              \
+               (abs(INTERNAL_YDSTOWS(dc, (y)))))
+
     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
@@ -1302,7 +1145,8 @@ BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
         ret = TRUE;
-
+#undef WDPTOLP
+#undef HDPTOLP
     TRACE("text metrics:\n"
           "    Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
           "    Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
@@ -1378,19 +1222,19 @@ UINT WINAPI GetOutlineTextMetricsA(
     needed = sizeof(OUTLINETEXTMETRICA);
     if(lpOTMW->otmpFamilyName)
         needed += WideCharToMultiByte(CP_ACP, 0,
-          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1, 
+          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
                                      NULL, 0, NULL, NULL);
     if(lpOTMW->otmpFaceName)
         needed += WideCharToMultiByte(CP_ACP, 0,
-          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1, 
+          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
                                      NULL, 0, NULL, NULL);
     if(lpOTMW->otmpStyleName)
         needed += WideCharToMultiByte(CP_ACP, 0,
-          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1, 
+          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
                                      NULL, 0, NULL, NULL);
     if(lpOTMW->otmpFullName)
         needed += WideCharToMultiByte(CP_ACP, 0,
-          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1, 
+          (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
                                      NULL, 0, NULL, NULL);
 
     if(!lpOTM) {
@@ -1440,7 +1284,7 @@ UINT WINAPI GetOutlineTextMetricsA(
     if(lpOTMW->otmpFamilyName) {
         lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
        len = WideCharToMultiByte(CP_ACP, 0,
-            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1, 
+            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
                                  ptr, left, NULL, NULL);
        left -= len;
        ptr += len;
@@ -1450,7 +1294,7 @@ UINT WINAPI GetOutlineTextMetricsA(
     if(lpOTMW->otmpFaceName) {
         lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
        len = WideCharToMultiByte(CP_ACP, 0,
-            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1, 
+            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
                                  ptr, left, NULL, NULL);
        left -= len;
        ptr += len;
@@ -1460,7 +1304,7 @@ UINT WINAPI GetOutlineTextMetricsA(
     if(lpOTMW->otmpStyleName) {
         lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
        len = WideCharToMultiByte(CP_ACP, 0,
-            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1, 
+            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
                                  ptr, left, NULL, NULL);
        left -= len;
        ptr += len;
@@ -1470,14 +1314,14 @@ UINT WINAPI GetOutlineTextMetricsA(
     if(lpOTMW->otmpFullName) {
         lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
        len = WideCharToMultiByte(CP_ACP, 0,
-            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1, 
+            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
                                  ptr, left, NULL, NULL);
        left -= len;
     } else
         lpOTM->otmpFullName = 0;
-    
+
     assert(left == 0);
-    
+
     ret = needed;
 
 end:
@@ -1499,11 +1343,55 @@ UINT WINAPI GetOutlineTextMetricsW(
     DC *dc = DC_GetDCPtr( hdc );
     UINT ret;
 
-    TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
+    TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
     if(!dc) return 0;
 
-    if(dc->gdiFont)
+    if(dc->gdiFont) {
         ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
+       if(ret && ret <= cbData) {
+#define WDPTOLP(x) ((x<0)?                                     \
+               (-abs(INTERNAL_XDSTOWS(dc, (x)))):              \
+               (abs(INTERNAL_XDSTOWS(dc, (x)))))
+#define HDPTOLP(y) ((y<0)?                                     \
+               (-abs(INTERNAL_YDSTOWS(dc, (y)))):              \
+               (abs(INTERNAL_YDSTOWS(dc, (y)))))
+
+           lpOTM->otmTextMetrics.tmHeight           = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
+           lpOTM->otmTextMetrics.tmAscent           = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
+           lpOTM->otmTextMetrics.tmDescent          = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
+           lpOTM->otmTextMetrics.tmInternalLeading  = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
+           lpOTM->otmTextMetrics.tmExternalLeading  = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
+           lpOTM->otmTextMetrics.tmAveCharWidth     = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
+           lpOTM->otmTextMetrics.tmMaxCharWidth     = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
+           lpOTM->otmTextMetrics.tmOverhang         = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
+           lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
+           lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
+           lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
+           lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
+           lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
+           lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
+           lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
+           lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
+           lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
+           lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
+           lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
+           lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
+           lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
+           lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
+           lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
+           lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
+           lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
+           lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
+           lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
+           lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
+           lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
+           lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
+           lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
+           lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
+#undef WDPTOLP
+#undef HDPTOLP
+       }
+    }
 
     else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
              but really this should just be a return 0. */
@@ -1528,42 +1416,6 @@ UINT WINAPI GetOutlineTextMetricsW(
 }
 
 
-/***********************************************************************
- *           GetCharWidth    (GDI.350)
- */
-BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
-                              LPINT16 buffer )
-{
-    BOOL       retVal = FALSE;
-
-    if( firstChar != lastChar )
-    {
-       LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
-                                sizeof(INT)*(1 + (lastChar - firstChar)));
-       if( buf32 )
-       {
-           LPINT       obuf32 = buf32;
-           int         i;
-
-            retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
-           if (retVal)
-           {
-               for (i = firstChar; i <= lastChar; i++)
-                   *buffer++ = *buf32++;
-           }
-           HeapFree(GetProcessHeap(), 0, obuf32);
-       }
-    }
-    else /* happens quite often to warrant a special treatment */
-    {
-       INT chWidth;
-       retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
-       *buffer = chWidth;
-    }
-    return retVal;
-}
-
-
 /***********************************************************************
  *           GetCharWidthW      (GDI32.@)
  *           GetCharWidth32W    (GDI32.@)
@@ -1608,7 +1460,7 @@ BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
     BOOL ret = TRUE;
 
     if(count <= 0) return FALSE;
-    
+
     str = HeapAlloc(GetProcessHeap(), 0, count);
     for(i = 0; i < count; i++)
        str[i] = (BYTE)(firstChar + i);
@@ -1633,15 +1485,6 @@ BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
 
 
 /* FIXME: all following APIs ******************************************/
-
-/***********************************************************************
- *           SetMapperFlags    (GDI.349)
- */
-DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
-{
-    return SetMapperFlags( hDC, dwFlag );
-}
 
 
 /***********************************************************************
@@ -1650,12 +1493,12 @@ DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
 {
     DC *dc = DC_GetDCPtr( hDC );
-    DWORD ret = 0; 
+    DWORD ret = 0;
     if(!dc) return 0;
     if(dc->funcs->pSetMapperFlags)
         ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
     else
-        FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
+        FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
     GDI_ReleaseObj( hDC );
     return ret;
 }
@@ -1674,33 +1517,10 @@ BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
  */
 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
 {
-  FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
+  FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
   return FALSE;
 }
 
-/***********************************************************************
- *           GetCharABCWidths   (GDI.307)
- */
-BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
-                                  LPABC16 abc )
-{
-    LPABC      abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
-    int                i;
-
-    if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
-       HeapFree(GetProcessHeap(),0,abc32);
-       return FALSE;
-    }
-
-    for (i=firstChar;i<=lastChar;i++) {
-       abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
-       abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
-       abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
-    }
-    HeapFree(GetProcessHeap(),0,abc32);
-    return TRUE;
-}
-
 
 /***********************************************************************
  *           GetCharABCWidthsA   (GDI32.@)
@@ -1714,7 +1534,7 @@ BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
     BOOL ret = TRUE;
 
     if(count <= 0) return FALSE;
-    
+
     str = HeapAlloc(GetProcessHeap(), 0, count);
     for(i = 0; i < count; i++)
        str[i] = (BYTE)(firstChar + i);
@@ -1822,7 +1642,7 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
     DC *dc = DC_GetDCPtr(hdc);
     DWORD ret;
 
-    TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
+    TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
          hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
 
     if(!dc) return GDI_ERROR;
@@ -1837,16 +1657,6 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
     return ret;
 }
 
-/***********************************************************************
- *           CreateScalableFontResource   (GDI.310)
- */
-BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
-                                            LPCSTR lpszResourceFile,
-                                            LPCSTR fontFile, LPCSTR path )
-{
-    return CreateScalableFontResourceA( fHidden, lpszResourceFile,
-                                          fontFile, path );
-}
 
 /***********************************************************************
  *           CreateScalableFontResourceA   (GDI32.@)
@@ -1856,6 +1666,8 @@ BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
                                              LPCSTR lpszFontFile,
                                              LPCSTR lpszCurrentPath )
 {
+    HANDLE f;
+
     /* fHidden=1 - only visible for the calling app, read-only, not
      * enumbered with EnumFonts/EnumFontFamilies
      * lpszCurrentPath can be NULL
@@ -1863,6 +1675,13 @@ BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
     FIXME("(%ld,%s,%s,%s): stub\n",
           fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
           debugstr_a(lpszCurrentPath) );
+
+    /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
+    if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
+        CloseHandle(f);
+        SetLastError(ERROR_FILE_EXISTS);
+        return FALSE;
+    }
     return FALSE; /* create failed */
 }
 
@@ -1880,15 +1699,6 @@ BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
 }
 
 
-/*************************************************************************
- *             GetRasterizerCaps   (GDI.313)
- */
-BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
-{
-    return GetRasterizerCaps( lprs, cbNumBytes );
-}
-
-
 /*************************************************************************
  *             GetRasterizerCaps   (GDI32.@)
  */
@@ -1901,38 +1711,13 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
 }
 
 
-/*************************************************************************
- *             GetKerningPairs   (GDI.332)
- *
- */
-INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
-                                LPKERNINGPAIR16 lpKerningPairs )
-{
-    /* At this time kerning is ignored (set to 0) */
-    int i;
-    FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
-    if (lpKerningPairs)
-        for (i = 0; i < cPairs; i++) 
-            lpKerningPairs[i].iKernAmount = 0;
- /* FIXME: Should this function call SetLastError (0)?  This is yet another
-  * Microsoft function that can return 0 on success or failure
-  */
-    return 0;
-}
-
-
-
 /*************************************************************************
  *             GetKerningPairsA   (GDI32.@)
  */
 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
-                                 LPKERNINGPAIR lpKerningPairs )
+                               LPKERNINGPAIR lpKerningPairs )
 {
-    int i;
-    FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
-    for (i = 0; i < cPairs; i++) 
-        lpKerningPairs[i].iKernAmount = 0;
-    return 0;
+    return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
 }
 
 
@@ -1942,16 +1727,19 @@ DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
                                  LPKERNINGPAIR lpKerningPairs )
 {
-    return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
+    int i;
+    FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
+    for (i = 0; i < cPairs; i++)
+        lpKerningPairs[i].iKernAmount = 0;
+    return 0;
 }
 
 /*************************************************************************
  * TranslateCharsetInfo [GDI32.@]
- * TranslateCharsetInfo [USER32.@]
  *
  * Fills a CHARSETINFO structure for a character set, code page, or
  * font. This allows making the correspondance between different labelings
- * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
+ * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
  * of the same encoding.
  *
  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
@@ -1992,35 +1780,65 @@ BOOL WINAPI TranslateCharsetInfo(
 /*************************************************************************
  *             GetFontLanguageInfo   (GDI32.@)
  */
-DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
-       /* return value 0 is correct for most cases anyway */
-        FIXME("(%x):stub!\n", hdc);
-       return 0;
-}
+DWORD WINAPI GetFontLanguageInfo(HDC hdc)
+{
+       FONTSIGNATURE fontsig;
+       static const DWORD GCP_DBCS_MASK=0x003F0000,
+               GCP_DIACRITIC_MASK=0x00000000,
+               FLI_GLYPHS_MASK=0x00000000,
+               GCP_GLYPHSHAPE_MASK=0x00000040,
+               GCP_KASHIDA_MASK=0x00000000,
+               GCP_LIGATE_MASK=0x00000000,
+               GCP_USEKERNING_MASK=0x00000000,
+               GCP_REORDER_MASK=0x00000060;
 
-/*************************************************************************
- *             GetFontLanguageInfo   (GDI.616)
- */
-DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
-       /* return value 0 is correct for most cases anyway */
-       FIXME("(%x):stub!\n",hdc);
-       return 0;
+       DWORD result=0;
+
+       GetTextCharsetInfo( hdc, &fontsig, 0 );
+       /* We detect each flag we return using a bitmask on the Codepage Bitfields */
+
+       if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
+               result|=GCP_DBCS;
+
+       if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
+               result|=GCP_DIACRITIC;
+
+       if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
+               result|=FLI_GLYPHS;
+
+       if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
+               result|=GCP_GLYPHSHAPE;
+
+       if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
+               result|=GCP_KASHIDA;
+
+       if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
+               result|=GCP_LIGATE;
+
+       if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
+               result|=GCP_USEKERNING;
+
+       if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
+               result|=GCP_REORDER;
+
+       return result;
 }
 
+
 /*************************************************************************
  * GetFontData [GDI32.@] Retrieve data for TrueType font
  *
  * RETURNS
  *
- * success: Number of bytes returned 
+ * success: Number of bytes returned
  * failure: GDI_ERROR
  *
  * NOTES
  *
- * Calls SetLastError()  
+ * Calls SetLastError()
  *
  */
-DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
+DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
     LPVOID buffer, DWORD length)
 {
     DC *dc = DC_GetDCPtr(hdc);
@@ -2035,16 +1853,6 @@ DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
     return ret;
 }
 
-/*************************************************************************
- * GetFontData [GDI.311]
- *
- */
-DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
-                           LPVOID lpvBuffer, DWORD cbData)
-{
-    return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
-}
-
 /*************************************************************************
  * GetGlyphIndicesA [GDI32.@]
  */
@@ -2055,8 +1863,8 @@ DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
     WCHAR *lpstrW;
     INT countW;
 
-    TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
-       hdc, debugstr_an(lpstr, count), count, pgi, flags);
+    TRACE("(%p, %s, %d, %p, 0x%lx)\n",
+          hdc, debugstr_an(lpstr, count), count, pgi, flags);
 
     lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
     ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
@@ -2074,8 +1882,8 @@ DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
     DC *dc = DC_GetDCPtr(hdc);
     DWORD ret = GDI_ERROR;
 
-    TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
-       hdc, debugstr_wn(lpstr, count), count, pgi, flags);
+    TRACE("(%p, %s, %d, %p, 0x%lx)\n",
+          hdc, debugstr_wn(lpstr, count), count, pgi, flags);
 
     if(!dc) return GDI_ERROR;
 
@@ -2098,7 +1906,7 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
                         DWORD dwFlags)
 {
     WCHAR *lpStringW;
-    INT uCountW;
+    INT uCountW, i;
     GCP_RESULTSW resultsW;
     DWORD ret;
     UINT font_cp;
@@ -2111,15 +1919,18 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
 
     lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
     if(lpResults->lpOutString)
-       resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
-    else
-       resultsW.lpOutString = NULL;
+        resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
 
     ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
 
-    if(lpResults->lpOutString)
-       WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
-                           lpResults->lpOutString, uCount, NULL, NULL );
+    if(lpResults->lpOutString) {
+        if(font_cp != CP_SYMBOL)
+            WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
+                                lpResults->lpOutString, uCount, NULL, NULL );
+        else
+            for(i = 0; i < uCount; i++)
+                lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
+    }
 
     HeapFree(GetProcessHeap(), 0, lpStringW);
     HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
@@ -2129,11 +1940,31 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
 
 /*************************************************************************
  * GetCharacterPlacementW [GDI32.@]
+ *
+ *   Retrieve information about a string. This includes the width, reordering,
+ *   Glyphing and so on.
+ *
+ * RETURNS
+ *
+ *   The width and height of the string if successful, 0 if failed.
+ *
+ * BUGS
+ *
+ *   All flags except GCP_REORDER are not yet implemented.
+ *   Reordering is not 100% complient to the Windows BiDi method.
+ *   Caret positioning is not yet implemented.
+ *   Classes are not yet implemented.
+ *
  */
 DWORD WINAPI
-GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
-                        INT nMaxExtent, GCP_RESULTSW *lpResults,
-                        DWORD dwFlags)
+GetCharacterPlacementW(
+               HDC hdc,                /* [in] Device context for which the rendering is to be done */
+               LPCWSTR lpString,       /* [in] The string for which information is to be returned */
+               INT uCount,             /* [in] Number of WORDS in string. */
+               INT nMaxExtent,         /* [in] Maximum extent the string is to take (in HDC logical units) */
+               GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
+               DWORD dwFlags           /* [in] Flags specifying how to process the string */
+               )
 {
     DWORD ret=0;
     SIZE size;
@@ -2148,37 +1979,45 @@ GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
            lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
            lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
 
-    if(dwFlags)                        FIXME("flags 0x%08lx ignored\n", dwFlags);
+    if(dwFlags&(~GCP_REORDER))                 FIXME("flags 0x%08lx ignored\n", dwFlags);
     if(lpResults->lpCaretPos)  FIXME("caret positions not implemented\n");
     if(lpResults->lpClass)     FIXME("classes not implemented\n");
 
-    /* FIXME: reordering not implemented */
-    /* copy will do if the GCP_REORDER flag is not set */
-    if(lpResults->lpOutString)
-      lstrcpynW(lpResults->lpOutString, lpString, uCount);
-
-    nSet = (UINT)uCount;
-    if(nSet > lpResults->nGlyphs)
-       nSet = lpResults->nGlyphs;
+       nSet = (UINT)uCount;
+       if(nSet > lpResults->nGlyphs)
+               nSet = lpResults->nGlyphs;
 
-    /* return number of initialized fields */
-    lpResults->nGlyphs = nSet;
+       /* return number of initialized fields */
+       lpResults->nGlyphs = nSet;
 
-    if(lpResults->lpOrder)
-    {
-       for(i = 0; i < nSet; i++)
-           lpResults->lpOrder[i] = i;
-    }
+       if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
+       {
+               /* Treat the case where no special handling was requested in a fastpath way */
+               /* copy will do if the GCP_REORDER flag is not set */
+               if(lpResults->lpOutString)
+                    strncpyW( lpResults->lpOutString, lpString, nSet );
+
+               if(lpResults->lpOrder)
+               {
+                       for(i = 0; i < nSet; i++)
+                               lpResults->lpOrder[i] = i;
+               }
+       } else
+       {
+            BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
+                          nSet, lpResults->lpOrder );
+       }
 
-    if (lpResults->lpDx)
-    {
-      int c;
-      for (i = 0; i < nSet; i++)
-      { 
-        if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
-          lpResults->lpDx[i]= c;
-      }
-    }
+       /* FIXME: Will use the placement chars */
+       if (lpResults->lpDx)
+       {
+               int c;
+               for (i = 0; i < nSet; i++)
+               {
+                       if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
+                               lpResults->lpDx[i]= c;
+               }
+       }
 
     if(lpResults->lpGlyphs)
        GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
@@ -2228,99 +2067,119 @@ BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
        return 0;
 }
+
 
 /***********************************************************************
  *                                                                    *
  *           Font Resource API                                        *
  *                                                                    *
  ***********************************************************************/
-/***********************************************************************
- *           AddFontResource    (GDI.119)
- *
- *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
- *
- *  FIXME: Load header and find the best-matching font in the fontList;
- *        fixup dfPoints if all metrics are identical, otherwise create
- *        new fontAlias. When soft font support is ready this will
- *        simply create a new fontResource ('filename' will go into
- *        the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
- *        flag set. 
- */
-INT16 WINAPI AddFontResource16( LPCSTR filename )
-{
-    return AddFontResourceA( filename );
-}
-
 
 /***********************************************************************
  *           AddFontResourceA    (GDI32.@)
  */
 INT WINAPI AddFontResourceA( LPCSTR str )
 {
-    FIXME("(%s): stub! Read the Wine User Guide on how to install "
-            "this font manually.\n", debugres_a(str));
-    return 1;
+    return AddFontResourceExA( str, 0, NULL);
 }
 
-
 /***********************************************************************
  *           AddFontResourceW    (GDI32.@)
  */
 INT WINAPI AddFontResourceW( LPCWSTR str )
 {
-    FIXME("(%s): stub! Read the Wine User Guide on how to install "
-            "this font manually.\n", debugres_w(str));
-    return 1;
+    return AddFontResourceExW(str, 0, NULL);
 }
 
+
 /***********************************************************************
- *           RemoveFontResource    (GDI.136)
+ *           AddFontResourceExA    (GDI32.@)
  */
-BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
+INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
 {
-    FIXME("(%s): stub\n", debugres_a(str));
-    return TRUE;
+    DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    INT ret;
+
+    MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
+    ret = AddFontResourceExW(strW, fl, pdv);
+    HeapFree(GetProcessHeap(), 0, strW);
+    return ret;
 }
 
+/***********************************************************************
+ *           AddFontResourceExW    (GDI32.@)
+ */
+INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
+{
+    return WineEngAddFontResourceEx(str, fl, pdv);
+}
 
 /***********************************************************************
  *           RemoveFontResourceA    (GDI32.@)
  */
 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
 {
-/*  This is how it should look like */
-/*
-    fontResource** ppfr;
-    BOOL32 retVal = FALSE;
-
-    EnterCriticalSection( &crtsc_fonts_X11 );
-    for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
-        if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
-        {
-            if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
-                (*ppfr)->hOwnerProcess == GetCurrentProcess() )
-            {
-                if( (*ppfr)->fo_count )
-                    (*ppfr)->fr_flags |= FR_REMOVED;
-                else
-                    XFONT_RemoveFontResource( ppfr );
-            }
-            retVal = TRUE;
-        }
-    LeaveCriticalSection( &crtsc_fonts_X11 );
-    return retVal;
- */
-    FIXME("(%s): stub\n", debugres_a(str));
-    return TRUE;
+    return RemoveFontResourceExA(str, 0, 0);
 }
 
-
 /***********************************************************************
  *           RemoveFontResourceW    (GDI32.@)
  */
 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
 {
-    FIXME("(%s): stub\n", debugres_w(str) );
-    return TRUE;
+    return RemoveFontResourceExW(str, 0, 0);
+}
+
+/***********************************************************************
+ *           RemoveFontResourceExA    (GDI32.@)
+ */
+BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
+{
+    DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    INT ret;
+
+    MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
+    ret = RemoveFontResourceExW(strW, fl, pdv);
+    HeapFree(GetProcessHeap(), 0, strW);
+    return ret;
+}
+
+/***********************************************************************
+ *           RemoveFontResourceExW    (GDI32.@)
+ */
+BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
+{
+    return WineEngRemoveFontResourceEx(str, fl, pdv);
+}
+
+/***********************************************************************
+ *           GetTextCharset    (GDI32.@)
+ */
+UINT WINAPI GetTextCharset(HDC hdc)
+{
+    /* MSDN docs say this is equivalent */
+    return GetTextCharsetInfo(hdc, NULL, 0);
+}
+
+/***********************************************************************
+ *           GetTextCharsetInfo    (GDI32.@)
+ */
+UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
+{
+    UINT ret = DEFAULT_CHARSET;
+    DC *dc = DC_GetDCPtr(hdc);
+
+    if (!dc) goto done;
+
+    if (dc->gdiFont)
+        ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
+
+    GDI_ReleaseObj(hdc);
+
+done:
+    if (ret == DEFAULT_CHARSET && fs)
+        memset(fs, 0, sizeof(FONTSIGNATURE));
+    return ret;
 }