Handle a missing output buffer in NtGdiGetCharABCWidthsW
[reactos.git] / reactos / subsystems / win32 / win32k / objects / freetype.c
index 328f5fe..c13c31b 100644 (file)
@@ -75,8 +75,6 @@ static FAST_MUTEX FontListLock;
 static BOOL RenderingEnabled = TRUE;
 
 #define MAX_FONT_CACHE 256
-UINT Hits;
-UINT Misses;
 
 typedef struct _FONT_CACHE_ENTRY
 {
@@ -423,7 +421,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
 
     if (Characteristics & FR_PRIVATE)
     {
-        PW32PROCESS Win32Process = PsGetCurrentProcessWin32Process();
+        PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
         IntLockProcessPrivateFonts(Win32Process);
         InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry);
         IntUnLockProcessPrivateFonts(Win32Process);
@@ -942,7 +940,7 @@ FindFaceNameInList(PUNICODE_STRING FaceName, PLIST_ENTRY Head)
 static PFONTGDI FASTCALL
 FindFaceNameInLists(PUNICODE_STRING FaceName)
 {
-    PW32PROCESS Win32Process;
+    PPROCESSINFO Win32Process;
     PFONTGDI Font;
 
     /* Search the process local list */
@@ -1322,8 +1320,6 @@ ftGdiGlyphCacheGet(
     PLIST_ENTRY CurrentEntry;
     PFONT_CACHE_ENTRY FontEntry;
 
-//   DbgPrint("CacheGet\n");
-
     CurrentEntry = FontCacheListHead.Flink;
     while (CurrentEntry != &FontCacheListHead)
     {
@@ -1337,29 +1333,11 @@ ftGdiGlyphCacheGet(
 
     if (CurrentEntry == &FontCacheListHead)
     {
-//      DbgPrint("Miss! %x\n", FontEntry->Glyph);
-        /*
-              Misses++;
-              if (Misses>100) {
-                 DbgPrint ("Hits: %d Misses: %d\n", Hits, Misses);
-                 Hits = Misses = 0;
-              }
-        */
         return NULL;
     }
 
     RemoveEntryList(CurrentEntry);
     InsertHeadList(&FontCacheListHead, CurrentEntry);
-
-//   DbgPrint("Hit! %x\n", FontEntry->Glyph);
-    /*
-       Hits++;
-
-          if (Hits>100) {
-             DbgPrint ("Hits: %d Misses: %d\n", Hits, Misses);
-             Hits = Misses = 0;
-          }
-    */
     return FontEntry->Glyph;
 }
 
@@ -1375,25 +1353,23 @@ ftGdiGlyphCacheSet(
     INT error;
     PFONT_CACHE_ENTRY NewEntry;
 
-//   DbgPrint("CacheSet.\n");
-
     error = FT_Get_Glyph(GlyphSlot, &GlyphCopy);
     if (error)
     {
-        DbgPrint("Failure caching glyph.\n");
+        DPRINT1("Failure caching glyph.\n");
         return NULL;
     };
     error = FT_Glyph_To_Bitmap(&GlyphCopy, RenderMode, 0, 1);
     if (error)
     {
-        DbgPrint("Failure rendering glyph.\n");
+        DPRINT1("Failure rendering glyph.\n");
         return NULL;
     };
 
     NewEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_CACHE_ENTRY), TAG_FONT);
     if (!NewEntry)
     {
-        DbgPrint("Alloc failure caching glyph.\n");
+        DPRINT1("Alloc failure caching glyph.\n");
         FT_Done_Glyph(GlyphCopy);
         return NULL;
     }
@@ -1413,8 +1389,6 @@ ftGdiGlyphCacheSet(
         FontCacheNumEntries--;
     }
 
-//   DbgPrint("Returning the glyphcopy: %x\n", GlyphCopy);
-
     return GlyphCopy;
 }
 
@@ -2716,7 +2690,7 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
     NTSTATUS Status = STATUS_SUCCESS;
     PTEXTOBJ TextObj;
     UNICODE_STRING FaceName;
-    PW32PROCESS Win32Process;
+    PPROCESSINFO Win32Process;
     UINT MatchScore;
 
     if (!pTextObj)
@@ -3029,7 +3003,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
     LOGFONTW LogFont;
     PFONTFAMILYINFO Info;
     DWORD Count;
-    PW32PROCESS Win32Process;
+    PPROCESSINFO Win32Process;
 
     /* Make a safe copy */
     Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
@@ -3136,12 +3110,13 @@ GreExtTextOutW(
     FONTOBJ *FontObj;
     PFONTGDI FontGDI;
     PTEXTOBJ TextObj = NULL;
-    XLATEOBJ *XlateObj=NULL, *XlateObj2=NULL;
+    EXLATEOBJ exloRGB2Dst, exloDst2RGB;
     FT_Render_Mode RenderMode;
     BOOLEAN Render;
     POINT Start;
     BOOL DoBreak = FALSE;
     HPALETTE hDestPalette;
+    PPALETTE ppalDst;
     USHORT DxShift;
 
     // TODO: Write test-cases to exactly match real Windows in different
@@ -3197,7 +3172,7 @@ GreExtTextOutW(
         IntLPtoDP(dc, (POINT *)lprc, 2);
     }
 
-    psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
+    psurf = dc->dclevel.pSurface;
     if (!psurf)
     {
         goto fail;
@@ -3211,20 +3186,6 @@ GreExtTextOutW(
     RealXStart = (Start.x + dc->ptlDCOrig.x) << 6;
     YStart = Start.y + dc->ptlDCOrig.y;
 
-    /* Create the brushes */
-    hDestPalette = psurf->hDIBPalette;
-    if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault;
-    XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, PAL_RGB, hDestPalette, NULL);
-    if ( !XlateObj )
-    {
-        goto fail;
-    }
-    XlateObj2 = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, hDestPalette);
-    if ( !XlateObj2 )
-    {
-        goto fail;
-    }
-
     SourcePoint.x = 0;
     SourcePoint.y = 0;
     MaskRect.left = 0;
@@ -3423,6 +3384,15 @@ GreExtTextOutW(
     TextTop = YStart;
     BackgroundLeft = (RealXStart + 32) >> 6;
 
+    /* Create the xlateobj */
+    hDestPalette = psurf->hDIBPalette;
+    if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
+    ppalDst = PALETTE_LockPalette(hDestPalette);
+    EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
+    EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
+    PALETTE_UnlockPalette(ppalDst);
+
+
     /*
      * The main rendering loop.
      */
@@ -3442,7 +3412,7 @@ GreExtTextOutW(
             {
                 DPRINT1("Failed to load and render glyph! [index: %u]\n", glyph_index);
                 IntUnLockFreeType;
-                goto fail;
+                goto fail2;
             }
             glyph = face->glyph;
             realglyph = ftGdiGlyphCacheSet(face,
@@ -3454,11 +3424,9 @@ GreExtTextOutW(
             {
                 DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index);
                 IntUnLockFreeType;
-                goto fail;
+                goto fail2;
             }
         }
-//      DbgPrint("realglyph: %x\n", realglyph);
-//      DbgPrint("TextLeft: %d\n", TextLeft);
 
         /* retrieve kerning distance and move pen position */
         if (use_kerning && previous && glyph_index && NULL == Dx)
@@ -3467,24 +3435,23 @@ GreExtTextOutW(
             FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
             TextLeft += delta.x;
         }
-//      DPRINT1("TextLeft: %d\n", TextLeft);
-//      DPRINT1("TextTop: %d\n", TextTop);
+        DPRINT("TextLeft: %d\n", TextLeft);
+        DPRINT("TextTop: %d\n", TextTop);
 
         if (realglyph->format == ft_glyph_format_outline)
         {
-            DbgPrint("Should already be done\n");
+            DPRINT1("Should already be done\n");
 //         error = FT_Render_Glyph(glyph, RenderMode);
             error = FT_Glyph_To_Bitmap(&realglyph, RenderMode, 0, 0);
             if (error)
             {
                 DPRINT1("WARNING: Failed to render glyph!\n");
-                goto fail;
+                goto fail2;
             }
         }
         realglyph2 = (FT_BitmapGlyph)realglyph;
 
-//      DPRINT1("Pitch: %d\n", pitch);
-//      DPRINT1("Advance: %d\n", realglyph->advance.x);
+        DPRINT("Advance: %d\n", realglyph->advance.x);
 
         if (fuOptions & ETO_OPAQUE)
         {
@@ -3537,7 +3504,7 @@ GreExtTextOutW(
             DPRINT1("WARNING: EngLockSurface() failed!\n");
             // FT_Done_Glyph(realglyph);
             IntUnLockFreeType;
-            goto fail;
+            goto fail2;
         }
         SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
         if ( !SourceGlyphSurf )
@@ -3545,7 +3512,7 @@ GreExtTextOutW(
             EngDeleteSurface((HSURF)HSourceGlyph);
             DPRINT1("WARNING: EngLockSurface() failed!\n");
             IntUnLockFreeType;
-            goto fail;
+            goto fail2;
         }
 
         /*
@@ -3568,8 +3535,8 @@ GreExtTextOutW(
             SurfObj,
             SourceGlyphSurf,
             dc->rosdc.CombinedClip,
-            XlateObj,
-            XlateObj2,
+            &exloRGB2Dst.xlo,
+            &exloDst2RGB.xlo,
             &DestRect,
             (PPOINTL)&MaskRect,
             &dc->eboText.BrushObject,
@@ -3586,12 +3553,12 @@ GreExtTextOutW(
         if (NULL == Dx)
         {
             TextLeft += realglyph->advance.x >> 10;
-//         DbgPrint("new TextLeft: %d\n", TextLeft);
+             DPRINT("new TextLeft: %d\n", TextLeft);
         }
         else
         {
             TextLeft += Dx[i<<DxShift] << 6;
-//         DbgPrint("new TextLeft2: %d\n", TextLeft);
+             DPRINT("new TextLeft2: %d\n", TextLeft);
         }
 
         if (DxShift)
@@ -3606,9 +3573,8 @@ GreExtTextOutW(
 
     IntUnLockFreeType;
 
-    EngDeleteXlate(XlateObj);
-    EngDeleteXlate(XlateObj2);
-    SURFACE_UnlockSurface(psurf);
+    EXLATEOBJ_vCleanup(&exloRGB2Dst);
+    EXLATEOBJ_vCleanup(&exloDst2RGB);
     if (TextObj != NULL)
         TEXTOBJ_UnlockText(TextObj);
 good:
@@ -3616,15 +3582,12 @@ good:
 
     return TRUE;
 
+fail2:
+    EXLATEOBJ_vCleanup(&exloRGB2Dst);
+    EXLATEOBJ_vCleanup(&exloDst2RGB);
 fail:
-    if ( XlateObj2 != NULL )
-        EngDeleteXlate(XlateObj2);
-    if ( XlateObj != NULL )
-        EngDeleteXlate(XlateObj);
     if (TextObj != NULL)
         TEXTOBJ_UnlockText(TextObj);
-    if (psurf != NULL)
-        SURFACE_UnlockSurface(psurf);
     DC_UnlockDc(dc);
 
     return FALSE;
@@ -3798,6 +3761,12 @@ NtGdiGetCharABCWidthsW(
         return FALSE;
     }
 
+    if (!Buffer)
+    {
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
     BufferSize = Count * sizeof(ABC); // Same size!
     SafeBuff = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_GDITEXT);
     if (!fl) SafeBuffF = (LPABCFLOAT) SafeBuff;