2008-03-25 17:34:57 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2007 Google (Evan Stade)
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "wingdi.h"
|
|
|
|
#include "winnls.h"
|
2008-07-02 08:19:00 +00:00
|
|
|
#include "winreg.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
#include "wine/unicode.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL (gdiplus);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
#include "objbase.h"
|
|
|
|
|
|
|
|
#include "gdiplus.h"
|
|
|
|
#include "gdiplus_private.h"
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
static const REAL mm_per_inch = 25.4;
|
|
|
|
static const REAL inch_per_point = 1.0/72.0;
|
|
|
|
|
2009-05-09 09:26:16 +00:00
|
|
|
static GpFontCollection installedFontCollection = {0};
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
static inline REAL get_dpi (void)
|
|
|
|
{
|
|
|
|
REAL dpi;
|
|
|
|
GpGraphics *graphics;
|
|
|
|
HDC hdc = GetDC(0);
|
|
|
|
GdipCreateFromHDC (hdc, &graphics);
|
|
|
|
GdipGetDpiX(graphics, &dpi);
|
|
|
|
GdipDeleteGraphics(graphics);
|
|
|
|
ReleaseDC (0, hdc);
|
|
|
|
|
|
|
|
return dpi;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline REAL point_to_pixel (REAL point)
|
|
|
|
{
|
|
|
|
return point * get_dpi() * inch_per_point;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline REAL inch_to_pixel (REAL inch)
|
|
|
|
{
|
|
|
|
return inch * get_dpi();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline REAL document_to_pixel (REAL doc)
|
|
|
|
{
|
|
|
|
return doc * (get_dpi() / 300.0); /* Per MSDN */
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline REAL mm_to_pixel (REAL mm)
|
|
|
|
{
|
|
|
|
return mm * (get_dpi() / mm_per_inch);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCreateFont [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Create a new font based off of a FontFamily
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* *fontFamily [I] Family to base the font off of
|
|
|
|
* emSize [I] Size of the font
|
|
|
|
* style [I] Bitwise OR of FontStyle enumeration
|
|
|
|
* unit [I] Unit emSize is measured in
|
|
|
|
* **font [I] the resulting Font object
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter if fontfamily or font is NULL.
|
|
|
|
* FAILURE: FontFamilyNotFound if an invalid FontFamily is given
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* UnitDisplay is unsupported.
|
|
|
|
* emSize is stored separately from lfHeight, to hold the fraction.
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
|
|
|
REAL emSize, INT style, Unit unit, GpFont **font)
|
|
|
|
{
|
|
|
|
WCHAR facename[LF_FACESIZE];
|
|
|
|
LOGFONTW* lfw;
|
2008-08-05 12:23:58 +00:00
|
|
|
const NEWTEXTMETRICW* tmw;
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus stat;
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if (!fontFamily || !font)
|
2008-07-02 08:19:00 +00:00
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
TRACE("%p (%s), %f, %d, %d, %p\n", fontFamily,
|
|
|
|
debugstr_w(fontFamily->FamilyName), emSize, style, unit, font);
|
|
|
|
|
|
|
|
stat = GdipGetFamilyName (fontFamily, facename, 0);
|
|
|
|
if (stat != Ok) return stat;
|
|
|
|
*font = GdipAlloc(sizeof(GpFont));
|
|
|
|
|
|
|
|
tmw = &fontFamily->tmw;
|
|
|
|
lfw = &((*font)->lfw);
|
|
|
|
ZeroMemory(&(*lfw), sizeof(*lfw));
|
|
|
|
|
|
|
|
lfw->lfWeight = tmw->tmWeight;
|
|
|
|
lfw->lfItalic = tmw->tmItalic;
|
|
|
|
lfw->lfUnderline = tmw->tmUnderlined;
|
|
|
|
lfw->lfStrikeOut = tmw->tmStruckOut;
|
|
|
|
lfw->lfCharSet = tmw->tmCharSet;
|
|
|
|
lfw->lfPitchAndFamily = tmw->tmPitchAndFamily;
|
2008-08-05 12:23:58 +00:00
|
|
|
lstrcpynW(lfw->lfFaceName, facename, LF_FACESIZE);
|
2008-07-02 08:19:00 +00:00
|
|
|
|
|
|
|
switch (unit)
|
|
|
|
{
|
|
|
|
case UnitWorld:
|
|
|
|
/* FIXME: Figure out when World != Pixel */
|
|
|
|
lfw->lfHeight = emSize; break;
|
|
|
|
case UnitDisplay:
|
|
|
|
FIXME("Unknown behavior for UnitDisplay! Please report!\n");
|
|
|
|
/* FIXME: Figure out how this works...
|
|
|
|
* MSDN says that if "DISPLAY" is a monitor, then pixel should be
|
|
|
|
* used. That's not what I got. Tests on Windows revealed no output,
|
|
|
|
* and the tests in tests/font crash windows */
|
|
|
|
lfw->lfHeight = 0; break;
|
|
|
|
case UnitPixel:
|
|
|
|
lfw->lfHeight = emSize; break;
|
|
|
|
case UnitPoint:
|
|
|
|
lfw->lfHeight = point_to_pixel(emSize); break;
|
|
|
|
case UnitInch:
|
|
|
|
lfw->lfHeight = inch_to_pixel(emSize); break;
|
|
|
|
case UnitDocument:
|
|
|
|
lfw->lfHeight = document_to_pixel(emSize); break;
|
|
|
|
case UnitMillimeter:
|
|
|
|
lfw->lfHeight = mm_to_pixel(emSize); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
lfw->lfHeight *= -1;
|
|
|
|
|
|
|
|
lfw->lfWeight = style & FontStyleBold ? 700 : 400;
|
|
|
|
lfw->lfItalic = style & FontStyleItalic;
|
|
|
|
lfw->lfUnderline = style & FontStyleUnderline;
|
|
|
|
lfw->lfStrikeOut = style & FontStyleStrikeout;
|
|
|
|
|
|
|
|
(*font)->unit = unit;
|
|
|
|
(*font)->emSize = emSize;
|
2008-12-06 09:26:01 +00:00
|
|
|
(*font)->height = tmw->ntmSizeEM;
|
|
|
|
(*font)->line_spacing = tmw->tmAscent + tmw->tmDescent + tmw->tmExternalLeading;
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *font);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCreateFontFromLogfontW [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
|
|
|
|
GDIPCONST LOGFONTW *logfont, GpFont **font)
|
|
|
|
{
|
|
|
|
HFONT hfont, oldfont;
|
|
|
|
TEXTMETRICW textmet;
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p, %p)\n", hdc, logfont, font);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!logfont || !font)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
if (logfont->lfFaceName[0] == 0)
|
|
|
|
return NotTrueTypeFont;
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
*font = GdipAlloc(sizeof(GpFont));
|
|
|
|
if(!*font) return OutOfMemory;
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
memcpy((*font)->lfw.lfFaceName, logfont->lfFaceName, LF_FACESIZE *
|
2008-03-25 17:34:57 +00:00
|
|
|
sizeof(WCHAR));
|
|
|
|
(*font)->lfw.lfHeight = logfont->lfHeight;
|
|
|
|
(*font)->lfw.lfItalic = logfont->lfItalic;
|
|
|
|
(*font)->lfw.lfUnderline = logfont->lfUnderline;
|
|
|
|
(*font)->lfw.lfStrikeOut = logfont->lfStrikeOut;
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
(*font)->emSize = logfont->lfHeight;
|
|
|
|
(*font)->unit = UnitPixel;
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
hfont = CreateFontIndirectW(&(*font)->lfw);
|
|
|
|
oldfont = SelectObject(hdc, hfont);
|
|
|
|
GetTextMetricsW(hdc, &textmet);
|
|
|
|
|
2009-05-09 09:26:16 +00:00
|
|
|
(*font)->lfw.lfHeight = -(textmet.tmHeight-textmet.tmInternalLeading);
|
2008-03-25 17:34:57 +00:00
|
|
|
(*font)->lfw.lfWeight = textmet.tmWeight;
|
2008-12-16 18:41:07 +00:00
|
|
|
(*font)->lfw.lfCharSet = textmet.tmCharSet;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
(*font)->height = 1; /* FIXME: need NEWTEXTMETRIC.ntmSizeEM here */
|
|
|
|
(*font)->line_spacing = textmet.tmAscent + textmet.tmDescent + textmet.tmExternalLeading;
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
SelectObject(hdc, oldfont);
|
|
|
|
DeleteObject(hfont);
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *font);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCreateFontFromLogfontA [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateFontFromLogfontA(HDC hdc,
|
|
|
|
GDIPCONST LOGFONTA *lfa, GpFont **font)
|
|
|
|
{
|
|
|
|
LOGFONTW lfw;
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p, %p)\n", hdc, lfa, font);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!lfa || !font)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-06-01 13:14:02 +00:00
|
|
|
memcpy(&lfw, lfa, FIELD_OFFSET(LOGFONTA,lfFaceName) );
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if(!MultiByteToWideChar(CP_ACP, 0, lfa->lfFaceName, -1, lfw.lfFaceName, LF_FACESIZE))
|
|
|
|
return GenericError;
|
|
|
|
|
2009-05-05 15:35:05 +00:00
|
|
|
return GdipCreateFontFromLogfontW(hdc, &lfw, font);
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipDeleteFont [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipDeleteFont(GpFont* font)
|
|
|
|
{
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p)\n", font);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!font)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
GdipFree(font);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCreateFontFromDC [GDIPLUS.@]
|
|
|
|
*/
|
2008-05-04 19:41:25 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC hdc, GpFont **font)
|
|
|
|
{
|
|
|
|
HFONT hfont;
|
|
|
|
LOGFONTW lfw;
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p)\n", hdc, font);
|
|
|
|
|
2008-05-04 19:41:25 +00:00
|
|
|
if(!font)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
hfont = GetCurrentObject(hdc, OBJ_FONT);
|
2008-05-04 19:41:25 +00:00
|
|
|
if(!hfont)
|
|
|
|
return GenericError;
|
|
|
|
|
|
|
|
if(!GetObjectW(hfont, sizeof(LOGFONTW), &lfw))
|
|
|
|
return GenericError;
|
|
|
|
|
|
|
|
return GdipCreateFontFromLogfontW(hdc, &lfw, font);
|
|
|
|
}
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetFamily [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Returns the FontFamily for the specified Font
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* font [I] Font to request from
|
|
|
|
* family [O] Resulting FontFamily object
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: An element of GpStatus
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
|
|
|
|
{
|
|
|
|
TRACE("%p %p\n", font, family);
|
|
|
|
|
|
|
|
if (!(font && family))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return GdipCreateFontFamilyFromName(font->lfw.lfFaceName, NULL, family);
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* GdipGetFontSize [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Returns the size of the font in Units
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* *font [I] The font to retrieve size from
|
|
|
|
* *size [O] Pointer to hold retrieved value
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
2009-05-05 15:35:05 +00:00
|
|
|
* FAILURE: InvalidParameter (font or size was NULL)
|
2008-07-02 08:19:00 +00:00
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Size returned is actually emSize -- not internal size used for drawing.
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
|
|
|
|
{
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p)\n", font, size);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if (!(font && size)) return InvalidParameter;
|
|
|
|
|
|
|
|
*size = font->emSize;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetFontStyle [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Gets the font's style, returned in bitwise OR of FontStyle enumeration
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* font [I] font to request from
|
|
|
|
* style [O] resulting pointer to a FontStyle enumeration
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
|
|
|
|
{
|
|
|
|
TRACE("%p %p\n", font, style);
|
|
|
|
|
|
|
|
if (!(font && style))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if (font->lfw.lfWeight > 400)
|
|
|
|
*style = FontStyleBold;
|
|
|
|
else
|
|
|
|
*style = 0;
|
|
|
|
if (font->lfw.lfItalic)
|
|
|
|
*style |= FontStyleItalic;
|
|
|
|
if (font->lfw.lfUnderline)
|
|
|
|
*style |= FontStyleUnderline;
|
|
|
|
if (font->lfw.lfStrikeOut)
|
|
|
|
*style |= FontStyleStrikeout;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetFontUnit [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* font [I] Font to retrieve from
|
|
|
|
* unit [O] Return value
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* FAILURE: font or unit was NULL
|
|
|
|
* OK: otherwise
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
|
|
|
|
{
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p)\n", font, unit);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if (!(font && unit)) return InvalidParameter;
|
|
|
|
|
|
|
|
*unit = font->unit;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2009-02-14 08:14:34 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetLogFontA [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetLogFontA(GpFont *font, GpGraphics *graphics,
|
|
|
|
LOGFONTA *lfa)
|
|
|
|
{
|
|
|
|
GpStatus status;
|
|
|
|
LOGFONTW lfw;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %p)\n", font, graphics, lfa);
|
|
|
|
|
|
|
|
status = GdipGetLogFontW(font, graphics, &lfw);
|
|
|
|
if(status != Ok)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
memcpy(lfa, &lfw, FIELD_OFFSET(LOGFONTA,lfFaceName) );
|
|
|
|
|
2009-05-05 15:35:05 +00:00
|
|
|
if(!WideCharToMultiByte(CP_ACP, 0, lfw.lfFaceName, -1, lfa->lfFaceName, LF_FACESIZE, NULL, NULL))
|
2009-02-14 08:14:34 +00:00
|
|
|
return GenericError;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetLogFontW [GDIPLUS.@]
|
|
|
|
*/
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
|
|
|
|
LOGFONTW *lfw)
|
|
|
|
{
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p, %p)\n", font, graphics, lfw);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/* FIXME: use graphics */
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!font || !graphics || !lfw)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*lfw = font->lfw;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
2008-05-04 19:41:25 +00:00
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCloneFont [GDIPLUS.@]
|
|
|
|
*/
|
2008-05-04 19:41:25 +00:00
|
|
|
GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
|
|
|
|
{
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %p)\n", font, cloneFont);
|
|
|
|
|
2008-05-04 19:41:25 +00:00
|
|
|
if(!font || !cloneFont)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*cloneFont = GdipAlloc(sizeof(GpFont));
|
|
|
|
if(!*cloneFont) return OutOfMemory;
|
|
|
|
|
|
|
|
**cloneFont = *font;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetFontHeight [GDIPLUS.@]
|
|
|
|
* PARAMS
|
|
|
|
* font [I] Font to retrieve height from
|
|
|
|
* graphics [I] The current graphics context
|
|
|
|
* height [O] Resulting height
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: Another element of GpStatus
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Forwards to GdipGetFontHeightGivenDPI
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
|
|
|
|
GDIPCONST GpGraphics *graphics, REAL *height)
|
|
|
|
{
|
|
|
|
REAL dpi;
|
2010-11-20 11:24:17 +00:00
|
|
|
GpStatus stat;
|
2008-09-07 10:32:49 +00:00
|
|
|
|
|
|
|
TRACE("%p %p %p\n", font, graphics, height);
|
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
|
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
stat = GdipGetFontHeightGivenDPI(font, dpi, height);
|
2008-09-07 10:32:49 +00:00
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
return stat;
|
2008-09-07 10:32:49 +00:00
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetFontHeightGivenDPI [GDIPLUS.@]
|
|
|
|
* PARAMS
|
|
|
|
* font [I] Font to retrieve DPI from
|
|
|
|
* dpi [I] DPI to assume
|
|
|
|
* height [O] Return value
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter if font or height is NULL
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* According to MSDN, the result is (lineSpacing)*(fontSize / emHeight)*dpi
|
|
|
|
* (for anything other than unit Pixel)
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
REAL font_height;
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("%p (%s), %f, %p\n", font,
|
|
|
|
debugstr_w(font->lfw.lfFaceName), dpi, height);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if (!(font && height)) return InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
font_height = font->line_spacing * (font->emSize / font->height);
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
switch (font->unit)
|
|
|
|
{
|
|
|
|
case UnitPixel:
|
2010-04-20 08:30:10 +00:00
|
|
|
case UnitWorld:
|
2008-12-06 09:26:01 +00:00
|
|
|
*height = font_height;
|
|
|
|
break;
|
|
|
|
case UnitPoint:
|
|
|
|
*height = font_height * dpi * inch_per_point;
|
|
|
|
break;
|
|
|
|
case UnitInch:
|
|
|
|
*height = font_height * dpi;
|
|
|
|
break;
|
|
|
|
case UnitDocument:
|
|
|
|
*height = font_height * (dpi / 300.0);
|
|
|
|
break;
|
|
|
|
case UnitMillimeter:
|
|
|
|
*height = font_height * (dpi / mm_per_inch);
|
2008-09-07 10:32:49 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
FIXME("Unhandled unit type: %d\n", font->unit);
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
2008-08-05 12:23:58 +00:00
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Borrowed from GDI32:
|
|
|
|
*
|
|
|
|
* Elf is really an ENUMLOGFONTEXW, and ntm is a NEWTEXTMETRICEXW.
|
|
|
|
* We have to use other types because of the FONTENUMPROCW definition.
|
|
|
|
*/
|
2008-07-02 08:19:00 +00:00
|
|
|
static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
|
|
|
|
const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
if (!ntm || type == RASTER_FONTTYPE)
|
2008-08-05 12:23:58 +00:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(NEWTEXTMETRICW*)lParam = *(const NEWTEXTMETRICW*)ntm;
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
static BOOL find_installed_font(const WCHAR *name, NEWTEXTMETRICW *ntm)
|
2008-07-02 08:19:00 +00:00
|
|
|
{
|
|
|
|
HDC hdc = GetDC(0);
|
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
2008-11-25 14:17:27 +00:00
|
|
|
if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)ntm))
|
2008-07-02 08:19:00 +00:00
|
|
|
ret = TRUE;
|
|
|
|
|
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCreateFontFamilyFromName [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Creates a font family object based on a supplied name
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* name [I] Name of the font
|
|
|
|
* fontCollection [I] What font collection (if any) the font belongs to (may be NULL)
|
|
|
|
* FontFamily [O] Pointer to the resulting FontFamily object
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: FamilyNotFound if the requested FontFamily does not exist on the system
|
|
|
|
* FAILURE: Invalid parameter if FontFamily or name is NULL
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* If fontCollection is NULL then the object is not part of any collection
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
|
|
|
GpFontCollection *fontCollection,
|
|
|
|
GpFontFamily **FontFamily)
|
|
|
|
{
|
|
|
|
GpFontFamily* ffamily;
|
2008-08-05 12:23:58 +00:00
|
|
|
NEWTEXTMETRICW ntm;
|
2008-07-02 08:19:00 +00:00
|
|
|
|
|
|
|
TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily);
|
|
|
|
|
|
|
|
if (!(name && FontFamily))
|
|
|
|
return InvalidParameter;
|
|
|
|
if (fontCollection)
|
|
|
|
FIXME("No support for FontCollections yet!\n");
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if (!find_installed_font(name, &ntm))
|
2008-07-02 08:19:00 +00:00
|
|
|
return FontFamilyNotFound;
|
|
|
|
|
|
|
|
ffamily = GdipAlloc(sizeof (GpFontFamily));
|
|
|
|
if (!ffamily) return OutOfMemory;
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
ffamily->tmw = ntm;
|
|
|
|
lstrcpynW(ffamily->FamilyName, name, LF_FACESIZE);
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
*FontFamily = ffamily;
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", ffamily);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* GdipCloneFontFamily [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Creates a deep copy of a Font Family object
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* FontFamily [I] Font to clone
|
|
|
|
* clonedFontFamily [O] The resulting cloned font
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily** clonedFontFamily)
|
|
|
|
{
|
|
|
|
if (!(FontFamily && clonedFontFamily)) return InvalidParameter;
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
TRACE("stub: %p (%s), %p\n", FontFamily,
|
|
|
|
debugstr_w(FontFamily->FamilyName), clonedFontFamily);
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
*clonedFontFamily = GdipAlloc(sizeof(GpFontFamily));
|
|
|
|
if (!*clonedFontFamily) return OutOfMemory;
|
|
|
|
|
|
|
|
(*clonedFontFamily)->tmw = FontFamily->tmw;
|
|
|
|
lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName);
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *clonedFontFamily);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetFamilyName [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Returns the family name into name
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* *family [I] Family to retrieve from
|
|
|
|
* *name [O] WCHARS of the family name
|
|
|
|
* LANGID [I] charset
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter if family is NULL
|
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* If name is a NULL ptr, then both XP and Vista will crash (so we do as well)
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFamilyName (GDIPCONST GpFontFamily *family,
|
|
|
|
WCHAR *name, LANGID language)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
static int lang_fixme;
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if (family == NULL)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
TRACE("%p, %p, %d\n", family, name, language);
|
|
|
|
|
2010-04-20 08:30:10 +00:00
|
|
|
if (language != LANG_NEUTRAL && !lang_fixme++)
|
2008-07-02 08:19:00 +00:00
|
|
|
FIXME("No support for handling of multiple languages!\n");
|
|
|
|
|
|
|
|
lstrcpynW (name, family->FamilyName, LF_FACESIZE);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipDeleteFontFamily [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Removes the specified FontFamily
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* *FontFamily [I] The family to delete
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter if FontFamily is NULL.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
|
|
|
|
{
|
|
|
|
if (!FontFamily)
|
|
|
|
return InvalidParameter;
|
|
|
|
TRACE("Deleting %p (%s)\n", FontFamily, debugstr_w(FontFamily->FamilyName));
|
|
|
|
|
|
|
|
GdipFree (FontFamily);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily *family,
|
|
|
|
INT style, UINT16* CellAscent)
|
|
|
|
{
|
|
|
|
if (!(family && CellAscent)) return InvalidParameter;
|
|
|
|
|
|
|
|
*CellAscent = family->tmw.tmAscent;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily *family,
|
|
|
|
INT style, UINT16* CellDescent)
|
|
|
|
{
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p, %d, %p)\n", family, style, CellDescent);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if (!(family && CellDescent)) return InvalidParameter;
|
|
|
|
|
|
|
|
*CellDescent = family->tmw.tmDescent;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetEmHeight [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Gets the height of the specified family in EmHeights
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* family [I] Family to retrieve from
|
|
|
|
* style [I] (optional) style
|
|
|
|
* EmHeight [O] return value
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, UINT16* EmHeight)
|
|
|
|
{
|
|
|
|
if (!(family && EmHeight)) return InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p (%s), %d, %p\n", family, debugstr_w(family->FamilyName), style, EmHeight);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
*EmHeight = family->tmw.ntmSizeEM;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* GdipGetLineSpacing [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Returns the line spacing in design units
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* family [I] Family to retrieve from
|
|
|
|
* style [I] (Optional) font style
|
|
|
|
* LineSpacing [O] Return value
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* SUCCESS: Ok
|
|
|
|
* FAILURE: InvalidParameter (family or LineSpacing was NULL)
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family,
|
|
|
|
INT style, UINT16* LineSpacing)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p, %d, %p\n", family, style, LineSpacing);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if (!(family && LineSpacing))
|
|
|
|
return InvalidParameter;
|
2008-08-05 12:23:58 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
if (style) FIXME("ignoring style\n");
|
|
|
|
|
|
|
|
*LineSpacing = family->tmw.tmAscent + family->tmw.tmDescent + family->tmw.tmExternalLeading;
|
|
|
|
|
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
static INT CALLBACK font_has_style_proc(const LOGFONTW *elf,
|
|
|
|
const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
|
|
|
|
{
|
|
|
|
INT fontstyle=0;
|
|
|
|
|
|
|
|
if (!ntm) return 1;
|
|
|
|
|
|
|
|
if (ntm->tmWeight >= FW_BOLD) fontstyle |= FontStyleBold;
|
|
|
|
if (ntm->tmItalic) fontstyle |= FontStyleItalic;
|
|
|
|
if (ntm->tmUnderlined) fontstyle |= FontStyleUnderline;
|
|
|
|
if (ntm->tmStruckOut) fontstyle |= FontStyleStrikeout;
|
|
|
|
|
|
|
|
return (INT)lParam != fontstyle;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily* family,
|
|
|
|
INT style, BOOL* IsStyleAvailable)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
HDC hdc;
|
|
|
|
|
|
|
|
TRACE("%p %d %p\n", family, style, IsStyleAvailable);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if (!(family && IsStyleAvailable))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
*IsStyleAvailable = FALSE;
|
|
|
|
|
|
|
|
hdc = GetDC(0);
|
|
|
|
|
|
|
|
if(!EnumFontFamiliesW(hdc, family->FamilyName, font_has_style_proc, (LPARAM)style))
|
|
|
|
*IsStyleAvailable = TRUE;
|
|
|
|
|
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
|
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetGenericFontFamilyMonospace [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Obtains a serif family (Courier New on Windows)
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* **nativeFamily [I] Where the font will be stored
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* InvalidParameter if nativeFamily is NULL.
|
|
|
|
* Ok otherwise.
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily)
|
|
|
|
{
|
|
|
|
static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
|
|
|
|
|
|
|
|
if (nativeFamily == NULL) return InvalidParameter;
|
|
|
|
|
|
|
|
return GdipCreateFontFamilyFromName(CourierNew, NULL, nativeFamily);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetGenericFontFamilySerif [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Obtains a serif family (Times New Roman on Windows)
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* **nativeFamily [I] Where the font will be stored
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* InvalidParameter if nativeFamily is NULL.
|
|
|
|
* Ok otherwise.
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
|
|
|
|
{
|
|
|
|
static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
|
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p)\n", nativeFamily);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if (nativeFamily == NULL) return InvalidParameter;
|
|
|
|
|
|
|
|
return GdipCreateFontFamilyFromName(TimesNewRoman, NULL, nativeFamily);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetGenericFontFamilySansSerif [GDIPLUS.@]
|
|
|
|
*
|
|
|
|
* Obtains a serif family (Microsoft Sans Serif on Windows)
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* **nativeFamily [I] Where the font will be stored
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* InvalidParameter if nativeFamily is NULL.
|
|
|
|
* Ok otherwise.
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily)
|
|
|
|
{
|
2010-04-20 08:30:10 +00:00
|
|
|
GpStatus stat;
|
|
|
|
static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
|
|
|
|
static const WCHAR Tahoma[] = {'T','a','h','o','m','a','\0'};
|
2008-07-02 08:19:00 +00:00
|
|
|
|
2008-09-07 10:32:49 +00:00
|
|
|
TRACE("(%p)\n", nativeFamily);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if (nativeFamily == NULL) return InvalidParameter;
|
|
|
|
|
2010-04-20 08:30:10 +00:00
|
|
|
stat = GdipCreateFontFamilyFromName(MicrosoftSansSerif, NULL, nativeFamily);
|
|
|
|
|
|
|
|
if (stat == FontFamilyNotFound)
|
|
|
|
/* FIXME: Microsoft Sans Serif is not installed on Wine. */
|
|
|
|
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, nativeFamily);
|
|
|
|
|
|
|
|
return stat;
|
2008-07-02 08:19:00 +00:00
|
|
|
}
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetGenericFontFamilySansSerif [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection** fontCollection)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p\n", fontCollection);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if (!fontCollection)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
*fontCollection = GdipAlloc(sizeof(GpFontCollection));
|
|
|
|
if (!*fontCollection) return OutOfMemory;
|
|
|
|
|
|
|
|
(*fontCollection)->FontFamilies = NULL;
|
|
|
|
(*fontCollection)->count = 0;
|
2009-05-23 10:32:19 +00:00
|
|
|
(*fontCollection)->allocated = 0;
|
2010-03-04 13:34:05 +00:00
|
|
|
|
|
|
|
TRACE("<-- %p\n", *fontCollection);
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipDeletePrivateFontCollection [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection **fontCollection)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
INT i;
|
|
|
|
|
|
|
|
TRACE("%p\n", fontCollection);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if (!fontCollection)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
for (i = 0; i < (*fontCollection)->count; i++) GdipFree((*fontCollection)->FontFamilies[i]);
|
|
|
|
GdipFree(*fontCollection);
|
|
|
|
|
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipPrivateAddFontFile [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection* fontCollection,
|
|
|
|
GDIPCONST WCHAR* filename)
|
|
|
|
{
|
|
|
|
FIXME("stub: %p, %s\n", fontCollection, debugstr_w(filename));
|
|
|
|
|
|
|
|
if (!(fontCollection && filename))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipPrivateAddMemoryFont [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
|
|
|
|
GDIPCONST void* memory, INT length)
|
|
|
|
{
|
|
|
|
FIXME("%p, %p, %d\n", fontCollection, memory, length);
|
|
|
|
|
|
|
|
if (!(fontCollection && memory && length))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetFontCollectionFamilyCount [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontCollectionFamilyCount(
|
|
|
|
GpFontCollection* fontCollection, INT* numFound)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p, %p\n", fontCollection, numFound);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if (!(fontCollection && numFound))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
*numFound = fontCollection->count;
|
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* GdipGetFontCollectionFamilyList [GDIPLUS.@]
|
|
|
|
*/
|
|
|
|
GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(
|
|
|
|
GpFontCollection* fontCollection, INT numSought,
|
|
|
|
GpFontFamily* gpfamilies[], INT* numFound)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
INT i;
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
GpStatus stat=Ok;
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
TRACE("%p, %d, %p, %p\n", fontCollection, numSought, gpfamilies, numFound);
|
2008-08-05 12:23:58 +00:00
|
|
|
|
|
|
|
if (!(fontCollection && gpfamilies && numFound))
|
|
|
|
return InvalidParameter;
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
memset(gpfamilies, 0, sizeof(*gpfamilies) * numSought);
|
|
|
|
|
|
|
|
for (i = 0; i < numSought && i < fontCollection->count && stat == Ok; i++)
|
2008-12-06 09:26:01 +00:00
|
|
|
{
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
stat = GdipCloneFontFamily(fontCollection->FontFamilies[i], &gpfamilies[i]);
|
2008-12-06 09:26:01 +00:00
|
|
|
}
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
|
|
|
|
if (stat == Ok)
|
|
|
|
*numFound = i;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int numToFree=i;
|
|
|
|
for (i=0; i<numToFree; i++)
|
|
|
|
{
|
|
|
|
GdipDeleteFontFamily(gpfamilies[i]);
|
|
|
|
gpfamilies[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return stat;
|
2008-12-06 09:26:01 +00:00
|
|
|
}
|
|
|
|
|
2009-05-23 10:32:19 +00:00
|
|
|
void free_installed_fonts(void)
|
|
|
|
{
|
|
|
|
while (installedFontCollection.count)
|
|
|
|
GdipDeleteFontFamily(installedFontCollection.FontFamilies[--installedFontCollection.count]);
|
|
|
|
HeapFree(GetProcessHeap(), 0, installedFontCollection.FontFamilies);
|
|
|
|
installedFontCollection.FontFamilies = NULL;
|
|
|
|
installedFontCollection.allocated = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
|
|
|
|
DWORD type, LPARAM lParam)
|
|
|
|
{
|
|
|
|
GpFontCollection* fonts = (GpFontCollection*)lParam;
|
|
|
|
int i;
|
|
|
|
|
2010-04-20 08:30:10 +00:00
|
|
|
if (type == RASTER_FONTTYPE)
|
|
|
|
return 1;
|
|
|
|
|
2009-05-23 10:32:19 +00:00
|
|
|
/* skip duplicates */
|
|
|
|
for (i=0; i<fonts->count; i++)
|
|
|
|
if (strcmpiW(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (fonts->allocated == fonts->count)
|
|
|
|
{
|
|
|
|
INT new_alloc_count = fonts->allocated+50;
|
|
|
|
GpFontFamily** new_family_list = HeapAlloc(GetProcessHeap(), 0, new_alloc_count*sizeof(void*));
|
|
|
|
|
|
|
|
if (!new_family_list)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memcpy(new_family_list, fonts->FontFamilies, fonts->count*sizeof(void*));
|
|
|
|
HeapFree(GetProcessHeap(), 0, fonts->FontFamilies);
|
|
|
|
fonts->FontFamilies = new_family_list;
|
|
|
|
fonts->allocated = new_alloc_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &fonts->FontFamilies[fonts->count]) == Ok)
|
|
|
|
fonts->count++;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipNewInstalledFontCollection(
|
|
|
|
GpFontCollection** fontCollection)
|
|
|
|
{
|
2009-05-23 10:32:19 +00:00
|
|
|
TRACE("(%p)\n",fontCollection);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
if (!fontCollection)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2009-05-23 10:32:19 +00:00
|
|
|
if (installedFontCollection.count == 0)
|
|
|
|
{
|
|
|
|
HDC hdc;
|
|
|
|
LOGFONTW lfw;
|
|
|
|
|
|
|
|
hdc = GetDC(0);
|
|
|
|
|
|
|
|
lfw.lfCharSet = DEFAULT_CHARSET;
|
|
|
|
lfw.lfFaceName[0] = 0;
|
|
|
|
lfw.lfPitchAndFamily = 0;
|
|
|
|
|
|
|
|
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)&installedFontCollection, 0))
|
|
|
|
{
|
|
|
|
free_installed_fonts();
|
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
return OutOfMemory;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
}
|
|
|
|
|
2009-05-09 09:26:16 +00:00
|
|
|
*fontCollection = &installedFontCollection;
|
|
|
|
|
|
|
|
return Ok;
|
2008-08-05 12:23:58 +00:00
|
|
|
}
|