xref: /reactos/win32ss/gdi/dib/dib24bppc.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * PROJECT:         Win32 subsystem
3*c2c66affSColin Finck  * LICENSE:         See COPYING in the top level directory
4*c2c66affSColin Finck  * FILE:            win32ss/gdi/dib/dib24bppc.c
5*c2c66affSColin Finck  * PURPOSE:         C language equivalents of asm optimised 24bpp functions
6*c2c66affSColin Finck  * PROGRAMMERS:     Jason Filby
7*c2c66affSColin Finck  *                  Magnus Olsen
8*c2c66affSColin Finck  */
9*c2c66affSColin Finck 
10*c2c66affSColin Finck #include <win32k.h>
11*c2c66affSColin Finck 
12*c2c66affSColin Finck #define NDEBUG
13*c2c66affSColin Finck #include <debug.h>
14*c2c66affSColin Finck 
15*c2c66affSColin Finck VOID
DIB_24BPP_HLine(SURFOBJ * SurfObj,LONG x1,LONG x2,LONG y,ULONG c)16*c2c66affSColin Finck DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
17*c2c66affSColin Finck {
18*c2c66affSColin Finck   PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
19*c2c66affSColin Finck   ULONG Count = x2 - x1;
20*c2c66affSColin Finck 
21*c2c66affSColin Finck   if (Count < 8)
22*c2c66affSColin Finck   {
23*c2c66affSColin Finck     /* For small fills, don't bother doing anything fancy */
24*c2c66affSColin Finck     while (Count--)
25*c2c66affSColin Finck     {
26*c2c66affSColin Finck       *(PUSHORT)(addr) = c;
27*c2c66affSColin Finck       addr += 2;
28*c2c66affSColin Finck       *(addr) = c >> 16;
29*c2c66affSColin Finck       addr += 1;
30*c2c66affSColin Finck     }
31*c2c66affSColin Finck   }
32*c2c66affSColin Finck   else
33*c2c66affSColin Finck   {
34*c2c66affSColin Finck     ULONG Fill[3];
35*c2c66affSColin Finck     ULONG MultiCount;
36*c2c66affSColin Finck 
37*c2c66affSColin Finck     /* Align to 4-byte address */
38*c2c66affSColin Finck     while (0 != ((ULONG_PTR) addr & 0x3))
39*c2c66affSColin Finck     {
40*c2c66affSColin Finck       *(PUSHORT)(addr) = c;
41*c2c66affSColin Finck       addr += 2;
42*c2c66affSColin Finck       *(addr) = c >> 16;
43*c2c66affSColin Finck       addr += 1;
44*c2c66affSColin Finck       Count--;
45*c2c66affSColin Finck     }
46*c2c66affSColin Finck     /* If the color we need to fill with is 0ABC, then the final mem pattern
47*c2c66affSColin Finck     * (note little-endianness) would be:
48*c2c66affSColin Finck     *
49*c2c66affSColin Finck     * |C.B.A|C.B.A|C.B.A|C.B.A|   <- pixel borders
50*c2c66affSColin Finck     * |C.B.A.C|B.A.C.B|A.C.B.A|   <- ULONG borders
51*c2c66affSColin Finck     *
52*c2c66affSColin Finck     * So, taking endianness into account again, we need to fill with these
53*c2c66affSColin Finck     * ULONGs: CABC BCAB ABCA */
54*c2c66affSColin Finck 
55*c2c66affSColin Finck     c = c & 0xffffff;                /* 0ABC */
56*c2c66affSColin Finck     Fill[0] = c | (c << 24);         /* CABC */
57*c2c66affSColin Finck     Fill[1] = (c >> 8) | (c << 16);  /* BCAB */
58*c2c66affSColin Finck     Fill[2] = (c << 8) | (c >> 16);  /* ABCA */
59*c2c66affSColin Finck     MultiCount = Count / 4;
60*c2c66affSColin Finck     do
61*c2c66affSColin Finck     {
62*c2c66affSColin Finck       *(PULONG)addr = Fill[0];
63*c2c66affSColin Finck       addr += 4;
64*c2c66affSColin Finck       *(PULONG)addr = Fill[1];
65*c2c66affSColin Finck       addr += 4;
66*c2c66affSColin Finck       *(PULONG)addr = Fill[2];
67*c2c66affSColin Finck       addr += 4;
68*c2c66affSColin Finck     }
69*c2c66affSColin Finck     while (0 != --MultiCount);
70*c2c66affSColin Finck 
71*c2c66affSColin Finck     Count = Count & 0x03;
72*c2c66affSColin Finck     while (0 != Count--)
73*c2c66affSColin Finck     {
74*c2c66affSColin Finck       *(PUSHORT)(addr) = c;
75*c2c66affSColin Finck       addr += 2;
76*c2c66affSColin Finck       *(addr) = c >> 16;
77*c2c66affSColin Finck       addr += 1;
78*c2c66affSColin Finck     }
79*c2c66affSColin Finck   }
80*c2c66affSColin Finck }
81