xref: /reactos/base/applications/mspaint/dib.cpp (revision 53221834)
1 /*
2  * PROJECT:     PAINT for ReactOS
3  * LICENSE:     LGPL
4  * FILE:        base/applications/mspaint/dib.cpp
5  * PURPOSE:     Some DIB related functions
6  * PROGRAMMERS: Benedikt Freisen
7  */
8 
9 /* INCLUDES *********************************************************/
10 
11 #include "precomp.h"
12 
13 /* FUNCTIONS ********************************************************/
14 
15 HBITMAP
16 CreateDIBWithProperties(int width, int height)
17 {
18     BITMAPINFO bmi;
19     ZeroMemory(&bmi, sizeof(BITMAPINFO));
20     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
21     bmi.bmiHeader.biWidth = width;
22     bmi.bmiHeader.biHeight = height;
23     bmi.bmiHeader.biPlanes = 1;
24     bmi.bmiHeader.biBitCount = 24;
25     bmi.bmiHeader.biCompression = BI_RGB;
26     return CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
27 }
28 
29 HBITMAP
30 CreateColorDIB(int width, int height, COLORREF rgb)
31 {
32     HBITMAP ret = CreateDIBWithProperties(width, height);
33     if (!ret)
34         return NULL;
35 
36     if (rgb)
37     {
38         HDC hdc = CreateCompatibleDC(NULL);
39         HGDIOBJ hbmOld = SelectObject(hdc, ret);
40         RECT rc;
41         SetRect(&rc, 0, 0, width, height);
42         HBRUSH hbr = CreateSolidBrush(rgb);
43         FillRect(hdc, &rc, hbr);
44         DeleteObject(hbr);
45         SelectObject(hdc, hbmOld);
46         DeleteDC(hdc);
47     }
48 
49     return ret;
50 }
51 
52 int
53 GetDIBWidth(HBITMAP hBitmap)
54 {
55     BITMAP bm;
56     GetObject(hBitmap, sizeof(BITMAP), &bm);
57     return bm.bmWidth;
58 }
59 
60 int
61 GetDIBHeight(HBITMAP hBitmap)
62 {
63     BITMAP bm;
64     GetObject(hBitmap, sizeof(BITMAP), &bm);
65     return bm.bmHeight;
66 }
67 
68 BOOL SaveDIBToFile(HBITMAP hBitmap, LPTSTR FileName, HDC hDC)
69 {
70     CImage img;
71     img.Attach(hBitmap);
72     img.Save(FileName);  // TODO: error handling
73     img.Detach();
74 
75     WIN32_FIND_DATA find;
76     HANDLE hFind = FindFirstFile(FileName, &find);
77     if (hFind == INVALID_HANDLE_VALUE)
78     {
79         ShowFileLoadError(FileName);
80         return FALSE;
81     }
82     FindClose(hFind);
83 
84     // update time and size
85     FILETIME ft;
86     FileTimeToLocalFileTime(&find.ftLastWriteTime, &ft);
87     FileTimeToSystemTime(&ft, &fileTime);
88     fileSize = find.nFileSizeLow;
89 
90     // TODO: update hRes and vRes
91 
92     registrySettings.SetMostRecentFile(FileName);
93 
94     isAFile = TRUE;
95     imageSaved = TRUE;
96     return TRUE;
97 }
98 
99 void ShowFileLoadError(LPCTSTR name)
100 {
101     CString strText;
102     strText.Format(IDS_LOADERRORTEXT, (LPCTSTR) name);
103     CString strProgramName;
104     strProgramName.LoadString(IDS_PROGRAMNAME);
105     mainWindow.MessageBox(strText, strProgramName, MB_OK | MB_ICONEXCLAMATION);
106 }
107 
108 HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile)
109 {
110     if (hBitmap == NULL)
111     {
112         COLORREF white = RGB(255, 255, 255);
113         hBitmap = CreateColorDIB(registrySettings.BMPWidth,
114                                  registrySettings.BMPHeight, white);
115         if (hBitmap == NULL)
116             return FALSE;
117 
118         fileHPPM = fileVPPM = 2834;
119         ZeroMemory(&fileTime, sizeof(fileTime));
120         isFile = FALSE;
121     }
122     else
123     {
124         // update PPMs
125         HDC hScreenDC = GetDC(NULL);
126         fileHPPM = (int)(GetDeviceCaps(hScreenDC, LOGPIXELSX) * 1000 / 25.4);
127         fileVPPM = (int)(GetDeviceCaps(hScreenDC, LOGPIXELSY) * 1000 / 25.4);
128         ReleaseDC(NULL, hScreenDC);
129     }
130 
131     // update image
132     imageModel.Insert(hBitmap);
133     imageModel.ClearHistory();
134 
135     // update fileSize
136     fileSize = dwFileSize;
137 
138     // update filepathname
139     if (name && name[0])
140         GetFullPathName(name, SIZEOF(filepathname), filepathname, NULL);
141     else
142         LoadString(hProgInstance, IDS_DEFAULTFILENAME, filepathname, SIZEOF(filepathname));
143 
144     // set title
145     CString strTitle;
146     strTitle.Format(IDS_WINDOWTITLE, PathFindFileName(filepathname));
147     mainWindow.SetWindowText(strTitle);
148 
149     // update file info and recent
150     isAFile = isFile;
151     if (isAFile)
152         registrySettings.SetMostRecentFile(filepathname);
153 
154     imageSaved = TRUE;
155 
156     return hBitmap;
157 }
158 
159 HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile)
160 {
161     // find the file
162     WIN32_FIND_DATA find;
163     HANDLE hFind = FindFirstFile(name, &find);
164     if (hFind == INVALID_HANDLE_VALUE)
165     {
166         // does not exist
167         CStringW strText;
168         strText.Format(IDS_LOADERRORTEXT, name);
169         MessageBoxW(hwnd, strText, NULL, MB_ICONERROR);
170         return NULL;
171     }
172     DWORD dwFileSize = find.nFileSizeLow; // get file size
173     FindClose(hFind);
174 
175     // is file empty?
176     if (dwFileSize == 0)
177     {
178         if (fIsMainFile)
179         {
180             FILETIME ft;
181             FileTimeToLocalFileTime(&find.ftLastWriteTime, &ft);
182             FileTimeToSystemTime(&ft, &fileTime);
183             return SetBitmapAndInfo(NULL, name, dwFileSize, TRUE);
184         }
185     }
186 
187     // load the image
188     CImage img;
189     img.Load(name);
190     HBITMAP hBitmap = img.Detach();
191 
192     if (hBitmap == NULL)
193     {
194         // cannot open
195         CStringW strText;
196         strText.Format(IDS_LOADERRORTEXT, name);
197         MessageBoxW(hwnd, strText, NULL, MB_ICONERROR);
198         return NULL;
199     }
200 
201     if (fIsMainFile)
202     {
203         FILETIME ft;
204         FileTimeToLocalFileTime(&find.ftLastWriteTime, &ft);
205         FileTimeToSystemTime(&ft, &fileTime);
206         SetBitmapAndInfo(hBitmap, name, dwFileSize, TRUE);
207     }
208 
209     return hBitmap;
210 }
211