|  | // Copyright 2019 The PDFium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "core/fxge/cfx_windowsrenderdevice.h" | 
|  |  | 
|  | #include <windows.h> | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "core/fxge/cfx_fillrenderoptions.h" | 
|  | #include "core/fxge/cfx_path.h" | 
|  | #include "core/fxge/win32/cfx_psfonttracker.h" | 
|  | #include "testing/embedder_test.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | constexpr CFX_Matrix kIdentityMatrix; | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | class CFX_WindowsRenderDeviceTest : public EmbedderTest { | 
|  | public: | 
|  | void SetUp() override { | 
|  | EmbedderTest::SetUp(); | 
|  |  | 
|  | // Get a device context with Windows GDI. | 
|  | m_hDC = CreateCompatibleDC(nullptr); | 
|  | ASSERT_TRUE(m_hDC); | 
|  | m_driver = std::make_unique<CFX_WindowsRenderDevice>( | 
|  | m_hDC, &m_PSFontTracker, /*encoder_iface=*/nullptr); | 
|  | m_driver->SaveState(); | 
|  | } | 
|  |  | 
|  | void TearDown() override { | 
|  | m_driver->RestoreState(false); | 
|  | m_driver.reset(); | 
|  | DeleteDC(m_hDC); | 
|  | EmbedderTest::TearDown(); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | HDC m_hDC; | 
|  | CFX_PSFontTracker m_PSFontTracker; | 
|  | std::unique_ptr<CFX_WindowsRenderDevice> m_driver; | 
|  | }; | 
|  |  | 
|  | TEST_F(CFX_WindowsRenderDeviceTest, SimpleClipTriangle) { | 
|  | CFX_Path path_data; | 
|  | CFX_PointF p1(0.0f, 0.0f); | 
|  | CFX_PointF p2(0.0f, 100.0f); | 
|  | CFX_PointF p3(100.0f, 100.0f); | 
|  |  | 
|  | path_data.AppendLine(p1, p2); | 
|  | path_data.AppendLine(p2, p3); | 
|  | path_data.AppendLine(p3, p1); | 
|  | path_data.ClosePath(); | 
|  | EXPECT_TRUE(m_driver->SetClip_PathFill( | 
|  | path_data, &kIdentityMatrix, CFX_FillRenderOptions::WindingOptions())); | 
|  | } | 
|  |  | 
|  | TEST_F(CFX_WindowsRenderDeviceTest, SimpleClipRect) { | 
|  | CFX_Path path_data; | 
|  |  | 
|  | path_data.AppendRect(0.0f, 100.0f, 200.0f, 0.0f); | 
|  | path_data.ClosePath(); | 
|  | EXPECT_TRUE(m_driver->SetClip_PathFill( | 
|  | path_data, &kIdentityMatrix, CFX_FillRenderOptions::WindingOptions())); | 
|  | } | 
|  |  | 
|  | TEST_F(CFX_WindowsRenderDeviceTest, GargantuanClipRect) { | 
|  | CFX_Path path_data; | 
|  |  | 
|  | path_data.AppendRect(-257698020.0f, -257697252.0f, 257698044.0f, | 
|  | 257698812.0f); | 
|  | path_data.ClosePath(); | 
|  | // These coordinates for a clip path are valid, just very large. Using these | 
|  | // for a clip path should allow IntersectClipRect() to return success; | 
|  | // however they do not because the GDI API IntersectClipRect() errors out and | 
|  | // affect subsequent imaging.  crbug.com/1019026 | 
|  | EXPECT_FALSE(m_driver->SetClip_PathFill( | 
|  | path_data, &kIdentityMatrix, CFX_FillRenderOptions::WindingOptions())); | 
|  | } | 
|  |  | 
|  | TEST_F(CFX_WindowsRenderDeviceTest, GargantuanClipRectWithBaseClip) { | 
|  | CFX_Path path_data; | 
|  | const FX_RECT kBaseClip(0, 0, 5100, 6600); | 
|  |  | 
|  | m_driver->SetBaseClip(kBaseClip); | 
|  | path_data.AppendRect(-257698020.0f, -257697252.0f, 257698044.0f, | 
|  | 257698812.0f); | 
|  | path_data.ClosePath(); | 
|  | // Use of a reasonable base clip ensures that we avoid getting an error back | 
|  | // from GDI API IntersectClipRect(). | 
|  | EXPECT_TRUE(m_driver->SetClip_PathFill( | 
|  | path_data, &kIdentityMatrix, CFX_FillRenderOptions::WindingOptions())); | 
|  | } |