1 /* $Id: font.c,v 1.3 2004/04/09 20:03:13 navaraf Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/gdi32/object/font.c
16 #include <rosrtl/logfont.h>
17 #include <ddk/ntddk.h>
18 #define NTOS_MODE_USER
20 #include <win32k/font.h>
21 #include <win32k/text.h>
22 #include <internal/font.h>
27 #define INITIAL_FAMILY_COUNT 64
30 MetricsCharConvert(WCHAR w
, CHAR
*b
)
32 UNICODE_STRING WString
;
46 RtlInitUnicodeString(&WString
, WBuf
);
49 RtlInitAnsiString(&AString
, ABuf
);
51 Status
= RtlUnicodeStringToAnsiString(&AString
, &WString
, FALSE
);
52 if (! NT_SUCCESS(Status
))
54 SetLastError(RtlNtStatusToDosError(Status
));
64 TextMetricW2A(TEXTMETRICA
*tma
, TEXTMETRICW
*tmw
)
66 UNICODE_STRING WString
;
73 tma
->tmHeight
= tmw
->tmHeight
;
74 tma
->tmAscent
= tmw
->tmAscent
;
75 tma
->tmDescent
= tmw
->tmDescent
;
76 tma
->tmInternalLeading
= tmw
->tmInternalLeading
;
77 tma
->tmExternalLeading
= tmw
->tmExternalLeading
;
78 tma
->tmAveCharWidth
= tmw
->tmAveCharWidth
;
79 tma
->tmMaxCharWidth
= tmw
->tmMaxCharWidth
;
80 tma
->tmWeight
= tmw
->tmWeight
;
81 tma
->tmOverhang
= tmw
->tmOverhang
;
82 tma
->tmDigitizedAspectX
= tmw
->tmDigitizedAspectX
;
83 tma
->tmDigitizedAspectY
= tmw
->tmDigitizedAspectY
;
85 /* The Unicode FirstChar/LastChar need not correspond to the ANSI
86 FirstChar/LastChar. For example, if the font contains glyphs for
87 letters A-Z and an accented version of the letter e, the Unicode
88 FirstChar would be A and the Unicode LastChar would be the accented
89 e. If you just translate those to ANSI, the range would become
90 letters A-E instead of A-Z.
91 We translate all possible ANSI chars to Unicode and find the first
92 and last translated character which fall into the Unicode FirstChar/
93 LastChar range and return the corresponding ANSI char. */
95 /* Setup an Ansi string containing all possible letters (note: skip '\0' at
96 the beginning since that would be interpreted as end-of-string, handle
98 for (Letter
= 1; Letter
< 256; Letter
++)
100 ABuf
[Letter
- 1] = (CHAR
) Letter
;
101 WBuf
[Letter
- 1] = L
' ';
105 RtlInitAnsiString(&AString
, ABuf
);
106 RtlInitUnicodeString(&WString
, WBuf
);
108 /* Find the corresponding Unicode characters */
109 Status
= RtlAnsiStringToUnicodeString(&WString
, &AString
, FALSE
);
110 if (! NT_SUCCESS(Status
))
112 SetLastError(RtlNtStatusToDosError(Status
));
116 /* Scan for the first ANSI character which maps to an Unicode character
118 tma
->tmFirstChar
= '\0';
119 if (L
'\0' != tmw
->tmFirstChar
)
121 for (Letter
= 1; Letter
< 256; Letter
++)
123 if (tmw
->tmFirstChar
<= WBuf
[Letter
- 1] &&
124 WBuf
[Letter
- 1] <= tmw
->tmLastChar
)
126 tma
->tmFirstChar
= (CHAR
) Letter
;
132 /* Scan for the last ANSI character which maps to an Unicode character
134 tma
->tmLastChar
= '\0';
135 if (L
'\0' != tmw
->tmLastChar
)
137 for (Letter
= 255; 0 < Letter
; Letter
--)
139 if (tmw
->tmFirstChar
<= WBuf
[Letter
- 1] &&
140 WBuf
[Letter
- 1] <= tmw
->tmLastChar
)
142 tma
->tmLastChar
= (CHAR
) Letter
;
148 if (! MetricsCharConvert(tmw
->tmDefaultChar
, &tma
->tmDefaultChar
) ||
149 ! MetricsCharConvert(tmw
->tmBreakChar
, &tma
->tmBreakChar
))
154 tma
->tmItalic
= tmw
->tmItalic
;
155 tma
->tmUnderlined
= tmw
->tmUnderlined
;
156 tma
->tmStruckOut
= tmw
->tmStruckOut
;
157 tma
->tmPitchAndFamily
= tmw
->tmPitchAndFamily
;
158 tma
->tmCharSet
= tmw
->tmCharSet
;
164 NewTextMetricW2A(NEWTEXTMETRICA
*tma
, NEWTEXTMETRICW
*tmw
)
166 if (! TextMetricW2A((TEXTMETRICA
*) tma
, (TEXTMETRICW
*) tmw
))
171 tma
->ntmFlags
= tmw
->ntmFlags
;
172 tma
->ntmSizeEM
= tmw
->ntmSizeEM
;
173 tma
->ntmCellHeight
= tmw
->ntmCellHeight
;
174 tma
->ntmAvgWidth
= tmw
->ntmAvgWidth
;
180 NewTextMetricExW2A(NEWTEXTMETRICEXA
*tma
, NEWTEXTMETRICEXW
*tmw
)
182 if (! NewTextMetricW2A(&tma
->ntmTm
, &tmw
->ntmTm
))
187 tma
->ntmFontSig
= tmw
->ntmFontSig
;
197 TranslateCharsetInfo(DWORD
*Src
, LPCHARSETINFO Cs
, DWORD Flags
)
199 return NtGdiTranslateCharsetInfo(Src
, Cs
, Flags
);
203 IntEnumFontFamilies(HDC Dc
, LPLOGFONTW LogFont
, PVOID EnumProc
, LPARAM lParam
,
207 unsigned FontFamilySize
;
208 PFONTFAMILYINFO Info
;
211 ENUMLOGFONTEXA EnumLogFontExA
;
212 NEWTEXTMETRICEXA NewTextMetricExA
;
214 Info
= RtlAllocateHeap(GetProcessHeap(), 0,
215 INITIAL_FAMILY_COUNT
* sizeof(FONTFAMILYINFO
));
220 FontFamilyCount
= NtGdiGetFontFamilyInfo(Dc
, LogFont
, Info
, INITIAL_FAMILY_COUNT
);
221 if (FontFamilyCount
< 0)
223 RtlFreeHeap(GetProcessHeap(), 0, Info
);
226 if (INITIAL_FAMILY_COUNT
< FontFamilyCount
)
228 FontFamilySize
= FontFamilyCount
;
229 RtlFreeHeap(GetProcessHeap(), 0, Info
);
230 Info
= RtlAllocateHeap(GetProcessHeap(), 0,
231 FontFamilyCount
* sizeof(FONTFAMILYINFO
));
236 FontFamilyCount
= NtGdiGetFontFamilyInfo(Dc
, LogFont
, Info
, FontFamilySize
);
237 if (FontFamilyCount
< 0 || FontFamilySize
< FontFamilyCount
)
239 RtlFreeHeap(GetProcessHeap(), 0, Info
);
244 for (i
= 0; i
< FontFamilyCount
; i
++)
248 Ret
= ((FONTENUMPROCW
) EnumProc
)(
249 (LPLOGFONTW
)&Info
[i
].EnumLogFontEx
,
250 (LPTEXTMETRICW
)&Info
[i
].NewTextMetricEx
,
251 Info
[i
].FontType
, lParam
);
255 RosRtlLogFontW2A(&EnumLogFontExA
.elfLogFont
, &Info
[i
].EnumLogFontEx
.elfLogFont
);
256 WideCharToMultiByte(CP_THREAD_ACP
, 0, Info
[i
].EnumLogFontEx
.elfFullName
, -1,
257 EnumLogFontExA
.elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
258 WideCharToMultiByte(CP_THREAD_ACP
, 0, Info
[i
].EnumLogFontEx
.elfStyle
, -1,
259 EnumLogFontExA
.elfStyle
, LF_FACESIZE
, NULL
, NULL
);
260 WideCharToMultiByte(CP_THREAD_ACP
, 0, Info
[i
].EnumLogFontEx
.elfScript
, -1,
261 EnumLogFontExA
.elfScript
, LF_FACESIZE
, NULL
, NULL
);
262 NewTextMetricExW2A(&NewTextMetricExA
,
263 &Info
[i
].NewTextMetricEx
);
264 Ret
= ((FONTENUMPROCA
) EnumProc
)(
265 (LPLOGFONTA
)&EnumLogFontExA
,
266 (LPTEXTMETRICA
)&NewTextMetricExA
,
267 Info
[i
].FontType
, lParam
);
271 RtlFreeHeap(GetProcessHeap(), 0, Info
);
280 EnumFontFamiliesExW(HDC Dc
, LPLOGFONTW LogFont
, FONTENUMPROCW EnumFontFamProc
,
281 LPARAM lParam
, DWORD Flags
)
283 return IntEnumFontFamilies(Dc
, LogFont
, EnumFontFamProc
, lParam
, TRUE
);
291 EnumFontFamiliesW(HDC Dc
, LPCWSTR Family
, FONTENUMPROCW EnumFontFamProc
,
296 ZeroMemory(&LogFont
, sizeof(LOGFONTW
));
297 LogFont
.lfCharSet
= DEFAULT_CHARSET
;
300 lstrcpynW(LogFont
.lfFaceName
, Family
, LF_FACESIZE
);
303 return IntEnumFontFamilies(Dc
, &LogFont
, EnumFontFamProc
, lParam
, TRUE
);
311 EnumFontFamiliesExA (HDC Dc
, LPLOGFONTA LogFont
, FONTENUMPROCA EnumFontFamProc
,
312 LPARAM lParam
, DWORD dwFlags
)
316 RosRtlLogFontA2W(&LogFontW
, LogFont
);
318 /* no need to convert LogFontW back to lpLogFont b/c it's an [in] parameter only */
319 return IntEnumFontFamilies(Dc
, &LogFontW
, EnumFontFamProc
, lParam
, FALSE
);
327 EnumFontFamiliesA(HDC Dc
, LPCSTR Family
, FONTENUMPROCA EnumFontFamProc
,
332 ZeroMemory(&LogFont
, sizeof(LOGFONTW
));
333 LogFont
.lfCharSet
= DEFAULT_CHARSET
;
336 MultiByteToWideChar(CP_THREAD_ACP
, 0, Family
, -1, LogFont
.lfFaceName
, LF_FACESIZE
);
339 return IntEnumFontFamilies(Dc
, &LogFont
, EnumFontFamProc
, lParam
, FALSE
);
355 /* FIXME what to do with iFirstChar and iLastChar ??? */
356 return NtGdiGetCharWidth32 ( hdc
, iFirstChar
, iLastChar
, lpBuffer
);
372 /* FIXME what to do with iFirstChar and iLastChar ??? */
373 return NtGdiGetCharWidth32 ( hdc
, iFirstChar
, iLastChar
, lpBuffer
);
389 return NtGdiGetCharWidth32 ( hdc
, iFirstChar
, iLastChar
, lpBuffer
);
405 return NtGdiGetCharWidth32 ( hdc
, iFirstChar
, iLastChar
, lpBuffer
);