Author: fireball
Date: Mon Feb  7 21:11:21 2011
New Revision: 50613

URL: http://svn.reactos.org/svn/reactos?rev=50613&view=rev
Log:
- Implement support for smoothed (gray) glyph rendering.
- Modify GreTextOut to use sharp rendering for non-antialised glyphs and smooth 
for AA ones respectively.
- Removed unnecessary unused code from font.c.
- This fixes bug 5327 if FontSmoothing is enabled in the registry.

Modified:
    branches/arwinss/reactos/subsystems/win32/win32k/gre/font.c

Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/font.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/gre/font.c?rev=50613&r1=50612&r2=50613&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gre/font.c [iso-8859-1] 
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gre/font.c [iso-8859-1] 
Mon Feb  7 21:11:21 2011
@@ -128,8 +128,8 @@
 #endif
 }
 
-static void SharpGlyphGray(PDC physDev, INT x, INT y,
-                           void *bitmap, GlyphInfo *gi, EBRUSHOBJ *pTextBrush)
+void SharpGlyphGray(PDC physDev, INT x, INT y,
+                    void *bitmap, GlyphInfo *gi, EBRUSHOBJ *pTextBrush)
 {
     unsigned char   *srcLine = bitmap, *src, bits;
     int             width = gi->width;
@@ -191,6 +191,136 @@
     }
 }
 
+/*static*/ void SmoothGlyphGray(PDC physDev, INT x, INT y,
+                            void *bitmap, GlyphInfo *gi, EBRUSHOBJ *pTextBrush)
+{
+    unsigned char   *srcLine = bitmap, *src, bits;
+    int             width = gi->width;
+    int             stride = ((width + 3) & ~3);
+    int             height = gi->height;
+    int             w,h;
+    RECTL           rcBounds;
+    COLORREF        srcColor;
+    BYTE            rVal, gVal, bVal;
+    PFN_DIB_PutPixel DibPutPixel;
+    PFN_DIB_GetPixel DibGetPixel;
+    SIZEL           slSize;
+    HBITMAP         charBitmap;
+    PSURFACE        pCharSurf;
+    POINTL          BrushOrigin = {0,0};
+    POINTL          SourcePoint;
+    BOOLEAN         bRet;
+    HPALETTE        hDestPalette;
+    PPALETTE        ppalDst;
+    EXLATEOBJ       exloRGB2Dst, exloDst2RGB;
+    ULONG           xlBrushColor;
+
+    /* Create a 24bpp bitmap for the glyph + background */
+    slSize.cx = gi->width;
+    slSize.cy = gi->height;
+    if (height == 0) return;
+    charBitmap = GreCreateBitmap(slSize, 0, BMF_24BPP, 0, NULL);
+
+    /* Get the object pointer */
+    pCharSurf = SURFACE_LockSurface(charBitmap);
+
+    /* Create XLATE objects */
+    /* (the following 3 lines is the old way of doing that,
+       until yarotows is merged) */
+    hDestPalette = physDev->dclevel.pSurface->hDIBPalette;
+    if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
+    ppalDst = PALETTE_LockPalette(hDestPalette);
+
+    EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, /*psurf->ppal*/ppalDst, 0, 
0, 0);
+    EXLATEOBJ_vInitialize(&exloDst2RGB, /*psurf->ppal*/ppalDst, &gpalRGB, 0, 
0, 0);
+
+    PALETTE_UnlockPalette(ppalDst);
+
+    /* Translate the brush color */
+    xlBrushColor = XLATEOBJ_iXlate(&exloDst2RGB.xlo, 
pTextBrush->BrushObject.iSolidColor);
+
+    /* Get pixel routines address */
+    DibPutPixel = 
DibFunctionsForBitmapFormat[pCharSurf->SurfObj.iBitmapFormat].DIB_PutPixel;
+    DibGetPixel = 
DibFunctionsForBitmapFormat[pCharSurf->SurfObj.iBitmapFormat].DIB_GetPixel;
+
+    /* Blit background into this bitmap */
+    rcBounds.left = 0; rcBounds.top = 0;
+    rcBounds.right = width; rcBounds.bottom = height;
+
+    x -= gi->x;
+    y -= gi->y;
+
+    SourcePoint.x = x; SourcePoint.y = y;
+
+    bRet = GrepBitBltEx(
+        &pCharSurf->SurfObj,
+        &physDev->dclevel.pSurface->SurfObj,
+        NULL,
+        NULL,
+        &exloDst2RGB.xlo,
+        &rcBounds,
+        &SourcePoint,
+        NULL,
+        &physDev->eboFill.BrushObject,
+        &BrushOrigin,
+        ROP3_TO_ROP4(SRCCOPY),
+        TRUE);
+
+    for (h=0; h<height; h++)
+    {
+        src = srcLine;
+        srcLine += stride;
+        bits = *src++;
+
+        for (w=0;w<width;w++)
+        {
+            if (bits == 0xff)
+            {
+                DibPutPixel(&pCharSurf->SurfObj, w, h, xlBrushColor);
+            }
+            else
+            {
+                srcColor = DibGetPixel(&pCharSurf->SurfObj, w, h);
+                rVal = ((UCHAR)~bits * (USHORT)GetRValue(srcColor) + bits * 
(USHORT)GetRValue(xlBrushColor)) >> 8;
+                gVal = ((UCHAR)~bits * (USHORT)GetGValue(srcColor) + bits * 
(USHORT)GetGValue(xlBrushColor)) >> 8;
+                bVal = ((UCHAR)~bits * (USHORT)GetBValue(srcColor) + bits * 
(USHORT)GetBValue(xlBrushColor)) >> 8;
+                DibPutPixel(&pCharSurf->SurfObj, w, h, RGB(rVal, gVal, bVal));
+            }
+
+            bits = *src++;
+        }
+    }
+
+    /* Blit the modified bitmap back */
+    rcBounds.left = x; rcBounds.top = y;
+    rcBounds.right = rcBounds.left + width; rcBounds.bottom = rcBounds.top + 
height;
+
+    SourcePoint.x = 0; SourcePoint.y = 0;
+
+    bRet = GrepBitBltEx(
+        &physDev->dclevel.pSurface->SurfObj,
+        &pCharSurf->SurfObj,
+        NULL,
+        physDev->CombinedClip,
+        &exloRGB2Dst.xlo,
+        &rcBounds,
+        &SourcePoint,
+        NULL,
+        &physDev->eboFill.BrushObject,
+        &BrushOrigin,
+        ROP3_TO_ROP4(SRCCOPY),
+        TRUE);
+
+    SURFACE_UnlockSurface(pCharSurf);
+
+    /* Cleanup exlate objects */
+    EXLATEOBJ_vCleanup(&exloRGB2Dst);
+    EXLATEOBJ_vCleanup(&exloDst2RGB);
+
+    /* Release the surface and delete the bitmap */
+    GreDeleteObject(charBitmap);
+}
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 VOID NTAPI
@@ -204,6 +334,7 @@
     EBRUSHOBJ pTextPen;
     PBRUSH ppen;
     HPEN hpen;
+    void (* sharp_glyph_fn)(PDC, INT, INT, void *, GlyphInfo *, EBRUSHOBJ *);
 
     /* Create pen for text output */
     hpen  = GreCreatePen(PS_SOLID, 1, pDC->crForegroundClr, NULL);
@@ -214,152 +345,34 @@
         return;
     EBRUSHOBJ_vInit(&pTextPen, ppen, pDC);
 
-    if(aa_type == AA_None || pDC->dclevel.pSurface->SurfObj.iBitmapFormat == 
BMF_1BPP)
-    {
-        void (* sharp_glyph_fn)(PDC, INT, INT, void *, GlyphInfo *, EBRUSHOBJ 
*);
-
-        if(aa_type == AA_None)
-            sharp_glyph_fn = SharpGlyphMono;
+    if(aa_type == AA_None)
+        sharp_glyph_fn = SharpGlyphMono;
+    else
+        sharp_glyph_fn = SmoothGlyphGray;
+
+    for(idx = 0; idx < count; idx++) {
+        sharp_glyph_fn(pDC,
+                       pDC->ptlDCOrig.x + x + offset.x,
+                       pDC->ptlDCOrig.y + y + offset.y,
+                       formatEntry->bitmaps[wstr[idx]],
+                       &formatEntry->gis[wstr[idx]],
+                       &pTextPen);
+        if(lpDx)
+        {
+            if(flags & ETO_PDY)
+            {
+                offset.x += lpDx[idx * 2];
+                offset.y += lpDx[idx * 2 + 1];
+            }
+            else
+                offset.x += lpDx[idx];
+        }
         else
-            sharp_glyph_fn = SharpGlyphGray;
-
-        for(idx = 0; idx < count; idx++) {
-            sharp_glyph_fn(pDC,
-                           pDC->ptlDCOrig.x + x + offset.x,
-                           pDC->ptlDCOrig.y + y + offset.y,
-                formatEntry->bitmaps[wstr[idx]],
-                &formatEntry->gis[wstr[idx]],
-                &pTextPen);
-            if(lpDx)
-            {
-                if(flags & ETO_PDY)
-                {
-                    offset.x += lpDx[idx * 2];
-                    offset.y += lpDx[idx * 2 + 1];
-            }
-                else
-                    offset.x += lpDx[idx];
-        }
-            else
-            {
-                offset.x += formatEntry->gis[wstr[idx]].xOff;
-                offset.y += formatEntry->gis[wstr[idx]].yOff;
-            }
-        }
-    } else {
-        UNIMPLEMENTED;
-#if 0
-        OUTDATED (need to merge 47289 and higher)
-        XImage *image;
-        int image_x, image_y, image_off_x, image_off_y, image_w, image_h;
-        RECT extents = {0, 0, 0, 0};
-        POINT cur = {0, 0};
-        int w = physDev->drawable_rect.right - physDev->drawable_rect.left;
-        int h = physDev->drawable_rect.bottom - physDev->drawable_rect.top;
-
-        TRACE("drawable %dx%d\n", w, h);
-
-        for(idx = 0; idx < count; idx++) {
-            if(extents.left > cur.x - formatEntry->gis[wstr[idx]].x)
-                extents.left = cur.x - formatEntry->gis[wstr[idx]].x;
-            if(extents.top > cur.y - formatEntry->gis[wstr[idx]].y)
-                extents.top = cur.y - formatEntry->gis[wstr[idx]].y;
-            if(extents.right < cur.x - formatEntry->gis[wstr[idx]].x + 
formatEntry->gis[wstr[idx]].width)
-                extents.right = cur.x - formatEntry->gis[wstr[idx]].x + 
formatEntry->gis[wstr[idx]].width;
-            if(extents.bottom < cur.y - formatEntry->gis[wstr[idx]].y + 
formatEntry->gis[wstr[idx]].height)
-                extents.bottom = cur.y - formatEntry->gis[wstr[idx]].y + 
formatEntry->gis[wstr[idx]].height;
-            if(lpDx) {
-                offset += lpDx[idx];
-                cur.x = offset * cosEsc;
-                cur.y = offset * -sinEsc;
-            } else {
-                cur.x += formatEntry->gis[wstr[idx]].xOff;
-                cur.y += formatEntry->gis[wstr[idx]].yOff;
-            }
-        }
-        TRACE("glyph extents %d,%d - %d,%d drawable x,y %d,%d\n", 
extents.left, extents.top,
-            extents.right, extents.bottom, physDev->dc_rect.left + x, 
physDev->dc_rect.top + y);
-
-        if(physDev->dc_rect.left + x + extents.left >= 0) {
-            image_x = physDev->dc_rect.left + x + extents.left;
-            image_off_x = 0;
-        } else {
-            image_x = 0;
-            image_off_x = physDev->dc_rect.left + x + extents.left;
-        }
-        if(physDev->dc_rect.top + y + extents.top >= 0) {
-            image_y = physDev->dc_rect.top + y + extents.top;
-            image_off_y = 0;
-        } else {
-            image_y = 0;
-            image_off_y = physDev->dc_rect.top + y + extents.top;
-        }
-        if(physDev->dc_rect.left + x + extents.right < w)
-            image_w = physDev->dc_rect.left + x + extents.right - image_x;
-        else
-            image_w = w - image_x;
-        if(physDev->dc_rect.top + y + extents.bottom < h)
-            image_h = physDev->dc_rect.top + y + extents.bottom - image_y;
-        else
-            image_h = h - image_y;
-
-        if(image_w <= 0 || image_h <= 0) goto no_image;
-
-        X11DRV_expect_error(gdi_display, XRenderErrorHandler, NULL);
-        image = XGetImage(gdi_display, physDev->drawable,
-            image_x, image_y, image_w, image_h,
-            AllPlanes, ZPixmap);
-        X11DRV_check_error();
-
-        TRACE("XGetImage(%p, %x, %d, %d, %d, %d, %lx, %x) depth = %d rets 
%p\n",
-            gdi_display, (int)physDev->drawable, image_x, image_y,
-            image_w, image_h, AllPlanes, ZPixmap,
-            physDev->depth, image);
-        if(!image) {
-            Pixmap xpm = XCreatePixmap(gdi_display, root_window, image_w, 
image_h,
-                physDev->depth);
-            GC gc;
-            XGCValues gcv;
-
-            gcv.graphics_exposures = False;
-            gc = XCreateGC(gdi_display, xpm, GCGraphicsExposures, &gcv);
-            XCopyArea(gdi_display, physDev->drawable, xpm, gc, image_x, 
image_y,
-                image_w, image_h, 0, 0);
-            XFreeGC(gdi_display, gc);
-            X11DRV_expect_error(gdi_display, XRenderErrorHandler, NULL);
-            image = XGetImage(gdi_display, xpm, 0, 0, image_w, image_h, 
AllPlanes,
-                ZPixmap);
-            X11DRV_check_error();
-            XFreePixmap(gdi_display, xpm);
-        }
-        if(!image) goto no_image;
-
-        image->red_mask = visual->red_mask;
-        image->green_mask = visual->green_mask;
-        image->blue_mask = visual->blue_mask;
-
-        offset = xoff = yoff = 0;
-        for(idx = 0; idx < count; idx++) {
-            SmoothGlyphGray(image, xoff + image_off_x - extents.left,
-                yoff + image_off_y - extents.top,
-                formatEntry->bitmaps[wstr[idx]],
-                &formatEntry->gis[wstr[idx]],
-                physDev->textPixel);
-            if(lpDx) {
-                offset += lpDx[idx];
-                xoff = offset * cosEsc;
-                yoff = offset * -sinEsc;
-            } else {
-                xoff += formatEntry->gis[wstr[idx]].xOff;
-                yoff += formatEntry->gis[wstr[idx]].yOff;
-            }
-        }
-        XPutImage(gdi_display, physDev->drawable, physDev->gc, image, 0, 0,
-            image_x, image_y, image_w, image_h);
-        XDestroyImage(image);
-#endif
+        {
+            offset.x += formatEntry->gis[wstr[idx]].xOff;
+            offset.y += formatEntry->gis[wstr[idx]].yOff;
+        }
     }
-//no_image:
 
     //Cleanup the temporary pen
     EBRUSHOBJ_vCleanup(&pTextPen);


Reply via email to