DWrite可以高速地呈现文字:
#include "stdafx.h"
class unicode_file
{
PCWSTR m_view;
UINT32 m_size;
public:
unicode_file();
~unicode_file();
PCWSTR text() const;
UINT32 size() const;
};
struct SampleWindow
: DesktopWindow<SampleWindow>
{
ComPtr<ID2D1SolidColorBrush> m_brush;
ComPtr<IDWriteTextLayout> m_textLayout;
float m_offset;
float m_anchor;
void CreateDeviceIndependentResources()
{
ComPtr<IDWriteFactory1> factory;
HR(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory1),
reinterpret_cast<IUnknown**>(factory.GetAddressOf())));
ComPtr<IDWriteTextFormat> format;
HR(factory->CreateTextFormat(L"Consolas",
nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, 12.0f,
L"", format.GetAddressOf()));
unicode_file file;
ASSERT(!m_textLayout);
HR(factory->CreateTextLayout(file.text(), file.size(),
format.Get(), 100.0f, 100.0f,
m_textLayout.GetAddressOf()));
m_offset = 0.0f;
}
LRESULT MouseLeftButtonDownHandler(UINT, WPARAM, LPARAM lparam, BOOL&)
{
SetCapture();
m_anchor = HIWORD(lparam) - m_offset;
return 0;
}
LRESULT MouseLeftButtonUpHandler(UINT, WPARAM, LPARAM, BOOL&)
{
ReleaseCapture();
return 0;
}
LRESULT MouseMoveHandler(UINT, WPARAM wparam, LPARAM lparam, BOOL&)
{
if (wparam & MK_LBUTTON)
{
m_offset = HIWORD(lparam) - m_anchor;
Invalidate();
}
return 0;
}
void CreateDeviceResources()
{
HR(m_target->CreateSolidColorBrush(COLOR_WHITE, m_brush.GetAddressOf()));
}
void Draw()
{
m_target->Clear(COLOR_BLACK);
//
auto size = m_target->GetSize();
auto margin = 50.0f;
size.width -= margin * 2.0f;
size.height -= margin * 2.0f;
if (m_textLayout->SetMaxWidth(size.width) == S_OK &&
m_textLayout->SetMaxHeight(size.height) == S_OK)
{
auto t = Matrix3x2F::Translation(0.0f, min(0.0f, m_offset));
m_target->SetTransform(t);
m_target->DrawTextLayout(Point2F(margin, margin),
m_textLayout.Get(), m_brush.Get(),
D2D1_DRAW_TEXT_OPTIONS_NONE);
}
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
ComInitialize com;
SampleWindow window;
return window.Run();
}
unicode_file::unicode_file()
{
auto file = CreateFile(L"D2DTest.cpp", GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
ASSERT(file);
LARGE_INTEGER size;
VERIFY(GetFileSizeEx(file, &size));
auto map = CreateFileMapping(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
ASSERT(map);
VERIFY(CloseHandle(file));
PSTR ansi = static_cast<PSTR>(MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0));
m_size = MultiByteToWideChar(CP_ACP, 0, ansi, -1, nullptr, 0);
PWSTR pwstr = new WCHAR[m_size];
MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, ansi, -1, pwstr, m_size);
m_view = static_cast<PCWSTR>(pwstr);
ASSERT(m_view);
VERIFY(CloseHandle(map));
VERIFY(UnmapViewOfFile(ansi));
}
unicode_file::~unicode_file()
{
PWSTR pwstr = const_cast<PWSTR>(m_view);
delete [] pwstr;
}
PCWSTR unicode_file::text() const
{
ASSERT(m_view);
return m_view;
}
UINT32 unicode_file::size() const
{
return m_size;
}