3 /* LoadLPK global variables */
5 LPKETO LpkExtTextOut
= NULL
;
6 LPKGCP LpkGetCharacterPlacement
= NULL
;
9 * @name CalculateColorTableSize
11 * Internal routine to calculate the number of color table entries.
13 * @param BitmapInfoHeader
14 * Input bitmap information header, can be any version of
15 * BITMAPINFOHEADER or BITMAPCOREHEADER.
18 * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
19 * or DIB_RGB_COLORS). On successful return this value is normalized
20 * according to the bitmap info.
22 * @param ColorTableSize
23 * On successful return this variable is filled with number of
24 * entries in color table for the image with specified parameters.
27 * TRUE if the input values together form a valid image, FALSE otherwise.
31 CalculateColorTableSize(
32 CONST BITMAPINFOHEADER
*BitmapInfoHeader
,
41 * At first get some basic parameters from the passed BitmapInfoHeader
42 * structure. It can have one of the following formats:
43 * - BITMAPCOREHEADER (the oldest one with totally different layout
45 * - BITMAPINFOHEADER (the standard and most common header)
46 * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
47 * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
50 if (BitmapInfoHeader
->biSize
== sizeof(BITMAPCOREHEADER
))
52 BitCount
= ((LPBITMAPCOREHEADER
)BitmapInfoHeader
)->bcBitCount
;
58 BitCount
= BitmapInfoHeader
->biBitCount
;
59 ClrUsed
= BitmapInfoHeader
->biClrUsed
;
60 Compression
= BitmapInfoHeader
->biCompression
;
66 if (*ColorSpec
== DIB_PAL_COLORS
)
67 *ColorSpec
= DIB_RGB_COLORS
;
69 if (BitCount
!= 16 && BitCount
!= 32)
73 * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
74 * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
75 * For BITMAPINFOHEADER the color masks are stored in the palette.
78 if (BitmapInfoHeader
->biSize
> sizeof(BITMAPINFOHEADER
))
89 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 2) : 2;
93 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 16) : 16;
97 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 256) : 256;
101 if (*ColorSpec
== DIB_PAL_COLORS
)
102 *ColorSpec
= DIB_RGB_COLORS
;
103 if (BitCount
!= 16 && BitCount
!= 24 && BitCount
!= 32)
105 *ColorTableSize
= ClrUsed
;
112 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 16) : 16;
120 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 256) : 256;
127 *ColorTableSize
= ClrUsed
;
136 * @name ConvertBitmapInfo
138 * Internal routine to convert a user-passed BITMAPINFO structure into
139 * unified BITMAPINFO structure.
142 * Input bitmap info, can be any version of BITMAPINFO or
145 * Specifies whether the bmiColors member of the BITMAPINFO structure
146 * contains a valid color table and, if so, whether the entries in
147 * this color table contain explicit red, green, blue (DIB_RGB_COLORS)
148 * values or palette indexes (DIB_PAL_COLORS).
149 * @param BitmapInfoSize
150 * On successful return contains the size of the returned BITMAPINFO
151 * structure. If FollowedByData is TRUE the size includes the number
152 * of bytes occupied by the image data.
153 * @param FollowedByData
154 * Specifies if the BITMAPINFO header is immediately followed
155 * by the actual bitmap data (eg. as passed to CreateDIBPatternBrush).
158 * Either the original BitmapInfo or newly allocated structure is
159 * returned. For the later case the caller is responsible for freeing the
160 * memory using RtlFreeHeap with the current process heap.
163 * PBITMAPINFO NewBitmapInfo;
164 * UINT NewBitmapInfoSize;
166 * NewBitmapInfo = ConvertBitmapInfo(OldBitmapInfo, DIB_RGB_COLORS,
167 * &NewBitmapInfoSize, FALSE);
170 * <do something with the bitmap info>
171 * if (NewBitmapInfo != OldBitmapInfo)
172 * RtlFreeHeap(RtlGetProcessHeap(), 0, NewBitmapInfo);
178 CONST BITMAPINFO
*BitmapInfo
,
180 UINT
*BitmapInfoSize
,
183 LPBITMAPINFO NewBitmapInfo
= (LPBITMAPINFO
)BitmapInfo
;
184 LPBITMAPCOREINFO CoreBitmapInfo
= (LPBITMAPCOREINFO
)BitmapInfo
;
187 UINT PaletteEntryCount
= 0;
190 * At first check if the passed BitmapInfo structure has valid size. It
191 * can have one of these headers: BITMAPCOREHEADER, BITMAPINFOHEADER,
192 * BITMAPV4HEADER or BITMAPV5HEADER (see CalculateColorTableSize for
197 (BitmapInfo
->bmiHeader
.biSize
!= sizeof(BITMAPCOREHEADER
) &&
198 (BitmapInfo
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
) ||
199 BitmapInfo
->bmiHeader
.biSize
> sizeof(BITMAPV5HEADER
))))
205 * Now calculate the color table size. Also if the bitmap info contains
206 * invalid color information it's rejected here.
209 if (!CalculateColorTableSize(&BitmapInfo
->bmiHeader
, &ColorSpec
,
216 * Calculate the size of image data if applicable. We must be careful
217 * to do proper aligning on line ends.
222 DataSize
= GdiGetBitmapBitsSize((PBITMAPINFO
)BitmapInfo
);
226 * If BitmapInfo was originally BITMAPCOREINFO then we need to convert
227 * it to the standard BITMAPINFO layout.
230 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
232 Size
= sizeof(BITMAPINFOHEADER
);
233 if (ColorSpec
== DIB_RGB_COLORS
)
234 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
236 Size
+= PaletteEntryCount
* sizeof(USHORT
);
239 NewBitmapInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
240 if (NewBitmapInfo
== NULL
)
245 NewBitmapInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
246 NewBitmapInfo
->bmiHeader
.biWidth
= CoreBitmapInfo
->bmciHeader
.bcWidth
;
247 NewBitmapInfo
->bmiHeader
.biHeight
= CoreBitmapInfo
->bmciHeader
.bcHeight
;
248 NewBitmapInfo
->bmiHeader
.biPlanes
= CoreBitmapInfo
->bmciHeader
.bcPlanes
;
249 NewBitmapInfo
->bmiHeader
.biBitCount
= CoreBitmapInfo
->bmciHeader
.bcBitCount
;
250 NewBitmapInfo
->bmiHeader
.biCompression
= BI_RGB
;
251 NewBitmapInfo
->bmiHeader
.biSizeImage
= 0;
252 NewBitmapInfo
->bmiHeader
.biXPelsPerMeter
= 0;
253 NewBitmapInfo
->bmiHeader
.biYPelsPerMeter
= 0;
254 NewBitmapInfo
->bmiHeader
.biClrUsed
= 0;
255 NewBitmapInfo
->bmiHeader
.biClrImportant
= 0;
257 if (PaletteEntryCount
!= 0)
259 if (ColorSpec
== DIB_RGB_COLORS
)
263 for (Index
= 0; Index
< PaletteEntryCount
; Index
++)
265 NewBitmapInfo
->bmiColors
[Index
].rgbRed
=
266 CoreBitmapInfo
->bmciColors
[Index
].rgbtRed
;
267 NewBitmapInfo
->bmiColors
[Index
].rgbGreen
=
268 CoreBitmapInfo
->bmciColors
[Index
].rgbtGreen
;
269 NewBitmapInfo
->bmiColors
[Index
].rgbBlue
=
270 CoreBitmapInfo
->bmciColors
[Index
].rgbtBlue
;
271 NewBitmapInfo
->bmiColors
[Index
].rgbReserved
= 0;
276 RtlCopyMemory(NewBitmapInfo
->bmiColors
,
277 CoreBitmapInfo
->bmciColors
,
278 PaletteEntryCount
* sizeof(USHORT
));
284 ULONG_PTR NewDataPtr
, OldDataPtr
;
286 if (ColorSpec
== DIB_RGB_COLORS
)
288 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
+
290 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
+
295 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
) +
296 PaletteEntryCount
* sizeof(USHORT
);
297 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
) +
298 PaletteEntryCount
* sizeof(USHORT
);
301 RtlCopyMemory((PVOID
)NewDataPtr
, (PVOID
)OldDataPtr
, DataSize
);
306 /* Verify some data validity */
307 switch (BitmapInfo
->bmiHeader
.biCompression
)
310 if (BitmapInfo
->bmiHeader
.biBitCount
!= 8)
312 if (BitmapInfo
->bmiHeader
.biHeight
< 0)
316 if (BitmapInfo
->bmiHeader
.biBitCount
!= 4)
318 if (BitmapInfo
->bmiHeader
.biHeight
< 0)
325 /* Non "standard" formats must have a valid size set */
326 if ((BitmapInfo
->bmiHeader
.biCompression
!= BI_RGB
) &&
327 (BitmapInfo
->bmiHeader
.biCompression
!= BI_BITFIELDS
))
329 if (BitmapInfo
->bmiHeader
.biSizeImage
== 0)
334 Size
= NewBitmapInfo
->bmiHeader
.biSize
;
335 if (ColorSpec
== DIB_RGB_COLORS
)
336 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
338 Size
+= PaletteEntryCount
* sizeof(USHORT
);
340 *BitmapInfoSize
= Size
;
342 return NewBitmapInfo
;
347 LogFontA2W(LPLOGFONTW pW
, CONST LOGFONTA
*pA
)
349 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
350 #define COPYN(f) pW->f = pA->f
355 COPYN(lfOrientation
);
361 COPYN(lfOutPrecision
);
362 COPYN(lfClipPrecision
);
364 COPYN(lfPitchAndFamily
);
365 COPYS(lfFaceName
,LF_FACESIZE
);
366 pW
->lfFaceName
[LF_FACESIZE
- 1] = '\0';
374 LogFontW2A(LPLOGFONTA pA
, CONST LOGFONTW
*pW
)
376 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
377 #define COPYN(f) pA->f = pW->f
382 COPYN(lfOrientation
);
388 COPYN(lfOutPrecision
);
389 COPYN(lfClipPrecision
);
391 COPYN(lfPitchAndFamily
);
392 COPYS(lfFaceName
,LF_FACESIZE
);
393 pA
->lfFaceName
[LF_FACESIZE
- 1] = '\0';
401 EnumLogFontExW2A( LPENUMLOGFONTEXA fontA
, CONST ENUMLOGFONTEXW
*fontW
)
403 LogFontW2A( (LPLOGFONTA
)fontA
, (CONST LOGFONTW
*)fontW
);
405 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfFullName
, -1,
406 (LPSTR
) fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
407 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
408 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfStyle
, -1,
409 (LPSTR
) fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
410 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
411 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfScript
, -1,
412 (LPSTR
) fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
413 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';
417 * LPK.DLL loader function
419 * Returns TRUE if a valid parameter was passed and loading was successful,
420 * retruns FALSE otherwise.
422 BOOL WINAPI
LoadLPK(INT LpkFunctionID
)
424 if(!hLpk
) // Check if the DLL is already loaded
425 hLpk
= LoadLibraryW(L
"lpk.dll");
429 switch (LpkFunctionID
)
435 if (!LpkExtTextOut
) // Check if the function is already loaded
436 LpkExtTextOut
= (LPKETO
) GetProcAddress(hLpk
, "LpkExtTextOut");
447 if (!LpkGetCharacterPlacement
) // Check if the function is already loaded
448 LpkGetCharacterPlacement
= (LPKGCP
) GetProcAddress(hLpk
, "LpkGetCharacterPlacement");
450 if (!LpkGetCharacterPlacement
)