[WIN32K]
[reactos.git] / reactos / subsystems / win32 / win32k / objects / freetype.c
index 4e941ee..e908e58 100644 (file)
@@ -1,53 +1,16 @@
-/*
- * FreeType font engine interface
- *
- * Copyright 2001 Huw D M Davies for CodeWeavers.
- * Copyright 2006 Dmitry Timoshkov for CodeWeavers.
- *
- * This file contains the WineEng* functions.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-/*
- *
- * Addaped for the use in ReactOS.
- *
- */
 /*
  * PROJECT:         ReactOS win32 kernel mode subsystem
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            subsystems/win32/win32k/objects/freetype.c
- * PURPOSE:         Freetype library support
- * PROGRAMMER:
+ * PURPOSE:         FreeType font engine interface
+ * PROGRAMMER:      Copyright 2001 Huw D M Davies for CodeWeavers.
+ *                  Copyright 2006 Dmitry Timoshkov for CodeWeavers.
  */
 
 /** Includes ******************************************************************/
 
 #include <win32k.h>
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-#include FT_TYPE1_TABLES_H
-#include <freetype/tttables.h>
-#include <freetype/fttrigon.h>
-#include <freetype/ftglyph.h>
-#include <freetype/ftbitmap.h>
-#include <freetype/ftoutln.h>
-#include <freetype/ftwinfnt.h>
-
 #define NDEBUG
 #include <debug.h>
 
@@ -302,9 +265,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
     PSECTION_OBJECT SectionObject;
     ULONG ViewSize = 0;
     LARGE_INTEGER SectionSize;
-#if 0 // Wine code
-    FT_Fixed XScale, YScale;
-#endif
     UNICODE_STRING FontRegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
 
     /* Open the font file */
@@ -396,22 +356,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
     FontGDI->Filename[FileName->Length / sizeof(WCHAR)] = L'\0';
     FontGDI->face = Face;
 
-    /* FIXME: Complete text metrics */
-#if 0 /* This (Wine) code doesn't seem to work correctly for us */
-    XScale = Face->size->metrics.x_scale;
-    YScale = Face->size->metrics.y_scale;
-    FontGDI->TextMetric.tmAscent =  (FT_MulFix(Face->ascender, YScale) + 32) >> 6;
-    FontGDI->TextMetric.tmDescent = (FT_MulFix(Face->descender, YScale) + 32) >> 6;
-    FontGDI->TextMetric.tmHeight =  (FT_MulFix(Face->ascender, YScale) -
-                                     FT_MulFix(Face->descender, YScale)) >> 6;
-#else
-    FontGDI->TextMetric.tmAscent  = (Face->size->metrics.ascender + 32) >> 6; /* units above baseline */
-    FontGDI->TextMetric.tmDescent = (32 - Face->size->metrics.descender) >> 6; /* units below baseline */
-    FontGDI->TextMetric.tmHeight = (Face->size->metrics.ascender - Face->size->metrics.descender) >> 6;
-#endif
-
-
-
     DPRINT("Font loaded: %s (%s)\n", Face->family_name, Face->style_name);
     DPRINT("Num glyphs: %u\n", Face->num_glyphs);
 
@@ -856,14 +800,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
 
     Otm->otmSize = Needed;
 
-//  FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &Win : 0);
-    if (!(FontGDI->flRealizedType & FDM_TYPE_TEXT_METRIC))
-    {
-        FillTM(&FontGDI->TextMetric, FontGDI, pOS2, pHori, !Error ? &Win : 0);
-        FontGDI->flRealizedType |= FDM_TYPE_TEXT_METRIC;
-    }
-
-    RtlCopyMemory(&Otm->otmTextMetrics, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
+    FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &Win : 0);
 
     Otm->otmFiller = 0;
     RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
@@ -882,8 +819,8 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
     Otm->otmrcFontBox.right = (FT_MulFix(FontGDI->face->bbox.xMax, XScale) + 32) >> 6;
     Otm->otmrcFontBox.top = (FT_MulFix(FontGDI->face->bbox.yMax, YScale) + 32) >> 6;
     Otm->otmrcFontBox.bottom = (FT_MulFix(FontGDI->face->bbox.yMin, YScale) + 32) >> 6;
-    Otm->otmMacAscent = FontGDI->TextMetric.tmAscent;
-    Otm->otmMacDescent = -FontGDI->TextMetric.tmDescent;
+    Otm->otmMacAscent = Otm->otmTextMetrics.tmAscent;
+    Otm->otmMacDescent = -Otm->otmTextMetrics.tmDescent;
     Otm->otmMacLineGap = Otm->otmLineGap;
     Otm->otmusMinimumPPEM = 0; /* TT Header */
     Otm->otmptSubscriptSize.x = (FT_MulFix(pOS2->ySubscriptXSize, XScale) + 32) >> 6;
@@ -1078,12 +1015,16 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
 
     ExFreePoolWithTag(Otm, GDITAG_TEXT);
 
-    wcsncpy(Info->EnumLogFontEx.elfLogFont.lfFaceName, FaceName, LF_FACESIZE);
-    wcsncpy(Info->EnumLogFontEx.elfFullName, FaceName, LF_FULLFACESIZE);
+    RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName,
+                     sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName),
+                     FaceName);
+    RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
+                     sizeof(Info->EnumLogFontEx.elfFullName),
+                     FaceName);
     RtlInitAnsiString(&StyleA, FontGDI->face->style_name);
-    RtlAnsiStringToUnicodeString(&StyleW, &StyleA, TRUE);
-    wcsncpy(Info->EnumLogFontEx.elfStyle, StyleW.Buffer, LF_FACESIZE);
-    RtlFreeUnicodeString(&StyleW);
+    StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
+    StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle);
+    RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE);
 
     Info->EnumLogFontEx.elfLogFont.lfCharSet = DEFAULT_CHARSET;
     Info->EnumLogFontEx.elfScript[0] = L'\0';
@@ -1267,8 +1208,10 @@ FontFamilyInfoQueryRegistryCallback(IN PWSTR ValueName, IN ULONG ValueType,
             if (InfoContext->Count < InfoContext->Size)
             {
                 InfoContext->Info[InfoContext->Count] = InfoContext->Info[Existing];
-                wcsncpy(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName,
-                        RegistryName.Buffer, LF_FACESIZE);
+                RtlStringCbCopyNW(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName,
+                                  sizeof(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName),
+                                  RegistryName.Buffer,
+                                  RegistryName.Length);
             }
             InfoContext->Count++;
             return STATUS_SUCCESS;
@@ -1423,6 +1366,7 @@ ftGdiGlyphCacheSet(
     if(FT_Bitmap_Convert(GlyphSlot->library, &BitmapGlyph->bitmap, &AlignedBitmap, 4))
     {
         DPRINT1("Conversion failed\n");
+        ExFreePoolWithTag(NewEntry, TAG_FONT);
         FT_Done_Glyph((FT_Glyph)BitmapGlyph);
         return NULL;
     }
@@ -1589,8 +1533,8 @@ ftGdiGetGlyphOutline(
 //  FT_Set_Pixel_Sizes(ft_face,
 //                     TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
     /* FIXME should set character height if neg */
-//                     (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
-//                      TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
+//                     (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+//                      dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)));
 
     TEXTOBJ_UnlockText(TextObj);
 
@@ -2185,9 +2129,8 @@ TextIntGetTextExtentPoint(PDC dc,
     error = FT_Set_Pixel_Sizes(face,
                                TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
                                /* FIXME should set character height if neg */
-                               (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ?
-                                - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
-                                TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
+                               (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+                                                          dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)));
     if (error)
     {
         DPRINT1("Error in setting pixel sizes: %u\n", error);
@@ -2248,7 +2191,8 @@ TextIntGetTextExtentPoint(PDC dc,
     IntUnLockFreeType;
 
     Size->cx = (TotalWidth + 32) >> 6;
-    Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
+    Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+                   dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
     Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72);
 
     return TRUE;
@@ -2472,9 +2416,8 @@ ftGdiGetTextMetricsW(
         Error = FT_Set_Pixel_Sizes(Face,
                                    TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
                                    /* FIXME should set character height if neg */
-                                   (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ?
-                                    - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
-                                    TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
+                                   (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+                                   dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)));
         IntUnLockFreeType;
         if (0 != Error)
         {
@@ -2506,13 +2449,8 @@ ftGdiGetTextMetricsW(
 
             if (NT_SUCCESS(Status))
             {
-                if (!(FontGDI->flRealizedType & FDM_TYPE_TEXT_METRIC))
-                {
-                    FillTM(&FontGDI->TextMetric, FontGDI, pOS2, pHori, !Error ? &Win : 0);
-                    FontGDI->flRealizedType |= FDM_TYPE_TEXT_METRIC;
-                }
+                FillTM(&ptmwi->TextMetric, FontGDI, pOS2, pHori, !Error ? &Win : 0);
 
-                RtlCopyMemory(&ptmwi->TextMetric, &FontGDI->TextMetric, sizeof(TEXTMETRICW));
                 /* FIXME: Fill Diff member */
                 RtlZeroMemory(&ptmwi->Diff, sizeof(ptmwi->Diff));
             }
@@ -2643,7 +2581,7 @@ FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont,
     PFONT_ENTRY CurrentEntry;
     FONTGDI *FontGDI;
     UINT Score;
-
+ASSERT(FontObj && MatchScore && LogFont && FaceName && Head);
     Entry = Head->Flink;
     while (Entry != Head)
     {
@@ -2808,7 +2746,6 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
         TextObj->Font->iUniq = 1; // Now it can be cached.
         IntFontType(FontGdi);
         FontGdi->flType = TextObj->Font->flFontType;
-        FontGdi->flRealizedType = 0;
         FontGdi->Underline = TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfUnderline ? 0xff : 0;
         FontGdi->StrikeOut = TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfStrikeOut ? 0xff : 0;
         TextObj->fl |= TEXTOBJECT_INIT;
@@ -3330,9 +3267,8 @@ GreExtTextOutW(
                 face,
                 TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
                 /* FIXME should set character height if neg */
-                (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ?
-                 - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
-                 TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
+                (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+                dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)));
     if (error)
     {
         DPRINT1("Error in setting pixel sizes: %u\n", error);
@@ -3422,13 +3358,13 @@ GreExtTextOutW(
 
         previous = 0;
 
-        if (pdcattr->lTextAlign & TA_RIGHT)
+        if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER)
         {
-            RealXStart -= TextWidth;
+            RealXStart -= TextWidth / 2;
         }
         else
         {
-            RealXStart -= TextWidth / 2;
+            RealXStart -= TextWidth;
         }
     }
 
@@ -3869,8 +3805,8 @@ NtGdiGetCharABCWidthsW(
     FT_Set_Pixel_Sizes(face,
                        TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
                        /* FIXME should set character height if neg */
-                       (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
-                        TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
+                       (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+                       dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)));
 
     for (i = FirstChar; i < FirstChar+Count; i++)
     {
@@ -4036,9 +3972,8 @@ NtGdiGetCharWidthW(
     FT_Set_Pixel_Sizes(face,
                        TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
                        /* FIXME should set character height if neg */
-                       (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ?
-                        - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
-                        TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
+                       (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ?
+                       dc->ppdev->devinfo.lfDefaultFont.lfHeight : abs(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)));
 
     for (i = FirstChar; i < FirstChar+Count; i++)
     {