1 /* $Id: font.c,v 1.1 2004/03/23 00:18:54 gvg 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 <win32k/font.h>
18 #include <internal/font.h>
23 #define INITIAL_FAMILY_COUNT 64
26 MetricsCharConvert(WCHAR w
, CHAR
*b
)
28 UNICODE_STRING WString
;
42 RtlInitUnicodeString(&WString
, WBuf
);
45 RtlInitAnsiString(&AString
, ABuf
);
47 Status
= RtlUnicodeStringToAnsiString(&AString
, &WString
, FALSE
);
48 if (! NT_SUCCESS(Status
))
50 SetLastError(RtlNtStatusToDosError(Status
));
60 TextMetricW2A(TEXTMETRICA
*tma
, TEXTMETRICW
*tmw
)
62 UNICODE_STRING WString
;
69 tma
->tmHeight
= tmw
->tmHeight
;
70 tma
->tmAscent
= tmw
->tmAscent
;
71 tma
->tmDescent
= tmw
->tmDescent
;
72 tma
->tmInternalLeading
= tmw
->tmInternalLeading
;
73 tma
->tmExternalLeading
= tmw
->tmExternalLeading
;
74 tma
->tmAveCharWidth
= tmw
->tmAveCharWidth
;
75 tma
->tmMaxCharWidth
= tmw
->tmMaxCharWidth
;
76 tma
->tmWeight
= tmw
->tmWeight
;
77 tma
->tmOverhang
= tmw
->tmOverhang
;
78 tma
->tmDigitizedAspectX
= tmw
->tmDigitizedAspectX
;
79 tma
->tmDigitizedAspectY
= tmw
->tmDigitizedAspectY
;
81 /* The Unicode FirstChar/LastChar need not correspond to the ANSI
82 FirstChar/LastChar. For example, if the font contains glyphs for
83 letters A-Z and an accented version of the letter e, the Unicode
84 FirstChar would be A and the Unicode LastChar would be the accented
85 e. If you just translate those to ANSI, the range would become
86 letters A-E instead of A-Z.
87 We translate all possible ANSI chars to Unicode and find the first
88 and last translated character which fall into the Unicode FirstChar/
89 LastChar range and return the corresponding ANSI char. */
91 /* Setup an Ansi string containing all possible letters (note: skip '\0' at
92 the beginning since that would be interpreted as end-of-string, handle
94 for (Letter
= 1; Letter
< 256; Letter
++)
96 ABuf
[Letter
- 1] = (CHAR
) Letter
;
97 WBuf
[Letter
- 1] = L
' ';
101 RtlInitAnsiString(&AString
, ABuf
);
102 RtlInitUnicodeString(&WString
, WBuf
);
104 /* Find the corresponding Unicode characters */
105 Status
= RtlAnsiStringToUnicodeString(&WString
, &AString
, FALSE
);
106 if (! NT_SUCCESS(Status
))
108 SetLastError(RtlNtStatusToDosError(Status
));
112 /* Scan for the first ANSI character which maps to an Unicode character
114 tma
->tmFirstChar
= '\0';
115 if (L
'\0' != tmw
->tmFirstChar
)
117 for (Letter
= 1; Letter
< 256; Letter
++)
119 if (tmw
->tmFirstChar
<= WBuf
[Letter
- 1] &&
120 WBuf
[Letter
- 1] <= tmw
->tmLastChar
)
122 tma
->tmFirstChar
= (CHAR
) Letter
;
128 /* Scan for the last ANSI character which maps to an Unicode character
130 tma
->tmLastChar
= '\0';
131 if (L
'\0' != tmw
->tmLastChar
)
133 for (Letter
= 255; 0 < Letter
; Letter
--)
135 if (tmw
->tmFirstChar
<= WBuf
[Letter
- 1] &&
136 WBuf
[Letter
- 1] <= tmw
->tmLastChar
)
138 tma
->tmLastChar
= (CHAR
) Letter
;
144 if (! MetricsCharConvert(tmw
->tmDefaultChar
, &tma
->tmDefaultChar
) ||
145 ! MetricsCharConvert(tmw
->tmBreakChar
, &tma
->tmBreakChar
))
150 tma
->tmItalic
= tmw
->tmItalic
;
151 tma
->tmUnderlined
= tmw
->tmUnderlined
;
152 tma
->tmStruckOut
= tmw
->tmStruckOut
;
153 tma
->tmPitchAndFamily
= tmw
->tmPitchAndFamily
;
154 tma
->tmCharSet
= tmw
->tmCharSet
;
160 NewTextMetricW2A(NEWTEXTMETRICA
*tma
, NEWTEXTMETRICW
*tmw
)
162 if (! TextMetricW2A((TEXTMETRICA
*) tma
, (TEXTMETRICW
*) tmw
))
167 tma
->ntmFlags
= tmw
->ntmFlags
;
168 tma
->ntmSizeEM
= tmw
->ntmSizeEM
;
169 tma
->ntmCellHeight
= tmw
->ntmCellHeight
;
170 tma
->ntmAvgWidth
= tmw
->ntmAvgWidth
;
176 NewTextMetricExW2A(NEWTEXTMETRICEXA
*tma
, NEWTEXTMETRICEXW
*tmw
)
178 if (! NewTextMetricW2A(&tma
->ntmTm
, &tmw
->ntmTm
))
183 tma
->ntmFontSig
= tmw
->ntmFontSig
;
193 TranslateCharsetInfo(DWORD
*Src
, LPCHARSETINFO Cs
, DWORD Flags
)
195 return NtGdiTranslateCharsetInfo(Src
, Cs
, Flags
);
199 IntEnumFontFamilies(HDC Dc
, LPLOGFONTW LogFont
, PVOID EnumProc
, LPARAM lParam
,
203 unsigned FontFamilySize
;
204 PFONTFAMILYINFO Info
;
207 ENUMLOGFONTEXA EnumLogFontExA
;
208 NEWTEXTMETRICEXA NewTextMetricExA
;
210 Info
= RtlAllocateHeap(GetProcessHeap(), 0,
211 INITIAL_FAMILY_COUNT
* sizeof(FONTFAMILYINFO
));
216 FontFamilyCount
= NtGdiGetFontFamilyInfo(Dc
, LogFont
, Info
, INITIAL_FAMILY_COUNT
);
217 if (FontFamilyCount
< 0)
219 RtlFreeHeap(GetProcessHeap(), 0, Info
);
222 if (INITIAL_FAMILY_COUNT
< FontFamilyCount
)
224 FontFamilySize
= FontFamilyCount
;
225 RtlFreeHeap(GetProcessHeap(), 0, Info
);
226 Info
= RtlAllocateHeap(GetProcessHeap(), 0,
227 FontFamilyCount
* sizeof(FONTFAMILYINFO
));
232 FontFamilyCount
= NtGdiGetFontFamilyInfo(Dc
, LogFont
, Info
, FontFamilySize
);
233 if (FontFamilyCount
< 0 || FontFamilySize
< FontFamilyCount
)
235 RtlFreeHeap(GetProcessHeap(), 0, Info
);
240 for (i
= 0; i
< FontFamilyCount
; i
++)
244 Ret
= ((FONTENUMEXPROCW
) EnumProc
)(&Info
[i
].EnumLogFontEx
, &Info
[i
].NewTextMetricEx
,
245 Info
[i
].FontType
, lParam
);
249 RosRtlLogFontW2A(&EnumLogFontExA
.elfLogFont
, &Info
[i
].EnumLogFontEx
.elfLogFont
);
250 WideCharToMultiByte(CP_THREAD_ACP
, 0, Info
[i
].EnumLogFontEx
.elfFullName
, -1,
251 EnumLogFontExA
.elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
252 WideCharToMultiByte(CP_THREAD_ACP
, 0, Info
[i
].EnumLogFontEx
.elfStyle
, -1,
253 EnumLogFontExA
.elfStyle
, LF_FACESIZE
, NULL
, NULL
);
254 WideCharToMultiByte(CP_THREAD_ACP
, 0, Info
[i
].EnumLogFontEx
.elfScript
, -1,
255 EnumLogFontExA
.elfScript
, LF_FACESIZE
, NULL
, NULL
);
256 NewTextMetricExW2A(&NewTextMetricExA
,
257 &Info
[i
].NewTextMetricEx
);
258 Ret
= ((FONTENUMEXPROCA
) EnumProc
)(&EnumLogFontExA
, &NewTextMetricExA
,
259 Info
[i
].FontType
, lParam
);
263 RtlFreeHeap(GetProcessHeap(), 0, Info
);
272 EnumFontFamiliesExW(HDC Dc
, LPLOGFONTW LogFont
, FONTENUMEXPROCW EnumFontFamProc
,
273 LPARAM lParam
, DWORD Flags
)
275 return IntEnumFontFamilies(Dc
, LogFont
, EnumFontFamProc
, lParam
, TRUE
);
283 EnumFontFamiliesW(HDC Dc
, LPCWSTR Family
, FONTENUMPROCW EnumFontFamProc
,
288 ZeroMemory(&LogFont
, sizeof(LOGFONTW
));
289 LogFont
.lfCharSet
= DEFAULT_CHARSET
;
292 lstrcpynW(LogFont
.lfFaceName
, Family
, LF_FACESIZE
);
295 return IntEnumFontFamilies(Dc
, &LogFont
, EnumFontFamProc
, lParam
, TRUE
);
303 EnumFontFamiliesExA (HDC Dc
, LPLOGFONTA LogFont
, FONTENUMEXPROCA EnumFontFamProc
,
304 LPARAM lParam
, DWORD dwFlags
)
308 RosRtlLogFontA2W(&LogFontW
, LogFont
);
310 /* no need to convert LogFontW back to lpLogFont b/c it's an [in] parameter only */
311 return IntEnumFontFamilies(Dc
, &LogFontW
, EnumFontFamProc
, lParam
, FALSE
);
319 EnumFontFamiliesA(HDC Dc
, LPCSTR Family
, FONTENUMPROCA EnumFontFamProc
,
324 ZeroMemory(&LogFont
, sizeof(LOGFONTW
));
325 LogFont
.lfCharSet
= DEFAULT_CHARSET
;
328 MultiByteToWideChar(CP_THREAD_ACP
, 0, Family
, -1, LogFont
.lfFaceName
, LF_FACESIZE
);
331 return IntEnumFontFamilies(Dc
, &LogFont
, EnumFontFamProc
, lParam
, FALSE
);