⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmfont.cpp

📁 WDK 下的XPSDrv 中filter 例子之 watermark
💻 CPP
字号:
/*++

Copyright (c) 2005 Microsoft Corporation

All rights reserved.

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

File Name:

   wmfont.cpp

Abstract:

   Watermark font implementation. The CWatermarkFont class is responsible
   for managing the font resource for a text watermark. This implements
   the IResWriter interface so that the font can be added to the resource
   cache.

--*/

#include "precomp.h"
#include "debug.h"
#include "globals.h"
#include "xdstring.h"
#include "wmfont.h"

using XDPrintSchema::PageWatermark::EWatermarkOption;
using XDPrintSchema::PageWatermark::TextWatermark;

//
// Watermark font obfuscation GUID
// GUID fontGUID = { 0x7671f478, 0xd7ad, 0x490e, { 0xab, 0x3a, 0xc5, 0x9f, 0x13, 0x72, 0x40, 0xac } };
//
// The above GUID is used to obfuscate the watermark font with the following byte ordering
//
// GUID             - B00 B01 B02 B03 - B10 B11 - B20 B21 - B30 B31 B32 B33 B34 B35 B36 B37
// Font Name Format - B03 B02 B01 B00 - B11 B10 - B21 B20 - B30 B31 B32 B33 B34 B35 B36 B37
// Byte obfuscation - B37 B36 B35 B34 B33 B32 B31 B30 - B20 B21 - B10 B11 - B00 B01 B02 B03
//

/*++

Routine Name:

    CWatermarkFont::CWatermarkFont

Routine Description:

    Constructor for the CWatermarkFont font management class which
    sets the member variables to sensible defaults and ensures the
    current watermark which uses this font is a text based watermark

Arguments:

    wmProps - Object containing the PrintTicket settings

Return Value:

    None
    Throws CXDException(HRESULT) on an error

--*/
CWatermarkFont::CWatermarkFont(
    __in CONST CWMPTProperties& wmProps
     ) :
    m_hDC(CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL)),
    m_WMProps(wmProps),
    m_hFont(NULL),
    m_hOldFont(NULL),
    m_bstrFaceName(L"Arial")
{
    HRESULT hr = S_OK;

    ASSERTMSG(m_hDC != NULL, "NULL DC passed.\n");

    EWatermarkOption wmType;

    if (SUCCEEDED(hr = m_WMProps.GetType(&wmType)))
    {
        if (wmType == TextWatermark)
        {
            hr = SetFont();
        }
        else
        {
            hr = E_INVALIDARG;
        }
    }

    if (FAILED(hr))
    {
        throw CXDException(hr);
    }
}

/*++

Routine Name:

    CWatermarkFont::~CWatermarkFont

Routine Description:

    Default destructor for the font management class

Arguments:

    None

Return Value:

    None

--*/
CWatermarkFont::~CWatermarkFont()
{
    UnsetFont();

    if (SUCCEEDED(CHECK_HANDLE(m_hDC, E_PENDING)))
    {
        DeleteDC(m_hDC);
    }
}

/*++

Routine Name:

    CWatermarkFont::WriteData

Routine Description:

    Method for writing out the font to the container

Arguments:

    pStream - Pointer to the stream to write the font out to

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWatermarkFont::WriteData(
    __in IPartBase*         pResource,
    __in IPrintWriteStream* pStream
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(pResource, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(pStream, E_POINTER)))
    {
        //
        // Find the size of the font data
        //
        DWORD cbFontData = GetFontData(m_hDC, 0, 0, 0, 0);

        if (cbFontData != GDI_ERROR)
        {
            PBYTE pFontData = new BYTE[cbFontData];

            if (SUCCEEDED(hr = CHECK_POINTER(pFontData, E_OUTOFMEMORY)))
            {
                //
                // Retrieve the font data
                //
                if (GDI_ERROR != GetFontData(m_hDC,
                                             0,
                                             0,
                                             reinterpret_cast<LPVOID>(pFontData),
                                             cbFontData))
                {
                    //
                    // Fonts embedded in the container should be obfuscated by XORing
                    // the first 32 bytes of font data with our font GUID
                    //
                    CComQIPtr<IPartFont> pFont = pResource;
                    if (SUCCEEDED(hr = CHECK_POINTER(pFont, E_NOINTERFACE)) &&
                        SUCCEEDED(hr = pFont->SetFontContent(CComBSTR(L"application/vnd.ms-package.obfuscated-opentype"))))
                    {
                        BYTE FontGUID[] = {0xAC, 0x40, 0x72, 0x13, 0x9F, 0xC5, 0x3A, 0xAB, 0x49, 0x0E, 0xD7, 0xAD, 0x76, 0x71, 0xF4, 0x78};
                        PBYTE pObfPointer = pFontData;

                        for (UINT guidByte = 0; guidByte < min(cbFontData, 32); guidByte++)
                        {
                            *pObfPointer ^= FontGUID[guidByte % countof(FontGUID)];
                            pObfPointer++;
                        }

                        //
                        // Write font data to stream
                        //
                        ULONG cbWritten = 0;
                        hr = pStream->WriteBytes(reinterpret_cast<LPVOID>(pFontData),
                                                 cbFontData,
                                                 &cbWritten);

                        ASSERTMSG(cbFontData == cbWritten, "Failed to write all font data.\n");
                    }
                }
                else
                {
                    hr = GetLastErrorAsHResult();
                }

                delete[] pFontData;
                pFontData = NULL;
            }
        }
        else
        {
            hr = GetLastErrorAsHResult();
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWatermarkFont::SetFont

Routine Description:

    Method to select a font into the device context

Arguments:

    None

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWatermarkFont::SetFont(
    VOID
    )
{
    ASSERTMSG(m_hFont == NULL, "Non NULL font handle when setting new font. Possible resource leak.\n");
    ASSERTMSG(m_hOldFont == NULL, "Non NULL old font handle when setting new font. Possible resource leak.\n");

    HRESULT hr = S_OK;

    INT      fontSize;

    if (SUCCEEDED(hr = m_WMProps.GetFontSize(&fontSize)))
    {
        LOGFONTW logfont;

        logfont.lfHeight = -MulDiv(fontSize, GetDeviceCaps(m_hDC, LOGPIXELSY), 72);
        logfont.lfWidth = 0;
        logfont.lfEscapement = 0;
        logfont.lfOrientation = 0;
        logfont.lfWeight = FW_NORMAL;
        logfont.lfItalic = FALSE;
        logfont.lfUnderline = FALSE;
        logfont.lfStrikeOut = FALSE;
        logfont.lfCharSet = ANSI_CHARSET;
        logfont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
        logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
        logfont.lfQuality = CLEARTYPE_QUALITY;
        logfont.lfPitchAndFamily = FF_DONTCARE;

        size_t cchSrc = 0;
        if (SUCCEEDED(hr = StringCchLength(m_bstrFaceName, LF_FACESIZE, &cchSrc)) &&
            SUCCEEDED(hr = StringCchCopyN(logfont.lfFaceName, LF_FACESIZE, m_bstrFaceName, cchSrc)))
        {
            if (m_hFont != NULL)
            {
                UnsetFont();
            }

            m_hFont = CreateFontIndirect(&logfont);

            if (m_hFont != NULL)
            {
                m_hOldFont = SelectFont(m_hDC, m_hFont);
            }
            else
            {
                hr = GetLastErrorAsHResult();
            }
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWatermarkFont::UnsetFont

Routine Description:

    Method de-select a font from the current device context

Arguments:

    None

Return Value:

    None

--*/
VOID
CWatermarkFont::UnsetFont(
    VOID
    )
{
    ASSERTMSG(m_hFont != NULL, "Attempting to deselect invalid font.\n");
    ASSERTMSG(m_hOldFont != NULL, "Attempting to select invalid font.\n");

    SelectFont(m_hDC, m_hOldFont);
    if (m_hFont != NULL)
    {
        DeleteObject(m_hFont);
        m_hFont = NULL;
    }
}

/*++

Routine Name:

    CWatermarkFont::GetKeyName

Routine Description:

    Method to obtain a unique key for the stored font based on the resource name

Arguments:

    pbstrKeyName - Pointer to the string to contain the generated key name

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWatermarkFont::GetKeyName(
    __deref_out BSTR* pbstrKeyName
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(pbstrKeyName, E_POINTER)))
    {
        try
        {
            //
            // The name of the resource is a suitable key
            //
            hr = m_bstrFaceName.CopyTo(pbstrKeyName);
        }
        catch (CXDException& e)
        {
            hr = e;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWatermarkFont::GetResURI

Routine Description:

    Method to obtain the URI to the stored font

Arguments:

    pbstrResURI - Pointer to the string to contain the font resource URI

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWatermarkFont::GetResURI(
    __deref_out BSTR* pbstrResURI
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(pbstrResURI, E_POINTER)))
    {
        *pbstrResURI = NULL;

        try
        {
            //
            // Create an obfuscated font name using our font GUID
            //
            CStringXDW cstrURI(L"78F47176-ADD7-0E49-AB3A-C59F137240AC.odttf");
            *pbstrResURI = cstrURI.AllocSysString();
        }
        catch (CXDException& e)
        {
            hr = e;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -