1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/graphics/graphbitmap.cpp
3 // Purpose: wxGraphicsBitmap unit test
4 // Author: Artur Wieczorek
5 // Created: 2021-02-05
6 // Copyright: (c) 2021 wxWidgets development team
7 ///////////////////////////////////////////////////////////////////////////////
8
9 // ----------------------------------------------------------------------------
10 // headers
11 // ----------------------------------------------------------------------------
12
13 #include "testprec.h"
14
15 #ifdef wxHAS_RAW_BITMAP
16
17 #include "wx/bitmap.h"
18 #include "wx/rawbmp.h"
19 #include "wx/dcmemory.h"
20 #include "wx/graphics.h"
21
22 #include "testimage.h"
23
24 #ifdef __WXMSW__
25 // Support for iteration over 32 bpp 0RGB bitmaps
26 typedef wxPixelFormat<unsigned char, 32, 2, 1, 0> wxNative32PixelFormat;
27 typedef wxPixelData<wxBitmap, wxNative32PixelFormat> wxNative32PixelData;
28 #endif // __WXMSW__
29 #ifdef __WXOSX__
30 // 32 bpp xRGB bitmaps are native ones
31 typedef wxNativePixelData wxNative32PixelData;
32 #endif // __WXOSX__
33
34 // ----------------------------------------------------------------------------
35 // tests
36 // ----------------------------------------------------------------------------
37
38 #if wxUSE_GRAPHICS_CONTEXT
39
40 namespace
41 {
DoCreateBitmapRGB(int w,int h,int bpp,bool withMask)42 wxBitmap DoCreateBitmapRGB(int w, int h, int bpp, bool withMask)
43 {
44 wxBitmap bmp(w, h, bpp);
45 {
46 wxMemoryDC dc(bmp);
47 dc.SetBackground(*wxBLUE_BRUSH);
48 dc.Clear();
49 dc.SetPen(*wxYELLOW_PEN);
50 dc.SetBrush(*wxYELLOW_BRUSH);
51 dc.DrawRectangle(2, 2, bmp.GetWidth() - 2, bmp.GetHeight() - 2);
52 }
53 REQUIRE_FALSE(bmp.HasAlpha());
54 REQUIRE(bmp.GetMask() == NULL);
55 if ( withMask )
56 {
57 // Mask
58 wxBitmap bmask(bmp.GetWidth(), bmp.GetHeight(), 1);
59 {
60 wxMemoryDC dc(bmask);
61 wxGraphicsContext* gc = dc.GetGraphicsContext();
62 if ( gc )
63 {
64 gc->SetAntialiasMode(wxANTIALIAS_NONE);
65 }
66 dc.SetBackground(*wxBLACK_BRUSH);
67 dc.Clear();
68 dc.SetPen(*wxWHITE_PEN);
69 dc.SetBrush(*wxWHITE_BRUSH);
70 dc.DrawRectangle(4, 4, 4, 4);
71 }
72 bmp.SetMask(new wxMask(bmask));
73 REQUIRE_FALSE(bmp.HasAlpha());
74 REQUIRE(bmp.GetMask() != NULL);
75 }
76
77 return bmp;
78 }
79
CreateBitmapRGB(int w,int h,bool withMask)80 wxBitmap CreateBitmapRGB(int w, int h, bool withMask)
81 {
82 return DoCreateBitmapRGB(w, h, 24, withMask);
83 }
84
85 #if defined(__WXMSW__) || defined(__WXOSX__)
86 // 32-bit RGB bitmap
CreateBitmapXRGB(int w,int h,bool withMask)87 wxBitmap CreateBitmapXRGB(int w, int h, bool withMask)
88 {
89 return DoCreateBitmapRGB(w, h, 32, withMask);
90 }
91 #endif // __WXMSW__ || __WXOSX__
92
CreateBitmapRGBA(int w,int h,bool withMask)93 wxBitmap CreateBitmapRGBA(int w, int h, bool withMask)
94 {
95 wxBitmap bmp(w, h, 32);
96 #if defined(__WXMSW__) || defined(__WXOSX__)
97 bmp.UseAlpha();
98 #endif // __WXMSW__ || __WXOSX__
99 {
100 const wxColour clrFg(*wxCYAN);
101 const wxColour clrBg(*wxGREEN);
102 const unsigned char alpha = 51;
103
104 #if defined(__WXMSW__) || defined(__WXOSX__)
105 // premultiplied values
106 const wxColour clrFgAlpha(((clrFg.Red() * alpha) + 127) / 255, ((clrFg.Green() * alpha) + 127) / 255, ((clrFg.Blue() * alpha) + 127) / 255);
107 #else
108 const wxColour clrFgAlpha(clrFg);
109 #endif // __WXMSW__ || __WXOSX__
110
111 wxAlphaPixelData data(bmp);
112 REQUIRE(data);
113 wxAlphaPixelData::Iterator p(data);
114 for ( int y = 0; y < bmp.GetHeight(); y++ )
115 {
116 wxAlphaPixelData::Iterator rowStart = p;
117 for ( int x = 0; x < bmp.GetWidth(); x++, ++p )
118 {
119 if ( x < bmp.GetWidth() / 2 )
120 { // opaque
121 p.Red() = clrFg.Red();
122 p.Green() = clrFg.Green();
123 p.Blue() = clrFg.Blue();
124 p.Alpha() = 255;
125 }
126 else
127 { // with transparency
128 p.Red() = clrFgAlpha.Red();
129 p.Green() = clrFgAlpha.Green();
130 p.Blue() = clrFgAlpha.Blue();
131 p.Alpha() = alpha;
132 }
133 }
134 p = rowStart;
135 p.OffsetY(data, 1);
136 }
137 }
138 REQUIRE(bmp.HasAlpha() == true);
139 REQUIRE(bmp.GetMask() == NULL);
140 if ( withMask )
141 {
142 // Mask
143 wxBitmap bmask(bmp.GetWidth(), bmp.GetHeight(), 1);
144 {
145 wxMemoryDC dc(bmask);
146 wxGraphicsContext* gc = dc.GetGraphicsContext();
147 if ( gc )
148 {
149 gc->SetAntialiasMode(wxANTIALIAS_NONE);
150 }
151 dc.SetBackground(*wxBLACK_BRUSH);
152 dc.Clear();
153 dc.SetPen(*wxWHITE_PEN);
154 dc.SetBrush(*wxWHITE_BRUSH);
155 dc.DrawRectangle(4, 4, 4, 4);
156 }
157 bmp.SetMask(new wxMask(bmask));
158 REQUIRE(bmp.HasAlpha() == true);
159 REQUIRE(bmp.GetMask() != NULL);
160 }
161
162 return bmp;
163 }
164
MakeReferenceImage(const wxImage & img)165 wxImage MakeReferenceImage(const wxImage& img)
166 {
167 wxImage refImg = img;
168 if ( refImg.HasMask() )
169 {
170 // wxGraphicsBitmap doesn't have a mask so we need wxImage
171 // without mask to be compared with created wxGraphicsBitmap.
172 if ( refImg.HasAlpha() )
173 {
174 // We need to blend mask with alpha values
175 size_t numPixels = refImg.GetWidth() * refImg.GetHeight();
176 unsigned char* oldAlpha = new unsigned char[numPixels];
177 memcpy(oldAlpha, refImg.GetAlpha(), numPixels);
178
179 refImg.ClearAlpha();
180 refImg.InitAlpha();
181 unsigned char* newAlpha = refImg.GetAlpha();
182 for ( size_t i = 0; i < numPixels; i++ )
183 {
184 if ( newAlpha[i] == wxIMAGE_ALPHA_OPAQUE )
185 newAlpha[i] = oldAlpha[i];
186 }
187 delete[]oldAlpha;
188 }
189 else
190 {
191 refImg.InitAlpha();
192 }
193 }
194
195 if ( refImg.HasAlpha() )
196 {
197 // We need also to remove mask colour from transparent pixels
198 // for compatibility with wxGraphicsBitmap.
199 for ( int y = 0; y < refImg.GetHeight(); y++ )
200 for ( int x = 0; x < refImg.GetWidth(); x++ )
201 {
202 if ( refImg.GetAlpha(x, y) == wxALPHA_TRANSPARENT )
203 {
204 refImg.SetRGB(x, y, 0, 0, 0);
205 }
206 }
207 }
208
209 return refImg;
210 }
211
CheckCreateGraphBitmap(wxGraphicsRenderer * gr,const wxBitmap & srcBmp,const wxImage & srcImg)212 inline void CheckCreateGraphBitmap(wxGraphicsRenderer* gr, const wxBitmap& srcBmp, const wxImage& srcImg)
213 {
214 wxGraphicsBitmap gbmp = gr->CreateBitmap(srcBmp);
215
216 wxImage gimage = gbmp.ConvertToImage();
217
218 // Reference image needs to be in the format compatible with wxGraphicsBitmap.
219 wxImage refImg = MakeReferenceImage(srcImg);
220
221 CHECK_THAT(gimage, RGBASameAs(refImg));
222 }
223
CheckCreateGraphSubBitmap(wxGraphicsRenderer * gr,const wxBitmap & srcBmp,double x,double y,double w,double h,const wxImage & srcImg)224 inline void CheckCreateGraphSubBitmap(wxGraphicsRenderer* gr, const wxBitmap& srcBmp,
225 double x, double y, double w, double h,
226 const wxImage& srcImg)
227 {
228 wxGraphicsBitmap gbmp = gr->CreateBitmap(srcBmp);
229 wxGraphicsBitmap gSubBmp = gr->CreateSubBitmap(gbmp, x, y, w, h);
230
231 wxImage gimage = gSubBmp.ConvertToImage();
232
233 // Reference image needs to be in the format compatible with wxGraphicsBitmap.
234 wxImage refImg = MakeReferenceImage(srcImg);
235
236 CHECK_THAT(gimage, RGBASameAs(refImg));
237 }
238
CheckCreateGraphBitmapFromImage(wxGraphicsRenderer * gr,const wxImage & srcImg)239 inline void CheckCreateGraphBitmapFromImage(wxGraphicsRenderer* gr, const wxImage& srcImg)
240 {
241 wxGraphicsBitmap gbmp = gr->CreateBitmapFromImage(srcImg);
242
243 wxImage gimage = gbmp.ConvertToImage();
244
245 // Reference image needs to be in the format compatible with wxGraphicsBitmap.
246 wxImage refImg = MakeReferenceImage(srcImg);
247
248 CHECK_THAT(gimage, RGBASameAs(refImg));
249 }
250 };
251
252 TEST_CASE("GraphicsBitmapTestCase::Create", "[graphbitmap][create]")
253 {
254 SECTION("RGB bitmap without mask")
255 {
256 // RGB bitmap
257 wxBitmap bmp = CreateBitmapRGB(8, 8, false);
258 REQUIRE_FALSE(bmp.HasAlpha());
259 REQUIRE(bmp.GetMask() == NULL);
260
261 // Reference image
262 wxImage image = bmp.ConvertToImage();
263 REQUIRE_FALSE(image.HasAlpha());
264 REQUIRE_FALSE(image.HasMask());
265 REQUIRE(image.GetWidth() == bmp.GetWidth());
266 REQUIRE(image.GetHeight() == bmp.GetHeight());
267
268 SECTION("Default GC")
269 {
270 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
271 REQUIRE(gr != NULL);
272 CheckCreateGraphBitmap(gr, bmp, image);
273 }
274
275 #if defined(__WXMSW__)
276 #if wxUSE_GRAPHICS_GDIPLUS
277 SECTION("GDI+ GC")
278 {
279 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
280 REQUIRE(gr != NULL);
281 CheckCreateGraphBitmap(gr, bmp, image);
282 }
283 #endif // wxUSE_GRAPHICS_GDIPLUS
284
285 #if wxUSE_GRAPHICS_DIRECT2D
286 SECTION("Direct2D GC")
287 {
288 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
289 REQUIRE(gr != NULL);
290 CheckCreateGraphBitmap(gr, bmp, image);
291 }
292 #endif // wxUSE_GRAPHICS_DIRECT2D
293 #endif // __WXMSW__
294
295 #if wxUSE_CAIRO
296 SECTION("Cairo GC")
297 {
298 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
299 REQUIRE(gr != NULL);
300 CheckCreateGraphBitmap(gr, bmp, image);
301 }
302 #endif // wxUSE_GRAPHICS_CAIRO
303 }
304
305 SECTION("RGB bitmap with mask")
306 {
307 // RGB bitmap
308 wxBitmap bmp = CreateBitmapRGB(8, 8, true);
309 REQUIRE_FALSE(bmp.HasAlpha());
310 REQUIRE(bmp.GetMask() != NULL);
311
312 // Reference image
313 wxImage image = bmp.ConvertToImage();
314 REQUIRE_FALSE(image.HasAlpha());
315 REQUIRE(image.HasMask() == true);
316 REQUIRE(image.GetWidth() == bmp.GetWidth());
317 REQUIRE(image.GetHeight() == bmp.GetHeight());
318 const wxColour maskCol(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
319 REQUIRE(maskCol.IsOk());
320
321 SECTION("Default GC")
322 {
323 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
324 REQUIRE(gr != NULL);
325 CheckCreateGraphBitmap(gr, bmp, image);
326 }
327
328 #if defined(__WXMSW__)
329 #if wxUSE_GRAPHICS_GDIPLUS
330 SECTION("GDI+ GC")
331 {
332 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
333 REQUIRE(gr != NULL);
334 CheckCreateGraphBitmap(gr, bmp, image);
335 }
336 #endif // wxUSE_GRAPHICS_GDIPLUS
337
338 #if wxUSE_GRAPHICS_DIRECT2D
339 SECTION("Direct2D GC")
340 {
341 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
342 REQUIRE(gr != NULL);
343 CheckCreateGraphBitmap(gr, bmp, image);
344 }
345 #endif // wxUSE_GRAPHICS_DIRECT2D
346 #endif // __WXMSW__
347
348 #if wxUSE_CAIRO
349 SECTION("Cairo GC")
350 {
351 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
352 REQUIRE(gr != NULL);
353 CheckCreateGraphBitmap(gr, bmp, image);
354 }
355 #endif // wxUSE_GRAPHICS_CAIRO
356 }
357
358 #if defined(__WXMSW__) || defined(__WXOSX__)
359 SECTION("xRGB bitmap without mask")
360 {
361 // xRGB bitmap
362 wxBitmap bmp = CreateBitmapXRGB(8, 8, false);
363 REQUIRE(bmp.GetDepth() == 32);
364 REQUIRE_FALSE(bmp.HasAlpha());
365 REQUIRE(bmp.GetMask() == NULL);
366
367 // Reference image
368 wxImage image = bmp.ConvertToImage();
369 REQUIRE_FALSE(image.HasAlpha());
370 REQUIRE_FALSE(image.HasMask());
371 REQUIRE(image.GetWidth() == bmp.GetWidth());
372 REQUIRE(image.GetHeight() == bmp.GetHeight());
373
374 SECTION("Default GC")
375 {
376 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
377 REQUIRE(gr != NULL);
378 CheckCreateGraphBitmap(gr, bmp, image);
379 }
380
381 #if defined(__WXMSW__)
382 #if wxUSE_GRAPHICS_GDIPLUS
383 SECTION("GDI+ GC")
384 {
385 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
386 REQUIRE(gr != NULL);
387 CheckCreateGraphBitmap(gr, bmp, image);
388 }
389 #endif // wxUSE_GRAPHICS_GDIPLUS
390
391 #if wxUSE_GRAPHICS_DIRECT2D
392 SECTION("Direct2D GC")
393 {
394 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
395 REQUIRE(gr != NULL);
396 CheckCreateGraphBitmap(gr, bmp, image);
397 }
398 #endif // wxUSE_GRAPHICS_DIRECT2D
399 #endif // __WXMSW__
400
401 #if wxUSE_CAIRO
402 SECTION("Cairo GC")
403 {
404 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
405 REQUIRE(gr != NULL);
406 CheckCreateGraphBitmap(gr, bmp, image);
407 }
408 #endif // wxUSE_GRAPHICS_CAIRO
409 }
410
411 SECTION("xRGB bitmap with mask")
412 {
413 // xRGB bitmap
414 wxBitmap bmp = CreateBitmapXRGB(8, 8, true);
415 REQUIRE(bmp.GetDepth() == 32);
416 REQUIRE_FALSE(bmp.HasAlpha());
417 REQUIRE(bmp.GetMask() != NULL);
418
419 // Reference image
420 wxImage image = bmp.ConvertToImage();
421 REQUIRE_FALSE(image.HasAlpha());
422 REQUIRE(image.HasMask() == true);
423 REQUIRE(image.GetWidth() == bmp.GetWidth());
424 REQUIRE(image.GetHeight() == bmp.GetHeight());
425 const wxColour maskCol(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
426 REQUIRE(maskCol.IsOk());
427
428 SECTION("Default GC")
429 {
430 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
431 REQUIRE(gr != NULL);
432 CheckCreateGraphBitmap(gr, bmp, image);
433 }
434
435 #if defined(__WXMSW__)
436 #if wxUSE_GRAPHICS_GDIPLUS
437 SECTION("GDI+ GC")
438 {
439 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
440 REQUIRE(gr != NULL);
441 CheckCreateGraphBitmap(gr, bmp, image);
442 }
443 #endif // wxUSE_GRAPHICS_GDIPLUS
444
445 #if wxUSE_GRAPHICS_DIRECT2D
446 SECTION("Direct2D GC")
447 {
448 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
449 REQUIRE(gr != NULL);
450 CheckCreateGraphBitmap(gr, bmp, image);
451 }
452 #endif // wxUSE_GRAPHICS_DIRECT2D
453 #endif // __WXMSW__
454
455 #if wxUSE_CAIRO
456 SECTION("Cairo GC")
457 {
458 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
459 REQUIRE(gr != NULL);
460 CheckCreateGraphBitmap(gr, bmp, image);
461 }
462 #endif // wxUSE_GRAPHICS_CAIRO
463 }
464 #endif // _WXMSW__ || __WXOSX__
465
466 SECTION("RGBA bitmap without mask")
467 {
468 // RGBA Bitmap
469 wxBitmap bmp = CreateBitmapRGBA(8, 8, false);
470 REQUIRE(bmp.HasAlpha() == true);
471 REQUIRE(bmp.GetMask() == NULL);
472
473 // Reference image
474 wxImage image = bmp.ConvertToImage();
475 REQUIRE(image.HasAlpha() == true);
476 REQUIRE_FALSE(image.HasMask());
477 REQUIRE(image.GetWidth() == bmp.GetWidth());
478 REQUIRE(image.GetHeight() == bmp.GetHeight());
479
480 SECTION("Default GC")
481 {
482 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
483 REQUIRE(gr != NULL);
484 CheckCreateGraphBitmap(gr, bmp, image);
485 }
486
487 #if defined(__WXMSW__)
488 #if wxUSE_GRAPHICS_GDIPLUS
489 SECTION("GDI+ GC")
490 {
491 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
492 REQUIRE(gr != NULL);
493 CheckCreateGraphBitmap(gr, bmp, image);
494 }
495 #endif // wxUSE_GRAPHICS_GDIPLUS
496
497 #if wxUSE_GRAPHICS_DIRECT2D
498 SECTION("Direct2D GC")
499 {
500 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
501 REQUIRE(gr != NULL);
502 CheckCreateGraphBitmap(gr, bmp, image);
503 }
504 #endif // wxUSE_GRAPHICS_DIRECT2D
505 #endif // __WXMSW__
506
507 #if wxUSE_CAIRO
508 SECTION("Cairo GC")
509 {
510 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
511 REQUIRE(gr != NULL);
512 CheckCreateGraphBitmap(gr, bmp, image);
513 }
514 #endif // wxUSE_GRAPHICS_CAIRO
515 }
516
517 SECTION("RGBA bitmap with mask")
518 {
519 // RGBA Bitmap
520 wxBitmap bmp = CreateBitmapRGBA(8, 8, true);
521 REQUIRE(bmp.HasAlpha() == true);
522 REQUIRE(bmp.GetMask() != NULL);
523
524 // Reference image
525 wxImage image = bmp.ConvertToImage();
526 REQUIRE(image.HasAlpha() == true);
527 REQUIRE(image.HasMask() == true);
528 REQUIRE(image.GetWidth() == bmp.GetWidth());
529 REQUIRE(image.GetHeight() == bmp.GetHeight());
530 const wxColour maskCol(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
531 REQUIRE(maskCol.IsOk());
532
533 SECTION("Default GC")
534 {
535 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
536 REQUIRE(gr != NULL);
537 CheckCreateGraphBitmap(gr, bmp, image);
538 }
539
540 #if defined(__WXMSW__)
541 #if wxUSE_GRAPHICS_GDIPLUS
542 SECTION("GDI+ GC")
543 {
544 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
545 REQUIRE(gr != NULL);
546 CheckCreateGraphBitmap(gr, bmp, image);
547 }
548 #endif // wxUSE_GRAPHICS_GDIPLUS
549
550 #if wxUSE_GRAPHICS_DIRECT2D
551 SECTION("Direct2D GC")
552 {
553 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
554 REQUIRE(gr != NULL);
555 CheckCreateGraphBitmap(gr, bmp, image);
556 }
557 #endif // wxUSE_GRAPHICS_DIRECT2D
558 #endif // __WXMSW__
559
560 #if wxUSE_CAIRO
561 SECTION("Cairo GC")
562 {
563 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
564 REQUIRE(gr != NULL);
565 CheckCreateGraphBitmap(gr, bmp, image);
566 }
567 #endif // wxUSE_GRAPHICS_CAIRO
568 }
569 }
570
571 TEST_CASE("GraphicsBitmapTestCase::SubBitmap", "[graphbitmap][subbitmap][create]")
572 {
573 SECTION("RGB bitmap without mask")
574 {
575 // RGB bitmap
576 wxBitmap bmp = CreateBitmapRGB(8, 8, false);
577 REQUIRE_FALSE(bmp.HasAlpha());
578 REQUIRE(bmp.GetMask() == NULL);
579
580 // Reference image
581 const int subX = 1;
582 const int subY = 1;
583 const int subW = 4;
584 const int subH = 5;
585 wxImage image = bmp.ConvertToImage().GetSubImage(wxRect(subX, subY, subW, subH));
586 REQUIRE_FALSE(image.HasAlpha());
587 REQUIRE_FALSE(image.HasMask());
588 REQUIRE(image.GetWidth() == subW);
589 REQUIRE(image.GetHeight() == subH);
590
591 SECTION("Default GC")
592 {
593 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
594 REQUIRE(gr != NULL);
595 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
596 }
597
598 #if defined(__WXMSW__)
599 #if wxUSE_GRAPHICS_GDIPLUS
600 SECTION("GDI+ GC")
601 {
602 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
603 REQUIRE(gr != NULL);
604 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
605 }
606 #endif // wxUSE_GRAPHICS_GDIPLUS
607
608 #if wxUSE_GRAPHICS_DIRECT2D
609 SECTION("Direct2D GC")
610 {
611 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
612 REQUIRE(gr != NULL);
613 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
614 }
615 #endif // wxUSE_GRAPHICS_DIRECT2D
616 #endif // __WXMSW__
617
618 #if wxUSE_CAIRO
619 SECTION("Cairo GC")
620 {
621 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
622 REQUIRE(gr != NULL);
623 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
624 }
625 #endif // wxUSE_GRAPHICS_CAIRO
626 }
627
628 SECTION("RGB bitmap with mask")
629 {
630 // RGB bitmap
631 wxBitmap bmp = CreateBitmapRGB(8, 8, true);
632 REQUIRE_FALSE(bmp.HasAlpha());
633 REQUIRE(bmp.GetMask() != NULL);
634
635 // Reference image
636 const int subX = 2;
637 const int subY = 2;
638 const int subW = 4;
639 const int subH = 5;
640 wxImage image = bmp.ConvertToImage().GetSubImage(wxRect(subX, subY, subW, subH));
641 REQUIRE_FALSE(image.HasAlpha());
642 REQUIRE(image.HasMask() == true);
643 REQUIRE(image.GetWidth() == subW);
644 REQUIRE(image.GetHeight() == subH);
645 const wxColour maskCol(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
646 REQUIRE(maskCol.IsOk());
647
648 SECTION("Default GC")
649 {
650 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
651 REQUIRE(gr != NULL);
652 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
653 }
654
655 #if defined(__WXMSW__)
656 #if wxUSE_GRAPHICS_GDIPLUS
657 SECTION("GDI+ GC")
658 {
659 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
660 REQUIRE(gr != NULL);
661 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
662 }
663 #endif // wxUSE_GRAPHICS_GDIPLUS
664
665 #if wxUSE_GRAPHICS_DIRECT2D
666 SECTION("Direct2D GC")
667 {
668 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
669 REQUIRE(gr != NULL);
670 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
671 }
672 #endif // wxUSE_GRAPHICS_DIRECT2D
673 #endif // __WXMSW__
674
675 #if wxUSE_CAIRO
676 SECTION("Cairo GC")
677 {
678 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
679 REQUIRE(gr != NULL);
680 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
681 }
682 #endif // wxUSE_GRAPHICS_CAIRO
683 }
684
685 #if defined(__WXMSW__) || defined(__WXOSX__)
686 SECTION("xRGB bitmap without mask")
687 {
688 // xRGB bitmap
689 wxBitmap bmp = CreateBitmapXRGB(8, 8, false);
690 REQUIRE(bmp.GetDepth() == 32);
691 REQUIRE_FALSE(bmp.HasAlpha());
692 REQUIRE(bmp.GetMask() == NULL);
693
694 // Reference image
695 const int subX = 1;
696 const int subY = 1;
697 const int subW = 4;
698 const int subH = 5;
699 wxImage image = bmp.ConvertToImage().GetSubImage(wxRect(subX, subY, subW, subH));
700 REQUIRE_FALSE(image.HasAlpha());
701 REQUIRE_FALSE(image.HasMask());
702 REQUIRE(image.GetWidth() == subW);
703 REQUIRE(image.GetHeight() == subH);
704
705 SECTION("Default GC")
706 {
707 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
708 REQUIRE(gr != NULL);
709 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
710 }
711
712 #if defined(__WXMSW__)
713 #if wxUSE_GRAPHICS_GDIPLUS
714 SECTION("GDI+ GC")
715 {
716 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
717 REQUIRE(gr != NULL);
718 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
719 }
720 #endif // wxUSE_GRAPHICS_GDIPLUS
721
722 #if wxUSE_GRAPHICS_DIRECT2D
723 SECTION("Direct2D GC")
724 {
725 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
726 REQUIRE(gr != NULL);
727 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
728 }
729 #endif // wxUSE_GRAPHICS_DIRECT2D
730 #endif // __WXMSW__
731
732 #if wxUSE_CAIRO
733 SECTION("Cairo GC")
734 {
735 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
736 REQUIRE(gr != NULL);
737 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
738 }
739 #endif // wxUSE_GRAPHICS_CAIRO
740 }
741
742 SECTION("xRGB bitmap with mask")
743 {
744 // xRGB bitmap
745 wxBitmap bmp = CreateBitmapXRGB(8, 8, true);
746 REQUIRE(bmp.GetDepth() == 32);
747 REQUIRE_FALSE(bmp.HasAlpha());
748 REQUIRE(bmp.GetMask() != NULL);
749
750 // Reference image
751 const int subX = 2;
752 const int subY = 2;
753 const int subW = 4;
754 const int subH = 5;
755 wxImage image = bmp.ConvertToImage().GetSubImage(wxRect(subX, subY, subW, subH));
756 REQUIRE_FALSE(image.HasAlpha());
757 REQUIRE(image.HasMask() == true);
758 REQUIRE(image.GetWidth() == subW);
759 REQUIRE(image.GetHeight() == subH);
760 const wxColour maskCol(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
761 REQUIRE(maskCol.IsOk());
762
763 // wxGraphicsBitmap doesn't have a mask so we need wxImage without mask
764 // to be compared with created wxGraphicsBitmap.
765 image.InitAlpha();
766 REQUIRE(image.HasAlpha() == true);
767 REQUIRE_FALSE(image.HasMask());
768 // We need also to remove mask colour from transparent pixels
769 // for compatibility with wxGraphicsMask.
770 for ( int y = 0; y < image.GetHeight(); y++ )
771 for ( int x = 0; x < image.GetWidth(); x++ )
772 {
773 if ( image.GetAlpha(x, y) == wxALPHA_TRANSPARENT )
774 {
775 image.SetRGB(x, y, 0, 0, 0);
776 }
777 }
778
779 SECTION("Default GC")
780 {
781 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
782 REQUIRE(gr != NULL);
783 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
784 }
785
786 #if defined(__WXMSW__)
787 #if wxUSE_GRAPHICS_GDIPLUS
788 SECTION("GDI+ GC")
789 {
790 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
791 REQUIRE(gr != NULL);
792 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
793 }
794 #endif // wxUSE_GRAPHICS_GDIPLUS
795
796 #if wxUSE_GRAPHICS_DIRECT2D
797 SECTION("Direct2D GC")
798 {
799 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
800 REQUIRE(gr != NULL);
801 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
802 }
803 #endif // wxUSE_GRAPHICS_DIRECT2D
804 #endif // __WXMSW__
805
806 #if wxUSE_CAIRO
807 SECTION("Cairo GC")
808 {
809 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
810 REQUIRE(gr != NULL);
811 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
812 }
813 #endif // wxUSE_GRAPHICS_CAIRO
814 }
815 #endif // __WXMSW__ || __WXOSX__
816
817 SECTION("RGBA bitmap without mask")
818 {
819 // RGBA Bitmap
820 wxBitmap bmp = CreateBitmapRGBA(8, 8, false);
821 REQUIRE(bmp.HasAlpha() == true);
822 REQUIRE(bmp.GetMask() == NULL);
823
824 // Reference image
825 const int subX = 2;
826 const int subY = 2;
827 const int subW = 4;
828 const int subH = 5;
829 wxImage image = bmp.ConvertToImage().GetSubImage(wxRect(subX, subY, subW, subH));
830 REQUIRE(image.HasAlpha() == true);
831 REQUIRE_FALSE(image.HasMask());
832 REQUIRE(image.GetWidth() == subW);
833 REQUIRE(image.GetHeight() == subH);
834
835 SECTION("Default GC")
836 {
837 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
838 REQUIRE(gr != NULL);
839 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
840 }
841
842 #if defined(__WXMSW__)
843 #if wxUSE_GRAPHICS_GDIPLUS
844 SECTION("GDI+ GC")
845 {
846 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
847 REQUIRE(gr != NULL);
848 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
849 }
850 #endif // wxUSE_GRAPHICS_GDIPLUS
851
852 #if wxUSE_GRAPHICS_DIRECT2D
853 SECTION("Direct2D GC")
854 {
855 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
856 REQUIRE(gr != NULL);
857 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
858 }
859 #endif // wxUSE_GRAPHICS_DIRECT2D
860 #endif // __WXMSW__
861
862 #if wxUSE_CAIRO
863 SECTION("Cairo GC")
864 {
865 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
866 REQUIRE(gr != NULL);
867 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
868 }
869 #endif // wxUSE_GRAPHICS_CAIRO
870 }
871
872 SECTION("RGBA bitmap with mask")
873 {
874 // RGBA Bitmap
875 wxBitmap bmp = CreateBitmapRGBA(8, 8, true);
876 REQUIRE(bmp.HasAlpha() == true);
877 REQUIRE(bmp.GetMask() != NULL);
878
879 // Reference image
880 const int subX = 2;
881 const int subY = 2;
882 const int subW = 4;
883 const int subH = 5;
884 wxImage image = bmp.ConvertToImage().GetSubImage(wxRect(subX, subY, subW, subH));
885 REQUIRE(image.HasAlpha() == true);
886 REQUIRE(image.HasMask() == true);
887 REQUIRE(image.GetWidth() == subW);
888 REQUIRE(image.GetHeight() == subH);
889 const wxColour maskCol(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
890 REQUIRE(maskCol.IsOk());
891
892 SECTION("Default GC")
893 {
894 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
895 REQUIRE(gr != NULL);
896 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
897 }
898
899 #if defined(__WXMSW__)
900 #if wxUSE_GRAPHICS_GDIPLUS
901 SECTION("GDI+ GC")
902 {
903 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
904 REQUIRE(gr != NULL);
905 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
906 }
907 #endif // wxUSE_GRAPHICS_GDIPLUS
908
909 #if wxUSE_GRAPHICS_DIRECT2D
910 SECTION("Direct2D GC")
911 {
912 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
913 REQUIRE(gr != NULL);
914 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
915 }
916 #endif // wxUSE_GRAPHICS_DIRECT2D
917 #endif // __WXMSW__
918
919 #if wxUSE_CAIRO
920 SECTION("Cairo GC")
921 {
922 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
923 REQUIRE(gr != NULL);
924 CheckCreateGraphSubBitmap(gr, bmp, subX, subY, subW, subH, image);
925 }
926 #endif // wxUSE_GRAPHICS_CAIRO
927 }
928 }
929
930 TEST_CASE("GraphicsBitmapTestCase::CreateFromImage", "[graphbitmap][create][fromimage]")
931 {
932 const wxColour maskCol(*wxRED);
933 const wxColour fillCol(*wxGREEN);
934
935 SECTION("RGB image without mask")
936 {
937 wxImage img(4, 4);
938 for ( int y = 0; y < img.GetHeight(); y++ )
939 for ( int x = 0; x < img.GetWidth(); x++ )
940 {
941 if ( x < img.GetWidth() / 2 )
942 img.SetRGB(x, y, maskCol.Red(), maskCol.Green(), maskCol.Blue());
943 else
944 img.SetRGB(x, y, fillCol.Red(), fillCol.Green(), fillCol.Blue());
945 }
946 REQUIRE_FALSE(img.HasAlpha());
947 REQUIRE_FALSE(img.HasMask());
948
949 SECTION("Default GC")
950 {
951 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
952 REQUIRE(gr != NULL);
953 CheckCreateGraphBitmapFromImage(gr, img);
954 }
955
956 #if defined(__WXMSW__)
957 #if wxUSE_GRAPHICS_GDIPLUS
958 SECTION("GDI+ GC")
959 {
960 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
961 REQUIRE(gr != NULL);
962 CheckCreateGraphBitmapFromImage(gr, img);
963 }
964 #endif // wxUSE_GRAPHICS_GDIPLUS
965
966 #if wxUSE_GRAPHICS_DIRECT2D
967 SECTION("Direct2D GC")
968 {
969 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
970 REQUIRE(gr != NULL);
971 CheckCreateGraphBitmapFromImage(gr, img);
972 }
973 #endif // wxUSE_GRAPHICS_DIRECT2D
974 #endif // __WXMSW__
975
976 #if wxUSE_CAIRO
977 SECTION("Cairo GC")
978 {
979 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
980 REQUIRE(gr != NULL);
981 CheckCreateGraphBitmapFromImage(gr, img);
982 }
983 #endif // wxUSE_GRAPHICS_CAIRO
984 }
985
986 SECTION("RGB image with mask")
987 {
988 wxImage img(4, 4);
989 for ( int y = 0; y < img.GetHeight(); y++ )
990 for ( int x = 0; x < img.GetWidth(); x++ )
991 {
992 if ( x < img.GetWidth() / 2 )
993 img.SetRGB(x, y, maskCol.Red(), maskCol.Green(), maskCol.Blue());
994 else
995 img.SetRGB(x, y, fillCol.Red(), fillCol.Green(), fillCol.Blue());
996 }
997 img.SetMaskColour(maskCol.Red(), maskCol.Green(), maskCol.Blue());
998 REQUIRE_FALSE(img.HasAlpha());
999 REQUIRE(img.HasMask() == true);
1000
1001 SECTION("Default GC")
1002 {
1003 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
1004 REQUIRE(gr != NULL);
1005 CheckCreateGraphBitmapFromImage(gr, img);
1006 }
1007
1008 #if defined(__WXMSW__)
1009 #if wxUSE_GRAPHICS_GDIPLUS
1010 SECTION("GDI+ GC")
1011 {
1012 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
1013 REQUIRE(gr != NULL);
1014 CheckCreateGraphBitmapFromImage(gr, img);
1015 }
1016 #endif // wxUSE_GRAPHICS_GDIPLUS
1017
1018 #if wxUSE_GRAPHICS_DIRECT2D
1019 SECTION("Direct2D GC")
1020 {
1021 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
1022 REQUIRE(gr != NULL);
1023 CheckCreateGraphBitmapFromImage(gr, img);
1024 }
1025 #endif // wxUSE_GRAPHICS_DIRECT2D
1026 #endif // __WXMSW__
1027
1028 #if wxUSE_CAIRO
1029 SECTION("Cairo GC")
1030 {
1031 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
1032 REQUIRE(gr != NULL);
1033 CheckCreateGraphBitmapFromImage(gr, img);
1034 }
1035 #endif // wxUSE_GRAPHICS_CAIRO
1036 }
1037
1038 SECTION("RGBA image without mask")
1039 {
1040 wxImage img(4, 4);
1041 img.SetAlpha();
1042 for ( int y = 0; y < img.GetHeight(); y++ )
1043 for ( int x = 0; x < img.GetWidth(); x++ )
1044 {
1045 if ( x < img.GetWidth() / 2 )
1046 img.SetRGB(x, y, maskCol.Red(), maskCol.Green(), maskCol.Blue());
1047 else
1048 img.SetRGB(x, y, fillCol.Red(), fillCol.Green(), fillCol.Blue());
1049
1050 if ( y < img.GetHeight() / 2 )
1051 img.SetAlpha(x, y, 128);
1052 else
1053 img.SetAlpha(x, y, 0);
1054 }
1055 REQUIRE(img.HasAlpha() == true);
1056 REQUIRE_FALSE(img.HasMask());
1057
1058 SECTION("Default GC")
1059 {
1060 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
1061 REQUIRE(gr != NULL);
1062 CheckCreateGraphBitmapFromImage(gr, img);
1063 }
1064
1065 #if defined(__WXMSW__)
1066 #if wxUSE_GRAPHICS_GDIPLUS
1067 SECTION("GDI+ GC")
1068 {
1069 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
1070 REQUIRE(gr != NULL);
1071 CheckCreateGraphBitmapFromImage(gr, img);
1072 }
1073 #endif // wxUSE_GRAPHICS_GDIPLUS
1074
1075 #if wxUSE_GRAPHICS_DIRECT2D
1076 SECTION("Direct2D GC")
1077 {
1078 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
1079 REQUIRE(gr != NULL);
1080 CheckCreateGraphBitmapFromImage(gr, img);
1081 }
1082 #endif // wxUSE_GRAPHICS_DIRECT2D
1083 #endif // __WXMSW__
1084
1085 #if wxUSE_CAIRO
1086 SECTION("Cairo GC")
1087 {
1088 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
1089 REQUIRE(gr != NULL);
1090 CheckCreateGraphBitmapFromImage(gr, img);
1091 }
1092 #endif // wxUSE_GRAPHICS_CAIRO
1093 }
1094
1095 SECTION("RGBA image with mask")
1096 {
1097 wxImage img(4, 4);
1098 img.SetAlpha();
1099 for ( int y = 0; y < img.GetHeight(); y++ )
1100 for ( int x = 0; x < img.GetWidth(); x++ )
1101 {
1102 if ( x < img.GetWidth() / 2 )
1103 img.SetRGB(x, y, maskCol.Red(), maskCol.Green(), maskCol.Blue());
1104 else
1105 img.SetRGB(x, y, fillCol.Red(), fillCol.Green(), fillCol.Blue());
1106
1107 if ( y < img.GetHeight() / 2 )
1108 img.SetAlpha(x, y, 128);
1109 else
1110 img.SetAlpha(x, y, 0);
1111 }
1112 img.SetMaskColour(maskCol.Red(), maskCol.Green(), maskCol.Blue());
1113 REQUIRE(img.HasAlpha() == true);
1114 REQUIRE(img.HasMask() == true);
1115
1116 SECTION("Default GC")
1117 {
1118 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDefaultRenderer();
1119 REQUIRE(gr != NULL);
1120 CheckCreateGraphBitmapFromImage(gr, img);
1121 }
1122
1123 #if defined(__WXMSW__)
1124 #if wxUSE_GRAPHICS_GDIPLUS
1125 SECTION("GDI+ GC")
1126 {
1127 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetGDIPlusRenderer();
1128 REQUIRE(gr != NULL);
1129 CheckCreateGraphBitmapFromImage(gr, img);
1130 }
1131 #endif // wxUSE_GRAPHICS_GDIPLUS
1132
1133 #if wxUSE_GRAPHICS_DIRECT2D
1134 SECTION("Direct2D GC")
1135 {
1136 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetDirect2DRenderer();
1137 REQUIRE(gr != NULL);
1138 CheckCreateGraphBitmapFromImage(gr, img);
1139 }
1140 #endif // wxUSE_GRAPHICS_DIRECT2D
1141 #endif // __WXMSW__
1142
1143 #if wxUSE_CAIRO
1144 SECTION("Cairo GC")
1145 {
1146 wxGraphicsRenderer* gr = wxGraphicsRenderer::GetCairoRenderer();
1147 REQUIRE(gr != NULL);
1148 CheckCreateGraphBitmapFromImage(gr, img);
1149 }
1150 #endif // wxUSE_GRAPHICS_CAIRO
1151 }
1152 }
1153 #endif // wxUSE_GRAPHICS_CONTEXT
1154
1155 #endif // wxHAS_RAW_BITMAP
1156