7b15ece11e59353e82716add890a8b63e74876ad
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv
);
29 static const DASHPATTERN dashPatterns
[4] =
34 {6, {9, 3, 3, 3, 3, 3}}
37 static inline void OrderEndPoints(int *s
, int *e
)
48 static void SolidPenHLine(DIBDRVPHYSDEV
*physDev
, int x1
, int x2
, int y
)
50 OrderEndPoints(&x1
, &x2
);
51 physDev
->physBitmap
.funcs
->SolidHLine(&physDev
->physBitmap
, x1
, x2
, y
, physDev
->penAnd
, physDev
->penXor
);
54 static void SolidPenVline(DIBDRVPHYSDEV
*physDev
, int x
, int y1
, int y2
)
56 OrderEndPoints(&y1
, &y2
);
57 physDev
->physBitmap
.funcs
->SolidVLine(&physDev
->physBitmap
, x
, y1
, y2
, physDev
->penAnd
, physDev
->penXor
);
60 static void WINAPI
SolidPenLineCallback(int x
, int y
, LPARAM lparam
)
62 DIBDRVPHYSDEV
*physDev
= (DIBDRVPHYSDEV
*)lparam
;
64 physDev
->physBitmap
.funcs
->SetPixel(&physDev
->physBitmap
, x
, y
, physDev
->penAnd
, physDev
->penXor
);
68 void SolidPenLine(DIBDRVPHYSDEV
*physDev
, int x1
, int y1
, int x2
, int y2
)
70 LineDDA(x1
, y1
, x2
, y2
, SolidPenLineCallback
, (LPARAM
)physDev
);
73 static inline void GetDashColors(DIBDRVPHYSDEV
*physDev
, DWORD
*and, DWORD
*xor)
75 if(physDev
->markSpace
== mark
)
77 *and = physDev
->penAnd
;
78 *xor = physDev
->penXor
;
80 else if(GetBkMode(physDev
->hdc
) == OPAQUE
)
82 *and = physDev
->backgroundAnd
;
83 *xor = physDev
->backgroundXor
;
92 static inline void NextDash(DIBDRVPHYSDEV
*physDev
)
94 if(physDev
->leftInDash
!= 0)
98 if(physDev
->curDash
== physDev
->penPattern
->count
)
100 physDev
->leftInDash
= physDev
->penPattern
->dashes
[physDev
->curDash
];
101 if(physDev
->markSpace
== mark
)
102 physDev
->markSpace
= space
;
104 physDev
->markSpace
= mark
;
107 static void DashedPenHLine(DIBDRVPHYSDEV
*physDev
, int x1
, int x2
, int y
)
117 GetDashColors(physDev
, &and, &xor);
119 dashLen
= physDev
->leftInDash
;
123 physDev
->physBitmap
.funcs
->SolidHLine(&physDev
->physBitmap
, x
, x
+ dashLen
, y
, and, xor);
126 physDev
->leftInDash
-= dashLen
;
134 GetDashColors(physDev
, &and, &xor);
136 dashLen
= physDev
->leftInDash
;
137 if(x
- (int)dashLen
< x2
)
140 physDev
->physBitmap
.funcs
->SolidHLine(&physDev
->physBitmap
, x
- dashLen
+ 1, x
+ 1, y
, and, xor);
143 physDev
->leftInDash
-= dashLen
;
149 static void DashedPenVLine(DIBDRVPHYSDEV
*physDev
, int x
, int y1
, int y2
)
159 GetDashColors(physDev
, &and, &xor);
161 dashLen
= physDev
->leftInDash
;
165 physDev
->physBitmap
.funcs
->SolidVLine(&physDev
->physBitmap
, x
, y
, y
+ dashLen
, and, xor);
168 physDev
->leftInDash
-= dashLen
;
176 GetDashColors(physDev
, &and, &xor);
178 dashLen
= physDev
->leftInDash
;
179 if(y
- (int)dashLen
< y2
)
182 physDev
->physBitmap
.funcs
->SolidVLine(&physDev
->physBitmap
, x
, y
- dashLen
+ 1, y
+ 1, and, xor);
185 physDev
->leftInDash
-= dashLen
;
191 static void WINAPI
DashedPenLineCallback(int x
, int y
, LPARAM lparam
)
193 DIBDRVPHYSDEV
*physDev
= (DIBDRVPHYSDEV
*)lparam
;
196 GetDashColors(physDev
, &and, &xor);
198 physDev
->physBitmap
.funcs
->SetPixel(&physDev
->physBitmap
, x
, y
, and, xor);
200 physDev
->leftInDash
--;
206 static void DashedPenLine(DIBDRVPHYSDEV
*physDev
, int x1
, int y1
, int x2
, int y2
)
208 LineDDA(x1
, y1
, x2
, y2
, DashedPenLineCallback
, (LPARAM
)physDev
);
211 void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV
*physDev
)
213 physDev
->curDash
= 0;
214 if(physDev
->penPattern
)
215 physDev
->leftInDash
= physDev
->penPattern
->dashes
[0];
216 physDev
->markSpace
= mark
;
220 /* For 1bpp bitmaps, unless the selected foreground color exactly
221 matches foreground's colortable OR it's the WHITE color,
222 the background color is used -- tested on WinXP */
223 static DWORD
AdjustFgColor(DIBDRVPHYSDEV
*physDev
, COLORREF color
)
225 RGBQUAD
*fore
= physDev
->physBitmap
.colorTable
+1;
227 if((color
& 0x00ffffff) == 0x00ffffff ||
229 fore
->rgbRed
== GetRValue(color
) &&
230 fore
->rgbGreen
== GetGValue(color
) &&
231 fore
->rgbBlue
== GetBValue(color
)
237 static void FixupFgColors1(DIBDRVPHYSDEV
*physDev
)
239 int rop
= GetROP2(physDev
->hdc
);
241 physDev
->penColor
= AdjustFgColor(physDev
, physDev
->penColorref
);
242 physDev
->brushColor
= AdjustFgColor(physDev
, physDev
->brushColorref
);
244 _DIBDRV_CalcAndXorMasks(rop
, physDev
->penColor
, &physDev
->penAnd
, &physDev
->penXor
);
245 _DIBDRV_CalcAndXorMasks(rop
, physDev
->brushColor
, &physDev
->brushAnd
, &physDev
->brushXor
);
246 HeapFree(GetProcessHeap(), 0, physDev
->brushAnds
);
247 HeapFree(GetProcessHeap(), 0, physDev
->brushXors
);
248 physDev
->brushAnds
= NULL
;
249 physDev
->brushXors
= NULL
;
252 static void SolidBrushHLine(DIBDRVPHYSDEV
*physDev
, int x1
, int x2
, int y
)
254 OrderEndPoints(&x1
, &x2
);
255 physDev
->physBitmap
.funcs
->SolidHLine(&physDev
->physBitmap
, x1
, x2
, y
, physDev
->brushAnd
, physDev
->brushXor
);
259 static void GenerateMasks(DIBDRVPHYSDEV
*physDev
, DIBDRVBITMAP
*bmp
, DWORD
**and, DWORD
**xor)
261 int rop
= GetROP2(physDev
->hdc
);
262 DWORD
*color_ptr
, *and_ptr
, *xor_ptr
;
263 DWORD size
= bmp
->height
* abs(bmp
->stride
);
265 *and = HeapAlloc(GetProcessHeap(), 0, size
);
266 *xor = HeapAlloc(GetProcessHeap(), 0, size
);
268 color_ptr
= bmp
->bits
;
274 _DIBDRV_CalcAndXorMasks(rop
, *color_ptr
++, and_ptr
++, xor_ptr
++);
279 static void PatternBrushHLine(DIBDRVPHYSDEV
*physDev
, int x1
, int x2
, int y
)
281 DWORD
*and, *xor, brushY
= y
% physDev
->brushBitmap
.height
;
283 if(!physDev
->brushAnds
)
284 GenerateMasks(physDev
, &physDev
->brushBitmap
, &physDev
->brushAnds
, &physDev
->brushXors
);
286 OrderEndPoints(&x1
, &x2
);
287 and = (DWORD
*)((char *)physDev
->brushAnds
+ brushY
* physDev
->brushBitmap
.stride
);
288 xor = (DWORD
*)((char *)physDev
->brushXors
+ brushY
* physDev
->brushBitmap
.stride
);
290 physDev
->physBitmap
.funcs
->PatternHLine(&physDev
->physBitmap
, x1
, x2
, y
, and, xor, physDev
->brushBitmap
.width
, x1
% physDev
->brushBitmap
.width
);
293 /* null function for PS_NULL and BS_NULL pen and brush styles */
294 void NullPenHLine(DIBDRVPHYSDEV
*physDev
, int x1
, int x2
, int y
) {}
295 void NullPenVLine(DIBDRVPHYSDEV
*physDev
, int x
, int y1
, int y2
) {}
296 void NullPenLine(DIBDRVPHYSDEV
*physDev
, int x1
, int y1
, int x2
, int y2
) {}
297 void NullBrushHLine(DIBDRVPHYSDEV
*physDev
, int x1
, int x2
, int y
) {}
299 /***********************************************************************
302 HPEN
DIBDRV_SelectPen( DIBDRVPHYSDEV
*physDev
, HPEN hpen
)
307 MAYBE(TRACE("physDev:%p, hpen:%p\n", physDev
, hpen
));
311 GetObjectW(hpen
, sizeof(logpen
), &logpen
);
313 physDev
->penColorref
= logpen
.lopnColor
;
315 if(physDev
->physBitmap
.bitCount
== 1)
316 FixupFgColors1(physDev
);
318 physDev
->penColor
= physDev
->physBitmap
.funcs
->ColorToPixel(&physDev
->physBitmap
, logpen
.lopnColor
);
320 _DIBDRV_CalcAndXorMasks(GetROP2(physDev
->hdc
), physDev
->penColor
, &physDev
->penAnd
, &physDev
->penXor
);
322 switch(logpen
.lopnStyle
)
325 ONCE(FIXME("Unhandled pen style %d\n", logpen
.lopnStyle
));
328 physDev
->penHLine
= SolidPenHLine
;
329 physDev
->penVLine
= SolidPenVline
;
330 physDev
->penLine
= SolidPenLine
;
331 physDev
->penPattern
= NULL
;
338 physDev
->penHLine
= DashedPenHLine
;
339 physDev
->penVLine
= DashedPenVLine
;
340 physDev
->penLine
= DashedPenLine
;
341 physDev
->penPattern
= &dashPatterns
[logpen
.lopnStyle
- PS_DASH
];
342 _DIBDRV_ResetDashOrigin(physDev
);
345 physDev
->penHLine
= NullPenHLine
;
346 physDev
->penVLine
= NullPenVLine
;
347 physDev
->penLine
= NullPenLine
;
348 physDev
->penPattern
= NULL
;
355 /* DDB selected in, use X11 driver */
356 res
= _DIBDRV_GetDisplayDriver()->pSelectPen(physDev
->X11PhysDev
, hpen
);
361 /***********************************************************************
362 * DIBDRV_SetDCPenColor
364 COLORREF
DIBDRV_SetDCPenColor( DIBDRVPHYSDEV
*physDev
, COLORREF crColor
)
368 MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev
, crColor
));
372 /* DIB section selected in, use DIB Engine */
373 ONCE(FIXME("STUB\n"));
378 /* DDB selected in, use X11 driver */
379 res
= _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev
->X11PhysDev
, crColor
);
384 /***********************************************************************
387 HBRUSH
DIBDRV_SelectBrush( DIBDRVPHYSDEV
*physDev
, HBRUSH hbrush
)
393 MAYBE(TRACE("physDev:%p, hbrush:%p\n", physDev
, hbrush
));
397 GetObjectW(hbrush
, sizeof(logbrush
), &logbrush
);
399 /* frees any currently selected DIB brush and cache */
400 _DIBDRVBITMAP_Free(&physDev
->brushBitmap
);
401 _DIBDRVBITMAP_Free(&physDev
->brushBmpCache
);
402 if(physDev
->brushAnds
)
404 HeapFree(GetProcessHeap(), 0, physDev
->brushAnds
);
405 HeapFree(GetProcessHeap(), 0, physDev
->brushXors
);
407 physDev
->brushAnds
= NULL
;
408 physDev
->brushXors
= NULL
;
410 switch (logbrush
.lbStyle
)
413 FIXME("Unhandled brush style %d\n", logbrush
.lbStyle
);
414 physDev
->brushColorref
= 0;
418 physDev
->brushColorref
= logbrush
.lbColor
;
420 MAYBE(TRACE("SOLID Pattern -- color is %x\n", physDev
->brushColorref
));
421 physDev
->brushStyle
= BS_SOLID
;
422 physDev
->brushHLine
= SolidBrushHLine
;
424 if(physDev
->physBitmap
.bitCount
== 1)
425 FixupFgColors1(physDev
);
427 physDev
->brushColor
= physDev
->physBitmap
.funcs
->ColorToPixel(&physDev
->physBitmap
, logbrush
.lbColor
);
429 _DIBDRV_CalcAndXorMasks(physDev
->rop2
, physDev
->brushColor
,
430 &physDev
->brushAnd
, &physDev
->brushXor
);
432 /* set the physDev brush style */
433 physDev
->brushStyle
= BS_SOLID
;
434 physDev
->isBrushBitmap
= FALSE
;
438 case BS_DIBPATTERN8X8
:
444 FIXME("DIB Pattern\n");
446 /* if no DIB selected in, fallback to null brush */
447 if(!physDev
->physBitmap
.bits
)
449 physDev
->brushColorref
= 0;
453 /* gets brush DIB's pointer */
454 bmi
= GlobalLock16(logbrush
.lbHatch
);
456 /* initializes a temporary DIB with brush's one */
457 if(!_DIBDRVBITMAP_InitFromBitmapinfo(&src
, bmi
))
459 ERR("Failed to initialize brush DIB\n");
464 /* converts brush bitmap to match currently selected one's format */
465 if(!_DIBDRVBITMAP_Convert(&physDev
->brushBitmap
, &src
, &physDev
->physBitmap
))
467 ERR("Failed to convert brush DIB\n");
468 _DIBDRVBITMAP_Free(&src
);
473 /* frees temporary DIB's data */
474 _DIBDRVBITMAP_Free(&src
);
476 /* use DIB pattern for brush lines */
477 physDev
->brushHLine
= PatternBrushHLine
;
480 /* frees brush's DIB pointer */
481 GlobalUnlock16(logbrush
.lbHatch
);
485 case BS_DIBPATTERNPT
:
486 FIXME("BS_DIBPATTERNPT not supported\n");
487 physDev
->brushColorref
= 0;
491 FIXME("BS_HATCHED not supported\n");
492 physDev
->brushColorref
= 0;
497 MAYBE(TRACE("NULL Pattern\n"));
498 physDev
->brushColorref
= 0;
499 physDev
->brushHLine
= NullBrushHLine
;
505 FIXME("BS_PATTERN not supported\n");
506 physDev
->brushColorref
= 0;
510 MAYBE(TRACE("END\n"));
515 /* DDB selected in, use X11 driver */
517 /* we must check if a DIB pattern is requested */
518 GetObjectW(hbrush
, sizeof(logbrush
), &logbrush
);
519 switch (logbrush
.lbStyle
)
521 case BS_DIBPATTERN8X8
:
523 case BS_DIBPATTERNPT
:
524 FIXME("A DIB pattern was requested for a DDB bitmap\n");
535 res
= _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev
->X11PhysDev
, hbrush
);
540 /***********************************************************************
541 * DIBDRV_SetDCBrushColor
543 COLORREF
DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV
*physDev
, COLORREF crColor
)
547 MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev
, crColor
));
551 /* DIB section selected in, use DIB Engine */
552 ONCE(FIXME("STUB\n"));
557 /* DDB selected in, use X11 driver */
558 res
= _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev
->X11PhysDev
, crColor
);
563 /***********************************************************************
566 int DIBDRV_SetROP2( DIBDRVPHYSDEV
*physDev
, int rop
)
570 MAYBE(TRACE("physDev:%p, rop:%x\n", physDev
, rop
));
572 prevRop
= physDev
->rop2
;
577 _DIBDRV_CalcAndXorMasks(rop
, physDev
->penColor
, &physDev
->penAnd
, &physDev
->penXor
);
578 _DIBDRV_CalcAndXorMasks(rop
, physDev
->brushColor
, &physDev
->brushAnd
, &physDev
->brushXor
);
579 _DIBDRV_CalcAndXorMasks(rop
, physDev
->backgroundColor
, &physDev
->backgroundAnd
, &physDev
->backgroundXor
);
580 if(physDev
->brushAnds
)
582 HeapFree(GetProcessHeap(), 0, physDev
->brushAnds
);
583 HeapFree(GetProcessHeap(), 0, physDev
->brushXors
);
585 physDev
->brushAnds
= NULL
;
586 physDev
->brushXors
= NULL
;
590 /* note : X11 Driver don't have SetROP2() function exported */
593 /***********************************************************************
596 COLORREF
DIBDRV_SetBkColor( DIBDRVPHYSDEV
*physDev
, COLORREF color
)
600 MAYBE(TRACE("physDev:%p, color:%x\n", physDev
, color
));
604 physDev
->backgroundColor
= physDev
->physBitmap
.funcs
->ColorToPixel(&physDev
->physBitmap
, color
);
606 if(physDev
->physBitmap
.bitCount
== 1)
607 FixupFgColors1(physDev
);
608 _DIBDRV_CalcAndXorMasks(physDev
->rop2
, physDev
->backgroundColor
, &physDev
->backgroundAnd
, &physDev
->backgroundXor
);
614 /* DDB selected in, use X11 driver */
615 res
= _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev
->X11PhysDev
, color
);