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/win3…
==============================================================================
--- 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);