2025-11-28 00:35:46 +09:00

129 lines
3.2 KiB
C++

// 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.
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
//----------------------------------------------------------------------------
#include "Common.h"
#include "ResourceFontFileStream.h"
HMODULE const ResourceFontFileStream::moduleHandle_(GetCurrentModule());
// GetCurrentModule
//
// Helper to get the module handle for the application.
//
HMODULE ResourceFontFileStream::GetCurrentModule()
{
HMODULE handle = NULL;
// Determine the module handle from the address of this function.
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
reinterpret_cast<LPCTSTR>(&GetCurrentModule),
&handle
);
return handle;
}
ResourceFontFileStream::ResourceFontFileStream(UINT resourceID) :
refCount_(0),
resourcePtr_(NULL),
resourceSize_(0)
{
HRSRC resource = FindResource(moduleHandle_, MAKEINTRESOURCE(resourceID), RT_FONT);
if (resource != NULL)
{
HGLOBAL memHandle = LoadResource(moduleHandle_, resource);
if (memHandle != NULL)
{
resourcePtr_ = LockResource(memHandle);
if (resourcePtr_ != NULL)
{
resourceSize_ = SizeofResource(moduleHandle_, resource);
}
}
}
}
// IUnknown methods
HRESULT STDMETHODCALLTYPE ResourceFontFileStream::QueryInterface(REFIID iid, void** ppvObject)
{
if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream))
{
*ppvObject = this;
AddRef();
return S_OK;
}
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE ResourceFontFileStream::AddRef()
{
return InterlockedIncrement(&refCount_);
}
ULONG STDMETHODCALLTYPE ResourceFontFileStream::Release()
{
ULONG newCount = InterlockedDecrement(&refCount_);
if (newCount == 0)
delete this;
return newCount;
}
// IDWriteFontFileStream methods
HRESULT STDMETHODCALLTYPE ResourceFontFileStream::ReadFileFragment(
void const** fragmentStart, // [fragmentSize] in bytes
UINT64 fileOffset,
UINT64 fragmentSize,
OUT void** fragmentContext
)
{
// The loader is responsible for doing a bounds check.
if (fileOffset <= resourceSize_ &&
fragmentSize <= resourceSize_ - fileOffset)
{
*fragmentStart = static_cast<BYTE const*>(resourcePtr_) + static_cast<size_t>(fileOffset);
*fragmentContext = NULL;
return S_OK;
}
else
{
*fragmentStart = NULL;
*fragmentContext = NULL;
return E_FAIL;
}
}
void STDMETHODCALLTYPE ResourceFontFileStream::ReleaseFileFragment(
void* fragmentContext
)
{
}
HRESULT STDMETHODCALLTYPE ResourceFontFileStream::GetFileSize(
OUT UINT64* fileSize
)
{
*fileSize = resourceSize_;
return S_OK;
}
HRESULT STDMETHODCALLTYPE ResourceFontFileStream::GetLastWriteTime(
OUT UINT64* lastWriteTime
)
{
// The concept of last write time does not apply to this loader.
*lastWriteTime = 0;
return E_NOTIMPL;
}