1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10 #include <cppunit/TestAssert.h>
11 #include <cppunit/TestFixture.h>
12 #include <cppunit/extensions/HelperMacros.h>
13 #include <cppunit/plugin/TestPlugIn.h>
14
15 #include <com/sun/star/beans/PropertyValue.hpp>
16
17 #include <vcl/bitmapaccess.hxx>
18 #include <vcl/graph.hxx>
19 #include <vcl/graphicfilter.hxx>
20 #include <tools/stream.hxx>
21 #include <unotest/directories.hxx>
22
23 using namespace css;
24
25 namespace
26 {
27 class GraphicTest : public CppUnit::TestFixture
28 {
29 void testUnloadedGraphic();
30 void testUnloadedGraphicLoading();
31 void testUnloadedGraphicWmf();
32 void testUnloadedGraphicAlpha();
33 void testUnloadedGraphicSizeUnit();
34
35 CPPUNIT_TEST_SUITE(GraphicTest);
36 CPPUNIT_TEST(testUnloadedGraphic);
37 CPPUNIT_TEST(testUnloadedGraphicLoading);
38 CPPUNIT_TEST(testUnloadedGraphicWmf);
39 CPPUNIT_TEST(testUnloadedGraphicAlpha);
40 CPPUNIT_TEST(testUnloadedGraphicSizeUnit);
41 CPPUNIT_TEST_SUITE_END();
42 };
43
createBitmap(bool alpha=false)44 BitmapEx createBitmap(bool alpha = false)
45 {
46 Bitmap aBitmap(Size(120, 100), 24);
47 aBitmap.Erase(COL_LIGHTRED);
48
49 aBitmap.SetPrefSize(Size(6000, 5000));
50 aBitmap.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
51
52 if (alpha)
53 {
54 sal_uInt8 uAlphaValue = 0x80;
55 AlphaMask aAlphaMask(Size(120, 100), &uAlphaValue);
56
57 return BitmapEx(aBitmap, aAlphaMask);
58 }
59 else
60 {
61 return BitmapEx(aBitmap);
62 }
63 }
64
createBitmapAndExportForType(SvStream & rStream,OUString const & sType,bool alpha)65 void createBitmapAndExportForType(SvStream& rStream, OUString const& sType, bool alpha)
66 {
67 BitmapEx aBitmapEx = createBitmap(alpha);
68
69 uno::Sequence<beans::PropertyValue> aFilterData;
70 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
71 sal_uInt16 nFilterFormat = rGraphicFilter.GetExportFormatNumberForShortName(sType);
72 rGraphicFilter.ExportGraphic(aBitmapEx, "none", rStream, nFilterFormat, &aFilterData);
73
74 rStream.Seek(STREAM_SEEK_TO_BEGIN);
75 }
76
makeUnloadedGraphic(OUString const & sType,bool alpha=false)77 Graphic makeUnloadedGraphic(OUString const& sType, bool alpha = false)
78 {
79 SvMemoryStream aStream;
80 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
81 createBitmapAndExportForType(aStream, sType, alpha);
82 return rGraphicFilter.ImportUnloadedGraphic(aStream);
83 }
84
85 char const DATA_DIRECTORY[] = "/vcl/qa/cppunit/data/";
86
testUnloadedGraphic()87 void GraphicTest::testUnloadedGraphic()
88 {
89 // make unloaded test graphic
90 Graphic aGraphic = makeUnloadedGraphic("png");
91 Graphic aGraphic2 = aGraphic;
92
93 // check available
94 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
95 CPPUNIT_ASSERT_EQUAL(false, aGraphic2.isAvailable());
96
97 CPPUNIT_ASSERT_EQUAL(true, aGraphic2.makeAvailable());
98 CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
99 CPPUNIT_ASSERT_EQUAL(true, aGraphic2.isAvailable());
100
101 // check GetSizePixel doesn't load graphic
102 aGraphic = makeUnloadedGraphic("png");
103 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
104 CPPUNIT_ASSERT_EQUAL(120L, aGraphic.GetSizePixel().Width());
105 CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Height());
106 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
107
108 // check GetPrefSize doesn't load graphic
109 CPPUNIT_ASSERT_EQUAL(6000L, aGraphic.GetPrefSize().Width());
110 CPPUNIT_ASSERT_EQUAL(5000L, aGraphic.GetPrefSize().Height());
111 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
112
113 // check GetSizeBytes loads graphic
114 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
115 CPPUNIT_ASSERT(aGraphic.GetSizeBytes() > 0);
116 CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
117 }
118
testUnloadedGraphicLoading()119 void GraphicTest::testUnloadedGraphicLoading()
120 {
121 const OUString aFormats[] = { "png", "gif", "jpg" };
122
123 for (OUString const& sFormat : aFormats)
124 {
125 Graphic aGraphic = makeUnloadedGraphic(sFormat);
126
127 // check available
128 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
129 CPPUNIT_ASSERT_EQUAL(120L, aGraphic.GetSizePixel().Width());
130 CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Height());
131 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
132 CPPUNIT_ASSERT(aGraphic.GetSizeBytes() > 0);
133 CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
134 Bitmap aBitmap(aGraphic.GetBitmapEx().GetBitmap());
135
136 {
137 Bitmap::ScopedReadAccess pReadAccess(aBitmap);
138 for (long y = 0; y < aGraphic.GetSizePixel().Height(); y++)
139 {
140 for (long x = 0; x < aGraphic.GetSizePixel().Width(); x++)
141 {
142 if (pReadAccess->HasPalette())
143 {
144 Color aColor
145 = pReadAccess->GetPaletteColor(pReadAccess->GetPixelIndex(y, x));
146 CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), aColor.AsRGBHexString());
147 }
148 else
149 {
150 Color aColor = pReadAccess->GetPixel(y, x);
151 if (sFormat != "jpg")
152 CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), aColor.AsRGBHexString());
153 }
154 }
155 }
156 }
157 }
158 }
159
testUnloadedGraphicWmf()160 void GraphicTest::testUnloadedGraphicWmf()
161 {
162 // Create some in-memory WMF data, set its own preferred size to 99x99.
163 BitmapEx aBitmapEx = createBitmap();
164 SvMemoryStream aStream;
165 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
166 sal_uInt16 nFilterFormat = rGraphicFilter.GetExportFormatNumberForShortName("wmf");
167 Graphic aGraphic(aBitmapEx);
168 aGraphic.SetPrefSize(Size(99, 99));
169 aGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
170 rGraphicFilter.ExportGraphic(aGraphic, "none", aStream, nFilterFormat);
171 aStream.Seek(STREAM_SEEK_TO_BEGIN);
172
173 // Now lazy-load this WMF data, with a custom preferred size of 42x42.
174 Size aMtfSize100(42, 42);
175 aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream, 0, &aMtfSize100);
176 aGraphic.makeAvailable();
177
178 // Without the accompanying fix in place, this test would have failed with:
179 // - Expected: 42x42
180 // - Actual : 99x99
181 // i.e. the custom preferred size was lost after lazy-load.
182 CPPUNIT_ASSERT_EQUAL(Size(42, 42), aGraphic.GetPrefSize());
183 }
184
testUnloadedGraphicAlpha()185 void GraphicTest::testUnloadedGraphicAlpha()
186 {
187 // make unloaded test graphic with alpha
188 Graphic aGraphic = makeUnloadedGraphic("png", true);
189
190 CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsAlpha());
191 CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsTransparent());
192 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
193
194 // make unloaded test graphic without alpha
195 aGraphic = makeUnloadedGraphic("png", false);
196
197 CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsAlpha());
198 CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsTransparent());
199 CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
200 }
201
testUnloadedGraphicSizeUnit()202 void GraphicTest::testUnloadedGraphicSizeUnit()
203 {
204 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
205 test::Directories aDirectories;
206 OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "inch-size.emf";
207 Size aMtfSize100(42, 42);
208 SvFileStream aStream(aURL, StreamMode::READ);
209 Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream, 0, &aMtfSize100);
210 aGraphic.makeAvailable();
211
212 // Without the accompanying fix in place, this test would have failed with:
213 // - Expected: 400x363
214 // - Actual : 42x42
215 // i.e. a mm100 size was used as a hint and the inch size was set for a non-matching unit.
216 CPPUNIT_ASSERT_EQUAL(Size(400, 363), aGraphic.GetPrefSize());
217 }
218
219 } // namespace
220
221 CPPUNIT_TEST_SUITE_REGISTRATION(GraphicTest);
222
223 CPPUNIT_PLUGIN_IMPLEMENT();
224
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
226