]>
Commit | Line | Data |
---|---|---|
9a29912f JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: bmputils.h | |
3 | // Purpose: Utilities for manipulating bitmap and metafile images for | |
4 | // the purposes of conversion to RTF | |
5 | // Author: Julian Smart | |
b63b07a8 RL |
6 | // Modified by: Wlodzimiez ABX Skiba 2003/2004 Unicode support |
7 | // Ron Lee | |
9a29912f JS |
8 | // Created: 7.9.93 |
9 | // RCS-ID: $Id$ | |
10 | // Copyright: (c) Julian Smart | |
11 | // Licence: wxWindows licence | |
12 | ///////////////////////////////////////////////////////////////////////////// | |
13 | ||
14 | static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', | |
15 | 'C', 'D', 'E', 'F' }; | |
16 | ||
6c155d33 | 17 | void DecToHex(int dec, wxChar *buf) |
9a29912f JS |
18 | { |
19 | int firstDigit = (int)(dec/16.0); | |
20 | int secondDigit = (int)(dec - (firstDigit*16.0)); | |
21 | buf[0] = hexArray[firstDigit]; | |
22 | buf[1] = hexArray[secondDigit]; | |
23 | buf[2] = 0; | |
24 | } | |
25 | ||
26 | static unsigned int getshort(FILE *fp) | |
27 | { | |
28 | int c, c1; | |
29 | c = getc(fp); c1 = getc(fp); | |
30 | return ((unsigned int) c) + (((unsigned int) c1) << 8); | |
31 | } | |
32 | ||
33 | static unsigned long getint(FILE *fp) | |
34 | { | |
35 | int c, c1, c2, c3; | |
36 | c = getc(fp); c1 = getc(fp); c2 = getc(fp); c3 = getc(fp); | |
37 | return (long)((long) c) + | |
38 | (((long) c1) << 8) + | |
4fe30bce WS |
39 | (((long) c2) << 16) + |
40 | (((long) c3) << 24); | |
9a29912f JS |
41 | } |
42 | ||
43 | bool GetBMPHeader(FILE *fp, int *Width, int *Height, int *Planes, int *BitsPerPixel) | |
44 | { | |
6c155d33 JS |
45 | // Remember about all fields but store only important ones |
46 | unsigned long /* | |
47 | bfSize, | |
48 | bfOffBits, | |
49 | biSize, | |
50 | */ | |
51 | biWidth, | |
52 | biHeight, | |
53 | biPlanes, | |
54 | biBitCount | |
55 | /* , | |
56 | biCompression, | |
57 | biSizeImage, | |
58 | biXPelsPerMeter, | |
59 | biYPelsPerMeter, | |
60 | biClrUsed, | |
61 | biClrImportant | |
62 | */ | |
63 | ; | |
9a29912f JS |
64 | |
65 | /* read the file type (first two bytes) */ | |
66 | int c = getc(fp); int c1 = getc(fp); | |
b63b07a8 | 67 | if (c!='B' || c1!='M') { return false; } |
9a29912f | 68 | |
6c155d33 | 69 | /* bfSize = */ getint(fp); |
9a29912f JS |
70 | getshort(fp); /* reserved and ignored */ |
71 | getshort(fp); | |
6c155d33 | 72 | /* bfOffBits = */ getint(fp); |
9a29912f | 73 | |
6c155d33 | 74 | /* biSize = */ getint(fp); |
9a29912f JS |
75 | biWidth = getint(fp); |
76 | biHeight = getint(fp); | |
77 | biPlanes = getshort(fp); | |
78 | biBitCount = getshort(fp); | |
6c155d33 JS |
79 | /* biCompression = */ getint(fp); |
80 | /* biSizeImage = */ getint(fp); | |
81 | /* biXPelsPerMeter = */ getint(fp); | |
82 | /* biYPelsPerMeter = */ getint(fp); | |
83 | /* biClrUsed = */ getint(fp); | |
84 | /* biClrImportant = */ getint(fp); | |
9a29912f JS |
85 | |
86 | *Width = (int)biWidth; | |
87 | *Height = (int)biHeight; | |
88 | *Planes = (int)biPlanes; | |
89 | *BitsPerPixel = (int)biBitCount; | |
90 | ||
91 | // fseek(fp, bfOffBits, SEEK_SET); | |
b63b07a8 RL |
92 | |
93 | return true; | |
9a29912f JS |
94 | } |
95 | ||
96 | static int scanLineWidth = 0; | |
97 | ||
b63b07a8 | 98 | bool OutputBitmapHeader(FILE *fd, bool isWinHelp = false) |
9a29912f JS |
99 | { |
100 | int Width, Height, Planes, BitsPerPixel; | |
101 | if (!GetBMPHeader(fd, &Width, &Height, &Planes, &BitsPerPixel)) | |
b63b07a8 | 102 | return false; |
9a29912f JS |
103 | |
104 | scanLineWidth = (int)((float)Width/(8.0/(float)BitsPerPixel)); | |
105 | if ((float)((int)(scanLineWidth/2.0)) != (float)(scanLineWidth/2.0)) | |
106 | scanLineWidth ++; | |
b63b07a8 | 107 | |
9a29912f JS |
108 | int goalW = 15*Width; |
109 | int goalH = 15*Height; | |
110 | ||
6c155d33 JS |
111 | TexOutput(_T("{\\pict")); |
112 | if (isWinHelp) TexOutput(_T("\\wbitmap0")); | |
113 | else TexOutput(_T("\\dibitmap)")); | |
114 | ||
115 | wxChar buf[50]; | |
b63b07a8 RL |
116 | TexOutput(_T("\\picw")); wxSnprintf(buf, sizeof(buf), _T("%d"), Width); TexOutput(buf); |
117 | TexOutput(_T("\\pich")); wxSnprintf(buf, sizeof(buf), _T("%d"), Height); TexOutput(buf); | |
118 | TexOutput(_T("\\wbmbitspixel")); wxSnprintf(buf, sizeof(buf), _T("%d"), BitsPerPixel); TexOutput(buf); | |
119 | TexOutput(_T("\\wbmplanes")); wxSnprintf(buf, sizeof(buf), _T("%d"), Planes); TexOutput(buf); | |
120 | TexOutput(_T("\\wbmwidthbytes")); wxSnprintf(buf, sizeof(buf), _T("%d"), scanLineWidth); TexOutput(buf); | |
121 | TexOutput(_T("\\picwgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalW); TexOutput(buf); | |
122 | TexOutput(_T("\\pichgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalH); TexOutput(buf); | |
6c155d33 | 123 | TexOutput(_T("\n")); |
b63b07a8 | 124 | return true; |
9a29912f JS |
125 | } |
126 | ||
127 | ||
128 | bool OutputBitmapData(FILE *fd) | |
129 | { | |
130 | fseek(fd, 14, SEEK_SET); | |
131 | int bytesSoFar = 0; | |
132 | int ch = getc(fd); | |
6c155d33 | 133 | wxChar hexBuf[3]; |
9a29912f JS |
134 | while (ch != EOF) |
135 | { | |
136 | if (bytesSoFar == scanLineWidth) | |
137 | { | |
138 | bytesSoFar = 0; | |
6c155d33 | 139 | TexOutput(_T("\n")); |
9a29912f JS |
140 | } |
141 | DecToHex(ch, hexBuf); | |
142 | TexOutput(hexBuf); | |
143 | bytesSoFar ++; | |
144 | ch = getc(fd); | |
145 | } | |
6c155d33 | 146 | TexOutput(_T("\n}\n")); |
b63b07a8 | 147 | return true; |
9a29912f JS |
148 | } |
149 | ||
150 | #ifdef __WXMSW__ | |
151 | struct mfPLACEABLEHEADER { | |
4fe30bce WS |
152 | DWORD key; |
153 | HANDLE hmf; | |
154 | RECT bbox; | |
155 | WORD inch; | |
156 | DWORD reserved; | |
157 | WORD checksum; | |
9a29912f JS |
158 | }; |
159 | ||
160 | // Returns size in TWIPS | |
161 | bool GetMetafileHeader(FILE *handle, int *width, int *height) | |
162 | { | |
163 | char buffer[40]; | |
164 | mfPLACEABLEHEADER *theHeader = (mfPLACEABLEHEADER *)&buffer; | |
165 | fread((void *)theHeader, sizeof(char), sizeof(mfPLACEABLEHEADER), handle); | |
166 | if (theHeader->key != 0x9AC6CDD7) | |
167 | { | |
b63b07a8 | 168 | return false; |
9a29912f JS |
169 | } |
170 | ||
171 | float widthInUnits = (float)theHeader->bbox.right - theHeader->bbox.left; | |
172 | float heightInUnits = (float)theHeader->bbox.bottom - theHeader->bbox.top; | |
173 | *width = (int)((widthInUnits*1440.0)/theHeader->inch); | |
174 | *height = (int)((heightInUnits*1440.0)/theHeader->inch); | |
b63b07a8 | 175 | return true; |
9a29912f JS |
176 | } |
177 | ||
6c155d33 | 178 | bool OutputMetafileHeader(FILE *handle, bool WXUNUSED(isWinHelp), int userWidth, int userHeight) |
9a29912f JS |
179 | { |
180 | int Width, Height; | |
181 | if (!GetMetafileHeader(handle, &Width, &Height)) | |
b63b07a8 | 182 | return false; |
9a29912f JS |
183 | |
184 | scanLineWidth = 64; | |
185 | int goalW = Width; | |
186 | int goalH = Height; | |
187 | ||
188 | // Scale to user's dimensions if we have the information | |
189 | if (userWidth > 0 && userHeight == 0) | |
190 | { | |
191 | double scaleFactor = ((double)userWidth/(double)goalW); | |
192 | goalW = userWidth; | |
193 | goalH = (int)((goalH * scaleFactor) + 0.5); | |
194 | } | |
195 | else if (userWidth == 0 && userHeight > 0) | |
196 | { | |
197 | double scaleFactor = ((double)userHeight/(double)goalH); | |
198 | goalH = userHeight; | |
199 | goalW = (int)((goalW * scaleFactor) + 0.5); | |
200 | } | |
201 | else if (userWidth > 0 && userHeight > 0) | |
202 | { | |
203 | goalW = userWidth; | |
204 | goalH = userHeight; | |
205 | } | |
206 | ||
6c155d33 JS |
207 | TexOutput(_T("{\\pict")); |
208 | TexOutput(_T("\\wmetafile8")); | |
9a29912f | 209 | |
6c155d33 | 210 | wxChar buf[50]; |
b63b07a8 RL |
211 | TexOutput(_T("\\picw")); wxSnprintf(buf, sizeof(buf), _T("%d"), Width); TexOutput(buf); |
212 | TexOutput(_T("\\pich")); wxSnprintf(buf, sizeof(buf), _T("%d"), Height); TexOutput(buf); | |
213 | TexOutput(_T("\\picwgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalW); TexOutput(buf); | |
214 | TexOutput(_T("\\pichgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalH); TexOutput(buf); | |
6c155d33 | 215 | TexOutput(_T("\n")); |
b63b07a8 | 216 | return true; |
9a29912f JS |
217 | } |
218 | ||
219 | bool OutputMetafileData(FILE *handle) | |
220 | { | |
221 | int bytesSoFar = 0; | |
6c155d33 | 222 | wxChar hexBuf[3]; |
9a29912f JS |
223 | int ch; |
224 | do | |
225 | { | |
226 | ch = getc(handle); | |
227 | if (bytesSoFar == scanLineWidth) | |
228 | { | |
229 | bytesSoFar = 0; | |
6c155d33 | 230 | TexOutput(_T("\n")); |
9a29912f JS |
231 | } |
232 | if (ch != EOF) | |
233 | { | |
234 | DecToHex(ch, hexBuf); | |
235 | TexOutput(hexBuf); | |
236 | bytesSoFar ++; | |
237 | } | |
238 | } while (ch != EOF); | |
6c155d33 | 239 | TexOutput(_T("\n}\n")); |
b63b07a8 | 240 | return true; |
9a29912f JS |
241 | } |
242 | ||
243 | #endif | |
244 |