📄 pagescale.cpp
字号:
}
/*++
Routine Name:
CPageScaling::CalculateMatrix
Routine Description:
Calculates a matrix transform from the current page scaling properties.
Arguments:
pMatrix - Pointer to a Matrix class object that is modified to reflect the current transform.
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CPageScaling::CalculateMatrix(
__inout Matrix* pMatrix
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pMatrix, E_POINTER)))
{
REAL xScale = 1.0f;
REAL yScale = 1.0f;
REAL widthOffset = 0.0f;
REAL heightOffset = 0.0f;
EScaleOption pgscOption;
if (SUCCEEDED(hr = m_PGSCProps.GetOption(&pgscOption)))
{
switch (pgscOption)
{
case Custom:
case CustomSquare:
{
//
// The PrintTicket property handler for Custom and CustomSquare
// already handle mapping of x and y.
//
if (SUCCEEDED(hr = m_PGSCProps.GetWidthScale(&xScale)) &&
SUCCEEDED(hr = m_PGSCProps.GetHeightScale(&yScale)) &&
SUCCEEDED(hr = m_PGSCProps.GetWidthOffset(&widthOffset)))
{
hr = m_PGSCProps.GetHeightOffset(&heightOffset);
}
}
break;
case FitBleedToImageable: // ImageableSize <- BleedBox
case FitContentToImageable: // ImageableSize <- ContentBox
case FitMediaToImageable: // ImageableSize <- FixedPage
case FitMediaToMedia: // Mediasize <- FixedPage
{
EScaleOffsetOption offsetOption;
if (SUCCEEDED(hr = m_PGSCProps.GetOffsetOption(&offsetOption)))
{
RectF targetPage;
RectF sourcePage;
switch (pgscOption)
{
case FitBleedToImageable:
{
m_PGSCProps.GetImageableRect(&targetPage);
sourcePage = m_bleedBox;
}
break;
case FitContentToImageable:
{
m_PGSCProps.GetImageableRect(&targetPage);
sourcePage = m_contentBox;
}
break;
case FitMediaToImageable:
{
m_PGSCProps.GetImageableRect(&targetPage);
sourcePage = RectF(0, 0, m_pageDimensions.Width, m_pageDimensions.Height);
}
break;
case FitMediaToMedia:
{
SizeF pageSize;
m_PGSCProps.GetPageSize(&pageSize);
targetPage = RectF(0, 0, pageSize.Width, pageSize.Height);
sourcePage = RectF(0, 0, m_pageDimensions.Width, m_pageDimensions.Height);
}
break;
}
//
// Calculate scaling factors
//
xScale = static_cast<REAL>(targetPage.Width / sourcePage.Width);
yScale = static_cast<REAL>(targetPage.Height / sourcePage.Height);
//
// Best Fit, always maintain aspect ratio
// Select the smallest of the two scale factors,
// This will ensure that the image always fits on the page.
//
if (xScale < yScale)
{
yScale = xScale;
}
else
{
xScale = yScale;
}
//
// Calculate the offset to meet the offset alignment setting
//
RectF scaledPage(xScale*sourcePage.X, yScale*sourcePage.Y, xScale*sourcePage.Width, yScale*sourcePage.Height);
switch (offsetOption)
{
case BottomCenter:
{
widthOffset = (targetPage.X + (targetPage.Width/2.0f)) - (scaledPage.X + (scaledPage.Width/2.0f));
heightOffset = (targetPage.Y + targetPage.Height) - (scaledPage.Y + scaledPage.Height);
}
break;
case BottomLeft:
{
widthOffset = targetPage.X - scaledPage.X;
heightOffset = targetPage.Y + targetPage.Height - (scaledPage.Y + scaledPage.Height);
}
break;
case BottomRight:
{
widthOffset = (targetPage.X + targetPage.Width) - (scaledPage.X + scaledPage.Width);
heightOffset = (targetPage.Y + targetPage.Height) - (scaledPage.Y + scaledPage.Height);
}
break;
case Center:
{
widthOffset = (targetPage.X + (targetPage.Width/2.0f)) - (scaledPage.X + (scaledPage.Width/2.0f));
heightOffset = (targetPage.Y + (targetPage.Height/2.0f)) - (scaledPage.Y + (scaledPage.Height/2.0f));
}
break;
case LeftCenter:
{
widthOffset = targetPage.X - scaledPage.X;
heightOffset = (targetPage.Y + (targetPage.Height/2.0f)) - (scaledPage.Y + (scaledPage.Height/2.0f));
}
break;
case RightCenter:
{
widthOffset = (targetPage.X + targetPage.Width) - (scaledPage.X + scaledPage.Width);
heightOffset = (targetPage.Y + (targetPage.Height/2.0f)) - (scaledPage.Y + (scaledPage.Height/2.0f));
}
break;
case TopCenter:
{
widthOffset = (targetPage.X + (targetPage.Width/2.0f)) - (scaledPage.X + (scaledPage.Width/2.0f));
heightOffset = targetPage.Y - scaledPage.Y;
}
break;
default:
case TopLeft:
{
//
// Default Top Left
//
widthOffset = targetPage.X - scaledPage.X;
heightOffset = targetPage.Y - scaledPage.Y;
}
break;
case TopRight:
{
widthOffset = (targetPage.X + targetPage.Width) - (scaledPage.X + scaledPage.Width);
heightOffset = targetPage.Y - scaledPage.Y;
}
break;
}
}
}
break;
default:
{
//
// No Scaling required.
//
}
break;
}
}
//
// Apply the transforms to the matrix
//
Status gdiPlusStatus = pMatrix->Scale(xScale, yScale, MatrixOrderAppend);
if (gdiPlusStatus == Ok)
{
gdiPlusStatus = pMatrix->Translate(widthOffset, heightOffset, MatrixOrderAppend);
}
if (gdiPlusStatus != Ok)
{
hr = GetGDIStatusErrorAsHResult(gdiPlusStatus);
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CPageScaling::CreateTransform
Routine Description:
Creates a string representation of the current page scaling matrix.
The string is suitable for use in XPS markup with the 'RenderTransform' keyword.
Arguments:
pbstrMatrixXForm - Address of a pointer that will be modified to point to a string
that is filled out with the matrix.
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CPageScaling::CreateTransform(
__deref_out BSTR* pbstrMatrixXForm
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pbstrMatrixXForm, E_POINTER)))
{
*pbstrMatrixXForm = NULL;
//
// Start with the identity matrix
//
Matrix xForm;
if (SUCCEEDED(hr = CalculateMatrix(&xForm)))
{
//
// Retrieve the matrix string
//
hr = MatrixToXML(&xForm, pbstrMatrixXForm);
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CPageScaling::GetOpenTagXML
Routine Description:
Creates a string that contains the open tag XPS markup required to
scale the page content. Page Scaling is achieved by wrapping the page content
in a canvas and applying a RenderTransform which reflects the current page scaling properties.
Arguments:
pbstrXML - Address of a pointer that will be modified to point to a string
that is filled out with the page scaling close tag XPS markup.
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CPageScaling::GetOpenTagXML(
__deref_out BSTR* pbstrXML
)
{
HRESULT hr = S_OK;
//
// Create the Canvas with Render Transform
//
try
{
CComBSTR bstrMatrixXForm;
if (SUCCEEDED(hr = CreateTransform(&bstrMatrixXForm)))
{
CStringXDW cstrCanvas;
cstrCanvas.Format(L"<Canvas RenderTransform=\"%s\"", bstrMatrixXForm);
*pbstrXML = cstrCanvas.AllocSysString();
}
}
catch (CXDException& e)
{
hr = e;
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CPageScaling::GetCloseTagXML
Routine Description:
Creates a string that contains the close tag XPS markup.
This is achived by closing the canvas tag.
Arguments:
pbstrXML - Address of a pointer that will be modified to point to a string
that is filled out with the page scaling close tag XPS markup.
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CPageScaling::GetCloseTagXML(
__deref_out BSTR* pbstrXML
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pbstrXML, E_POINTER)))
{
try
{
CStringXDW cstrCanvas(L"</Canvas>\n");
*pbstrXML = cstrCanvas.AllocSysString();
}
catch (CXDException& e)
{
hr = e;
}
}
ERR_ON_HR(hr);
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -