From 0f8f2f51cec72acfcdc5e70db20dd20ad979de6d Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 17 Dec 2015 17:44:42 +0000 Subject: [PATCH] [WIN32K] Implement support for styled lines. CORE-9984 #resolve svn path=/trunk/; revision=70387 --- reactos/win32ss/gdi/eng/lineto.c | 135 ++++++++++++++++++++++++++++-- reactos/win32ss/gdi/ntgdi/brush.h | 3 +- reactos/win32ss/gdi/ntgdi/pen.c | 51 +++++++---- 3 files changed, 165 insertions(+), 24 deletions(-) diff --git a/reactos/win32ss/gdi/eng/lineto.c b/reactos/win32ss/gdi/eng/lineto.c index e5ff302ac78..12e09220bf3 100644 --- a/reactos/win32ss/gdi/eng/lineto.c +++ b/reactos/win32ss/gdi/eng/lineto.c @@ -28,6 +28,63 @@ TranslateRects(RECT_ENUM *RectEnum, POINTL* Translate) } } +LONG +HandleStyles( + BRUSHOBJ *pbo, + POINTL* Translate, + LONG x, + LONG y, + LONG deltax, + LONG deltay, + LONG dx, + LONG dy, + PULONG piStyle) +{ + PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo; + PULONG pulStyles = pebo->pbrush->pStyle; + ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount; + LONG diStyle, offStyle, lStyleMax; + + if (cStyles > 0) + { + if (deltax > deltay) + { + offStyle = (x - Translate->x) % pebo->pbrush->ulStyleSize; + diStyle = dx; + lStyleMax = x; + } + else + { + offStyle = (y - Translate->y) % pebo->pbrush->ulStyleSize; + diStyle = dy; + lStyleMax = y; + } + + /* Now loop until we have found the style index */ + for (iStyle = 0; offStyle >= pulStyles[iStyle]; iStyle++) + { + offStyle -= pulStyles[iStyle]; + } + + if (diStyle > 0) + { + lStyleMax += pulStyles[iStyle] - offStyle; + } + else + { + lStyleMax -= offStyle + 1; + } + } + else + { + iStyle = 0; + lStyleMax = MAX_COORD; + } + + *piStyle = iStyle; + return lStyleMax; +} + /* * Draw a line from top-left to bottom-right */ @@ -43,6 +100,12 @@ NWtoSE(SURFOBJ* OutputObj, CLIPOBJ* Clip, RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo; + PULONG pulStyles = pebo->pbrush->pStyle; + ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount; + LONG lStyleMax; + + lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, 1, 1, &iStyle); CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); @@ -72,7 +135,7 @@ NWtoSE(SURFOBJ* OutputObj, CLIPOBJ* Clip, } if (ClipRect < RectEnum.arcl + RectEnum.c) /* If there's no current clip rect we're done */ { - if (ClipRect->left <= x && ClipRect->top <= y) + if ((ClipRect->left <= x && ClipRect->top <= y) && ((iStyle & 1) == 0)) { DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( OutputObj, x, y, Pixel); @@ -80,6 +143,11 @@ NWtoSE(SURFOBJ* OutputObj, CLIPOBJ* Clip, if (deltax < deltay) { y++; + if (y == lStyleMax) + { + iStyle = (iStyle + 1) % cStyles; + lStyleMax = y + pulStyles[iStyle]; + } error = error + deltax; if (deltay <= error) { @@ -90,6 +158,11 @@ NWtoSE(SURFOBJ* OutputObj, CLIPOBJ* Clip, else { x++; + if (x == lStyleMax) + { + iStyle = (iStyle + 1) % cStyles; + lStyleMax = x + pulStyles[iStyle]; + } error = error + deltay; if (deltax <= error) { @@ -114,6 +187,12 @@ SWtoNE(SURFOBJ* OutputObj, CLIPOBJ* Clip, RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo; + PULONG pulStyles = pebo->pbrush->pStyle; + ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount; + LONG lStyleMax; + + lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, 1, -1, &iStyle); CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); @@ -142,7 +221,7 @@ SWtoNE(SURFOBJ* OutputObj, CLIPOBJ* Clip, } if (ClipRect < RectEnum.arcl + RectEnum.c) { - if (ClipRect->left <= x && y < ClipRect->bottom) + if ((ClipRect->left <= x && y < ClipRect->bottom) && ((iStyle & 1) == 0)) { DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( OutputObj, x, y, Pixel); @@ -150,6 +229,11 @@ SWtoNE(SURFOBJ* OutputObj, CLIPOBJ* Clip, if (deltax < deltay) { y--; + if (y == lStyleMax) + { + iStyle = (iStyle - 1) % cStyles; + lStyleMax = y - pulStyles[iStyle]; + } error = error + deltax; if (deltay <= error) { @@ -160,6 +244,11 @@ SWtoNE(SURFOBJ* OutputObj, CLIPOBJ* Clip, else { x++; + if (x == lStyleMax) + { + iStyle = (iStyle + 1) % cStyles; + lStyleMax = x + pulStyles[iStyle]; + } error = error + deltay; if (deltax <= error) { @@ -184,6 +273,12 @@ NEtoSW(SURFOBJ* OutputObj, CLIPOBJ* Clip, RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo; + PULONG pulStyles = pebo->pbrush->pStyle; + ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount; + LONG lStyleMax; + + lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, -1, 1, &iStyle); CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); @@ -212,7 +307,7 @@ NEtoSW(SURFOBJ* OutputObj, CLIPOBJ* Clip, } if (ClipRect < RectEnum.arcl + RectEnum.c) { - if (x < ClipRect->right && ClipRect->top <= y) + if ((x < ClipRect->right && ClipRect->top <= y) && ((iStyle & 1) == 0)) { DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( OutputObj, x, y, Pixel); @@ -220,6 +315,11 @@ NEtoSW(SURFOBJ* OutputObj, CLIPOBJ* Clip, if (deltax < deltay) { y++; + if (y == lStyleMax) + { + iStyle = (iStyle + 1) % cStyles; + lStyleMax = y + pulStyles[iStyle]; + } error = error + deltax; if (deltay <= error) { @@ -230,6 +330,11 @@ NEtoSW(SURFOBJ* OutputObj, CLIPOBJ* Clip, else { x--; + if (x == lStyleMax) + { + iStyle = (iStyle - 1) % cStyles; + lStyleMax = x - pulStyles[iStyle]; + } error = error + deltay; if (deltax <= error) { @@ -254,6 +359,12 @@ SEtoNW(SURFOBJ* OutputObj, CLIPOBJ* Clip, RECT_ENUM RectEnum; ULONG Pixel = pbo->iSolidColor; LONG delta; + PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo; + PULONG pulStyles = pebo->pbrush->pStyle; + ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount; + LONG lStyleMax; + + lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, -1, -1, &iStyle); CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, 0); EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); @@ -282,7 +393,7 @@ SEtoNW(SURFOBJ* OutputObj, CLIPOBJ* Clip, } if (ClipRect < RectEnum.arcl + RectEnum.c) { - if (x < ClipRect->right && y < ClipRect->bottom) + if ((x < ClipRect->right && y < ClipRect->bottom) && ((iStyle & 1) == 0)) { DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel( OutputObj, x, y, Pixel); @@ -290,6 +401,11 @@ SEtoNW(SURFOBJ* OutputObj, CLIPOBJ* Clip, if (deltax < deltay) { y--; + if (y == lStyleMax) + { + iStyle = (iStyle - 1) % cStyles; + lStyleMax = y - pulStyles[iStyle]; + } error = error + deltax; if (deltay <= error) { @@ -300,6 +416,11 @@ SEtoNW(SURFOBJ* OutputObj, CLIPOBJ* Clip, else { x--; + if (x == lStyleMax) + { + iStyle = (iStyle - 1) % cStyles; + lStyleMax = x - pulStyles[iStyle]; + } error = error + deltay; if (deltax <= error) { @@ -337,6 +458,8 @@ EngLineTo( RECT_ENUM RectEnum; BOOL EnumMore; CLIPOBJ *pcoPriv = NULL; + PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo; + ULONG cStyles = pebo->pbrush->dwStyleCount; if (x1 < x2) { @@ -413,7 +536,7 @@ EngLineTo( vy = y1; } - if (y1 == y2) + if ((y1 == y2) && (cStyles == 0)) { CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); do @@ -437,7 +560,7 @@ EngLineTo( } while (EnumMore); } - else if (x1 == x2) + else if ((x1 == x2) && (cStyles == 0)) { CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); do diff --git a/reactos/win32ss/gdi/ntgdi/brush.h b/reactos/win32ss/gdi/ntgdi/brush.h index ec1759b5870..e16a2dae3c5 100644 --- a/reactos/win32ss/gdi/ntgdi/brush.h +++ b/reactos/win32ss/gdi/ntgdi/brush.h @@ -43,7 +43,8 @@ typedef struct _BRUSHBODY INT iBrushStyle; // 0x070 //PREGION prgn; // 0x074 //DWORD unk078; // 0x078 - DWORD unk07c; // 0x07c + //DWORD unk07c; // 0x07c + ULONG ulStyleSize; LIST_ENTRY ListHead; // 0x080 } BRUSHBODY; diff --git a/reactos/win32ss/gdi/ntgdi/pen.c b/reactos/win32ss/gdi/ntgdi/pen.c index 07126387e08..cbfa4ce405a 100644 --- a/reactos/win32ss/gdi/ntgdi/pen.c +++ b/reactos/win32ss/gdi/ntgdi/pen.c @@ -86,11 +86,12 @@ IntGdiExtCreatePen( { HPEN hPen; PBRUSH pbrushPen; - static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55, 0}; - static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0, 0}; - static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38, 0}; - static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0, 0}; - static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38, 0}; + static ULONG aulStyleAlternate[] = { 1, 1 }; + static ULONG aulStyleDash[] = { 6, 2 }; + static ULONG aulStyleDot[] = { 1, 1 }; + static ULONG aulStyleDashDot[] = { 3, 2, 1, 2 }; + static ULONG aulStyleDashDotDot[] = { 3, 1, 1, 1, 1, 1 }; + ULONG i; dwWidth = abs(dwWidth); @@ -128,7 +129,8 @@ IntGdiExtCreatePen( // FIXME: Copy the bitmap first ? pbrushPen->hbmClient = (HANDLE)ulClientHatch; pbrushPen->dwStyleCount = dwStyleCount; - pbrushPen->pStyle = pStyle; + pbrushPen->pStyle = NULL; + pbrushPen->ulStyleSize = 0; pbrushPen->flAttrs = bOldStylePen ? BR_IS_OLDSTYLEPEN : BR_IS_PEN; @@ -150,28 +152,33 @@ IntGdiExtCreatePen( break; case PS_ALTERNATE: - pbrushPen->flAttrs |= BR_IS_BITMAP; - pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate); + pbrushPen->flAttrs |= BR_IS_SOLID; + pbrushPen->pStyle = aulStyleAlternate; + pbrushPen->dwStyleCount = _countof(aulStyleAlternate); break; case PS_DOT: - pbrushPen->flAttrs |= BR_IS_BITMAP; - pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot); + pbrushPen->flAttrs |= BR_IS_SOLID; + pbrushPen->pStyle = aulStyleDot; + pbrushPen->dwStyleCount = _countof(aulStyleDot); break; case PS_DASH: - pbrushPen->flAttrs |= BR_IS_BITMAP; - pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash); + pbrushPen->flAttrs |= BR_IS_SOLID; + pbrushPen->pStyle = aulStyleDash; + pbrushPen->dwStyleCount = _countof(aulStyleDash); break; case PS_DASHDOT: - pbrushPen->flAttrs |= BR_IS_BITMAP; - pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot); + pbrushPen->flAttrs |= BR_IS_SOLID; + pbrushPen->pStyle = aulStyleDashDot; + pbrushPen->dwStyleCount = _countof(aulStyleDashDot); break; case PS_DASHDOTDOT: - pbrushPen->flAttrs |= BR_IS_BITMAP; - pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot); + pbrushPen->flAttrs |= BR_IS_SOLID; + pbrushPen->pStyle = aulStyleDashDotDot; + pbrushPen->dwStyleCount = _countof(aulStyleDashDotDot); break; case PS_INSIDEFRAME: @@ -203,7 +210,9 @@ IntGdiExtCreatePen( } } /* FIXME: What style here? */ - pbrushPen->flAttrs |= 0; + pbrushPen->flAttrs |= BR_IS_SOLID; + pbrushPen->dwStyleCount = dwStyleCount; + pbrushPen->pStyle = pStyle; break; default: @@ -211,6 +220,14 @@ IntGdiExtCreatePen( goto ExitCleanup; } + if (pbrushPen->pStyle != NULL) + { + for (i = 0; i < pbrushPen->dwStyleCount; i++) + { + pbrushPen->ulStyleSize += pbrushPen->pStyle[i]; + } + } + PEN_UnlockPen(pbrushPen); return hPen;