2 * Copyright (C) 2007 Google (Evan Stade)
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/debug.h"
26 #include "wine/unicode.h"
28 WINE_DEFAULT_DEBUG_CHANNEL (gdiplus
);
33 #include "gdiplus_private.h"
35 GpStatus WINGDIPAPI
GdipCreateFontFromLogfontW(HDC hdc
,
36 GDIPCONST LOGFONTW
*logfont
, GpFont
**font
)
42 return InvalidParameter
;
44 *font
= GdipAlloc(sizeof(GpFont
));
45 if(!*font
) return OutOfMemory
;
47 memcpy(&(*font
)->lfw
.lfFaceName
, logfont
->lfFaceName
, LF_FACESIZE
*
49 (*font
)->lfw
.lfHeight
= logfont
->lfHeight
;
50 (*font
)->lfw
.lfItalic
= logfont
->lfItalic
;
51 (*font
)->lfw
.lfUnderline
= logfont
->lfUnderline
;
52 (*font
)->lfw
.lfStrikeOut
= logfont
->lfStrikeOut
;
54 hfont
= CreateFontIndirectW(&(*font
)->lfw
);
55 oldfont
= SelectObject(hdc
, hfont
);
56 GetTextMetricsW(hdc
, &textmet
);
58 (*font
)->lfw
.lfHeight
= -textmet
.tmHeight
;
59 (*font
)->lfw
.lfWeight
= textmet
.tmWeight
;
61 SelectObject(hdc
, oldfont
);
67 GpStatus WINGDIPAPI
GdipCreateFontFromLogfontA(HDC hdc
,
68 GDIPCONST LOGFONTA
*lfa
, GpFont
**font
)
73 return InvalidParameter
;
75 memcpy(&lfw
, lfa
, FIELD_OFFSET(LOGFONTA
,lfFaceName
) );
77 if(!MultiByteToWideChar(CP_ACP
, 0, lfa
->lfFaceName
, -1, lfw
.lfFaceName
, LF_FACESIZE
))
80 GdipCreateFontFromLogfontW(hdc
, &lfw
, font
);
85 GpStatus WINGDIPAPI
GdipDeleteFont(GpFont
* font
)
88 return InvalidParameter
;
95 GpStatus WINGDIPAPI
GdipCreateFontFromDC(HDC hdc
, GpFont
**font
)
101 return InvalidParameter
;
103 hfont
= (HFONT
)GetCurrentObject(hdc
, OBJ_FONT
);
107 if(!GetObjectW(hfont
, sizeof(LOGFONTW
), &lfw
))
110 return GdipCreateFontFromLogfontW(hdc
, &lfw
, font
);
113 /* FIXME: use graphics */
114 GpStatus WINGDIPAPI
GdipGetLogFontW(GpFont
*font
, GpGraphics
*graphics
,
117 if(!font
|| !graphics
|| !lfw
)
118 return InvalidParameter
;
125 GpStatus WINGDIPAPI
GdipCloneFont(GpFont
*font
, GpFont
**cloneFont
)
127 if(!font
|| !cloneFont
)
128 return InvalidParameter
;
130 *cloneFont
= GdipAlloc(sizeof(GpFont
));
131 if(!*cloneFont
) return OutOfMemory
;
138 /* Borrowed from GDI32 */
139 static INT CALLBACK
is_font_installed_proc(const LOGFONTW
*elf
,
140 const TEXTMETRICW
*ntm
, DWORD type
, LPARAM lParam
)
145 static BOOL
is_font_installed(const WCHAR
*name
)
150 if(!EnumFontFamiliesW(hdc
, name
, is_font_installed_proc
, 0))
157 /*******************************************************************************
158 * GdipCreateFontFamilyFromName [GDIPLUS.@]
160 * Creates a font family object based on a supplied name
163 * name [I] Name of the font
164 * fontCollection [I] What font collection (if any) the font belongs to (may be NULL)
165 * FontFamily [O] Pointer to the resulting FontFamily object
169 * FAILURE: FamilyNotFound if the requested FontFamily does not exist on the system
170 * FAILURE: Invalid parameter if FontFamily or name is NULL
173 * If fontCollection is NULL then the object is not part of any collection
177 GpStatus WINGDIPAPI
GdipCreateFontFamilyFromName(GDIPCONST WCHAR
*name
,
178 GpFontCollection
*fontCollection
,
179 GpFontFamily
**FontFamily
)
181 GpFontFamily
* ffamily
;
186 TRACE("%s, %p %p\n", debugstr_w(name
), fontCollection
, FontFamily
);
188 if (!(name
&& FontFamily
))
189 return InvalidParameter
;
191 FIXME("No support for FontCollections yet!\n");
192 if (!is_font_installed(name
))
193 return FontFamilyNotFound
;
195 ffamily
= GdipAlloc(sizeof (GpFontFamily
));
196 if (!ffamily
) return OutOfMemory
;
197 ffamily
->tmw
= GdipAlloc(sizeof (TEXTMETRICW
));
198 if (!ffamily
->tmw
) {GdipFree (ffamily
); return OutOfMemory
;}
201 lstrcpynW(lfw
.lfFaceName
, name
, sizeof(WCHAR
) * LF_FACESIZE
);
202 hFont
= CreateFontIndirectW (&lfw
);
203 SelectObject(hdc
, hFont
);
205 GetTextMetricsW(hdc
, ffamily
->tmw
);
207 ffamily
->FamilyName
= GdipAlloc(LF_FACESIZE
* sizeof (WCHAR
));
208 if (!ffamily
->FamilyName
)
214 lstrcpynW(ffamily
->FamilyName
, name
, sizeof(WCHAR
) * LF_FACESIZE
);
216 *FontFamily
= ffamily
;
222 /*******************************************************************************
223 * GdipGetFamilyName [GDIPLUS.@]
225 * Returns the family name into name
228 * *family [I] Family to retrieve from
229 * *name [O] WCHARS of the family name
234 * FAILURE: InvalidParameter if family is NULL
237 * If name is a NULL ptr, then both XP and Vista will crash (so we do as well)
239 GpStatus WINGDIPAPI
GdipGetFamilyName (GDIPCONST GpFontFamily
*family
,
240 WCHAR
*name
, LANGID language
)
243 return InvalidParameter
;
245 TRACE("%p, %p, %d\n", family
, name
, language
);
247 if (language
!= LANG_NEUTRAL
)
248 FIXME("No support for handling of multiple languages!\n");
250 lstrcpynW (name
, family
->FamilyName
, LF_FACESIZE
);
256 /*****************************************************************************
257 * GdipDeleteFontFamily [GDIPLUS.@]
259 * Removes the specified FontFamily
262 * *FontFamily [I] The family to delete
266 * FAILURE: InvalidParameter if FontFamily is NULL.
269 GpStatus WINGDIPAPI
GdipDeleteFontFamily(GpFontFamily
*FontFamily
)
272 return InvalidParameter
;
273 TRACE("Deleting %p (%s)\n", FontFamily
, debugstr_w(FontFamily
->FamilyName
));
275 if (FontFamily
->FamilyName
) GdipFree (FontFamily
->FamilyName
);
276 if (FontFamily
->tmw
) GdipFree (FontFamily
->tmw
);
277 GdipFree (FontFamily
);
282 /*****************************************************************************
283 * GdipGetGenericFontFamilyMonospace [GDIPLUS.@]
285 * Obtains a serif family (Courier New on Windows)
288 * **nativeFamily [I] Where the font will be stored
291 * InvalidParameter if nativeFamily is NULL.
294 GpStatus WINGDIPAPI
GdipGetGenericFontFamilyMonospace(GpFontFamily
**nativeFamily
)
296 static const WCHAR CourierNew
[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
298 if (nativeFamily
== NULL
) return InvalidParameter
;
300 return GdipCreateFontFamilyFromName(CourierNew
, NULL
, nativeFamily
);
303 /*****************************************************************************
304 * GdipGetGenericFontFamilySerif [GDIPLUS.@]
306 * Obtains a serif family (Times New Roman on Windows)
309 * **nativeFamily [I] Where the font will be stored
312 * InvalidParameter if nativeFamily is NULL.
315 GpStatus WINGDIPAPI
GdipGetGenericFontFamilySerif(GpFontFamily
**nativeFamily
)
317 static const WCHAR TimesNewRoman
[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
319 if (nativeFamily
== NULL
) return InvalidParameter
;
321 return GdipCreateFontFamilyFromName(TimesNewRoman
, NULL
, nativeFamily
);
324 /*****************************************************************************
325 * GdipGetGenericFontFamilySansSerif [GDIPLUS.@]
327 * Obtains a serif family (Microsoft Sans Serif on Windows)
330 * **nativeFamily [I] Where the font will be stored
333 * InvalidParameter if nativeFamily is NULL.
336 GpStatus WINGDIPAPI
GdipGetGenericFontFamilySansSerif(GpFontFamily
**nativeFamily
)
338 /* FIXME: On Windows this is called Microsoft Sans Serif, this shouldn't
340 static const WCHAR MSSansSerif
[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
342 if (nativeFamily
== NULL
) return InvalidParameter
;
344 return GdipCreateFontFamilyFromName(MSSansSerif
, NULL
, nativeFamily
);