145 lines
4.5 KiB
C++
145 lines
4.5 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 "CustomFont.h"
|
|
#include "Layout.h"
|
|
#include "resource.h"
|
|
|
|
float const Layout::leftMargin_ = 0.25f * 96;
|
|
float const Layout::rightMargin_ = 0.25f * 96;
|
|
float const Layout::minColumnWidth_ = 3.0f * 96;
|
|
|
|
struct Layout::Format
|
|
{
|
|
float pointSize;
|
|
float spaceBefore;
|
|
wchar_t const* familyName;
|
|
};
|
|
|
|
Layout::Format const Layout::formats_[] =
|
|
{
|
|
{ 20.0f, 12.0f, L"Pericles" },
|
|
{ 11.0f, 11.0f, L"Kootenay" }
|
|
};
|
|
|
|
UINT const Layout::paragraphs_[] =
|
|
{
|
|
IDS_HEADING,
|
|
IDS_BODY1,
|
|
IDS_BODY2,
|
|
IDS_BODY3
|
|
};
|
|
|
|
HRESULT Layout::Draw(float pageWidthInDips, ID2D1RenderTarget* renderTarget, ID2D1Brush* textBrush)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
static UINT const fontResourceIDs[] = { IDR_FONT_PERICLES, IDR_FONT_KOOTENAY };
|
|
|
|
// Create a custom font collection comprising our two font resources. We could have done this
|
|
// in the constructor rather than every time. However, if you set break points on the loader
|
|
// callbacks you'll find they're only called the first time the font collection is created.
|
|
// Thereafter the font collection data is cached so recreating it is quite fast.
|
|
hr = fontContext_.Initialize();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
IDWriteFontCollection* fontCollection = NULL;
|
|
hr = fontContext_.CreateFontCollection(
|
|
fontResourceIDs,
|
|
sizeof(fontResourceIDs),
|
|
&fontCollection
|
|
);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
// Set up for first paragraph.
|
|
float const columnWidth = std::max<float>(minColumnWidth_, pageWidthInDips - leftMargin_ - rightMargin_);
|
|
float y = 0;
|
|
|
|
float spaceBefore = 0;
|
|
IDWriteTextFormat* textFormat = NULL;
|
|
|
|
size_t const formatCount = sizeof(formats_) / sizeof(formats_[0]);
|
|
size_t const paragraphCount = sizeof(paragraphs_) / sizeof(paragraphs_[0]);
|
|
|
|
// Iterate over all the paragraphs.
|
|
for (size_t i = 0; i < paragraphCount; ++i)
|
|
{
|
|
// We create a different text format object for the first formatCount
|
|
// paragraphs. After that we reuse the last text format object.
|
|
if (i < formatCount)
|
|
{
|
|
// Create the text format object, specifying both the family name and the
|
|
// custom font collection in which to look for the family name. DirectWrite
|
|
// will only look for the family name in the specified collection so there
|
|
// is no ambiguity even if the system font collection happens to have a font
|
|
// with the same family name.
|
|
SafeRelease(&textFormat);
|
|
hr = g_dwriteFactory->CreateTextFormat(
|
|
formats_[i].familyName,
|
|
fontCollection,
|
|
DWRITE_FONT_WEIGHT_NORMAL,
|
|
DWRITE_FONT_STYLE_NORMAL,
|
|
DWRITE_FONT_STRETCH_NORMAL,
|
|
formats_[i].pointSize * (96.0f / 72),
|
|
L"en-us",
|
|
&textFormat
|
|
);
|
|
|
|
spaceBefore = formats_[i].spaceBefore * (96.0f / 72);
|
|
}
|
|
|
|
IDWriteTextLayout* textLayout = NULL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Load the string.
|
|
int const maxLength = 512;
|
|
wchar_t charBuffer[maxLength];
|
|
int stringLength = LoadString(g_instance, paragraphs_[i], charBuffer, maxLength);
|
|
|
|
// Create the text layout object.
|
|
hr = g_dwriteFactory->CreateTextLayout(
|
|
charBuffer,
|
|
stringLength,
|
|
textFormat,
|
|
columnWidth,
|
|
0,
|
|
&textLayout
|
|
);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Draw the text and update the y coordinate.
|
|
y += spaceBefore;
|
|
|
|
renderTarget->DrawTextLayout(
|
|
D2D1::Point2F(leftMargin_, y),
|
|
textLayout,
|
|
textBrush
|
|
);
|
|
|
|
DWRITE_TEXT_METRICS metrics;
|
|
hr = textLayout->GetMetrics(&metrics);
|
|
y += metrics.height;
|
|
}
|
|
SafeRelease(&textLayout);
|
|
|
|
if (FAILED(hr))
|
|
break;
|
|
}
|
|
|
|
SafeRelease(&textFormat);
|
|
SafeRelease(&fontCollection);
|
|
|
|
return hr;
|
|
}
|