milligram
Revision | 95a1138b2c84848686b704a4f0939e77733b2ae2 (tree) |
---|---|
Time | 2011-03-17 17:12:25 |
Author | beru <berupon@gmai...> |
Commiter | beru |
implemented part of BitBlt function
@@ -0,0 +1,60 @@ | ||
1 | +#include "stdafx.h" | |
2 | +#include "File.h" | |
3 | + | |
4 | +#include <io.h> | |
5 | +#include <assert.h> | |
6 | +#include <memory.h> | |
7 | +#include <stdio.h> | |
8 | + | |
9 | +#include <windows.h> | |
10 | + | |
11 | +File::File(HANDLE hFile) | |
12 | + : | |
13 | + hFile_(hFile) | |
14 | +{ | |
15 | +} | |
16 | + | |
17 | +File::File(FILE* pFile) | |
18 | +{ | |
19 | + hFile_ = (HANDLE) _get_osfhandle(_fileno(pFile)); | |
20 | +} | |
21 | + | |
22 | +bool File::Read(void* pBuffer, size_t nNumberOfBytesToRead, size_t& nNumberOfBytesRead) | |
23 | +{ | |
24 | + return ReadFile(hFile_, pBuffer, nNumberOfBytesToRead, (LPDWORD)&nNumberOfBytesRead, NULL); | |
25 | +} | |
26 | + | |
27 | +bool File::Write(const void* pBuffer, size_t nNumberOfBytesToWrite, size_t& nNumberOfBytesWritten) | |
28 | +{ | |
29 | + return WriteFile(hFile_, pBuffer, nNumberOfBytesToWrite, (LPDWORD)&nNumberOfBytesWritten, NULL); | |
30 | +} | |
31 | + | |
32 | +size_t File::Seek(long lDistanceToMove, size_t dwMoveMethod) | |
33 | +{ | |
34 | + return SetFilePointer(hFile_, lDistanceToMove, NULL, dwMoveMethod); | |
35 | +} | |
36 | + | |
37 | +size_t File::Tell() const | |
38 | +{ | |
39 | + /* | |
40 | + -- Reference -- | |
41 | + http://nukz.net/reference/fileio/hh/winbase/filesio_3vhu.htm | |
42 | + */ | |
43 | + return SetFilePointer( | |
44 | + hFile_, // must have GENERIC_READ and/or GENERIC_WRITE | |
45 | + 0, // do not move pointer | |
46 | + NULL, // hFile is not large enough to need this pointer | |
47 | + FILE_CURRENT | |
48 | + ); // provides offset from current position | |
49 | +} | |
50 | + | |
51 | +size_t File::Size() const | |
52 | +{ | |
53 | + return GetFileSize(hFile_, NULL); | |
54 | +} | |
55 | + | |
56 | +bool File::Flush() | |
57 | +{ | |
58 | + return FlushFileBuffers(hFile_); | |
59 | +} | |
60 | + |
@@ -0,0 +1,33 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include "IFile.h" | |
4 | + | |
5 | +#include <windows.h> | |
6 | +#include <stdio.h> | |
7 | + | |
8 | +class File : public IFile | |
9 | +{ | |
10 | +public: | |
11 | + File(HANDLE hFile); | |
12 | + | |
13 | + File(FILE* pFile); | |
14 | + | |
15 | + bool Read(void* pBuffer, size_t nNumberOfBytesToRead, size_t& nNumberOfBytesRead); | |
16 | + | |
17 | + bool Write(const void* pBuffer, size_t nNumberOfBytesToWrite, size_t& nNumberOfBytesWritten); | |
18 | + | |
19 | + size_t Seek(long lDistanceToMove, size_t dwMoveMethod); | |
20 | + | |
21 | + size_t Tell() const; | |
22 | + | |
23 | + size_t Size() const; | |
24 | + | |
25 | + bool Flush(); | |
26 | + | |
27 | + bool HasBuffer() const { return false; } | |
28 | + virtual const void* GetBuffer() const { return 0; } | |
29 | + | |
30 | +private: | |
31 | + HANDLE hFile_; | |
32 | +}; | |
33 | + |
@@ -0,0 +1,33 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +/*! | |
4 | + | |
5 | +概要 | |
6 | + 画像の入出力用に仮想的にFileを扱えるようにする | |
7 | + | |
8 | +制限 | |
9 | + 非同期操作には対応しない | |
10 | + 2GBまで | |
11 | + | |
12 | +備考 | |
13 | + CxImage by Davide Pizzolato (http://www.xdp.it/cximage.htm) を参考にしました。 | |
14 | + | |
15 | + InterfaceをWindowsAPIのFile関数に似せています | |
16 | + | |
17 | +*/ | |
18 | + | |
19 | +class IFile | |
20 | +{ | |
21 | +public: | |
22 | + virtual bool Read(void* pBuffer, size_t nNumberOfBytesToRead, size_t& nNumberOfBytesRead) = 0; | |
23 | + virtual bool Write(const void* pBuffer, size_t nNumberOfBytesToWrite, size_t& nNumberOfBytesWritten) = 0; | |
24 | + virtual size_t Seek(long lDistanceToMove, size_t dwMoveMethod) = 0; | |
25 | + virtual size_t Tell() const = 0; | |
26 | + virtual size_t Size() const = 0; | |
27 | + virtual bool IsEof() const { return Tell() == Size(); } | |
28 | + virtual bool Flush() = 0; | |
29 | + | |
30 | + virtual bool HasBuffer() const = 0; | |
31 | + virtual const void* GetBuffer() const = 0; | |
32 | +}; | |
33 | + |
@@ -0,0 +1,126 @@ | ||
1 | +#include "stdafx.h" | |
2 | + | |
3 | +#include "ReadImage.h" | |
4 | +#include "arrayutil.h" | |
5 | + | |
6 | +//#define TRACE printf | |
7 | +#define TRACE OutputDebugStringA | |
8 | +#include <assert.h> | |
9 | + | |
10 | +#include <windows.h> | |
11 | + | |
12 | +bool Read_BITMAPINFOHEADER(IFile& file, BITMAPINFOHEADER& bmih) | |
13 | +{ | |
14 | + size_t fileSize = file.Size(); | |
15 | + if (fileSize <= 54) { | |
16 | + TRACE("file size <= 54 bytes."); | |
17 | + return false; | |
18 | + } | |
19 | + BITMAPFILEHEADER bmpFileHeader; | |
20 | + size_t readBytes = 0; | |
21 | + file.Read(&bmpFileHeader, 14, readBytes); | |
22 | + assert(readBytes == 14); | |
23 | + if (bmpFileHeader.bfType != 19778) { | |
24 | + TRACE("file hedear bfType != 19778"); | |
25 | + return false; | |
26 | + } | |
27 | + | |
28 | + file.Read(&bmih, 40, readBytes); | |
29 | + if (readBytes != 40) { | |
30 | + TRACE("bmih shortage."); | |
31 | + return false; | |
32 | + } | |
33 | + | |
34 | + return true; | |
35 | +} | |
36 | + | |
37 | +bool ReadImageInfo_BMP(IFile& file, ImageInfo& info) | |
38 | +{ | |
39 | + BITMAPINFOHEADER bmih; | |
40 | + if (!Read_BITMAPINFOHEADER(file, bmih)) { | |
41 | + return false; | |
42 | + } | |
43 | + info.width = bmih.biWidth; | |
44 | + info.height = bmih.biHeight; | |
45 | + switch (bmih.biBitCount) { | |
46 | + case 1: | |
47 | + case 4: | |
48 | + case 8: | |
49 | + info.samplesPerPixel = 1; | |
50 | + break; | |
51 | + case 16: | |
52 | + case 24: | |
53 | + info.samplesPerPixel = 3; | |
54 | + break; | |
55 | + case 32: | |
56 | + info.samplesPerPixel = 4; | |
57 | + break; | |
58 | + } | |
59 | + info.bitsPerSample = 8; | |
60 | + return true; | |
61 | +} | |
62 | + | |
63 | +bool ReadImageData_BMP(IFile& file, unsigned char* dest, int lineOffset, void* palettes) | |
64 | +{ | |
65 | + file.Seek(0, FILE_BEGIN); | |
66 | + BITMAPINFOHEADER bmih; | |
67 | + if (!Read_BITMAPINFOHEADER(file, bmih)) { | |
68 | + return false; | |
69 | + } | |
70 | + size_t bmiColorsLen = 0; | |
71 | + switch (bmih.biBitCount) { | |
72 | + case 1: | |
73 | + bmiColorsLen = 2; | |
74 | + break; | |
75 | + case 4: | |
76 | + bmiColorsLen = 16; | |
77 | + break; | |
78 | + case 8: | |
79 | + bmiColorsLen = 256; | |
80 | + break; | |
81 | + case 16: | |
82 | + TRACE("16 bit BMP not supported."); | |
83 | + return false; | |
84 | + break; | |
85 | + case 32: | |
86 | + if (bmih.biCompression == BI_BITFIELDS) { | |
87 | + bmiColorsLen = 3; | |
88 | + } | |
89 | + } | |
90 | + size_t readBytes = 0; | |
91 | + if (bmiColorsLen) { | |
92 | + size_t needBytes = /*sizeof(RGBQUAD)*/4*bmiColorsLen; | |
93 | + file.Read(palettes, needBytes, readBytes); | |
94 | + if (readBytes != needBytes) { | |
95 | + TRACE("bmiColors read failed."); | |
96 | + return false; | |
97 | + } | |
98 | + } | |
99 | + const int lineBytes = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) >> 3); | |
100 | + const int lineIdx = (bmih.biHeight < 0) ? 0 : (bmih.biHeight-1); | |
101 | + OffsetPtr(dest, lineOffset * lineIdx); | |
102 | + lineOffset *= (bmih.biHeight < 0) ? 1 : -1; | |
103 | + | |
104 | + const size_t height = abs(bmih.biHeight); | |
105 | + for (size_t y=0; y<height; ++y) { | |
106 | + file.Read(dest, lineBytes, readBytes); | |
107 | + if (readBytes != lineBytes) { | |
108 | + TRACE("read bytes != lineBytes."); | |
109 | + return false; | |
110 | + } | |
111 | + OffsetPtr(dest, lineOffset); | |
112 | + } | |
113 | + | |
114 | + return true; | |
115 | +} | |
116 | + | |
117 | +bool ReadImageInfo(IFile& file, ImageInfo& info) | |
118 | +{ | |
119 | + return ReadImageInfo_BMP(file, info); | |
120 | +} | |
121 | + | |
122 | +bool ReadImageData(IFile& file, unsigned char* dest, int lineOffset, void* palettes) | |
123 | +{ | |
124 | + return ReadImageData_BMP(file, dest, lineOffset, palettes); | |
125 | +} | |
126 | + |
@@ -0,0 +1,15 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include "IFile.h" | |
4 | + | |
5 | +struct ImageInfo | |
6 | +{ | |
7 | + size_t width; | |
8 | + size_t height; | |
9 | + size_t bitsPerSample; | |
10 | + size_t samplesPerPixel; | |
11 | +}; | |
12 | + | |
13 | +bool ReadImageInfo(IFile& file, ImageInfo& info); | |
14 | +bool ReadImageData(IFile& file, unsigned char* dest, int lineOffset, void* palettes); | |
15 | + |
@@ -0,0 +1,37 @@ | ||
1 | +#include "stdafx.h" | |
2 | + | |
3 | +#include "winutil.h" | |
4 | + | |
5 | +HBITMAP CreateDIB(int width, int height, int bitsPerPixel, BITMAPINFO& bmi, void*& pBits) | |
6 | +{ | |
7 | + assert(bitsPerPixel % 8 == 0); | |
8 | + int bytesPerPixel = bitsPerPixel / 8; | |
9 | + assert(bytesPerPixel <= 4); | |
10 | + if (width % 4) { | |
11 | + width += 4 - (width % 4); | |
12 | + } | |
13 | + assert(width % 4 == 0); | |
14 | + BITMAPINFOHEADER& header = bmi.bmiHeader; | |
15 | + header.biSize = sizeof(BITMAPINFOHEADER); | |
16 | + header.biWidth = width; | |
17 | + header.biHeight = height; | |
18 | + header.biPlanes = 1; | |
19 | + header.biBitCount = bitsPerPixel; | |
20 | + header.biCompression = BI_RGB; | |
21 | + header.biSizeImage = width * abs(height) * bytesPerPixel; | |
22 | + header.biXPelsPerMeter = 0; | |
23 | + header.biYPelsPerMeter = 0; | |
24 | + header.biClrUsed = 0; | |
25 | + header.biClrImportant = 0; | |
26 | + | |
27 | + return ::CreateDIBSection( | |
28 | + (HDC)0, | |
29 | + &bmi, | |
30 | + DIB_RGB_COLORS, | |
31 | + &pBits, | |
32 | + NULL, | |
33 | + 0 | |
34 | + ); | |
35 | +} | |
36 | + | |
37 | + |
@@ -0,0 +1,3 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +HBITMAP CreateDIB(int width, int height, int bitsPerPixel, BITMAPINFO& bmi, void*& pBits); |
@@ -10,6 +10,10 @@ | ||
10 | 10 | #include "mg/container.h" |
11 | 11 | #include "mg/button.h" |
12 | 12 | |
13 | +#include "winutil.h" | |
14 | +#include "ReadImage/File.h" | |
15 | +#include "ReadImage/ReadImage.h" | |
16 | + | |
13 | 17 | namespace { |
14 | 18 | |
15 | 19 | HWND hWnd; |
@@ -26,38 +30,10 @@ MG::Container mg(elements, 128); | ||
26 | 30 | MG::Button button1; |
27 | 31 | MG::Button button2; |
28 | 32 | |
29 | -HBITMAP CreateDIB(int width, int height, int bitsPerPixel, BITMAPINFO& bmi, void*& pBits) | |
30 | -{ | |
31 | - assert(bitsPerPixel % 8 == 0); | |
32 | - int bytesPerPixel = bitsPerPixel / 8; | |
33 | - assert(bytesPerPixel <= 4); | |
34 | - if (width % 4) { | |
35 | - width += 4 - (width % 4); | |
36 | - } | |
37 | - assert(width % 4 == 0); | |
38 | - BITMAPINFOHEADER& header = bmi.bmiHeader; | |
39 | - header.biSize = sizeof(BITMAPINFOHEADER); | |
40 | - header.biWidth = width; | |
41 | - header.biHeight = height; | |
42 | - header.biPlanes = 1; | |
43 | - header.biBitCount = bitsPerPixel; | |
44 | - header.biCompression = BI_RGB; | |
45 | - header.biSizeImage = width * abs(height) * bytesPerPixel; | |
46 | - header.biXPelsPerMeter = 0; | |
47 | - header.biYPelsPerMeter = 0; | |
48 | - header.biClrUsed = 0; | |
49 | - header.biClrImportant = 0; | |
50 | - | |
51 | - return ::CreateDIBSection( | |
52 | - (HDC)0, | |
53 | - &bmi, | |
54 | - DIB_RGB_COLORS, | |
55 | - &pBits, | |
56 | - NULL, | |
57 | - 0 | |
58 | - ); | |
59 | -} | |
60 | - | |
33 | +std::vector<uint8_t> imageBuffer; | |
34 | +MG::Bitmap bmpContent; | |
35 | +MG::Element pic1; | |
36 | +MG::Element pic2; | |
61 | 37 | |
62 | 38 | } // anonymous namespace |
63 | 39 |
@@ -115,6 +91,51 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) | ||
115 | 91 | rect.h = 50; |
116 | 92 | button2.rect = rect; |
117 | 93 | mg.Add(button2); |
94 | + | |
95 | + // read content | |
96 | + { | |
97 | + FILE* file = fopen("test.bmp", "r"); | |
98 | + assert(file); | |
99 | + if (!file) { | |
100 | + return; | |
101 | + } | |
102 | + File fileProxy(file); | |
103 | + ImageInfo imageInfo; | |
104 | + ReadImageInfo(fileProxy, imageInfo); | |
105 | + assert(imageInfo.bitsPerSample == 8 && imageInfo.samplesPerPixel == 3); | |
106 | + imageBuffer.resize(imageInfo.width * imageInfo.height * imageInfo.samplesPerPixel); | |
107 | + int lineOffsetBytes = imageInfo.width * imageInfo.samplesPerPixel; | |
108 | + ReadImageData(fileProxy, &imageBuffer[0], lineOffsetBytes, 0); | |
109 | + fclose(file); | |
110 | + bmpContent.bitsPerPixel = imageInfo.bitsPerSample * imageInfo.samplesPerPixel; | |
111 | + bmpContent.width = imageInfo.width; | |
112 | + bmpContent.height = imageInfo.height; | |
113 | + bmpContent.lineOffsetBytes = lineOffsetBytes; | |
114 | + bmpContent.pBits = &imageBuffer[0]; | |
115 | + } | |
116 | + rect.x = 100; | |
117 | + rect.y = 300; | |
118 | + pic1.rect = rect; | |
119 | + MG::Rectangle irec; | |
120 | + irec.x = irec.y = 0; | |
121 | + irec.w = 400; | |
122 | + irec.h = 400; | |
123 | + pic1.bg.image.rect = irec; | |
124 | + pic1.bg.image.pBitmap = &bmpContent; | |
125 | + pic1.needsToDraw = true; | |
126 | + mg.Add(pic1); | |
127 | + | |
128 | + rect.x = 300; | |
129 | + rect.y = 200; | |
130 | + rect.w = 300; | |
131 | + rect.h = 300; | |
132 | + pic2.rect = rect; | |
133 | + pic2.bg = pic1.bg; | |
134 | + irec.x = 510; | |
135 | + irec.y = 340; | |
136 | + pic2.bg.image.rect = irec; | |
137 | + pic2.needsToDraw = true; | |
138 | + mg.Add(pic2); | |
118 | 139 | |
119 | 140 | HDC hWndDC = ::GetDC(hWnd); |
120 | 141 | hMemDC = ::CreateCompatibleDC(hWndDC); |
@@ -42,7 +42,7 @@ | ||
42 | 42 | Name="VCCLCompilerTool" |
43 | 43 | Optimization="0" |
44 | 44 | AdditionalIncludeDirectories="./;./common/" |
45 | - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS" | |
45 | + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS" | |
46 | 46 | MinimalRebuild="true" |
47 | 47 | BasicRuntimeChecks="3" |
48 | 48 | RuntimeLibrary="3" |
@@ -116,7 +116,7 @@ | ||
116 | 116 | Optimization="2" |
117 | 117 | EnableIntrinsicFunctions="true" |
118 | 118 | AdditionalIncludeDirectories="./;./common/" |
119 | - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS" | |
119 | + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS" | |
120 | 120 | RuntimeLibrary="2" |
121 | 121 | EnableFunctionLevelLinking="true" |
122 | 122 | UsePrecompiledHeader="2" |
@@ -320,6 +320,38 @@ | ||
320 | 320 | RelativePath=".\common\stdint.h" |
321 | 321 | > |
322 | 322 | </File> |
323 | + <File | |
324 | + RelativePath=".\common\winutil.cpp" | |
325 | + > | |
326 | + </File> | |
327 | + <File | |
328 | + RelativePath=".\common\winutil.h" | |
329 | + > | |
330 | + </File> | |
331 | + </Filter> | |
332 | + <Filter | |
333 | + Name="ReadImage" | |
334 | + > | |
335 | + <File | |
336 | + RelativePath=".\ReadImage\File.cpp" | |
337 | + > | |
338 | + </File> | |
339 | + <File | |
340 | + RelativePath=".\ReadImage\File.h" | |
341 | + > | |
342 | + </File> | |
343 | + <File | |
344 | + RelativePath=".\ReadImage\IFile.h" | |
345 | + > | |
346 | + </File> | |
347 | + <File | |
348 | + RelativePath=".\ReadImage\ReadImage.cpp" | |
349 | + > | |
350 | + </File> | |
351 | + <File | |
352 | + RelativePath=".\ReadImage\ReadImage.h" | |
353 | + > | |
354 | + </File> | |
323 | 355 | </Filter> |
324 | 356 | <File |
325 | 357 | RelativePath=".\ReadMe.txt" |
@@ -1,6 +1,7 @@ | ||
1 | 1 | #include "stdafx.h" |
2 | 2 | |
3 | 3 | #include "bitmap.h" |
4 | +#include "arrayutil.h" | |
4 | 5 | |
5 | 6 | namespace MG { |
6 | 7 |
@@ -14,6 +15,63 @@ Rectangle Bitmap::GetRect() const | ||
14 | 15 | return ret; |
15 | 16 | } |
16 | 17 | |
18 | +void BitBlt_Src8_Dst24( | |
19 | + const Bitmap& src, const Rectangle& srcRect, | |
20 | + Bitmap& dst, const Rectangle& dstRect | |
21 | + ) | |
22 | +{ | |
23 | +} | |
24 | + | |
25 | +void BitBlt_Src8_Dst32( | |
26 | + const Bitmap& src, const Rectangle& srcRect, | |
27 | + Bitmap& dst, const Rectangle& dstRect | |
28 | + ) | |
29 | +{ | |
30 | +} | |
31 | + | |
32 | +void BitBlt_Src24_Dst24( | |
33 | + const Bitmap& src, const Rectangle& srcRect, | |
34 | + Bitmap& dst, const Rectangle& dstRect | |
35 | + ) | |
36 | +{ | |
37 | + const uint8_t* pSrc = (const uint8_t*) src.pBits; | |
38 | + OffsetPtr(pSrc, src.lineOffsetBytes * srcRect.y); | |
39 | + pSrc += 3 * srcRect.x; | |
40 | + | |
41 | + uint8_t* pDst = (uint8_t*) dst.pBits; | |
42 | + OffsetPtr(pDst, dst.lineOffsetBytes * dstRect.y); | |
43 | + pDst += 3 * dstRect.x; | |
44 | + | |
45 | + for (size_t y=0; y<dstRect.h; ++y) { | |
46 | + for (size_t x=0; x<dstRect.w * 3; ++x) { | |
47 | + pDst[x] = pSrc[x]; | |
48 | + } | |
49 | + OffsetPtr(pSrc, src.lineOffsetBytes); | |
50 | + OffsetPtr(pDst, dst.lineOffsetBytes); | |
51 | + } | |
52 | +} | |
53 | + | |
54 | +void BitBlt_Src24_Dst32( | |
55 | + const Bitmap& src, const Rectangle& srcRect, | |
56 | + Bitmap& dst, const Rectangle& dstRect | |
57 | + ) | |
58 | +{ | |
59 | +} | |
60 | + | |
61 | +void BitBlt_Src32_Dst24( | |
62 | + const Bitmap& src, const Rectangle& srcRect, | |
63 | + Bitmap& dst, const Rectangle& dstRect | |
64 | + ) | |
65 | +{ | |
66 | +} | |
67 | + | |
68 | +void BitBlt_Src32_Dst32( | |
69 | + const Bitmap& src, const Rectangle& srcRect, | |
70 | + Bitmap& dst, const Rectangle& dstRect | |
71 | + ) | |
72 | +{ | |
73 | +} | |
74 | + | |
17 | 75 | Rectangle BitBlt( |
18 | 76 | const Bitmap& src, const Rectangle& srcRect, |
19 | 77 | Bitmap& dst, const Rectangle& dstRect |
@@ -26,24 +84,46 @@ Rectangle BitBlt( | ||
26 | 84 | Rectangle dbr = dst.GetRect(); |
27 | 85 | dbr.Intersect(dstRect); |
28 | 86 | |
87 | + Rectangle sbr2 = sbr; | |
88 | + sbr2.x = dbr.x; | |
89 | + sbr2.y = dbr.y; | |
90 | + dbr.Intersect(sbr2); | |
91 | + | |
29 | 92 | assert(dst.bitsPerPixel == 24 || dst.bitsPerPixel == 32); |
30 | - if (src.bitsPerPixel == dst.bitsPerPixel) { | |
31 | - ; | |
32 | - }else { | |
33 | - switch (src.bitsPerPixel) { | |
34 | - case 8: | |
35 | - | |
93 | + switch (src.bitsPerPixel) { | |
94 | + case 8: | |
95 | + switch (dst.bitsPerPixel) { | |
96 | + case 24: | |
97 | + BitBlt_Src8_Dst24(src, sbr, dst, dbr); | |
98 | + break; | |
99 | + case 32: | |
100 | + BitBlt_Src8_Dst32(src, sbr, dst, dbr); | |
101 | + break; | |
102 | + } | |
103 | + break; | |
104 | + case 24: | |
105 | + switch (dst.bitsPerPixel) { | |
106 | + case 24: | |
107 | + BitBlt_Src24_Dst24(src, sbr, dst, dbr); | |
108 | + break; | |
109 | + case 32: | |
110 | + BitBlt_Src24_Dst32(src, sbr, dst, dbr); | |
36 | 111 | break; |
112 | + } | |
113 | + break; | |
114 | + case 32: | |
115 | + switch (dst.bitsPerPixel) { | |
37 | 116 | case 24: |
38 | - | |
117 | + BitBlt_Src32_Dst24(src, sbr, dst, dbr); | |
39 | 118 | break; |
40 | 119 | case 32: |
41 | - | |
120 | + BitBlt_Src32_Dst32(src, sbr, dst, dbr); | |
42 | 121 | break; |
43 | 122 | } |
123 | + break; | |
44 | 124 | } |
45 | 125 | |
46 | - return ret; | |
126 | + return dbr; | |
47 | 127 | } |
48 | 128 | |
49 | 129 |
@@ -11,8 +11,21 @@ struct Bitmap | ||
11 | 11 | uint8_t bitsPerPixel; |
12 | 12 | int lineOffsetBytes; |
13 | 13 | void* pBits; |
14 | + | |
15 | + Rectangle GetRect() const; | |
16 | +}; | |
14 | 17 | |
15 | - Rectangle GetRect() const; | |
18 | +struct Image { | |
19 | + Bitmap* pBitmap; | |
20 | + Rectangle rect; | |
21 | + | |
22 | + Rectangle GetRect() const { | |
23 | + if (pBitmap) { | |
24 | + return Rectangle::Intersect(pBitmap->GetRect(), rect); | |
25 | + }else { | |
26 | + return rect; | |
27 | + } | |
28 | + } | |
16 | 29 | }; |
17 | 30 | |
18 | 31 | Rectangle BitBlt( |
@@ -10,19 +10,14 @@ void Element::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer) | ||
10 | 10 | Rectangle r = rect; |
11 | 11 | r.x += offsetX; |
12 | 12 | r.y += offsetY; |
13 | - | |
13 | + | |
14 | 14 | if (bg.color) { |
15 | 15 | Color c = *bg.color; |
16 | 16 | renderer.FillRectangle(r, c); |
17 | 17 | } |
18 | - if (bg.pBitmap) { | |
19 | - const Bitmap& bmp = *bg.pBitmap; | |
20 | - Rectangle sr; | |
21 | - sr.x = 0; | |
22 | - sr.y = 0; | |
23 | - sr.w = bmp.width; | |
24 | - sr.h = bmp.height; | |
25 | - renderer.DrawBitmap(bmp, sr, r); | |
18 | + if (bg.image.pBitmap) { | |
19 | + const Bitmap& bmp = *bg.image.pBitmap; | |
20 | + renderer.DrawBitmap(bmp, bg.image.GetRect(), r); | |
26 | 21 | } |
27 | 22 | |
28 | 23 | } |
@@ -13,7 +13,6 @@ public: | ||
13 | 13 | needsToDraw(false), |
14 | 14 | bClickable_(false) |
15 | 15 | { |
16 | - bg.pBitmap = NULL; | |
17 | 16 | bg.repeatX = true; |
18 | 17 | bg.repeatY = true; |
19 | 18 | } |
@@ -27,20 +26,20 @@ public: | ||
27 | 26 | } |
28 | 27 | |
29 | 28 | virtual void Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer); |
30 | - virtual bool HitTest(int16_t x, int16_t y) const = 0; | |
31 | - virtual void OnMouseDown(int16_t x, int16_t y) = 0; | |
32 | - virtual void OnMouseUp(int16_t x, int16_t y) = 0; | |
33 | - virtual void OnMouseMove(int16_t x, int16_t y) = 0; | |
29 | + virtual bool HitTest(int16_t x, int16_t y) const { return false; } | |
30 | + virtual void OnMouseDown(int16_t x, int16_t y) {} | |
31 | + virtual void OnMouseUp(int16_t x, int16_t y) {} | |
32 | + virtual void OnMouseMove(int16_t x, int16_t y) {} | |
34 | 33 | |
35 | 34 | Rectangle rect; |
36 | 35 | bool needsToDraw; |
37 | - | |
36 | + | |
38 | 37 | struct Background { |
39 | 38 | optional<Color> color; |
40 | - const Bitmap* pBitmap; | |
39 | + Image image; | |
41 | 40 | bool repeatX; |
42 | 41 | bool repeatY; |
43 | - }bg; | |
42 | + } bg; | |
44 | 43 | protected: |
45 | 44 | bool bClickable_; |
46 | 45 | }; |
@@ -22,10 +22,10 @@ bool Rectangle::Contains(int16_t x, int16_t y) | ||
22 | 22 | { |
23 | 23 | return |
24 | 24 | 1 |
25 | - && this->x <= x | |
26 | - && x < this->x + this->w | |
27 | - && this->y <= y | |
28 | - && y < this->y + this->h | |
25 | + && Left() <= x | |
26 | + && x < Right() | |
27 | + && Top() <= y | |
28 | + && y < Bottom() | |
29 | 29 | ; |
30 | 30 | } |
31 | 31 |
@@ -36,7 +36,17 @@ bool Rectangle::Contains(const Rectangle& r) | ||
36 | 36 | |
37 | 37 | void Rectangle::Intersect(const Rectangle& r) |
38 | 38 | { |
39 | + int16_t left = std::max<int16_t>(Left(), r.Left()); | |
40 | + int16_t right = std::min<int16_t>(Right(), r.Right()); | |
39 | 41 | |
42 | + int16_t top = std::max<int16_t>(Top(), r.Top()); | |
43 | + int16_t bottom = std::min<int16_t>(Bottom(), r.Bottom()); | |
44 | + | |
45 | + x = left; | |
46 | + w = std::max<int16_t>(0, right-left); | |
47 | + | |
48 | + y = top; | |
49 | + h = std::max<int16_t>(0, bottom-top); | |
40 | 50 | } |
41 | 51 | |
42 | 52 | // static |
@@ -11,6 +11,11 @@ struct Rectangle | ||
11 | 11 | uint16_t w; |
12 | 12 | uint16_t h; |
13 | 13 | |
14 | + int16_t Left() const { return x; } | |
15 | + int16_t Right() const { return x+w; } | |
16 | + int16_t Top() const { return y; } | |
17 | + int16_t Bottom() const { return y+h; } | |
18 | + | |
14 | 19 | void Offset(int16_t x, int16_t y); |
15 | 20 | static Rectangle Offset(const Rectangle& r, int16_t x, int16_t y); |
16 | 21 |