linamh/app-emulation/wine/files/0008-dib-engine-fixes-clipping-text.patch
2009-08-01 09:30:00 +00:00

1805 lines
67 KiB
Diff

DIB Engine: fixes clipping, text and more
From: Massimo Del Fedele <max@veneto.com>
---
dlls/winedib.drv/bitblt.c | 22 +++
dlls/winedib.drv/clipping.c | 63 +++++----
dlls/winedib.drv/dc.c | 16 ++
dlls/winedib.drv/dib.c | 41 +++++-
dlls/winedib.drv/dibdrv.h | 27 ++++
dlls/winedib.drv/font.c | 68 ++++++++-
dlls/winedib.drv/freetype.c | 6 +
dlls/winedib.drv/freetype.h | 4 +
dlls/winedib.drv/graphics.c | 204 +++++++++++++++++++++-------
dlls/winedib.drv/palette.c | 16 +-
dlls/winedib.drv/pen_brush.c | 13 ++
dlls/winedib.drv/primitives.c | 18 +-
dlls/winedib.drv/primitives_bitblt.c | 26 ++--
dlls/winedib.drv/primitives_convert.c | 24 ++-
dlls/winedib.drv/primitives_font.c | 242 +++++++++++++++++++++++++--------
dlls/winedib.drv/primitives_rop3.c | 2
dlls/winedib.drv/text.c | 239 +++++++++++++++++++--------------
17 files changed, 738 insertions(+), 293 deletions(-)
diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c
index 05c9392..db66142 100644
--- a/dlls/winedib.drv/bitblt.c
+++ b/dlls/winedib.drv/bitblt.c
@@ -261,6 +261,12 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
SIZE szSrc, szDst;
int iRec;
RECT dstClip, srcClip;
+
+ /* converts to device spaces */
+ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst);
+ _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst);
+ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
+ _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc);
/* first clip on physical DC sizes */
setPoint(&pd, xDst, yDst);
@@ -320,7 +326,6 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
xDst, yDst, widthDst, heightDst,
physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
xSrc, ySrc, widthSrc, heightSrc));
-
/* if sizes are null or negative, returns false */
if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0)
@@ -422,6 +427,12 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
int iRec;
RECT dstClip, srcClip;
+ /* converts to device spaces */
+ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst);
+ _DIBDRV_Sizes_ws2ds(physDevDst, &width, &height);
+ if(physDevSrc)
+ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
+
/* first clip on physical DC sizes */
setPoint(&pd, xDst, yDst);
setPoint(&ps, xSrc, ySrc);
@@ -633,6 +644,15 @@ BOOL _DIBDRV_InternalStretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
int iRec;
RECT dstClip, srcClip;
+ /* converts to device spaces */
+ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst);
+ _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst);
+ if(physDevSrc)
+ {
+ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
+ _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc);
+ }
+
/* first clip on physical DC sizes */
setPoint(&pd, xDst, yDst);
setPoint(&ps, xSrc, ySrc);
diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c
index ed10b92..ada1f7f 100644
--- a/dlls/winedib.drv/clipping.c
+++ b/dlls/winedib.drv/clipping.c
@@ -36,39 +36,44 @@ void DIBDRV_SetDeviceClipping( DIBDRVPHYSDEV *physDev, HRGN vis_rgn, HRGN clip_r
MAYBE(TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn));
- /* sets the region for X11 driver anyways... we may change bitmap later on */
- _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn);
-
- /* then we set the region for DIB engine, same reason */
+ if(physDev->hasDIB)
+ {
+ /* DIB section selected in, use DIB Engine */
- CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
+ CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
- /* get region rectangles */
- if(!(size = GetRegionData(physDev->region, 0, NULL)))
- return;
- data = HeapAlloc(GetProcessHeap(), 0, size);
- if (!GetRegionData(physDev->region, size, data))
- {
- HeapFree( GetProcessHeap(), 0, data );
- return;
- }
-
- /* frees any previous regions rectangles in DC */
- if(physDev->regionData)
- HeapFree(GetProcessHeap(), 0, physDev->regionData);
+ /* get region rectangles */
+ if(!(size = GetRegionData(physDev->region, 0, NULL)))
+ return;
+ data = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!GetRegionData(physDev->region, size, data))
+ {
+ HeapFree( GetProcessHeap(), 0, data );
+ return;
+ }
- /* sets the rectangles on physDev */
- physDev->regionData = data;
- physDev->regionRects = (RECT *)data->Buffer;
- physDev->regionRectCount = data->rdh.nCount;
-
- if(TRACE_ON(dibdrv))
- {
- TRACE("Region dump : %d rectangles\n", physDev->regionRectCount);
- for(iRect = 0; iRect < physDev->regionRectCount; iRect++)
+ /* frees any previous regions rectangles in DC */
+ if(physDev->regionData)
+ HeapFree(GetProcessHeap(), 0, physDev->regionData);
+
+ /* sets the rectangles on physDev */
+ physDev->regionData = data;
+ physDev->regionRects = (RECT *)data->Buffer;
+ physDev->regionRectCount = data->rdh.nCount;
+
+ if(TRACE_ON(dibdrv))
{
- RECT *r = physDev->regionRects + iRect;
- TRACE("Rect #%03d, x1:%4d, y1:%4d, x2:%4d, y2:%4d\n", iRect, r->left, r->top, r->right, r->bottom);
+ TRACE("Region dump : %d rectangles\n", physDev->regionRectCount);
+ for(iRect = 0; iRect < physDev->regionRectCount; iRect++)
+ {
+ RECT *r = physDev->regionRects + iRect;
+ TRACE("Rect #%03d, x1:%4d, y1:%4d, x2:%4d, y2:%4d\n", iRect, r->left, r->top, r->right, r->bottom);
+ }
}
}
+ else
+ {
+ /* DDB selected in, use X11 driver */
+ _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn);
+ }
}
diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c
index 8212d42..9ffceee 100644
--- a/dlls/winedib.drv/dc.c
+++ b/dlls/winedib.drv/dc.c
@@ -43,11 +43,12 @@ static int device_init_done;
/* NOTE :
Removing TC_RA_ABLE avoids bitmapped fonts, so FT_Face is always non-NULL
+ UPDATE : remove TC_RA_ABLE seems unneeded
Adding TC_VA_ABLE forces to use gdi fonts always, so we can get an FT_Face
*/
unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER |
- TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE /* | TC_RA_ABLE */ | TC_VA_ABLE);
+ TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE | TC_VA_ABLE);
/* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */
@@ -119,6 +120,10 @@ static void device_init(void)
device_init_done = TRUE;
}
+/* dummy null function for pen and brush */
+static void dummy3(DIBDRVPHYSDEV *p, int a, int b, int c) {}
+static void dummy4(DIBDRVPHYSDEV *p, int a, int b, int c, int d) {}
+
/**********************************************************************
* DIBDRV_CreateDC
*/
@@ -178,12 +183,19 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev
physDev->penColor = 0;
_DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
+ physDev->penStyle = PS_NULL;
+ physDev->penHLine = dummy3;
+ physDev->penVLine = dummy3;
+ physDev->penLine = dummy4;
+ physDev->penPattern = NULL;
+
physDev->brushColor = 0;
_DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor);
physDev->brushAnds = NULL;
physDev->brushXors = NULL;
physDev->brushStyle = BS_NULL;
+ physDev->brushHLine = dummy3;
physDev->isBrushBitmap = FALSE;
_DIBDRVBITMAP_Clear(&physDev->brushBitmap);
@@ -193,8 +205,10 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev
physDev->textColor = 0;
physDev->textBackground = 0;
+#ifdef DIBDRV_ANTIALIASED_FONTS
/* text color table for antialiased fonts */
memset(physDev->textColorTable, 0, 256);
+#endif
/* freetype face associated to current DC HFONT */
physDev->face = NULL;
diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c
index b72c34a..653148d 100644
--- a/dlls/winedib.drv/dib.c
+++ b/dlls/winedib.drv/dib.c
@@ -65,15 +65,46 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
const RGBQUAD *colors )
{
- UINT res;
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
MAYBE(TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors));
/* SetDIBColorTable operates on a DIB, so we use the engine */
- ONCE(FIXME("STUB\n"));
- res = 0;
-
- return res;
+
+ /* if bpp > 8, some error occurred... */
+ if(dib->bitCount > 8)
+ {
+ ERR("Called for BPP > 8\n");
+ return 0;
+ }
+
+ /* if dib hasn't a color table, or has a small one, we must before
+ create/extend it */
+ if(!(dib->colorTable))
+ {
+ dib->colorTableSize = (1 << dib->bitCount);
+ dib->colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(RGBQUAD) * dib->colorTableSize);
+ }
+ else if(dib->colorTableSize < (1 << dib->bitCount))
+ {
+ int newSize = (1 << dib->bitCount);
+ RGBQUAD *newTable = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RGBQUAD) * newSize);
+ memcpy(newTable, dib->colorTable, sizeof(RGBQUAD) * dib->colorTableSize);
+ HeapFree(GetProcessHeap(), 0, dib->colorTable);
+ dib->colorTable = newTable;
+ dib->colorTableSize = newSize;
+ }
+
+ /* sanity check */
+ if(start + count > dib->colorTableSize)
+ {
+ ERR("Out of range setting color table, size is %d, requested is %d\n", dib->colorTableSize, start+count);
+ return 0;
+ }
+ memcpy(dib->colorTable + start, colors, sizeof(RGBQUAD) * count);
+ dib->colorTableGrabbed = TRUE;
+
+ return TRUE;
}
/***********************************************************************
diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h
index b0f128e..66cc114 100644
--- a/dlls/winedib.drv/dibdrv.h
+++ b/dlls/winedib.drv/dibdrv.h
@@ -44,6 +44,9 @@
/* enable this if you want debugging (i.e. TRACEs) output */
#define DIBDRV_ENABLE_MAYBE
+/* enable this if you want antialiased fonts */
+#define DIBDRV_ANTIALIASED_FONTS
+
/* provide a way to make debugging output appear
only once. Usage example:
ONCE(FIXME("Some message\n")); */
@@ -102,7 +105,7 @@ typedef struct _DIBDRV_PRIMITIVE_FUNCS
const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, DWORD rop );
/* font drawing helper */
- void (* FreetypeBlit) ( struct _DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp);
+ void (* FreetypeBlit) ( struct _DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
} DIBDRV_PRIMITIVE_FUNCS;
@@ -225,6 +228,9 @@ typedef struct _DIBDRVPHYSDEV
DWORD curDash, leftInDash;
enum MARKSPACE { mark, space } markSpace;
+ /* pen style */
+ UINT penStyle;
+
/* pen drawing functions */
void (* penHLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y);
void (* penVLine) (struct _DIBDRVPHYSDEV *physDev, int x, int y1, int y2);
@@ -250,8 +256,10 @@ typedef struct _DIBDRVPHYSDEV
COLORREF textColor;
COLORREF textBackground;
+#ifdef DIBDRV_ANTIALIASED_FONTS
/* text color table for antialiased fonts */
COLORREF textColorTable[256];
+#endif
/* freetype face associated to current DC HFONT */
FT_Face face;
@@ -388,4 +396,21 @@ HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc,
* DIBDRV_GetDeviceCaps */
INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap );
+/* *********************************************************************
+ * GEOMETRIC UTILITIES
+ * ********************************************************************/
+
+/* intersect 2 rectangles (just to not use USER32 one...) */
+BOOL _DIBDRV_IntersectRect(RECT *d, const RECT *s1, const RECT *s2);
+
+/* converts positions from Word space to Device space */
+void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV *physDev, int *x, int *y);
+void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2);
+
+/* converts sizes from Word space to Device space */
+void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h);
+
+/* converts a rectangle form Word space to Device space */
+void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst);
+
#endif
diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c
index 215b27d..f7ea8dc 100644
--- a/dlls/winedib.drv/font.c
+++ b/dlls/winedib.drv/font.c
@@ -26,14 +26,56 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+#if 0
+/* prints out some info about face */
+void PrintFaceInfo(FT_Face face)
+{
+ int i;
+
+ fprintf(stderr, "----------------------------------------------------------\n");
+ fprintf(stderr, "Family name :%s\n", face->family_name);
+ fprintf(stderr, "Style name :%s\n", face->style_name);
+ fprintf(stderr, "Num fixed sizes : %d\n", face->num_fixed_sizes);
+ if(face->num_fixed_sizes)
+ {
+ fprintf(stderr, "Fixed sizes :");
+ for(i = 0; i < face->num_fixed_sizes; i++)
+ fprintf(stderr, " (%d, %d)", face->available_sizes[i].width, face->available_sizes[i].height);
+ fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "Face flags: ");
+ if(face->face_flags & FT_FACE_FLAG_SCALABLE ) fprintf(stderr, "FT_FACE_FLAG_SCALABLE ");
+ if(face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) fprintf(stderr, "FT_FACE_FLAG_FIXED_SIZES ");
+ if(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) fprintf(stderr, "FT_FACE_FLAG_FIXED_WIDTH ");
+ if(face->face_flags & FT_FACE_FLAG_SFNT ) fprintf(stderr, "FT_FACE_FLAG_SFNT ");
+ if(face->face_flags & FT_FACE_FLAG_HORIZONTAL ) fprintf(stderr, "FT_FACE_FLAG_HORIZONTAL ");
+ if(face->face_flags & FT_FACE_FLAG_VERTICAL ) fprintf(stderr, "FT_FACE_FLAG_VERTICAL ");
+ if(face->face_flags & FT_FACE_FLAG_KERNING ) fprintf(stderr, "FT_FACE_FLAG_KERNING ");
+ if(face->face_flags & FT_FACE_FLAG_FAST_GLYPHS ) fprintf(stderr, "FT_FACE_FLAG_FAST_GLYPHS ");
+ if(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) fprintf(stderr, "FT_FACE_FLAG_MULTIPLE_MASTERS ");
+ if(face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) fprintf(stderr, "FT_FACE_FLAG_GLYPH_NAMES ");
+ if(face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) fprintf(stderr, "FT_FACE_FLAG_EXTERNAL_STREAM ");
+ if(face->face_flags & FT_FACE_FLAG_HINTER ) fprintf(stderr, "FT_FACE_FLAG_HINTER ");
+ if(face->face_flags & FT_FACE_FLAG_CID_KEYED ) fprintf(stderr, "FT_FACE_FLAG_CID_KEYED ");
+ if(face->face_flags & FT_FACE_FLAG_TRICKY ) fprintf(stderr, "FT_FACE_FLAG_TRICKY ");
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, "Style flags: ");
+ if(face->style_flags & FT_STYLE_FLAG_ITALIC) fprintf(stderr, "FT_STYLE_FLAG_ITALIC ");
+ if(face->style_flags & FT_STYLE_FLAG_BOLD) fprintf(stderr, "FT_STYLE_FLAG_BOLD ");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "----------------------------------------------------------\n");
+}
+#endif
+
+
/**********************************************************************
* DIBDRV_SetTextColor
*/
COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color )
{
COLORREF res;
- INT r, g, b;
- INT i;
MAYBE(TRACE("physDev:%p, color:%08x\n", physDev, color));
@@ -45,24 +87,30 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color )
if(color == physDev->textColor)
return color;
- /* stores old color */
+ /* stores old color and sets new one */
res = physDev->textColor;
-
+ physDev->textColor = color;
+
+#ifdef DIBDRV_ANTIALIASED_FONTS
/* fills the text color table used on antialiased font display */
if(physDev->physBitmap.funcs)
{
+ BYTE r, g, b;
+ INT i;
+
r = GetRValue(color);
g = GetGValue(color);
b = GetBValue(color);
for(i = 0; i < 256; i++)
{
physDev->textColorTable[i] = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, RGB(
- MulDiv(r, i, 256),
- MulDiv(g, i, 256),
- MulDiv(b, i, 256)
+ MulDiv(r, i, 255),
+ MulDiv(g, i, 255),
+ MulDiv(b, i, 255)
));
}
}
+#endif
/* returns previous text color */
return res;
@@ -111,7 +159,11 @@ HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, GdiFont *gdiFont )
FIXME("Error, null Ft_Face\n");
return hfont;
}
-
+
+#if 0
+ /* prints out some info about face */
+ if(TRACE_ON(dibdrv)) MAYBE(PrintFaceInfo(physDev->face));
+#endif
/* setup the correct charmap.... maybe */
for (i = 0; i < physDev->face->num_charmaps; ++i)
{
diff --git a/dlls/winedib.drv/freetype.c b/dlls/winedib.drv/freetype.c
index 111a18b..f1cd7b4 100644
--- a/dlls/winedib.drv/freetype.c
+++ b/dlls/winedib.drv/freetype.c
@@ -46,6 +46,9 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes)
MAKE_FUNCPTR(FT_Get_First_Char)
MAKE_FUNCPTR(FT_Render_Glyph)
MAKE_FUNCPTR(FT_Glyph_Transform)
+MAKE_FUNCPTR(FT_Bitmap_New)
+MAKE_FUNCPTR(FT_Bitmap_Done)
+MAKE_FUNCPTR(FT_Bitmap_Convert)
#undef MAKE_FUNCPTR
/* freetype initialization flag */
@@ -95,6 +98,9 @@ BOOL _DIBDRV_FreeType_Init(void)
LOAD_FUNCPTR(FT_Get_First_Char)
LOAD_FUNCPTR(FT_Render_Glyph)
LOAD_FUNCPTR(FT_Glyph_Transform)
+ LOAD_FUNCPTR(FT_Bitmap_New)
+ LOAD_FUNCPTR(FT_Bitmap_Done)
+ LOAD_FUNCPTR(FT_Bitmap_Convert)
#undef LOAD_FUNCPTR
error = pFT_Init_FreeType(&DIBDRV_ftLibrary);
diff --git a/dlls/winedib.drv/freetype.h b/dlls/winedib.drv/freetype.h
index 93619ff..3517af5 100644
--- a/dlls/winedib.drv/freetype.h
+++ b/dlls/winedib.drv/freetype.h
@@ -28,6 +28,7 @@
#include FT_TRUETYPE_TABLES_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_IDS_H
+#include FT_BITMAP_H
/* freetype library handle */
extern FT_Library DIBDRV_ftLibrary;
@@ -179,6 +180,9 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes)
MAKE_FUNCPTR(FT_Get_First_Char)
MAKE_FUNCPTR(FT_Render_Glyph)
MAKE_FUNCPTR(FT_Glyph_Transform)
+MAKE_FUNCPTR(FT_Bitmap_New)
+MAKE_FUNCPTR(FT_Bitmap_Done)
+MAKE_FUNCPTR(FT_Bitmap_Convert)
#undef MAKE_FUNCPTR
#endif /* HAVE_FREETYPE */
diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c
index e416488..af264d0 100644
--- a/dlls/winedib.drv/graphics.c
+++ b/dlls/winedib.drv/graphics.c
@@ -295,7 +295,7 @@ static BOOL ScanPolygon(const POINT *pt, int count, int ys, POINT **scans, int *
}
/* gets bounding box of a polygon */
-void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox)
+static void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox)
{
const POINT *p;
int iPoint;
@@ -311,6 +311,76 @@ void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox)
}
}
+/* intersect 2 rectangles (just to not use USER32 one...)
+ bottom and tight sides are considered OUTSIDE */
+BOOL _DIBDRV_IntersectRect(RECT *d, const RECT *s1, const RECT *s2)
+{
+ if(s1->right <= s2->left ||
+ s2->right <= s1->left ||
+ s1->bottom <= s2->top ||
+ s2->bottom <= s1->top
+ )
+ return FALSE;
+ d->left = s1->left > s2->left ? s1->left : s2->left;
+ d->top = s1->top > s2->top ? s1->top : s2->top;
+ d->right = s1->right < s2->right ? s1->right : s2->right;
+ d->bottom = s1->bottom < s2->bottom ? s1->bottom : s2->bottom;
+ return TRUE;
+}
+
+/* converts a rectangle form Word space to Device space */
+void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst)
+{
+ POINT pts[2];
+ pts[0].x = src->left;
+ pts[0].y = src->top;
+ pts[1].x = src->right;
+ pts[1].y = src->bottom;
+ LPtoDP(physDev->hdc, pts, 2);
+ dst->left = pts[0].x;
+ dst->top = pts[0].y;
+ dst->right = pts[1].x;
+ dst->bottom = pts[1].y;
+}
+
+/* converts positions from Word space to Device space */
+void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV *physDev, int *x, int *y)
+{
+ POINT p;
+ p.x = *x;
+ p.y = *y;
+ LPtoDP(physDev->hdc, &p, 1);
+ *x = p.x;
+ *y = p.y;
+}
+
+void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2)
+{
+ POINT pts[2];
+ pts[0].x = *x1;
+ pts[0].y = *y1;
+ pts[1].x = *x2;
+ pts[1].y = *y2;
+ LPtoDP(physDev->hdc, pts, 2);
+ *x1 = pts[0].x;
+ *y1 = pts[0].y;
+ *x2 = pts[1].x;
+ *y2 = pts[1].y;
+}
+
+/* converts sizes from Word space to Device space */
+void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h)
+{
+ POINT pts[2];
+ pts[0].x = 0;
+ pts[0].y = 0;
+ pts[1].x = *w;
+ pts[1].y = *h;
+ LPtoDP(physDev->hdc, pts, 2);
+ *w = pts[1].x - pts[0].x;
+ *h = pts[1].y - pts[0].y;
+}
+
/***********************************************************************
* DIBDRV_Arc
*/
@@ -446,6 +516,7 @@ COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y )
if(physDev->hasDIB)
{
+ _DIBDRV_Position_ws2ds(physDev, &x, &y);
res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y);
}
else
@@ -463,22 +534,44 @@ BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, int x, int y )
{
BOOL res;
POINT curPos;
+ RECT *r;
+ int iRec;
+ POINT p1, p2, pc1, pc2;
MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
if(physDev->hasDIB)
{
+ res = FALSE;
GetCurrentPositionEx(physDev->hdc, &curPos);
- _DIBDRV_ResetDashOrigin(physDev);
+ /* converts position to device space */
+ p1.x = curPos.x; p1.y = curPos.y;
+ p2.x = x; p2.y = y;
+ LPtoDP(physDev->hdc, &p1, 1);
+ LPtoDP(physDev->hdc, &p2, 1);
- if(curPos.y == y)
- physDev->penHLine(physDev, curPos.x, x, y);
- else if(curPos.x == x)
- physDev->penVLine(physDev, x, curPos.y, y);
- else
- physDev->penLine(physDev, curPos.x, curPos.y, x, y);
- res = TRUE;
+ /* cycle on all current clipping rectangles */
+ r = physDev->regionRects;
+ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
+ {
+ _DIBDRV_ResetDashOrigin(physDev);
+
+ /* clipe line on current region area */
+ if(ClipLine(&p1, &p2, r, &pc1, &pc2))
+ {
+ if(pc1.y == pc2.y)
+ physDev->penHLine(physDev, pc1.x, pc2.x, pc1.y);
+ else if(pc1.x == pc2.x)
+ physDev->penVLine(physDev, pc1.x, pc1.y, pc2.y);
+ else
+ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y);
+ res = TRUE;
+ }
+ }
+
+ /* moves current position to next point */
+ MoveToEx(physDev->hdc, x, y, NULL);
}
else
{
@@ -583,7 +676,7 @@ BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count )
POINT pc1, pc2;
MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, ptw, count));
-
+
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
@@ -771,58 +864,67 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD*
*/
BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
{
- BOOL res = TRUE;
+ BOOL res;
int i;
- DIBDRVBITMAP *bmp = &physDev->physBitmap;
+ RECT rWorld, rDevice, rClipped;
+ RECT *r;
+ int iRec;
MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev, x1, y1, x2, y2));
if(physDev->hasDIB)
{
+ res = FALSE;
+
OrderInt(&x1, &x2);
OrderInt(&y1, &y2);
- /* temporary fix.... should be done by clipping */
- if(x1 < 0) x1 = 0;
- if(x2 < 0) x2 = 0;
- if(y1 < 0) y1 = 0;
- if(y2 < 0) y2 = 0;
- if(x1 >= bmp->width) x1 = bmp->width - 1;
- if(y1 >= bmp->height) y1 = bmp->height - 1;
- if(x2 > bmp->width) x2 = bmp->width;
- if(y2 > bmp->height) y2 = bmp->height ;
- if(x1 >= x2 || y1 >= y2)
- goto fin;
+ /* converts to device space */
+ rWorld.left = x1; rWorld.top = y1; rWorld.right = x2; rWorld.bottom = y2;
+ _DIBDRV_Rect_ws2ds(physDev, &rWorld, &rDevice);
- _DIBDRV_ResetDashOrigin(physDev);
-
- /* particular case where the rectangle
- degenerates to a line or a point */
- if(x1 >= x2 - 1)
- {
- physDev->penVLine(physDev, x1, y1, y2);
- goto fin;
- }
- else if (y1 >= y2 -1)
+ /* loop on all clip region rectangles */
+ r = physDev->regionRects;
+ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
{
- physDev->penHLine(physDev, x1, x2, y1);
- goto fin;
- }
-
- /* Draw the perimeter */
- physDev->penHLine(physDev, x1 , x2 , y1 );
- physDev->penHLine(physDev, x1 , x2 , y2 - 1);
- physDev->penVLine(physDev, x1 , y1 + 1, y2 - 1);
- physDev->penVLine(physDev, x2 - 1, y1 + 1, y2 - 1);
-
- /* fill the inside */
- if(x2 >= x1 + 2)
- for (i = y1 + 1; i < y2 - 1; i++)
- physDev->brushHLine(physDev, x1 + 1, x2 - 1, i);
+ /* clips rectangle to current region */
+ if(_DIBDRV_IntersectRect(&rClipped, &rDevice, r))
+ {
+ x1 = rClipped.left; y1 = rClipped.top;
+ x2 = rClipped.right; y2 = rClipped.bottom;
+
+ _DIBDRV_ResetDashOrigin(physDev);
+
+ /* fill the inside, if not null brush */
+ if(physDev->brushStyle != BS_NULL)
+ {
+ if(x2 > x1)
+ for (i = y1; i < y2; i++)
+ physDev->brushHLine(physDev, x1, x2, i);
+ }
- res = TRUE;
-fin:
- ;
+ /* draw perimeter, if not null pen */
+ if(physDev->penStyle != PS_NULL)
+ {
+
+ /* particular case where the rectangle
+ degenerates to a line or a point */
+ if(x1 >= x2 - 1)
+ physDev->penVLine(physDev, x1, y1, y2);
+ else if (y1 >= y2 -1)
+ physDev->penHLine(physDev, x1, x2, y1);
+ else
+ {
+ /* Draw the perimeter */
+ physDev->penHLine(physDev, x1 , x2 , y1 );
+ physDev->penHLine(physDev, x1 , x2 , y2 - 1);
+ physDev->penVLine(physDev, x1 , y1 + 1, y2 - 1);
+ physDev->penVLine(physDev, x2 - 1, y1 + 1, y2 - 1);
+ }
+ }
+ res = TRUE;
+ }
+ }
}
else
{
@@ -870,6 +972,8 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color )
if(physDev->hasDIB)
{
+ _DIBDRV_Position_ws2ds(physDev, &x, &y);
+
/* gets previous pixel */
res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y);
diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c
index 148a6d5..a1aa648 100644
--- a/dlls/winedib.drv/palette.c
+++ b/dlls/winedib.drv/palette.c
@@ -30,18 +30,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
*/
UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary )
{
- UINT res;
+ UINT res = 0;
MAYBE(TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE")));
- /* we should in any case call X11 function, as UnrealizePalette() doesn't
- * take a physDev parameter */
- res = _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev->X11PhysDev, hpal, primary);
-
- if(physDev->hasDIB)
+ if(physDev && physDev->hasDIB)
{
/* DIB section selected in, additional (if needed) engine code */
ONCE(FIXME("STUB\n"));
+ res = 0;
+ }
+ else
+ {
+ /* we should in any case call X11 function, as UnrealizePalette() doesn't
+ * take a physDev parameter */
+ res = _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev ? physDev->X11PhysDev : NULL, hpal, primary);
+
}
return res;
diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c
index 31c9cd2..7b15ece 100644
--- a/dlls/winedib.drv/pen_brush.c
+++ b/dlls/winedib.drv/pen_brush.c
@@ -290,6 +290,12 @@ static void PatternBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
physDev->physBitmap.funcs->PatternHLine(&physDev->physBitmap, x1, x2, y, and, xor, physDev->brushBitmap.width, x1 % physDev->brushBitmap.width);
}
+/* null function for PS_NULL and BS_NULL pen and brush styles */
+void NullPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) {}
+void NullPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) {}
+void NullPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) {}
+void NullBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) {}
+
/***********************************************************************
* DIBDRV_SelectPen
*/
@@ -335,6 +341,12 @@ HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen )
physDev->penPattern = &dashPatterns[logpen.lopnStyle - PS_DASH];
_DIBDRV_ResetDashOrigin(physDev);
break;
+ case PS_NULL:
+ physDev->penHLine = NullPenHLine;
+ physDev->penVLine = NullPenVLine;
+ physDev->penLine = NullPenLine;
+ physDev->penPattern = NULL;
+ break;
}
res = hpen;
}
@@ -484,6 +496,7 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush )
{
MAYBE(TRACE("NULL Pattern\n"));
physDev->brushColorref = 0;
+ physDev->brushHLine = NullBrushHLine;
goto solid;
}
diff --git a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c
index a2fa04a..2b0fc6e 100644
--- a/dlls/winedib.drv/primitives.c
+++ b/dlls/winedib.drv/primitives.c
@@ -139,15 +139,15 @@ BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, int xDst, int yDst,
/* ------------------------------------------------------------*/
/* FREETYPE FONT BITMAP BLITTING */
-void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_32_RGB (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_24 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_16_RGB (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_8 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_4 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
-void _DIBDRV_freetype_blit_1 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_32_RGB (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_24 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_16_RGB (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_8 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_4 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_1 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB =
{
diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c
index 7540dad..7feeb49 100644
--- a/dlls/winedib.drv/primitives_bitblt.c
+++ b/dlls/winedib.drv/primitives_bitblt.c
@@ -216,7 +216,7 @@ BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
PemultiplyLine(strBuf, widthDst, constAlpha);
/* blends source on dest */
- BlendLine(dBuf, sBuf, widthDst);
+ BlendLine(dBuf, strBuf, widthDst);
/* puts dest line back */
dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
@@ -391,6 +391,10 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
+ /* sanity check -- MSN messenger crashes without */
+ if(useSrc && !physDevSrc)
+ return FALSE;
+
/* gets source, dest and pattern bitmaps, if available */
if(usePat && physDevDst->isBrushBitmap)
patBmp = &physDevDst->brushBmpCache;
@@ -501,8 +505,8 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
{
srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
- wDstPnt = sBuf;
- wSrcPnt = sBuf;
+ wDstPnt = dBuf;
+ wSrcPnt = dBuf;
wPatPnt = pBuf;
for(i = width; i > 0 ; i--)
{
@@ -521,8 +525,8 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
{
srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
- wDstPnt = sBuf;
- wSrcPnt = sBuf;
+ wDstPnt = dBuf;
+ wSrcPnt = dBuf;
for(i = width; i > 0 ; i--)
{
*wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
@@ -538,9 +542,9 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
goto error;
for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
{
- dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
- wDstPnt = sBuf;
+ wDstPnt = dBuf;
wPatPnt = pBuf;
for(i = width; i > 0 ; i--)
{
@@ -558,8 +562,8 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
MAYBE(TRACE("BitBlt use: dst\n"));
for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
{
- dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
- wDstPnt = sBuf;
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
+ wDstPnt = dBuf;
for(i = width; i > 0 ; i--)
{
*wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
@@ -638,6 +642,10 @@ BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
+ /* sanity check -- MSN messenger crashes without */
+ if(useSrc && !physDevSrc)
+ return FALSE;
+
/* gets source, dest and pattern bitmaps, if available */
if(usePat && physDevDst->isBrushBitmap)
patBmp = &physDevDst->brushBmpCache;
diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c
index 800e3fd..f8f87ce 100644
--- a/dlls/winedib.drv/primitives_convert.c
+++ b/dlls/winedib.drv/primitives_convert.c
@@ -292,7 +292,7 @@ BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3));
/* get first partial byte, if any */
- startx = (8 - (startx & 0x03)) & 0x03;
+ startx = (8 - (startx & 0x07)) & 0x07;
width -= startx;
if(startx)
{
@@ -322,7 +322,7 @@ BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
}
/* last partial byte, if any */
- if(width)
+ if(width > 0)
{
b = *src;
while(width--)
@@ -398,13 +398,17 @@ BOOL _DIBDRV_PutLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx,
DWORD *dwBuf = (DWORD *)buf;
WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
DWORD c;
+
+ BYTE bShift = 8 - bmp->blueLen;
+ BYTE gShift = 16 - bmp->greenLen;
+ BYTE rShift = 24 - bmp->redLen;
for(; width; width--)
{
c = *dwBuf++;
*dst++ =
- ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) |
- ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) |
- ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask);
+ ((((c & 0x000000ff) >> bShift) << bmp->blueShift) & bmp->blueMask) |
+ ((((c & 0x0000ff00) >> gShift) << bmp->greenShift) & bmp->greenMask) |
+ ((((c & 0x00ff0000) >> rShift) << bmp->redShift) & bmp->redMask);
}
return TRUE;
}
@@ -480,7 +484,7 @@ BOOL _DIBDRV_PutLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
}
/* last nibble, if any */
- if(width)
+ if(width > 0)
{
c = *dwBuf;
@@ -500,14 +504,14 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
BYTE b, mask;
char i;
DWORD c;
-
+
/* get foreground color */
DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff;
/* put first partial byte, if any */
- startx &= 0x03;
+ startx &= 0x07;
mask = 0x80 >> startx;
- startx = (8 - startx) & 0x03;
+ startx = (8 - startx) & 0x07;
if(startx)
{
width -= startx;
@@ -540,7 +544,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
}
/* last partial byte, if any */
- if(width)
+ if(width > 0)
{
b = *dst;
mask = 0x80;
diff --git a/dlls/winedib.drv/primitives_font.c b/dlls/winedib.drv/primitives_font.c
index dd1d64b..e604a39 100644
--- a/dlls/winedib.drv/primitives_font.c
+++ b/dlls/winedib.drv/primitives_font.c
@@ -27,7 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
/* ------------------------------------------------------------*/
/* FREETYPE FONT BITMAP BLITTING */
-void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -35,13 +35,20 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
- DWORD c;
+ int xMin, xMax, yMin, yMax;
DWORD *ptr;
+#ifdef DIBDRV_ANTIALIASED_FONTS
+ DWORD c;
+ BYTE r, g, b, negColor;
+#else
+ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
+#endif
- /* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ /* gets clip limits */
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -50,9 +57,21 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap
ptr = (DWORD *)((BYTE *)dib->bits + (dibY * dib->stride) + x * 4);
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
{
+#ifdef DIBDRV_ANTIALIASED_FONTS
c = physDev->textColorTable[*buf];
+ if(*buf < 255)
+ {
+ negColor = 255 - *buf;
+ r = (*ptr >> 16) & 0xff;
+ g = (*ptr >> 8) & 0xff;
+ b = *ptr & 0xff;
+ c += MulDiv(r, 255 - *buf, 255) << 16 |
+ MulDiv(g, 255 - *buf, 255) << 8 |
+ MulDiv(r, 255 - *buf, 255);
+ }
+#endif
*ptr = c;
}
buf++;
@@ -61,7 +80,7 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap
}
}
-void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -69,30 +88,52 @@ void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
+ int xMin, xMax, yMin, yMax;
+ DWORD *ptr;
+#ifdef DIBDRV_ANTIALIASED_FONTS
DWORD c;
+ BYTE r, g, b, negColor;
+#else
+ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
+#endif
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
{
+ ptr = (DWORD *)((BYTE *)dib->bits + (dibY * dib->stride) + x * 4);
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
{
+#ifdef DIBDRV_ANTIALIASED_FONTS
c = physDev->textColorTable[*buf];
- dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ if(*buf < 255)
+ {
+ negColor = 255 - *buf;
+ r = (*ptr >> 16) & 0xff;
+ g = (*ptr >> 8) & 0xff;
+ b = *ptr & 0xff;
+ c += MulDiv(r, 255 - *buf, 255) << 16 |
+ MulDiv(g, 255 - *buf, 255) << 8 |
+ MulDiv(r, 255 - *buf, 255);
+ }
+#endif
+ *ptr = c;
}
buf++;
+ ptr++;
}
}
}
-void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -100,12 +141,20 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
+ int xMin, xMax, yMin, yMax;
+#ifdef DIBDRV_ANTIALIASED_FONTS
DWORD c;
+ COLORREF pix;
+ BYTE r, g, b, negColor;
+#else
+ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
+#endif
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -113,9 +162,22 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
{
+#ifdef DIBDRV_ANTIALIASED_FONTS
c = physDev->textColorTable[*buf];
+ if(*buf < 255)
+ {
+ negColor = 255 - *buf;
+ pix = dib->funcs->GetPixel(dib, dibX, dibY);
+ r = pix & 0xff;
+ g = (pix >> 8) & 0xff;
+ b = (pix >> 16) & 0xff;
+ c += MulDiv(r, 255 - *buf, 255) << 16 |
+ MulDiv(g, 255 - *buf, 255) << 8 |
+ MulDiv(r, 255 - *buf, 255);
+ }
+#endif
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
}
buf++;
@@ -123,7 +185,7 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT
}
}
-void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -131,12 +193,20 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *b
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
+ int xMin, xMax, yMin, yMax;
+#ifdef DIBDRV_ANTIALIASED_FONTS
DWORD c;
+ COLORREF pix;
+ BYTE r, g, b, negColor;
+#else
+ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
+#endif
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -144,9 +214,22 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *b
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
{
+#ifdef DIBDRV_ANTIALIASED_FONTS
c = physDev->textColorTable[*buf];
+ if(*buf < 255)
+ {
+ negColor = 255 - *buf;
+ pix = dib->funcs->GetPixel(dib, dibX, dibY);
+ r = pix & 0xff;
+ g = (pix >> 8) & 0xff;
+ b = (pix >> 16) & 0xff;
+ c += MulDiv(r, 255 - *buf, 255) << 16 |
+ MulDiv(g, 255 - *buf, 255) << 8 |
+ MulDiv(r, 255 - *buf, 255);
+ }
+#endif
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
}
buf++;
@@ -154,7 +237,7 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *b
}
}
-void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -162,12 +245,20 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
+ int xMin, xMax, yMin, yMax;
+#ifdef DIBDRV_ANTIALIASED_FONTS
DWORD c;
+ COLORREF pix;
+ BYTE r, g, b, negColor;
+#else
+ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
+#endif
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -175,9 +266,22 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
{
+#ifdef DIBDRV_ANTIALIASED_FONTS
c = physDev->textColorTable[*buf];
+ if(*buf < 255)
+ {
+ negColor = 255 - *buf;
+ pix = dib->funcs->GetPixel(dib, dibX, dibY);
+ r = pix & 0xff;
+ g = (pix >> 8) & 0xff;
+ b = (pix >> 16) & 0xff;
+ c += MulDiv(r, 255 - *buf, 255) << 16 |
+ MulDiv(g, 255 - *buf, 255) << 8 |
+ MulDiv(r, 255 - *buf, 255);
+ }
+#endif
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
}
buf++;
@@ -185,7 +289,7 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma
}
}
-void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -193,12 +297,20 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
+ int xMin, xMax, yMin, yMax;
+#ifdef DIBDRV_ANTIALIASED_FONTS
DWORD c;
+ COLORREF pix;
+ BYTE r, g, b, negColor;
+#else
+ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
+#endif
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -206,9 +318,22 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
{
+#ifdef DIBDRV_ANTIALIASED_FONTS
c = physDev->textColorTable[*buf];
+ if(*buf < 255)
+ {
+ negColor = 255 - *buf;
+ pix = dib->funcs->GetPixel(dib, dibX, dibY);
+ r = pix & 0xff;
+ g = (pix >> 8) & 0xff;
+ b = (pix >> 16) & 0xff;
+ c += MulDiv(r, 255 - *buf, 255) << 16 |
+ MulDiv(g, 255 - *buf, 255) << 8 |
+ MulDiv(r, 255 - *buf, 255);
+ }
+#endif
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
}
buf++;
@@ -216,7 +341,7 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT
}
}
-void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -224,12 +349,14 @@ void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
- DWORD c;
+ int xMin, xMax, yMin, yMax;
+ DWORD c = physDev->textColor;
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -237,17 +364,14 @@ void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
- {
- c = physDev->textColorTable[*buf];
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
- }
buf++;
}
}
}
-void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -255,12 +379,14 @@ void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
- DWORD c;
+ int xMin, xMax, yMin, yMax;
+ DWORD c = physDev->textColor;
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -268,17 +394,14 @@ void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
- {
- c = physDev->textColorTable[*buf];
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
- }
buf++;
}
}
}
-void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
{
/* FIXME : MUST BE OPTIMIZED !!! */
@@ -286,12 +409,14 @@ void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm
int bmpX, bmpY;
BYTE *buf;
int dibX, dibY;
- int DIBX, DIBY;
- DWORD c;
+ int xMin, xMax, yMin, yMax;
+ DWORD c = physDev->textColor;
/* gets DIB limits */
- DIBX = dib->width;
- DIBY = dib->height;
+ xMin = clipRec->left;
+ yMin = clipRec->top;
+ xMax = clipRec->right;
+ yMax = clipRec->bottom;
/* loop for every pixel in bitmap */
buf = bmp->buffer;
@@ -299,11 +424,8 @@ void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm
{
for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
{
- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
- {
- c = physDev->textColorTable[*buf];
+ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
- }
buf++;
}
}
diff --git a/dlls/winedib.drv/primitives_rop3.c b/dlls/winedib.drv/primitives_rop3.c
index 398258b..05ce494 100644
--- a/dlls/winedib.drv/primitives_rop3.c
+++ b/dlls/winedib.drv/primitives_rop3.c
@@ -413,7 +413,7 @@ DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop)
return (0x123456) & 0x00ffffff;
case 0x85: /* PDSPnoaxn */
- return (0x123456) & 0x00ffffff;
+ return (~(p ^ (d & (s | ~p)))) & 0x00ffffff;
case 0x86: /* DSPDSoaxx */
return (0x123456) & 0x00ffffff;
diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c
index e2cea0c..0ae3575 100644
--- a/dlls/winedib.drv/text.c
+++ b/dlls/winedib.drv/text.c
@@ -25,19 +25,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
-/* converts font sizes from Word space to Device space */
-static void FontSizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h)
-{
- POINT pts[2];
- pts[0].x = 0;
- pts[0].y = 0;
- pts[1].x = abs(*w);
- pts[1].y = abs(*h);
- LPtoDP(physDev->hdc, pts, 2);
- *w = pts[1].x - pts[0].x;
- *h = pts[1].y - pts[0].y;
-}
-
/***********************************************************************
* DIBDRV_ExtTextOut
*/
@@ -57,12 +44,17 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags,
LPCWSTR wstrPnt;
FT_Glyph glyph;
- FT_BitmapGlyph bitmap;
+ FT_BitmapGlyph bitmapGlyph;
+ FT_Bitmap *bitmap, bitmap8;
double cosEsc, sinEsc;
FT_Matrix matrix;
FT_Vector start;
int dx, dy;
+ RECT *r;
+ int iRec;
+ RECT clipRec;
+ DWORD backPixel;
MAYBE(TRACE("physDev:%p, x:%d, y:%d, flags:%x, lprect:%p, wstr:%s, count:%d, lpDx:%p\n",
physDev, x, y, flags, lprect, debugstr_w(wstr), count, lpDx));
@@ -94,114 +86,155 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags,
HeapFree(GetProcessHeap(), 0, str);
}
+ /* gets background pixel value for opaque text */
+ backPixel = physDev->backgroundColor;
+
/* gets font data, etc */
GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
/* convert sizes to device space */
- w = lf.lfWidth; h = lf.lfHeight;
- FontSizes_ws2ds(physDev, &w, &h);
-
- /* if opaque, paint the font background */
-/*
- if(flags | ETO_OPAQUE)
- {
- int iLine;
- for(iLine = lprect->top; iLine < lprect->bottom; iLine++)
- physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap,
- lprect->left, lprect->right-1, iLine, 0, physDev->backgroundColor);
- }
-*/
- /* sets character pixel size */
- error = pFT_Set_Pixel_Sizes(
- face,
- MulDiv(w, 96, DIBDRV_GetDeviceCaps(physDev, LOGPIXELSX)),
- MulDiv(h, 96, DIBDRV_GetDeviceCaps(physDev, LOGPIXELSY))
- );
- if(error)
- ERR("Couldn't set char size to (%d,%d)\n", lf.lfWidth, lf.lfHeight);
-
- /* transformation matrix and vector */
- start.x = 0;
- start.y = 0;
- if(lf.lfEscapement != 0)
+ w = abs(lf.lfWidth); h = abs(lf.lfHeight);
+ _DIBDRV_Sizes_ws2ds(physDev, &w, &h);
+
+ /* loop on all clip region rectangles */
+ r = physDev->regionRects;
+ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
{
- cosEsc = cos(lf.lfEscapement * M_PI / 1800);
- sinEsc = sin(lf.lfEscapement * M_PI / 1800);
- }
- else
- {
- cosEsc = 1;
- sinEsc = 0;
- }
- matrix.xx = (FT_Fixed)( cosEsc * 0x10000L );
- matrix.xy = (FT_Fixed)(-sinEsc * 0x10000L );
- matrix.yx = (FT_Fixed)( sinEsc * 0x10000L );
- matrix.yy = (FT_Fixed)( cosEsc * 0x10000L );
-
- /* outputs characters one by one */
- wstrPnt = wstr;
- for ( n = 0; n < count; n++ )
- {
- /* retrieve glyph index from character code */
- if(flags & ETO_GLYPH_INDEX)
- glyph_index = *wstrPnt++;
+ /* if clipped on text rect, intersect with current region */
+ if(flags & ETO_CLIPPED)
+ {
+ if(!_DIBDRV_IntersectRect(&clipRec, r, lprect))
+ continue;
+ }
else
- glyph_index = pFT_Get_Char_Index( face, *wstrPnt++);
+ memcpy(&clipRec, r, sizeof(RECT));
+
+ /* if opaque, paint the font background */
+ if(flags & ETO_OPAQUE)
+ {
+ int iLine;
+ RECT tr;
+
+ /* clips text rectangle */
+ if(_DIBDRV_IntersectRect(&tr, r, lprect))
+ {
+ /* paints the backgound */
+ for(iLine = tr.top; iLine < tr.bottom; iLine++)
+ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap,
+ tr.left, tr.right-1, iLine, 0, backPixel);
+ }
+ }
- /* load glyph image into the slot (erase previous one) */
- error = pFT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
+ /* sets character pixel size */
+ error = pFT_Set_Pixel_Sizes(face, w, h);
if(error)
+ ONCE(ERR("Couldn't set char size to (%d,%d), code %d\n", lf.lfWidth, lf.lfHeight, error));
+
+ /* transformation matrix and vector */
+ start.x = 0;
+ start.y = 0;
+ if(lf.lfEscapement != 0)
{
- ERR("Couldn't load glyph at index %d\n", glyph_index);
- /* ignore errors */
- continue;
+ cosEsc = cos(lf.lfEscapement * M_PI / 1800);
+ sinEsc = sin(lf.lfEscapement * M_PI / 1800);
}
- error = pFT_Get_Glyph(face->glyph, &glyph);
- if ( error )
+ else
{
- FIXME("Couldn't get glyph\n");
- continue;
+ cosEsc = 1;
+ sinEsc = 0;
}
-
- /* apply transformation to glyph */
- if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
- pFT_Glyph_Transform(glyph, &matrix, &start );
-
- /* gets advance BEFORE transforming... */
- dx = glyph->advance.x;
- dy = glyph->advance.y;
-
- /* convert to an anti-aliased bitmap, if needed */
- if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ matrix.xx = (FT_Fixed)( cosEsc * 0x10000L );
+ matrix.xy = (FT_Fixed)(-sinEsc * 0x10000L );
+ matrix.yx = (FT_Fixed)( sinEsc * 0x10000L );
+ matrix.yy = (FT_Fixed)( cosEsc * 0x10000L );
+
+ /* outputs characters one by one */
+ wstrPnt = wstr;
+ for ( n = 0; n < count; n++ )
{
- error = pFT_Glyph_To_Bitmap(
- &glyph,
- FT_RENDER_MODE_NORMAL,
- 0, /* no additional translation */
- 1 /* destroy copy in "image" */
- );
-
- /* ignore errors */
- if ( error )
+ /* retrieve glyph index from character code */
+ if(flags & ETO_GLYPH_INDEX)
+ glyph_index = *wstrPnt++;
+ else
+ glyph_index = pFT_Get_Char_Index( face, *wstrPnt++);
+
+ /* load glyph image into the slot (erase previous one) */
+ error = pFT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
+ if(error)
{
- FIXME("Couldn't render glyph\n");
- pFT_Done_Glyph(glyph);
+ ERR("Couldn't load glyph at index %d\n", glyph_index);
+ /* ignore errors */
continue;
}
- }
+ error = pFT_Get_Glyph(face->glyph, &glyph);
+ if ( error )
+ {
+ FIXME("Couldn't get glyph\n");
+ continue;
+ }
+
+ /* apply transformation to glyph */
+ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ pFT_Glyph_Transform(glyph, &matrix, &start );
+
+ /* gets advance BEFORE transforming... */
+ dx = glyph->advance.x;
+ dy = glyph->advance.y;
+
+ /* convert to an anti-aliased bitmap, if needed */
+ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ {
+ error = pFT_Glyph_To_Bitmap(
+ &glyph,
+ #ifdef DIBDRV_ANTIALIASED_FONTS
+ physDev->physBitmap.bitCount > 8 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
+ #else
+ FT_RENDER_MODE_MONO,
+ #endif
+ 0, /* no additional translation */
+ 1 /* destroy copy in "image" */
+ );
+
+ /* ignore errors */
+ if ( error )
+ {
+ FIXME("Couldn't render glyph\n");
+ pFT_Done_Glyph(glyph);
+ continue;
+ }
+ }
+ bitmapGlyph = (FT_BitmapGlyph)glyph;
+
+ /* convert the bitmap in an 8bpp 1 byte aligned one if needed */
+ bitmap = &bitmapGlyph->bitmap;
+ if(bitmap->pixel_mode != FT_PIXEL_MODE_GRAY)
+ {
+ pFT_Bitmap_New(&bitmap8);
+ if(pFT_Bitmap_Convert(glyph->library, bitmap, &bitmap8, 1))
+ {
+ FIXME("Couldn't convert bitmap to 8 bit grayscale\n");
+ pFT_Done_Glyph(glyph);
+ continue;
+ }
+ bitmap = &bitmap8;
+ }
- /* now, draw to our target surface */
- bitmap = (FT_BitmapGlyph)glyph;
- physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmap->left, y-bitmap->top, &bitmap->bitmap);
+ /* now, draw to our target surface */
+ physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmapGlyph->left, y-bitmapGlyph->top, &clipRec, bitmap);
+
+ /* frees converted bitmap, if any */
+ if(bitmap != &bitmapGlyph->bitmap)
+ pFT_Bitmap_Done(glyph->library, bitmap);
- /* increment pen position */
- x += dx>>16;
- y -= dy>>16;
+ /* increment pen position */
+ x += dx>>16;
+ y -= dy>>16;
- pFT_Done_Glyph(glyph);
-
- res = TRUE;
- }
+ pFT_Done_Glyph(glyph);
+
+ res = TRUE;
+ }
+ } /* end region rects loop */
}
else
{