Fix a cut & paste error.
[reactos.git] / reactos / subsys / win32k / objects / text.c
index 4d8d2ee..89589ea 100644 (file)
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 /* $Id$ */
+
 #include <w32k.h>
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include <freetype/tttables.h>
 
+#define NDEBUG
+#include <debug.h>
+
 FT_Library  library;
 
 typedef struct _FONT_ENTRY {
@@ -110,7 +114,7 @@ static CHARSETINFO FontTci[MAXTCIINDEX] = {
   { DEFAULT_CHARSET, 0, FS(0)},
   /* reserved for system */
   { DEFAULT_CHARSET, 0, FS(0)},
-  { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
+  { SYMBOL_CHARSET, 42 /* CP_SYMBOL */, FS(31)},
 };
 
 VOID FASTCALL
@@ -185,7 +189,7 @@ IntLoadSystemFonts(VOID)
          return;
       }
 
-      FileName.Buffer = ExAllocatePool(PagedPool, MAX_PATH);
+      FileName.Buffer = ExAllocatePool(PagedPool, MAX_PATH * sizeof(WCHAR));
       if (FileName.Buffer == NULL)
       {
          ExFreePool(DirInfoBuffer);
@@ -193,7 +197,7 @@ IntLoadSystemFonts(VOID)
          return;
       }
       FileName.Length = 0;
-      FileName.MaximumLength = MAX_PATH;
+      FileName.MaximumLength = MAX_PATH * sizeof(WCHAR);
 
       while (1)
       {
@@ -251,23 +255,24 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
    NTSTATUS Status;
    HANDLE FileHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
-   FILE_STANDARD_INFORMATION FileStdInfo;
-   PVOID Buffer;
+   PVOID Buffer = NULL;
    IO_STATUS_BLOCK Iosb;
    INT Error;
    FT_Face Face;
    ANSI_STRING AnsiFaceName;
    PFONT_ENTRY Entry;
+   PSECTION_OBJECT SectionObject;
+   ULONG ViewSize = 0;
 
    /* Open the font file */
 
    InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL);
    Status = ZwOpenFile(
       &FileHandle,
-      GENERIC_READ | SYNCHRONIZE,
+      FILE_GENERIC_READ | SYNCHRONIZE,
       &ObjectAttributes,
       &Iosb,
-      0,
+      FILE_SHARE_READ,
       FILE_SYNCHRONOUS_IO_NONALERT);
 
    if (!NT_SUCCESS(Status))
@@ -276,64 +281,30 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
       return 0;
    }
 
-   /* Get the size of the file */
-
-   Status = NtQueryInformationFile(
-      FileHandle,
-      &Iosb,
-      &FileStdInfo,
-      sizeof(FileStdInfo),
-      FileStandardInformation);
-
+   Status = MmCreateSection(&SectionObject, SECTION_ALL_ACCESS,
+                            NULL, NULL, PAGE_READONLY,
+                            0, FileHandle, NULL);
    if (!NT_SUCCESS(Status))
    {
-      DPRINT("Could not get file size\n");
-      ZwClose(FileHandle);
-      return 0;
-   }
-
-   /* Allocate pageable memory for the font */
-
-   Buffer = ExAllocatePoolWithTag(
-      PagedPool,
-      FileStdInfo.EndOfFile.u.LowPart,
-      TAG_FNTFILE);
-
-   if (Buffer == NULL)
-   {
-      DPRINT("Could not allocate memory for font");
+      DPRINT("Could not map file: %wZ\n", FileName);
       ZwClose(FileHandle);
       return 0;
    }
 
-   /* Load the font into memory chunk */
-
-   Status = ZwReadFile(
-      FileHandle,
-      NULL,
-      NULL,
-      NULL,
-      &Iosb,
-      Buffer,
-      FileStdInfo.EndOfFile.u.LowPart,
-      NULL,
-      NULL);
+   ZwClose(FileHandle);
 
+   Status = MmMapViewInSystemSpace(SectionObject, &Buffer, &ViewSize);
    if (!NT_SUCCESS(Status))
    {
-      DPRINT("Could not read the font file into memory");
-      ExFreePool(Buffer);
-      ZwClose(FileHandle);
-      return 0;
+      DPRINT("Could not map file: %wZ\n", FileName);
+      return Status;
    }
 
-   ZwClose(FileHandle);
-
    IntLockFreeType;
    Error = FT_New_Memory_Face(
       library,
       Buffer,
-      FileStdInfo.EndOfFile.u.LowPart,
+      ViewSize,
       0,
       &Face);
    IntUnLockFreeType;
@@ -344,7 +315,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
          DPRINT("Unknown font file format\n");
       else
          DPRINT("Error reading font file (error code: %u)\n", Error);
-      ExFreePool(Buffer);
+      ObDereferenceObject(SectionObject);
       return 0;
    }
 
@@ -352,7 +323,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
    if (!Entry)
    {
       FT_Done_Face(Face);
-      ExFreePool(Buffer);
+      ObDereferenceObject(SectionObject);
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
       return 0;
    }
@@ -361,7 +332,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
    if(FontGDI == NULL)
    {
       FT_Done_Face(Face);
-      ExFreePool(Buffer);
+      ObDereferenceObject(SectionObject);
       ExFreePool(Entry);
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
       return 0;
@@ -1040,7 +1011,7 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI)
   TEXTMETRICW *TM;
   NEWTEXTMETRICW *Ntm;
 
-  ZeroMemory(Info, sizeof(FONTFAMILYINFO));
+  RtlZeroMemory(Info, sizeof(FONTFAMILYINFO));
   Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
   Otm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
   if (NULL == Otm)
@@ -1482,12 +1453,12 @@ NtGdiExtTextOut(
 
    DC *dc;
    SURFOBJ *SurfObj;
-   BITMAPOBJ *BitmapObj;
+   BITMAPOBJ *BitmapObj = NULL;
    int error, glyph_index, n, i;
    FT_Face face;
    FT_GlyphSlot glyph;
    LONGLONG TextLeft, RealXStart;
-   ULONG TextTop, pitch, previous, BackgroundLeft;
+   ULONG TextTop, previous, BackgroundLeft;
    FT_Bool use_kerning;
    RECTL DestRect, MaskRect, SpecifiedDestRect;
    POINTL SourcePoint, BrushOrigin;
@@ -1583,7 +1554,7 @@ NtGdiExtTextOut(
    {
       goto fail;
    }
-   hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
+   hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor), 0);
    if ( !hBrushFg )
    {
       goto fail;
@@ -1596,7 +1567,7 @@ NtGdiExtTextOut(
    IntGdiInitBrushInstance(&BrushFgInst, BrushFg, NULL);
    if ((fuOptions & ETO_OPAQUE) || dc->w.backgroundMode == OPAQUE)
    {
-      hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor));
+      hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor), 0);
       if ( !hBrushBg )
       {
          goto fail;
@@ -1627,8 +1598,9 @@ NtGdiExtTextOut(
       DestRect.top    = SpecifiedDestRect.top    + dc->w.DCOrgY;
       DestRect.right  = SpecifiedDestRect.right  + dc->w.DCOrgX;
       DestRect.bottom = SpecifiedDestRect.bottom + dc->w.DCOrgY;
+      IntLPtoDP(dc, (LPPOINT)&DestRect, 2);
       IntEngBitBlt(
-         BitmapObj,
+         &BitmapObj->SurfObj,
          NULL,
          NULL,
          dc->CombinedClip,
@@ -1660,6 +1632,7 @@ NtGdiExtTextOut(
    FontGDI = ObjToGDI(FontObj, FONT);
    ASSERT(FontGDI);
 
+   IntLockFreeType;
    face = FontGDI->face;
    if (face->charmap == NULL)
    {
@@ -1680,10 +1653,8 @@ NtGdiExtTextOut(
       {
          DPRINT1("WARNING: Could not find desired charmap!\n");
       }
-      IntLockFreeType;
       error = FT_Set_Charmap(face, found);
-      IntUnLockFreeType;
-      if (error)
+         if (error)
       {
          DPRINT1("WARNING: Could not set the charmap!\n");
       }
@@ -1695,7 +1666,6 @@ NtGdiExtTextOut(
    else
       RenderMode = FT_RENDER_MODE_MONO;
 
-   IntLockFreeType;
    error = FT_Set_Pixel_Sizes(
       face,
       TextObj->logfont.lfWidth,
@@ -1703,10 +1673,10 @@ NtGdiExtTextOut(
       (TextObj->logfont.lfHeight < 0 ?
       - TextObj->logfont.lfHeight :
       TextObj->logfont.lfHeight == 0 ? 11 : TextObj->logfont.lfHeight));
-   IntUnLockFreeType;
    if (error)
    {
       DPRINT1("Error in setting pixel sizes: %u\n", error);
+      IntUnLockFreeType;
       goto fail;
    }
 
@@ -1751,10 +1721,8 @@ NtGdiExtTextOut(
 
       for (i = Start; i < Count; i++)
       {
-         IntLockFreeType;
          glyph_index = FT_Get_Char_Index(face, *TempText);
          error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
-         IntUnLockFreeType;
 
          if (error)
          {
@@ -1767,9 +1735,7 @@ NtGdiExtTextOut(
          if (use_kerning && previous && glyph_index)
          {
             FT_Vector delta;
-            IntLockFreeType;
             FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
-            IntUnLockFreeType;
             TextWidth += delta.x;
          }
 
@@ -1801,14 +1767,13 @@ NtGdiExtTextOut(
 
    for (i = 0; i < Count; i++)
    {
-      IntLockFreeType;
       glyph_index = FT_Get_Char_Index(face, *String);
       error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
-      IntUnLockFreeType;
 
       if (error)
       {
          DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
+        IntUnLockFreeType;
          goto fail;
       }
 
@@ -1818,25 +1783,18 @@ NtGdiExtTextOut(
       if (use_kerning && previous && glyph_index && NULL == Dx)
       {
          FT_Vector delta;
-         IntLockFreeType;
          FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
-         IntUnLockFreeType;
          TextLeft += delta.x;
       }
 
       if (glyph->format == ft_glyph_format_outline)
       {
-         IntLockFreeType;
          error = FT_Render_Glyph(glyph, RenderMode);
-         IntUnLockFreeType;
          if (error)
          {
             DPRINT1("WARNING: Failed to render glyph!\n");
             goto fail;
          }
-         pitch = glyph->bitmap.pitch;
-      } else {
-         pitch = glyph->bitmap.width;
       }
 
       if (fuOptions & ETO_OPAQUE)
@@ -1846,7 +1804,7 @@ NtGdiExtTextOut(
          DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6);
          DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6);
          IntEngBitBlt(
-            BitmapObj,
+            &BitmapObj->SurfObj,
             NULL,
             NULL,
             dc->CombinedClip,
@@ -1874,12 +1832,21 @@ NtGdiExtTextOut(
        * We should create the bitmap out of the loop at the biggest possible
        * glyph size. Then use memset with 0 to clear it and sourcerect to
        * limit the work of the transbitblt.
+       *
+       * FIXME: DIB bitmaps should have an lDelta which is a multiple of 4.
+       * Here we pass in the pitch from the FreeType bitmap, which is not
+       * guaranteed to be a multiple of 4. If it's not, we should expand
+       * the FreeType bitmap to a temporary bitmap.
        */
 
-      HSourceGlyph = EngCreateBitmap(bitSize, pitch, (glyph->bitmap.pixel_mode == ft_pixel_mode_grays) ? BMF_8BPP : BMF_1BPP, BMF_TOPDOWN, glyph->bitmap.buffer);
+      HSourceGlyph = EngCreateBitmap(bitSize, glyph->bitmap.pitch,
+                                     (glyph->bitmap.pixel_mode == ft_pixel_mode_grays) ?
+                                     BMF_8BPP : BMF_1BPP, BMF_TOPDOWN,
+                                     glyph->bitmap.buffer);
       if ( !HSourceGlyph )
       {
         DPRINT1("WARNING: EngLockSurface() failed!\n");
+       IntUnLockFreeType;
         goto fail;
       }
       SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
@@ -1887,6 +1854,7 @@ NtGdiExtTextOut(
       {
         EngDeleteSurface((HSURF)HSourceGlyph);
         DPRINT1("WARNING: EngLockSurface() failed!\n");
+       IntUnLockFreeType;
         goto fail;
       }
 
@@ -1939,6 +1907,8 @@ NtGdiExtTextOut(
       String++;
    }
 
+   IntUnLockFreeType;
+
    EngDeleteXlate(XlateObj);
    EngDeleteXlate(XlateObj2);
    BITMAPOBJ_UnlockBitmap(BitmapObj);
@@ -2146,15 +2116,17 @@ NtGdiGetFontLanguageInfo(HDC  hDC)
   return 0;
 }
 
-DWORD
-STDCALL
-NtGdiGetGlyphOutline(HDC  hDC,
-                           UINT  Char,
-                           UINT  Format,
-                           LPGLYPHMETRICS  gm,
-                           DWORD  Bufsize,
-                           LPVOID  Buffer,
-                           CONST LPMAT2 mat2)
+ULONG
+APIENTRY
+NtGdiGetGlyphOutline(
+    IN HDC hdc,
+    IN WCHAR wch,
+    IN UINT iFormat,
+    OUT LPGLYPHMETRICS pgm,
+    IN ULONG cjBuf,
+    OUT OPTIONAL PVOID pvBuf,
+    IN LPMAT2 pmat2,
+    IN BOOL bIgnoreRotation)
 {
   UNIMPLEMENTED;
   return 0;
@@ -2181,9 +2153,10 @@ NtGdiGetOutlineTextMetrics(HDC  hDC,
 }
 
 BOOL
-STDCALL
-NtGdiGetRasterizerCaps(LPRASTERIZER_STATUS  rs,
-                            UINT  Size)
+APIENTRY
+NtGdiGetRasterizerCaps(
+    OUT LPRASTERIZER_STATUS praststat,
+    IN ULONG cjBytes)
 {
   UNIMPLEMENTED;
   return FALSE;
@@ -2197,11 +2170,12 @@ NtGdiGetTextCharset(HDC  hDC)
   return 0;
 }
 
-UINT
-STDCALL
-NtGdiGetTextCharsetInfo(HDC  hDC,
-                             LPFONTSIGNATURE  Sig,
-                             DWORD  Flags)
+INT
+APIENTRY
+NtGdiGetTextCharsetInfo(
+    IN HDC hdc,
+    OUT OPTIONAL LPFONTSIGNATURE lpSig,
+    IN DWORD dwFlags)
 {
   UNIMPLEMENTED;
   return 0;
@@ -2564,6 +2538,7 @@ INT STDCALL
 NtGdiGetTextFace(HDC hDC, INT Count, LPWSTR FaceName)
 {
    PDC Dc;
+   HFONT hFont;
    PTEXTOBJ TextObj;
    NTSTATUS Status;
 
@@ -2573,11 +2548,14 @@ NtGdiGetTextFace(HDC hDC, INT Count, LPWSTR FaceName)
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
-   TextObj = TEXTOBJ_LockText(Dc->w.hFont);
+   hFont = Dc->w.hFont;
    DC_UnlockDc(Dc);
 
+   TextObj = TEXTOBJ_LockText(hFont);
+   ASSERT(TextObj != NULL);
    Count = min(Count, wcslen(TextObj->logfont.lfFaceName));
    Status = MmCopyToCaller(FaceName, TextObj->logfont.lfFaceName, Count * sizeof(WCHAR));
+   TEXTOBJ_UnlockText(TextObj);
    if (!NT_SUCCESS(Status))
    {
       SetLastNtError(Status);
@@ -2878,7 +2856,7 @@ GetFontScore(LOGFONTW *LogFont, PUNICODE_STRING FaceName, PFONTGDI FontGDI)
   return Score;
 }
 
-static inline VOID
+static __inline VOID
 FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont,
                      PUNICODE_STRING FaceName, PLIST_ENTRY Head)
 {
@@ -2905,7 +2883,7 @@ FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont,
     }
 }
 
-static inline BOOLEAN
+static __inline BOOLEAN
 SubstituteFontFamilyKey(PUNICODE_STRING FaceName,
                         LPCWSTR Key)
 {
@@ -2941,7 +2919,7 @@ SubstituteFontFamilyKey(PUNICODE_STRING FaceName,
   return NT_SUCCESS(Status);
 }
 
-static inline void
+static __inline void
 SubstituteFontFamily(PUNICODE_STRING FaceName, UINT Level)
 {
   if (10 < Level) /* Enough is enough */