Index: lineto.c =================================================================== --- lineto.c (Revision 50148) +++ lineto.c (Arbeitskopie) @@ -24,6 +24,62 @@ #define NDEBUG #include + +/** + * Draw a vertical or horizontal patterned line + */ +BOOL FASTCALL +LineCosmeticPatterned(SURFOBJ* OutputObj, BRUSHOBJ* pbo, LONG x1, LONG x2, LONG y1, LONG y2) +{ + ULONG Pixel = pbo->iSolidColor; + + if (pbo && pbo->iSolidColor == 0xFFFFFFFF) { + PEBRUSHOBJ GdiBrush; + SURFOBJ* PatSurf; + + GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); + + /* Check if we have to draw a patterned brush */ + if (GdiBrush->pbrush->flAttrs & GDIBRUSH_IS_BITMAP && (PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern))) { + ULONG j, k = 0; + + if (y1 == y2) { + /* Horizontal line */ + for (k = 0, j = x1; j < x2; j++, k++) { + /* Set pixel if bit is set in pattern */ + if ((*(ULONG*)PatSurf->pvScan0 >> k) & 1) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, j, y1, Pixel + ); + } + + /* Wrap around pattern */ + if(k == ((PatSurf->cjBits - 1) << 2)) k = 0; + } + } else { + /* Vertical line */ + for (k = 0, j = y1; j < y2; j++, k++) { + /* Set pixel if bit is set in pattern */ + if ((*(ULONG*)PatSurf->pvScan0 >> k) & 1) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x1, j, Pixel + ); + } + + /* Wrap around pattern */ + if(k == ((PatSurf->cjBits - 1) << 2)) k = 0; + } + } + + EngUnlockSurface(PatSurf); + + return TRUE; + } + } + + return FALSE; +} + static void FASTCALL TranslateRects(RECT_ENUM *RectEnum, POINTL* Translate) { @@ -49,20 +105,29 @@ BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay, POINTL* Translate) { - int i; + int i, j; int error; BOOLEAN EnumMore; RECTL* ClipRect; RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ GdiBrush; + SURFOBJ* PatSurf = NULL; + /* Check if we have to draw a patterned brush */ + GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); + if (GdiBrush->pbrush->flAttrs & GDIBRUSH_IS_BITMAP && (PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern))) { + PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern); + } + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); TranslateRects(&RectEnum, Translate); ClipRect = RectEnum.arcl; delta = max(deltax, deltay); i = 0; + j = 0; error = delta >> 1; while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore)) { @@ -87,8 +152,18 @@ { if (ClipRect->left <= x && ClipRect->top <= y) { - DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( - OutputObj, x, y, Pixel); + if(PatSurf) { + /* Draw patterned line */ + if ((*(ULONG*)PatSurf->pvScan0 >> j) & 1) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } + + if(j == ((PatSurf->cjBits - 1) << 2)) j = 0; + } else { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } } if (deltax < deltay) { @@ -111,8 +186,13 @@ } } i++; + j++; } } + + if(PatSurf) { + EngUnlockSurface(PatSurf); + } } void FASTCALL @@ -120,20 +200,29 @@ BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay, POINTL* Translate) { - int i; + int i, j; int error; BOOLEAN EnumMore; RECTL* ClipRect; RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ GdiBrush; + SURFOBJ* PatSurf = NULL; + /* Check if we have to draw a patterned brush */ + GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); + if (GdiBrush->pbrush->flAttrs & GDIBRUSH_IS_BITMAP && (PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern))) { + PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern); + } + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); TranslateRects(&RectEnum, Translate); ClipRect = RectEnum.arcl; delta = max(deltax, deltay); - i = 0; + i = 0; + j = 0; error = delta >> 1; while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore)) { @@ -157,8 +246,18 @@ { if (ClipRect->left <= x && y < ClipRect->bottom) { - DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( - OutputObj, x, y, Pixel); + if(PatSurf) { + /* Draw patterned line */ + if ((*(ULONG*)PatSurf->pvScan0 >> j) & 1) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } + + if(j == ((PatSurf->cjBits - 1) << 2)) j = 0; + } else { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } } if (deltax < deltay) { @@ -181,8 +280,13 @@ } } i++; + j++; } } + + if(PatSurf) { + EngUnlockSurface(PatSurf); + } } void FASTCALL @@ -190,20 +294,29 @@ BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay, POINTL* Translate) { - int i; + int i, j; int error; BOOLEAN EnumMore; RECTL* ClipRect; RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ GdiBrush; + SURFOBJ* PatSurf = NULL; + /* Check if we have to draw a patterned brush */ + GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); + if (GdiBrush->pbrush->flAttrs & GDIBRUSH_IS_BITMAP && (PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern))) { + PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern); + } + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); TranslateRects(&RectEnum, Translate); ClipRect = RectEnum.arcl; delta = max(deltax, deltay); i = 0; + j = 0; error = delta >> 1; while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore)) { @@ -227,8 +340,18 @@ { if (x < ClipRect->right && ClipRect->top <= y) { - DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( - OutputObj, x, y, Pixel); + if(PatSurf) { + /* Draw patterned line */ + if ((*(ULONG*)PatSurf->pvScan0 >> j) & 1) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } + + if(j == ((PatSurf->cjBits - 1) << 2)) j = 0; + } else { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } } if (deltax < deltay) { @@ -251,8 +374,13 @@ } } i++; + j++; } } + + if(PatSurf) { + EngUnlockSurface(PatSurf); + } } void FASTCALL @@ -260,20 +388,29 @@ BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay, POINTL* Translate) { - int i; + int i, j; int error; BOOLEAN EnumMore; RECTL* ClipRect; RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ GdiBrush; + SURFOBJ* PatSurf = NULL; + /* Check if we have to draw a patterned brush */ + GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); + if (GdiBrush->pbrush->flAttrs & GDIBRUSH_IS_BITMAP && (PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern))) { + PatSurf = EngLockSurface(GdiBrush->pbrush->hbmPattern); + } + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); TranslateRects(&RectEnum, Translate); ClipRect = RectEnum.arcl; delta = max(deltax, deltay); i = 0; + j = 0; error = delta >> 1; while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore)) { @@ -297,8 +434,18 @@ { if (x < ClipRect->right && y < ClipRect->bottom) { - DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( - OutputObj, x, y, Pixel); + if(PatSurf) { + /* Draw patterned line */ + if ((*(ULONG*)PatSurf->pvScan0 >> j) & 1) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } + + if(j == ((PatSurf->cjBits - 1) << 2)) j = 0; + } else { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( + OutputObj, x, y, Pixel); + } } if (deltax < deltay) { @@ -321,8 +468,13 @@ } } i++; + j++; } } + + if(PatSurf) { + EngUnlockSurface(PatSurf); + } } /* @@ -438,11 +590,19 @@ max(hx, RectEnum.arcl[i].left + Translate.x) < min(hx + deltax, RectEnum.arcl[i].right + Translate.x)) { - DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_HLine( - OutputObj, + BOOL DrawDone = LineCosmeticPatterned( + OutputObj, pbo, max(hx, RectEnum.arcl[i].left + Translate.x), min(hx + deltax, RectEnum.arcl[i].right + Translate.x), - y1, Pixel); + y1, y1); + + if (!DrawDone) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_HLine( + OutputObj, + max(hx, RectEnum.arcl[i].left + Translate.x), + min(hx + deltax, RectEnum.arcl[i].right + Translate.x), + y1, Pixel); + } } } } @@ -461,11 +621,19 @@ RectEnum.arcl[i].top + Translate.y <= vy + deltay && vy < RectEnum.arcl[i].bottom + Translate.y) { - DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_VLine( - OutputObj, x1, + BOOL DrawDone = LineCosmeticPatterned( + OutputObj, pbo, + x1, x1, max(vy, RectEnum.arcl[i].top + Translate.y), - min(vy + deltay, RectEnum.arcl[i].bottom + Translate.y), - Pixel); + min(vy + deltay, RectEnum.arcl[i].bottom + Translate.y)); + + if(!DrawDone) { + DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_VLine( + OutputObj, x1, + max(vy, RectEnum.arcl[i].top + Translate.y), + min(vy + deltay, RectEnum.arcl[i].bottom + Translate.y), + Pixel); + } } } }