| // Copyright 2014 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| #include "fpdfsdk/pwl/cpwl_icon.h" | |
| #include <algorithm> | |
| #include <sstream> | |
| #include <utility> | |
| #include "core/fpdfdoc/cpdf_icon.h" | |
| #include "core/fpdfdoc/cpdf_iconfit.h" | |
| #include "fpdfsdk/pwl/cpwl_wnd.h" | |
| #include "third_party/base/check.h" | |
| CPWL_Icon::CPWL_Icon(const CreateParams& cp, | |
| std::unique_ptr<CPDF_Icon> pIcon, | |
| CPDF_IconFit* pFit) | |
| : CPWL_Wnd(cp, nullptr), m_pIcon(std::move(pIcon)), m_pIconFit(pFit) { | |
| DCHECK(m_pIcon); | |
| } | |
| CPWL_Icon::~CPWL_Icon() = default; | |
| CFX_SizeF CPWL_Icon::GetImageSize() { | |
| return m_pIcon->GetImageSize(); | |
| } | |
| CFX_Matrix CPWL_Icon::GetImageMatrix() { | |
| return m_pIcon->GetImageMatrix(); | |
| } | |
| ByteString CPWL_Icon::GetImageAlias() { | |
| return m_pIcon->GetImageAlias(); | |
| } | |
| CFX_PointF CPWL_Icon::GetIconPosition() { | |
| if (!m_pIconFit) | |
| return CFX_PointF(); | |
| return m_pIconFit->GetIconPosition(); | |
| } | |
| std::pair<float, float> CPWL_Icon::GetScale() { | |
| float fHScale = 1.0f; | |
| float fVScale = 1.0f; | |
| CFX_FloatRect rcPlate = GetClientRect(); | |
| float fPlateWidth = rcPlate.Width(); | |
| float fPlateHeight = rcPlate.Height(); | |
| CFX_SizeF image_size = GetImageSize(); | |
| float fImageWidth = image_size.width; | |
| float fImageHeight = image_size.height; | |
| CPDF_IconFit::ScaleMethod scale_method = | |
| m_pIconFit ? m_pIconFit->GetScaleMethod() | |
| : CPDF_IconFit::ScaleMethod::kAlways; | |
| switch (scale_method) { | |
| case CPDF_IconFit::ScaleMethod::kAlways: | |
| fHScale = fPlateWidth / std::max(fImageWidth, 1.0f); | |
| fVScale = fPlateHeight / std::max(fImageHeight, 1.0f); | |
| break; | |
| case CPDF_IconFit::ScaleMethod::kBigger: | |
| if (fPlateWidth < fImageWidth) | |
| fHScale = fPlateWidth / std::max(fImageWidth, 1.0f); | |
| if (fPlateHeight < fImageHeight) | |
| fVScale = fPlateHeight / std::max(fImageHeight, 1.0f); | |
| break; | |
| case CPDF_IconFit::ScaleMethod::kSmaller: | |
| if (fPlateWidth > fImageWidth) | |
| fHScale = fPlateWidth / std::max(fImageWidth, 1.0f); | |
| if (fPlateHeight > fImageHeight) | |
| fVScale = fPlateHeight / std::max(fImageHeight, 1.0f); | |
| break; | |
| case CPDF_IconFit::ScaleMethod::kNever: | |
| break; | |
| } | |
| if (m_pIconFit && m_pIconFit->IsProportionalScale()) { | |
| float min_scale = std::min(fHScale, fVScale); | |
| fHScale = min_scale; | |
| fVScale = min_scale; | |
| } | |
| return {fHScale, fVScale}; | |
| } | |
| std::pair<float, float> CPWL_Icon::GetImageOffset() { | |
| CFX_PointF icon_position = GetIconPosition(); | |
| float fLeft = icon_position.x; | |
| float fBottom = icon_position.y; | |
| CFX_SizeF image_size = GetImageSize(); | |
| float fImageWidth = image_size.width; | |
| float fImageHeight = image_size.height; | |
| float fHScale, fVScale; | |
| std::tie(fHScale, fVScale) = GetScale(); | |
| float fImageFactWidth = fImageWidth * fHScale; | |
| float fImageFactHeight = fImageHeight * fVScale; | |
| CFX_FloatRect rcPlate = GetClientRect(); | |
| float fPlateWidth = rcPlate.Width(); | |
| float fPlateHeight = rcPlate.Height(); | |
| return {(fPlateWidth - fImageFactWidth) * fLeft, | |
| (fPlateHeight - fImageFactHeight) * fBottom}; | |
| } |