mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 08:22:08 +08:00
1081 lines
30 KiB
C++
1081 lines
30 KiB
C++
// FontManager.h : Declaration of the CFontManager
|
|
|
|
#pragma once
|
|
#include "resource.h" // main symbols
|
|
#include "Registration.h"
|
|
#include "Consts.h"
|
|
#include "WinFont.h"
|
|
#include "Errors.h"
|
|
#include "FontUtils.h"
|
|
|
|
#include "FontEngine.h"
|
|
#include "FT_Font.h"
|
|
#include "Path.h"
|
|
|
|
#include FT_ADVANCES_H
|
|
#include FT_GLYPH_H
|
|
|
|
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
|
|
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
|
|
#endif
|
|
|
|
|
|
// IFontManager
|
|
[
|
|
object,
|
|
uuid("8C0DA859-68A6-4CDB-9C48-8B6D66EFAC1F"),
|
|
dual, helpstring("IFontManager Interface"),
|
|
pointer_default(unique)
|
|
]
|
|
__interface IFontManager : IDispatch
|
|
{
|
|
//----- Îòêðûòèå/çàêðûòèå øðèôòà --------------------------------------------------------------------
|
|
[id(001)] HRESULT Initialize([in] BSTR bsXmlOptions);
|
|
[id(002)] HRESULT LoadFontFromFile([in]BSTR bsSrcPath, [in] float fEmSize, [in] unsigned int unHorDPI, [in] unsigned int unVerDPI, [in] long lFaceIndex = 0);
|
|
[id(003)] HRESULT LoadFontByName([in]BSTR bsFamilyName, [in] float fEmSize, [in] long lStyle, [in] unsigned int unHorDPI, [in]unsigned int unVerDPI);
|
|
[id(004)] HRESULT GetFontType([out, retval] BSTR *pbsType);
|
|
[id(005)] HRESULT SetDefaultFont([in] BSTR bsFamilyName);
|
|
//----- Ôóíêöèè àíàëîãè÷íûå ìåòîäàì êëàññîâ Font è FontFamily â GDI+ --------------------------------
|
|
|
|
[id(101)] HRESULT GetCellAscent([out, retval] unsigned short *pusAscent);
|
|
[id(102)] HRESULT GetCellDescent([out, retval] unsigned short *pusDescent);
|
|
[id(103)] HRESULT GetEmHeight([out, retval] unsigned short *pusEmHeight);
|
|
[id(104)] HRESULT GetFamilyName([out, retval] BSTR *pbsFamilyName);
|
|
[id(105)] HRESULT GetLineSpacing([out, retval] unsigned short *pusLineSpacing);
|
|
[id(106)] HRESULT IsStyleAvailable([in] long lStyle, [out, retval] BOOL *pbAvailable);
|
|
[id(107)] HRESULT GetHeight([in] float fDPI, [out, retval] float *pfHeight);
|
|
|
|
//----- ×òåíèå ãëîáàëüíûõ ïàðàìåòðîâ øðèôòà ---------------------------------------------------------
|
|
[id(201)] HRESULT GetFacesCount([out, retval] long *plFacesCount);
|
|
[id(202)] HRESULT GetFaceIndex([out, retval] long *plFaceIndex);
|
|
[id(203)] HRESULT GetGlyphsCount([out, retval] long *plGlyphsCount);
|
|
[id(205)] HRESULT GetStyleName([out, retval] BSTR *pbsStyleName);
|
|
[id(206)] HRESULT IsCharAvailable([in] long lUnicode, [out, retval] BOOL *pbAvailable);
|
|
[id(207)] HRESULT GetUnderlinePosition([out, retval] short *pshUnderPos);
|
|
[id(208)] HRESULT GetUnderlineThickness([out, retval] short *pshUnderThick);
|
|
[id(209)] HRESULT GetMaxAdvanceWidth([out, retval] short *pshMaxAdvWidth);
|
|
[id(210)] HRESULT GetMaxAdvanceHeight([out, retval] short *pshMaxAdvHeight);
|
|
[id(211)] HRESULT GetBBox([out] long *plMinX, [out] long *plMinY, [out] long *plMaxX, [out] long *plMaxY);
|
|
[id(212)] HRESULT IsUnicodeRangeAvailable([in] unsigned long ulBit, [in] unsigned int unLongIndex, [out ,retval] VARIANT_BOOL *pvbSuccess);
|
|
|
|
//----- Ðàáîòà ñ ãëèôàìè ----------------------------------------------------------------------------
|
|
|
|
[id(301)] HRESULT GetGlyphPath([in] long lUnicode, [out, retval] BSTR *pbsXmlPath);
|
|
[id(302)] HRESULT GetStringPath([in] BSTR bsString, [out, retval] BSTR *pbsXmlPath);
|
|
[id(303)] HRESULT GetGlyphBitmap([in] long lUnicode, [out, retval]IUnknown **ppImage);
|
|
[id(304)] HRESULT GetStringBitmap([in] BSTR bsString, [out, retval] IUnknown **ppImage);
|
|
[id(305)] HRESULT LoadString([in] BSTR bsString);
|
|
[id(306)] HRESULT GetNextChar([out] IUnknown **ppImage, [out] float *pfX, [out] float *pfY, [out, retval] VARIANT_BOOL *pvbSuccess);
|
|
[id(307)] HRESULT GetCharBBox([out] float *pfLeft, [out] float *pfTop, [out] float *pfRight, [out] float *pfBottom);
|
|
[id(308)] HRESULT MeasureString([out] float *pfLeft, [out] float *pfTop, [out] float *pfRight, [out] float *pfBottom);
|
|
[id(309)] HRESULT ApplyTransform([in] float fA, [in] float fB, [in] float fC, [in] float fD, [in] float fE, [in] float fF);
|
|
|
|
//----- Ðàáîòà ñî øðèôòàìè Windows ------------------------------------------------------------------
|
|
|
|
[id(501)] HRESULT GetWinFontsCount([out, retval] long *plCount);
|
|
[id(502)] HRESULT GetWinFont([in] long nIndex, [out] BSTR *pbsFontName, [out] BSTR *pbsFontStyle, [out] BSTR *pbsFontPath, [out] long *plIndex, [out] BOOL *pbBold, [out] BOOL *pbItalic);
|
|
|
|
};
|
|
|
|
|
|
|
|
// CFontManager
|
|
|
|
[
|
|
coclass,
|
|
default(IFontManager),
|
|
threading(apartment),
|
|
vi_progid("AVSOfficeFontManager.FontManager"),
|
|
progid("AVSOfficeFontManager.FontManager.1"),
|
|
version(1.0),
|
|
uuid("0FF37CE6-DD3C-488F-8319-13D9E392F1D8"),
|
|
helpstring("FontManager Class")
|
|
]
|
|
class ATL_NO_VTABLE CFontManager :
|
|
public IFontManager
|
|
{
|
|
public:
|
|
|
|
private:
|
|
|
|
float m_fEmSize;
|
|
long m_lUnit;
|
|
|
|
TGlyph *m_pGlyphsBuffer; // Äëÿ ðàáîòû ñî ñòðîêîé
|
|
unsigned int m_nGlyphsCount; // Êîëè÷åñòâî ñèìâîëîâ â ñòðîêå
|
|
unsigned int m_nGlyphIndex; // Íîìåð òåêóùåãî ñèìâîëà
|
|
|
|
CFontEngine *m_pFontEngine; // Êëàññ äëÿ ðàáîòû ñî øðèôòàìè (óñòàíîâëåííûå øðèôòû, êýø øðèôòîâ è ò.ä.)
|
|
CFont *m_pFont; // Òåêóùèé øðèôò
|
|
|
|
public:
|
|
CFontManager()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
|
|
|
HRESULT FinalConstruct()
|
|
{
|
|
m_pFontEngine = NULL;
|
|
m_pFont = NULL;
|
|
|
|
m_pGlyphsBuffer = NULL;
|
|
m_nGlyphsCount = 0;
|
|
m_nGlyphIndex = -1;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void FinalRelease()
|
|
{
|
|
if ( m_pFontEngine )
|
|
{
|
|
delete m_pFontEngine;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
public:
|
|
|
|
//----- Îòêðûòèå/çàêðûòèå øðèôòà --------------------------------------------------------------------
|
|
STDMETHOD(Initialize)(BSTR bsXmlOptions)
|
|
{
|
|
m_pFontEngine = new CFontEngine(TRUE);
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(LoadFontFromFile)(BSTR bsSrcPath, float fEmSize, unsigned int unHorDpi, unsigned int unVerDpi, long lFaceIndex)
|
|
{
|
|
if ( !m_pFontEngine )
|
|
return S_FALSE;
|
|
|
|
CFontFile *pFontFile = NULL;
|
|
if ( !( pFontFile = m_pFontEngine->GetFontFile( bsSrcPath, lFaceIndex ) ) )
|
|
{
|
|
pFontFile = m_pFontEngine->LoadFont( bsSrcPath, lFaceIndex );
|
|
}
|
|
|
|
if ( !pFontFile )
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_OPEN_ERROR;
|
|
|
|
m_pFont = m_pFontEngine->GetFont( pFontFile );
|
|
if ( !m_pFont )
|
|
return S_FALSE;
|
|
|
|
UpdateStyles( m_pFont, FALSE, FALSE );
|
|
m_pFont->SetDefaultFont( m_pFontEngine->GetDefaultFont( FALSE, FALSE ) );
|
|
m_pFont->SetSizeAndDpi( fEmSize, unHorDpi, unVerDpi );
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(LoadFontByName)(BSTR bsFamilyName, float fEmSize, long lStyle, unsigned int unHorDpi, unsigned int unVerDpi)
|
|
{
|
|
if ( !m_pFontEngine )
|
|
return S_FALSE;
|
|
|
|
BOOL bBold = FALSE;
|
|
BOOL bItalic = FALSE;
|
|
|
|
switch (lStyle)
|
|
{
|
|
case FontConstants::FontStyle::FontStyleRegular: bBold = FALSE; bItalic = FALSE; break;
|
|
case FontConstants::FontStyle::FontStyleItalic: bBold = FALSE; bItalic = TRUE; break;
|
|
case FontConstants::FontStyle::FontStyleBold: bBold = TRUE; bItalic = FALSE; break;
|
|
case FontConstants::FontStyle::FontStyleBoldItalic: bBold = TRUE; bItalic = TRUE; break;
|
|
}
|
|
|
|
CFontFile *pFontFile = NULL;
|
|
|
|
if ( !( pFontFile = m_pFontEngine->GetFontFile( bsFamilyName, bBold, bItalic ) ) )
|
|
{
|
|
pFontFile = m_pFontEngine->LoadFont( bsFamilyName, bBold, bItalic );
|
|
}
|
|
|
|
if ( !pFontFile )
|
|
return AVS_OFFICEFONTMANAGER_ERROR_WIN_FONT_NOT_FOUND;
|
|
|
|
m_pFont = m_pFontEngine->GetFont( pFontFile );
|
|
|
|
if ( !m_pFont )
|
|
return S_FALSE;
|
|
|
|
UpdateStyles( m_pFont, bBold, bItalic );
|
|
m_pFont->SetDefaultFont( m_pFontEngine->GetDefaultFont( bBold, bItalic ) );
|
|
m_pFont->SetSizeAndDpi( fEmSize, unHorDpi, unVerDpi );
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetFontType)(BSTR *pbsType)
|
|
{
|
|
CStringW wsType = _T("");
|
|
if ( !m_pFont )
|
|
{
|
|
*pbsType = wsType.AllocSysString();
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
wsType = m_pFont->GetFontFormat();
|
|
*pbsType = wsType.AllocSysString();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(SetDefaultFont)(BSTR bsFamilyName)
|
|
{
|
|
if ( !m_pFontEngine )
|
|
return S_FALSE;
|
|
|
|
m_pFontEngine->SetDefaultFont( bsFamilyName );
|
|
|
|
return S_OK;
|
|
}
|
|
//----- Ôóíêöèè àíàëîãè÷íûå ìåòîäàì êëàññîâ Font è FontFamily â GDI+ --------------------------------
|
|
STDMETHOD(GetCellAscent)(unsigned short *pusAscent)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pusAscent = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pusAscent = m_pFont->GetAscender();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetCellDescent)(unsigned short *pusDescent)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pusDescent = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pusDescent = fabs( m_pFont->GetDescender() );
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetEmHeight)(unsigned short *pusEmHeight)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pusEmHeight = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pusEmHeight = m_pFont->GetUnitsPerEm();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetFamilyName)(BSTR *pbsFamilyName)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
CString sFamilyName( _T("") );
|
|
*pbsFamilyName = sFamilyName.AllocSysString();
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
CString sFamilyName( m_pFont->GetFamilyName() );
|
|
*pbsFamilyName = sFamilyName.AllocSysString();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHOD(GetLineSpacing)(unsigned short *pusLineSpacing)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pusLineSpacing = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pusLineSpacing = m_pFont->GetLineSpacing();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(IsStyleAvailable)(long lStyle, BOOL *pbAvailable)
|
|
{
|
|
if ( !m_pFontEngine || !m_pFont )
|
|
{
|
|
*pbAvailable = FALSE;
|
|
return S_OK;
|
|
}
|
|
|
|
*pbAvailable = m_pFontEngine->IsStyleAvailable( CStringW( m_pFont->GetFamilyName() ).GetBuffer(), lStyle );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
STDMETHOD(GetHeight)(float fDPI, float *pfHeight)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pfHeight = 0.0f;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
unsigned short usEmHeight = 0;
|
|
unsigned short usLineSpacing = 0;
|
|
|
|
HRESULT hRes = S_OK;
|
|
if ( FAILED( hRes = GetEmHeight( &usEmHeight ) ) || usEmHeight <= 0.0001 )
|
|
return hRes;
|
|
|
|
if ( FAILED( hRes = GetLineSpacing( &usLineSpacing ) ) )
|
|
return hRes;
|
|
|
|
float fKoef = 1.0f;
|
|
switch( m_lUnit )
|
|
{
|
|
case FontConstants::UnitPoint: fKoef = fDPI / 72; break;
|
|
case FontConstants::UnitInch: fKoef = fDPI; break;
|
|
case FontConstants::UnitDocument: fKoef = fDPI / 300; break;
|
|
case FontConstants::UnitMillimeter: fKoef = fDPI / 25.4; break;
|
|
}
|
|
|
|
*pfHeight = usLineSpacing * ( m_fEmSize / usEmHeight ) * fKoef;
|
|
|
|
return S_OK;
|
|
}
|
|
//----- ×òåíèå ãëîáàëüíûõ ïàðàìåòðîâ øðèôòà ---------------------------------------------------------
|
|
STDMETHOD(GetFacesCount)(long *plFacesCount)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*plFacesCount = 0;
|
|
return S_FALSE;
|
|
}
|
|
|
|
*plFacesCount = m_pFont->GetFacesCount();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetFaceIndex)(long *plFaceIndex)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*plFaceIndex = 0;
|
|
return S_FALSE;
|
|
}
|
|
|
|
*plFaceIndex = m_pFont->GetFaceIndex();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetGlyphsCount)(long *plGlyphsCount)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*plGlyphsCount = 0;
|
|
return S_FALSE;
|
|
}
|
|
|
|
*plGlyphsCount = m_pFont->GetGlyphsCount();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetStyleName)(BSTR *pbsStyleName)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
CString sStyleName( _T("") );
|
|
*pbsStyleName = sStyleName.AllocSysString();
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
CString sStyleName( m_pFont->GetStyleName() );
|
|
*pbsStyleName = sStyleName.AllocSysString();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHOD(IsCharAvailable)(long lUnicode, BOOL *pbAvailable)
|
|
{
|
|
if ( !m_pFont )
|
|
return S_FALSE;
|
|
|
|
*pbAvailable = m_pFont->IsCharAvailable( lUnicode );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHOD(GetUnderlinePosition)(short *pshUnderPos)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pshUnderPos = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pshUnderPos = m_pFont->GetUnderlinePosition();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetUnderlineThickness)(short *pshUnderThick)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pshUnderThick = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pshUnderThick = m_pFont->GetUnderlineThickness();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetMaxAdvanceWidth)(short *pshMaxAdvWidth)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pshMaxAdvWidth = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pshMaxAdvWidth = m_pFont->GetMaxAdvanceWidth();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetMaxAdvanceHeight)(short *pshMaxAdvHeight)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*pshMaxAdvHeight = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
*pshMaxAdvHeight = m_pFont->GetMaxAdvanceHeight();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetBBox)(long *plMinX, long *plMinY, long *plMaxX, long *plMaxY)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
*plMinX = 0;
|
|
*plMinY = 0;
|
|
*plMaxX = 0;
|
|
*plMaxY = 0;
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
}
|
|
|
|
m_pFont->GetBBox( plMinX, plMinY, plMaxX, plMaxY );
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(IsUnicodeRangeAvailable)(unsigned long ulBit, unsigned int unLongIndex, VARIANT_BOOL *pvbSuccess)
|
|
{
|
|
*pvbSuccess = VARIANT_FALSE;
|
|
if ( !m_pFont )
|
|
return AVS_OFFICEFONTMANAGER_ERROR_FONT_WASNT_LOAD;
|
|
|
|
if ( m_pFont->IsUnicodeRangeAvailable( ulBit, unLongIndex ) > 0 )
|
|
*pvbSuccess = VARIANT_TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
//----- Ðàáîòà ñ ãëèôàìè ----------------------------------------------------------------------------
|
|
STDMETHOD(GetGlyphPath)(long lUnicode, BSTR *pbsXmlPath)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
CString sXml( _T("") );
|
|
*pbsXmlPath = sXml.AllocSysString();
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
CPath *pPath = m_pFont->GetGlyphPath( lUnicode );
|
|
if ( !pPath )
|
|
return S_FALSE;
|
|
|
|
*pbsXmlPath = pPath->ToXmlString().AllocSysString();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetStringPath)(BSTR bsString, BSTR *pbsXmlPath)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
CString sXml( _T("") );
|
|
*pbsXmlPath = sXml.AllocSysString();
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
CStringW wsString( bsString );
|
|
CPath *pPath = m_pFont->GetStringPath( wsString.GetBuffer(), wsString.GetLength() );
|
|
if ( !pPath )
|
|
return S_FALSE;
|
|
|
|
*pbsXmlPath = pPath->ToXmlString().AllocSysString();
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetGlyphBitmap)(long lUnicode, IUnknown **ppImage)
|
|
{
|
|
if ( !m_pFont )
|
|
return S_FALSE;
|
|
|
|
TGlyphBitmap oBitmap;
|
|
m_pFont->GetGlyph( lUnicode, 0, 0, &oBitmap );
|
|
|
|
|
|
// Ïîäãîòàâëèâàåì pInterface
|
|
IUnknown **pInterface = (IUnknown**)ppImage;
|
|
if ( !pInterface )
|
|
return S_FALSE;
|
|
|
|
// create result interface
|
|
*pInterface = NULL;
|
|
HRESULT hRes = CoCreateInstance( MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)pInterface );
|
|
if ( hRes != S_OK || NULL == *pInterface )
|
|
return S_FALSE;
|
|
|
|
MediaCore::IAVSUncompressedVideoFrame* pMediaData = (MediaCore::IAVSUncompressedVideoFrame*)*pInterface;
|
|
|
|
int nWidth = oBitmap.nWidth;
|
|
int nHeight = oBitmap.nHeight;
|
|
int nBufferSize = 4 * nWidth * nHeight;
|
|
if ( nBufferSize < 1 )
|
|
return S_FALSE;
|
|
|
|
pMediaData->put_ColorSpace( ( 1 << 6) || ( 1 << 31 ) ); // CPS_BGRA | CPS_FLIP
|
|
pMediaData->put_Width( nWidth );
|
|
pMediaData->put_Height( nHeight );
|
|
pMediaData->put_AspectRatioX( nWidth );
|
|
pMediaData->put_AspectRatioY( nHeight );
|
|
pMediaData->put_Interlaced( VARIANT_FALSE );
|
|
pMediaData->put_Stride( 0, 4 * nWidth );
|
|
pMediaData->AllocateBuffer( nBufferSize );
|
|
|
|
unsigned char *pBufferPtr = NULL;
|
|
long nCreatedBufferSize = 0;
|
|
|
|
pMediaData->get_Buffer( &pBufferPtr );
|
|
pMediaData->get_BufferSize( &nCreatedBufferSize );
|
|
pMediaData->put_Plane( 0, pBufferPtr );
|
|
|
|
if ( !pBufferPtr || nCreatedBufferSize != nBufferSize )
|
|
return S_FALSE;
|
|
|
|
*pInterface = pMediaData;
|
|
|
|
// Ïèøåì äàííûå â pBufferPtr
|
|
|
|
for ( int nY = 0; nY < nHeight; nY++ )
|
|
{
|
|
for ( int nX = 0; nX < nWidth; nX++ )
|
|
{
|
|
unsigned char nG = 255 - oBitmap.pData[nWidth * nY + nX ];
|
|
pBufferPtr[0] = nG;
|
|
pBufferPtr[1] = nG;
|
|
pBufferPtr[2] = nG;
|
|
pBufferPtr[3] = 255;
|
|
pBufferPtr += 4;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetStringBitmap)(BSTR bsString, IUnknown **ppImage)
|
|
{
|
|
if ( !m_pFont )
|
|
return S_FALSE;
|
|
|
|
CStringW wsString( bsString );
|
|
TGlyphBitmap *pBitmaps = new TGlyphBitmap[ wsString.GetLength() ];
|
|
if ( !pBitmaps )
|
|
return S_FALSE;
|
|
|
|
int nHeight = 0;
|
|
int nWidth = 0;
|
|
|
|
for ( int nIndex = 0; nIndex < wsString.GetLength(); nIndex++ )
|
|
{
|
|
long lUnicode = wsString.GetAt( nIndex );
|
|
m_pFont->GetGlyph( lUnicode, 0, 0, &(pBitmaps[nIndex]) );
|
|
if ( nHeight < pBitmaps[nIndex].nHeight )
|
|
nHeight = pBitmaps[nIndex].nHeight;
|
|
|
|
nWidth += pBitmaps[nIndex].nWidth;
|
|
}
|
|
|
|
// Ïîäãîòàâëèâàåì pInterface
|
|
IUnknown **pInterface = (IUnknown**)ppImage;
|
|
if ( !pInterface )
|
|
return S_FALSE;
|
|
|
|
// create result interface
|
|
*pInterface = NULL;
|
|
HRESULT hRes = CoCreateInstance( MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)pInterface );
|
|
if ( hRes != S_OK || NULL == *pInterface )
|
|
return S_FALSE;
|
|
|
|
MediaCore::IAVSUncompressedVideoFrame* pMediaData = (MediaCore::IAVSUncompressedVideoFrame*)*pInterface;
|
|
|
|
int nBufferSize = 4 * nWidth * nHeight;
|
|
if ( nBufferSize < 1 )
|
|
return S_FALSE;
|
|
|
|
pMediaData->put_ColorSpace( ( 1 << 6) ); // CPS_BGRA
|
|
pMediaData->put_Width( nWidth );
|
|
pMediaData->put_Height( nHeight );
|
|
pMediaData->put_AspectRatioX( nWidth );
|
|
pMediaData->put_AspectRatioY( nHeight );
|
|
pMediaData->put_Interlaced( VARIANT_FALSE );
|
|
pMediaData->put_Stride( 0, 4 * nWidth );
|
|
pMediaData->AllocateBuffer( nBufferSize );
|
|
|
|
unsigned char *pBufferPtr = NULL;
|
|
long nCreatedBufferSize = 0;
|
|
|
|
pMediaData->get_Buffer( &pBufferPtr );
|
|
pMediaData->get_BufferSize( &nCreatedBufferSize );
|
|
pMediaData->put_Plane( 0, pBufferPtr );
|
|
|
|
if ( !pBufferPtr || nCreatedBufferSize != nBufferSize )
|
|
return S_FALSE;
|
|
|
|
*pInterface = pMediaData;
|
|
|
|
// Ïèøåì äàííûå â pBufferPtr
|
|
|
|
int nShiftX = 0;
|
|
for ( int nGlyphIndex = 0; nGlyphIndex < wsString.GetLength(); nGlyphIndex++ )
|
|
{
|
|
for ( int nY = 0; nY < nHeight; nY++ )
|
|
{
|
|
if ( nHeight - nY < pBitmaps[nGlyphIndex].nHeight )
|
|
{
|
|
for ( int nX = 0; nX < pBitmaps[nGlyphIndex].nWidth; nX++ )
|
|
{
|
|
int nCurY = nY - ( nHeight - pBitmaps[nGlyphIndex].nHeight );
|
|
unsigned char nG = 255 - pBitmaps[nGlyphIndex].pData[pBitmaps[nGlyphIndex].nWidth * nCurY + nX ];
|
|
int nIndex = (nX + nShiftX + nY * nWidth) * 4;
|
|
pBufferPtr[nIndex + 0] = nG;
|
|
pBufferPtr[nIndex + 1] = nG;
|
|
pBufferPtr[nIndex + 2] = nG;
|
|
pBufferPtr[nIndex + 3] = 255;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( int nX = 0; nX < pBitmaps[nGlyphIndex].nWidth; nX++ )
|
|
{
|
|
int nIndex = (nX + nShiftX + nY * nWidth) * 4;
|
|
pBufferPtr[nIndex + 0] = 255;
|
|
pBufferPtr[nIndex + 1] = 255;
|
|
pBufferPtr[nIndex + 2] = 255;
|
|
pBufferPtr[nIndex + 3] = 255;
|
|
}
|
|
}
|
|
}
|
|
nShiftX += pBitmaps[nGlyphIndex].nWidth;
|
|
}
|
|
|
|
delete []pBitmaps;
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(LoadString)(BSTR bsString)
|
|
{
|
|
if ( !m_pFont )
|
|
return FALSE;
|
|
|
|
CStringW wsBuffer = CStringW( bsString );
|
|
|
|
m_nGlyphsCount = wsBuffer.GetLength();
|
|
|
|
if ( m_pGlyphsBuffer )
|
|
delete []m_pGlyphsBuffer;
|
|
|
|
m_pGlyphsBuffer = new TGlyph[m_nGlyphsCount];
|
|
m_nGlyphIndex = -1;
|
|
|
|
for ( int nIndex = 0; nIndex < m_nGlyphsCount; nIndex++ )
|
|
{
|
|
m_pGlyphsBuffer[nIndex].lUnicode = wsBuffer.GetAt( nIndex );
|
|
}
|
|
|
|
m_pFont->GetString( m_pGlyphsBuffer, m_nGlyphsCount );
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetNextChar)(IUnknown **ppImage, float *pfX, float *pfY, VARIANT_BOOL *pvbSuccess)
|
|
{
|
|
*pvbSuccess = VARIANT_FALSE;
|
|
m_nGlyphIndex++;
|
|
|
|
if ( m_nGlyphIndex >= m_nGlyphsCount )
|
|
{
|
|
*ppImage = NULL;
|
|
*pfX = -0xFFFF;
|
|
*pfY = -0xFFFF;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
if ( !m_pFont || !m_pGlyphsBuffer )
|
|
return S_FALSE;
|
|
|
|
if ( glyphstateNormal == m_pGlyphsBuffer[m_nGlyphIndex].eState || ( glyphstateDeafault == m_pGlyphsBuffer[m_nGlyphIndex].eState && NULL != m_pFont->GetDefaultFont() ) )
|
|
{
|
|
long lUnicode = m_pGlyphsBuffer[m_nGlyphIndex].lUnicode;
|
|
|
|
TGlyphBitmap oBitmap;
|
|
CFont *pCurFont = NULL;
|
|
|
|
if ( glyphstateNormal == m_pGlyphsBuffer[m_nGlyphIndex].eState )
|
|
pCurFont = m_pFont;
|
|
else
|
|
pCurFont = m_pFont->GetDefaultFont();
|
|
|
|
pCurFont->GetGlyph( lUnicode, 0, 0, &oBitmap );
|
|
|
|
if ( oBitmap.nWidth > 0 && oBitmap.nHeight > 0 )
|
|
{
|
|
// Ïîäãîòàâëèâàåì pInterface
|
|
IUnknown **pInterface = (IUnknown**)ppImage;
|
|
if ( !pInterface )
|
|
return S_FALSE;
|
|
|
|
// create result interface
|
|
*pInterface = NULL;
|
|
HRESULT hRes = CoCreateInstance( MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)pInterface );
|
|
if ( hRes != S_OK || NULL == *pInterface )
|
|
return S_FALSE;
|
|
|
|
MediaCore::IAVSUncompressedVideoFrame* pMediaData = (MediaCore::IAVSUncompressedVideoFrame*)*pInterface;
|
|
|
|
int nWidth = oBitmap.nWidth;
|
|
int nHeight = oBitmap.nHeight;
|
|
|
|
if ( pCurFont->GetBold() )
|
|
nWidth++;
|
|
|
|
int nBufferSize = 4 * nWidth * nHeight;
|
|
if ( nBufferSize < 1 )
|
|
return S_FALSE;
|
|
|
|
pMediaData->put_ColorSpace( 1 << 6 ); // CPS_BGRA
|
|
pMediaData->put_Width( nWidth );
|
|
pMediaData->put_Height( nHeight );
|
|
pMediaData->put_AspectRatioX( nWidth );
|
|
pMediaData->put_AspectRatioY( nHeight );
|
|
pMediaData->put_Interlaced( VARIANT_FALSE );
|
|
pMediaData->put_Stride( 0, 4 * nWidth );
|
|
pMediaData->AllocateBuffer( nBufferSize );
|
|
|
|
unsigned char *pBufferPtr = NULL;
|
|
long nCreatedBufferSize = 0;
|
|
|
|
pMediaData->get_Buffer( &pBufferPtr );
|
|
pMediaData->get_BufferSize( &nCreatedBufferSize );
|
|
pMediaData->put_Plane( 0, pBufferPtr );
|
|
|
|
if ( !pBufferPtr || nCreatedBufferSize != nBufferSize )
|
|
return S_FALSE;
|
|
|
|
*pInterface = pMediaData;
|
|
|
|
// Ïèøåì äàííûå â pBufferPtr
|
|
|
|
if ( !pCurFont->GetBold() )
|
|
{
|
|
for ( int nY = 0; nY < nHeight; nY++ )
|
|
{
|
|
for ( int nX = 0; nX < nWidth; nX++ )
|
|
{
|
|
unsigned char nG = 255 - oBitmap.pData[nWidth * nY + nX ];
|
|
|
|
//pBufferPtr[0] = nG;
|
|
//pBufferPtr[1] = nG;
|
|
//pBufferPtr[2] = nG;
|
|
//pBufferPtr[3] = 255;
|
|
|
|
pBufferPtr[0] = 0;//nG;
|
|
pBufferPtr[1] = 0;//nG;
|
|
pBufferPtr[2] = 0;//nG;
|
|
pBufferPtr[3] = 255 - nG;
|
|
|
|
pBufferPtr += 4;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Çäåñü (nWidth = oBitmap.nWidth + 1)
|
|
for ( int nY = 0; nY < nHeight; nY++ )
|
|
{
|
|
for ( int nX = nWidth - 1; nX >= 0; nX-- )
|
|
{
|
|
int nDstIndex = nY * nWidth * 4 + nX * 4;
|
|
int nSrcIndex = nY * oBitmap.nWidth + nX;
|
|
|
|
if ( 0 != nX )
|
|
{
|
|
int nFirstByte, nSecondByte;
|
|
|
|
if ( nWidth - 1 == nX )
|
|
nFirstByte = 255;
|
|
else
|
|
nFirstByte = 255 - oBitmap.pData[nSrcIndex];
|
|
|
|
nSecondByte = 255 - oBitmap.pData[nSrcIndex - 1];
|
|
|
|
pBufferPtr[nDstIndex + 0] = 0;//nG;
|
|
pBufferPtr[nDstIndex + 1] = 0;//nG;
|
|
pBufferPtr[nDstIndex + 2] = 0;//nG;
|
|
pBufferPtr[nDstIndex + 3] = min( 255, 510 - (nFirstByte + nSecondByte) );
|
|
|
|
}
|
|
else
|
|
{
|
|
pBufferPtr[nDstIndex + 0] = 0;
|
|
pBufferPtr[nDstIndex + 1] = 0;
|
|
pBufferPtr[nDstIndex + 2] = 0;
|
|
pBufferPtr[nDstIndex + 3] = oBitmap.pData[nSrcIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*ppImage = NULL;
|
|
}
|
|
*pfX = m_pGlyphsBuffer[m_nGlyphIndex].fX + oBitmap.nX;
|
|
*pfY = m_pGlyphsBuffer[m_nGlyphIndex].fY + oBitmap.nY - oBitmap.nHeight; // Îòäàåì êîîðäèíàòó ëåâîãî âåðõíåãî óãëà
|
|
|
|
}
|
|
else
|
|
{
|
|
// Ñèìâîë íå íàéäåí, íè÷åãî íå ðèñóåì
|
|
*ppImage = NULL;
|
|
|
|
*pfX = m_pGlyphsBuffer[m_nGlyphIndex].fX;
|
|
*pfY = m_pGlyphsBuffer[m_nGlyphIndex].fY;
|
|
}
|
|
*pvbSuccess = VARIANT_TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetCharBBox)(float *pfLeft, float *pfTop, float *pfRight, float *pfBottom)
|
|
{
|
|
if ( !m_pGlyphsBuffer || m_nGlyphsCount <= 0 || m_nGlyphIndex < 0 || m_nGlyphIndex >= m_nGlyphsCount )
|
|
{
|
|
*pfBottom = 0;
|
|
*pfRight = 0;
|
|
*pfLeft = 0;
|
|
*pfTop = 0;
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
*pfBottom = m_pGlyphsBuffer[m_nGlyphIndex].fBottom;
|
|
*pfRight = m_pGlyphsBuffer[m_nGlyphIndex].fRight + m_pGlyphsBuffer[m_nGlyphIndex].fX;
|
|
*pfLeft = m_pGlyphsBuffer[m_nGlyphIndex].fLeft + m_pGlyphsBuffer[m_nGlyphIndex].fX;
|
|
*pfTop = m_pGlyphsBuffer[m_nGlyphIndex].fTop;
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetNextChar2)(BSTR *pbsTempPath, float *pfX, float *pfY, VARIANT_BOOL *pvbSuccess)
|
|
{
|
|
*pvbSuccess = VARIANT_FALSE;
|
|
|
|
if ( m_nGlyphIndex >= m_nGlyphsCount )
|
|
{
|
|
CStringW wsTemp = _T("");
|
|
*pbsTempPath = wsTemp.AllocSysString();
|
|
*pfX = -0xFFFF;
|
|
*pfY = -0xFFFF;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
if ( !m_pFont || !m_pGlyphsBuffer )
|
|
return S_FALSE;
|
|
|
|
long lUnicode = m_pGlyphsBuffer[m_nGlyphIndex].lUnicode;
|
|
|
|
int nX = (int)floor( (double)m_pGlyphsBuffer[m_nGlyphIndex].fX );
|
|
int nFracX = (int)floor( (double)(m_pGlyphsBuffer[m_nGlyphIndex].fX - nX) * FONT_FRACTION );
|
|
int nY = (int)floor( (double)m_pGlyphsBuffer[m_nGlyphIndex].fY );
|
|
int nFracY = (int)floor( (double)(m_pGlyphsBuffer[m_nGlyphIndex].fY - nY) * FONT_FRACTION );
|
|
|
|
TGlyphBitmap oBitmap;
|
|
m_pFont->GetGlyph( lUnicode, nFracX, nFracY, &oBitmap );
|
|
|
|
int nWidth = oBitmap.nWidth;
|
|
int nHeight = oBitmap.nHeight;
|
|
|
|
CStringW wsFileName = _T( "C:\\Temp.bmp" );
|
|
*pbsTempPath = wsFileName.AllocSysString();
|
|
|
|
FILE *pFile = NULL;
|
|
|
|
if ( !( pFile = ::_wfopen( wsFileName, _T("wb") ) ) )
|
|
return S_FALSE;
|
|
|
|
int nSize = 0, nStride;
|
|
BYTE *pBuffer = NULL, *pBufPointer;
|
|
BITMAPFILEHEADER oFileHeader;
|
|
BITMAPINFOHEADER oInfoHeader;
|
|
|
|
|
|
|
|
oFileHeader.bfType = 'M' * 256 + 'B';
|
|
oFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nHeight * nWidth * 4;
|
|
oFileHeader.bfReserved1 = 0;
|
|
oFileHeader.bfReserved2 = 0;
|
|
oFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
|
|
|
oInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
oInfoHeader.biWidth = nWidth;
|
|
oInfoHeader.biHeight = nHeight;
|
|
oInfoHeader.biPlanes = 1;
|
|
oInfoHeader.biBitCount = 32;
|
|
oInfoHeader.biCompression = BI_RGB;
|
|
oInfoHeader.biSizeImage = nHeight * nWidth * 4;
|
|
oInfoHeader.biXPelsPerMeter = 0;
|
|
oInfoHeader.biYPelsPerMeter = 0;
|
|
oInfoHeader.biClrUsed = 0;
|
|
oInfoHeader.biClrImportant = 0;
|
|
|
|
::fwrite( &oFileHeader, 1, sizeof(BITMAPFILEHEADER), pFile );
|
|
::fwrite( &oInfoHeader, 1, sizeof(BITMAPINFOHEADER), pFile );
|
|
|
|
nSize = nHeight * nWidth * 4;
|
|
|
|
pBuffer = new BYTE[nSize];
|
|
if ( !pBuffer )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
pBufPointer = pBuffer;
|
|
for ( int nY = 0; nY < nHeight; nY++ )
|
|
{
|
|
for ( int nX = 0; nX < nWidth; nX++, pBufPointer += 4 )
|
|
{
|
|
unsigned char nG = oBitmap.pData[nWidth * nY + nX ];
|
|
float fAlpha = nG / 255.f;
|
|
pBufPointer[0] = ( 1 - fAlpha ) * 216;
|
|
pBufPointer[1] = ( 1 - fAlpha ) * 236;
|
|
pBufPointer[2] = ( 1 - fAlpha ) * 236;
|
|
pBufPointer[3] = 255 * fAlpha;
|
|
}
|
|
}
|
|
pBufPointer = pBuffer;
|
|
nStride = nWidth * 4;
|
|
pBufPointer += (nHeight - 1) * nStride;
|
|
nStride = -nStride;
|
|
|
|
for( int nRow = nHeight; nRow > 0 ; --nRow, pBufPointer += nStride )
|
|
{
|
|
::fwrite( pBufPointer, 1, abs( nStride ), pFile );
|
|
}
|
|
delete []pBuffer;
|
|
fclose( pFile );
|
|
|
|
*pfX = m_pGlyphsBuffer[m_nGlyphIndex].fX - oBitmap.nX;
|
|
*pfY = m_pGlyphsBuffer[m_nGlyphIndex].fY - oBitmap.nY;
|
|
|
|
m_nGlyphIndex++;
|
|
|
|
*pvbSuccess = VARIANT_TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(MeasureString)(float *pfLeft, float *pfTop, float *pfRight, float *pfBottom)
|
|
{
|
|
if ( !m_pGlyphsBuffer || m_nGlyphsCount <= 0 )
|
|
{
|
|
*pfBottom = 0;
|
|
*pfRight = 0;
|
|
*pfLeft = 0;
|
|
*pfTop = 0;
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
// Ó÷èòûâàåì, ÷òî ìû èñïîëüçóåì ïåðåâåðíóòþ ñèñòåìó (ò.å. ìàòðèöà ïðåîáðàçîâàíèÿ áûë [1 0 0 -1 0 0])
|
|
// È òî ÷òî ñàìà ñèñòåìà êîîðäèíàò òîæå ïåðåâåðíóòà
|
|
float fTop = -0xFFFF, fBottom = 0xFFFF, fLeft = 0xFFFF, fRight = -0xFFFF;
|
|
for ( int nIndex = 0; nIndex < m_nGlyphsCount; nIndex++ )
|
|
{
|
|
if ( fBottom > m_pGlyphsBuffer[nIndex].fBottom )
|
|
fBottom = m_pGlyphsBuffer[nIndex].fBottom;
|
|
|
|
if ( fTop < m_pGlyphsBuffer[nIndex].fTop )
|
|
fTop = m_pGlyphsBuffer[nIndex].fTop;
|
|
}
|
|
|
|
fLeft = m_pGlyphsBuffer[0].fLeft;
|
|
fRight = m_pGlyphsBuffer[m_nGlyphsCount - 1].fRight + m_pGlyphsBuffer[m_nGlyphsCount - 1].fX;
|
|
|
|
*pfBottom = fBottom;
|
|
*pfRight = fRight;
|
|
*pfLeft = fLeft;
|
|
*pfTop = fTop;
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(ApplyTransform)(float fA, float fB, float fC, float fD, float fE, float fF)
|
|
{
|
|
if ( !m_pFont )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
m_pFont->ResetTransform();
|
|
m_pFont->ApplyTransform( fA, fB, fC, fD, fE, fF );
|
|
|
|
return S_OK;
|
|
}
|
|
//----- Ðàáîòà ñî øðèôòàìè Windows ------------------------------------------------------------------
|
|
STDMETHOD(GetWinFontsCount)(long *plCount)
|
|
{
|
|
if ( !m_pFontEngine )
|
|
{
|
|
*plCount = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
*plCount = m_pFontEngine->GetInstalledFontsCount();
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(GetWinFont)(long nIndex, BSTR *pbsFontName, BSTR *pbsFontStyle, BSTR *pbsFontPath, long *plIndex, BOOL *pbBold, BOOL *pbItalic)
|
|
{
|
|
if ( !m_pFontEngine )
|
|
{
|
|
*pbsFontName = CStringW( _T("") ).AllocSysString();
|
|
*pbsFontStyle = CStringW( _T("") ).AllocSysString();
|
|
*pbsFontPath = CStringW( _T("") ).AllocSysString();
|
|
*plIndex = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
CWinFontInfo *pFontInfo = m_pFontEngine->GetInstalledFont( nIndex );
|
|
|
|
*pbsFontName = CStringW( pFontInfo->m_wsFontName ).AllocSysString();
|
|
*pbsFontStyle = CStringW( pFontInfo->m_wsStyle ).AllocSysString();
|
|
*pbsFontPath = CStringW( pFontInfo->m_wsFontPath ).AllocSysString();
|
|
*plIndex = pFontInfo->m_lIndex;
|
|
*pbBold = pFontInfo->m_bBold;
|
|
*pbItalic = pFontInfo->m_bItalic;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
};
|
|
|