Line data Source code
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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <zlib.h>
21 :
22 : #include "outputwrap.hxx"
23 : #include "contentsink.hxx"
24 : #include "pdfihelper.hxx"
25 : #include "wrapper.hxx"
26 : #include "pdfparse.hxx"
27 : #include "../pdfiadaptor.hxx"
28 :
29 : #include <rtl/math.hxx>
30 : #include <osl/file.hxx>
31 : #include <comphelper/sequence.hxx>
32 :
33 : #include "cppunit/TestAssert.h"
34 : #include "cppunit/TestFixture.h"
35 : #include "cppunit/extensions/HelperMacros.h"
36 : #include "cppunit/plugin/TestPlugIn.h"
37 : #include <test/bootstrapfixture.hxx>
38 :
39 : #include <com/sun/star/rendering/XCanvas.hpp>
40 : #include <com/sun/star/rendering/XColorSpace.hpp>
41 : #include <com/sun/star/rendering/PathJoinType.hpp>
42 : #include <com/sun/star/rendering/PathCapType.hpp>
43 : #include <com/sun/star/rendering/BlendMode.hpp>
44 :
45 : #include <basegfx/matrix/b2dhommatrix.hxx>
46 : #include <basegfx/tools/canvastools.hxx>
47 : #include <basegfx/polygon/b2dpolygon.hxx>
48 : #include <basegfx/polygon/b2dpolypolygon.hxx>
49 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
50 : #include <basegfx/polygon/b2dpolygonclipper.hxx>
51 :
52 : #include <unordered_map>
53 : #include <vector>
54 :
55 : #include <cassert>
56 : #include <rtl/ustring.hxx>
57 :
58 : using namespace ::pdfparse;
59 : using namespace ::pdfi;
60 : using namespace ::com::sun::star;
61 :
62 : namespace
63 : {
64 :
65 : class TestSink : public ContentSink
66 : {
67 : public:
68 1 : TestSink() :
69 : m_nNextFontId( 1 ),
70 : m_aIdToFont(),
71 : m_aFontToId(),
72 : m_aGCStack(1),
73 : m_aPageSize(),
74 : m_aHyperlinkBounds(),
75 : m_aURI(),
76 : m_aTextOut(),
77 : m_nNumPages(0),
78 : m_bPageEnded(false),
79 : m_bRedCircleSeen(false),
80 : m_bGreenStrokeSeen(false),
81 : m_bDashedLineSeen(false),
82 1 : m_bImageSeen(false)
83 1 : {}
84 :
85 2 : virtual ~TestSink() {}
86 :
87 1 : void check()
88 : {
89 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Width", 79400, m_aPageSize.Width, 0.00000001);
90 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Height", 59500, m_aPageSize.Height, 0.0000001 );
91 1 : CPPUNIT_ASSERT_MESSAGE( "endPage() called", m_bPageEnded );
92 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "Num pages equal one", (sal_Int32) 1, m_nNumPages );
93 2 : CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box",
94 : rtl::math::approxEqual(m_aHyperlinkBounds.X1,34.7 ) &&
95 : rtl::math::approxEqual(m_aHyperlinkBounds.Y1,386.0) &&
96 : rtl::math::approxEqual(m_aHyperlinkBounds.X2,166.7) &&
97 1 : rtl::math::approxEqual(m_aHyperlinkBounds.Y2,406.2) );
98 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "Correct hyperlink URI", OUString("http://download.openoffice.org/"), m_aURI );
99 :
100 : const char* sText = " \n \nThis is a testtext\nNew paragraph,\nnew line\n"
101 1 : "Hyperlink, this is\n?\nThis is more text\noutline mode\n?\nNew paragraph\n";
102 1 : OString aTmp;
103 : m_aTextOut.makeStringAndClear().convertToString( &aTmp,
104 : RTL_TEXTENCODING_ASCII_US,
105 1 : OUSTRING_TO_OSTRING_CVTFLAGS );
106 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "Imported text is \"This is a testtext New paragraph, new line"
107 : " Hyperlink, this is * This is more text outline mode * New paragraph\"",
108 1 : aTmp, OString(sText) );
109 :
110 1 : CPPUNIT_ASSERT_MESSAGE( "red circle seen in input", m_bRedCircleSeen );
111 1 : CPPUNIT_ASSERT_MESSAGE( "green stroke seen in input", m_bGreenStrokeSeen );
112 1 : CPPUNIT_ASSERT_MESSAGE( "dashed line seen in input", m_bDashedLineSeen );
113 1 : CPPUNIT_ASSERT_MESSAGE( "image seen in input", m_bImageSeen );
114 1 : }
115 :
116 : private:
117 52 : GraphicsContext& getCurrentContext() { return m_aGCStack.back(); }
118 :
119 : // ContentSink interface implementation
120 1 : virtual void setPageNum( sal_Int32 nNumPages ) SAL_OVERRIDE
121 : {
122 1 : m_nNumPages = nNumPages;
123 1 : }
124 :
125 1 : virtual void startPage( const geometry::RealSize2D& rSize ) SAL_OVERRIDE
126 : {
127 1 : m_aPageSize = rSize;
128 1 : }
129 :
130 1 : virtual void endPage() SAL_OVERRIDE
131 : {
132 1 : m_bPageEnded = true;
133 1 : }
134 :
135 1 : virtual void hyperLink( const geometry::RealRectangle2D& rBounds,
136 : const OUString& rURI ) SAL_OVERRIDE
137 : {
138 1 : m_aHyperlinkBounds = rBounds;
139 1 : m_aURI = rURI;
140 1 : }
141 :
142 16 : virtual void pushState() SAL_OVERRIDE
143 : {
144 16 : GraphicsContextStack::value_type const a(m_aGCStack.back());
145 16 : m_aGCStack.push_back(a);
146 16 : }
147 :
148 16 : virtual void popState() SAL_OVERRIDE
149 : {
150 16 : m_aGCStack.pop_back();
151 16 : }
152 :
153 2 : virtual void setTransformation( const geometry::AffineMatrix2D& rMatrix ) SAL_OVERRIDE
154 : {
155 : basegfx::unotools::homMatrixFromAffineMatrix(
156 2 : getCurrentContext().Transformation,
157 2 : rMatrix );
158 2 : }
159 :
160 2 : virtual void setLineDash( const uno::Sequence<double>& dashes,
161 : double start ) SAL_OVERRIDE
162 : {
163 2 : GraphicsContext& rContext( getCurrentContext() );
164 2 : if( dashes.getLength() )
165 1 : comphelper::sequenceToContainer(rContext.DashArray,dashes);
166 2 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "line dashing start offset", 0.0, start, 0.000000001 );
167 2 : }
168 :
169 1 : virtual void setFlatness( double nFlatness ) SAL_OVERRIDE
170 : {
171 1 : getCurrentContext().Flatness = nFlatness;
172 1 : }
173 :
174 3 : virtual void setLineJoin(sal_Int8 nJoin) SAL_OVERRIDE
175 : {
176 3 : getCurrentContext().LineJoin = nJoin;
177 3 : }
178 :
179 3 : virtual void setLineCap(sal_Int8 nCap) SAL_OVERRIDE
180 : {
181 3 : getCurrentContext().LineCap = nCap;
182 3 : }
183 :
184 1 : virtual void setMiterLimit(double nVal) SAL_OVERRIDE
185 : {
186 1 : getCurrentContext().MiterLimit = nVal;
187 1 : }
188 :
189 4 : virtual void setLineWidth(double nVal) SAL_OVERRIDE
190 : {
191 4 : getCurrentContext().LineWidth = nVal;
192 4 : }
193 :
194 14 : virtual void setFillColor( const rendering::ARGBColor& rColor ) SAL_OVERRIDE
195 : {
196 14 : getCurrentContext().FillColor = rColor;
197 14 : }
198 :
199 4 : virtual void setStrokeColor( const rendering::ARGBColor& rColor ) SAL_OVERRIDE
200 : {
201 4 : getCurrentContext().LineColor = rColor;
202 4 : }
203 :
204 0 : virtual void setBlendMode(sal_Int8 nMode) SAL_OVERRIDE
205 : {
206 0 : getCurrentContext().BlendMode = nMode;
207 0 : }
208 :
209 11 : virtual void setFont( const FontAttributes& rFont ) SAL_OVERRIDE
210 : {
211 11 : FontToIdMap::const_iterator it = m_aFontToId.find( rFont );
212 11 : if( it != m_aFontToId.end() )
213 7 : getCurrentContext().FontId = it->second;
214 : else
215 : {
216 4 : m_aFontToId[ rFont ] = m_nNextFontId;
217 4 : m_aIdToFont[ m_nNextFontId ] = rFont;
218 4 : getCurrentContext().FontId = m_nNextFontId;
219 4 : m_nNextFontId++;
220 : }
221 11 : }
222 :
223 2 : virtual void strokePath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) SAL_OVERRIDE
224 : {
225 2 : GraphicsContext& rContext( getCurrentContext() );
226 2 : basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
227 2 : aPath.transform( rContext.Transformation );
228 :
229 2 : if( rContext.DashArray.empty() )
230 : {
231 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Alpha, 0.00000001);
232 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Blue, 0.00000001);
233 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Green, 0.00000001);
234 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Red, 0.00000001);
235 :
236 2 : CPPUNIT_ASSERT_MESSAGE( "Line width is 0",
237 1 : rtl::math::approxEqual(rContext.LineWidth, 28.3) );
238 :
239 1 : const char* sExportString = "m53570 7650-35430 24100";
240 2 : CPPUNIT_ASSERT_MESSAGE( "Stroke is m535.7 518.5-354.3-241",
241 1 : basegfx::tools::exportToSvgD( aPath, true, true, false ).equalsAscii(sExportString) );
242 :
243 1 : m_bGreenStrokeSeen = true;
244 : }
245 : else
246 : {
247 2 : CPPUNIT_ASSERT_MESSAGE( "Dash array consists of four entries",
248 : rContext.DashArray.size() == 4 &&
249 : rtl::math::approxEqual(rContext.DashArray[0],14.3764) &&
250 : rContext.DashArray[0] == rContext.DashArray[1] &&
251 : rContext.DashArray[1] == rContext.DashArray[2] &&
252 1 : rContext.DashArray[2] == rContext.DashArray[3] );
253 :
254 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001);
255 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001);
256 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001);
257 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001);
258 :
259 2 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line width is 0",
260 1 : 0, rContext.LineWidth, 0.0000001 );
261 :
262 1 : const char* sExportString = "m49890 5670.00000000001-35430 24090";
263 2 : CPPUNIT_ASSERT_MESSAGE( "Stroke is m49890 5670.00000000001-35430 24090",
264 1 : basegfx::tools::exportToSvgD( aPath, true, true, false ).equalsAscii(sExportString) );
265 :
266 1 : m_bDashedLineSeen = true;
267 : }
268 4 : CPPUNIT_ASSERT_MESSAGE( "Blend mode is normal",
269 2 : rContext.BlendMode == rendering::BlendMode::NORMAL );
270 4 : CPPUNIT_ASSERT_MESSAGE( "Join type is round",
271 2 : rContext.LineJoin == rendering::PathJoinType::ROUND );
272 4 : CPPUNIT_ASSERT_MESSAGE( "Cap type is butt",
273 2 : rContext.LineCap == rendering::PathCapType::BUTT );
274 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line miter limit is 10",
275 2 : 10, rContext.MiterLimit, 0.0000001 );
276 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0",
277 2 : 1, rContext.Flatness, 0.00000001 );
278 4 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0",
279 4 : (sal_Int32) 0, rContext.FontId );
280 2 : }
281 :
282 0 : virtual void fillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) SAL_OVERRIDE
283 : {
284 0 : GraphicsContext& rContext( getCurrentContext() );
285 0 : basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
286 0 : aPath.transform( rContext.Transformation );
287 :
288 0 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001);
289 0 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001);
290 0 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001);
291 0 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001);
292 :
293 0 : CPPUNIT_ASSERT_MESSAGE( "Blend mode is normal",
294 0 : rContext.BlendMode == rendering::BlendMode::NORMAL );
295 0 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 10",
296 0 : 10, rContext.Flatness, 0.00000001 );
297 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0",
298 0 : (sal_Int32) 0, rContext.FontId );
299 0 : }
300 :
301 1 : virtual void eoFillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) SAL_OVERRIDE
302 : {
303 1 : GraphicsContext& rContext( getCurrentContext() );
304 1 : basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
305 1 : aPath.transform( rContext.Transformation );
306 :
307 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001);
308 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001);
309 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001);
310 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001);
311 :
312 2 : CPPUNIT_ASSERT_MESSAGE( "Blend mode is normal",
313 1 : rContext.BlendMode == rendering::BlendMode::NORMAL );
314 2 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0",
315 1 : 1, rContext.Flatness, 0.00000001 );
316 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0",
317 1 : (sal_Int32) 0, rContext.FontId );
318 :
319 : const char* sExportString = "m12050 49610c-4310 0-7800-3490-7800-7800 0-4300 "
320 1 : "3490-7790 7800-7790 4300 0 7790 3490 7790 7790 0 4310-3490 7800-7790 7800z";
321 2 : CPPUNIT_ASSERT_MESSAGE( "Stroke is a 4-bezier circle",
322 1 : basegfx::tools::exportToSvgD( aPath, true, true, false ).equalsAscii(sExportString) );
323 :
324 1 : m_bRedCircleSeen = true;
325 1 : }
326 :
327 1 : virtual void intersectClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath) SAL_OVERRIDE
328 : {
329 1 : basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
330 2 : basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip;
331 :
332 1 : if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false)
333 0 : aNewClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false );
334 :
335 2 : getCurrentContext().Clip = aNewClip;
336 1 : }
337 :
338 1 : virtual void intersectEoClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath) SAL_OVERRIDE
339 : {
340 1 : basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
341 2 : basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip;
342 :
343 1 : if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false)
344 1 : aNewClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false );
345 :
346 2 : getCurrentContext().Clip = aNewClip;
347 1 : }
348 :
349 104 : virtual void drawGlyphs( const OUString& rGlyphs,
350 : const geometry::RealRectangle2D& /*rRect*/,
351 : const geometry::Matrix2D& /*rFontMatrix*/,
352 : double /*fontSize*/) SAL_OVERRIDE
353 : {
354 104 : m_aTextOut.append(rGlyphs);
355 104 : }
356 :
357 11 : virtual void endText() SAL_OVERRIDE
358 : {
359 11 : m_aTextOut.append( "\n" );
360 11 : }
361 :
362 0 : virtual void drawMask(const uno::Sequence<beans::PropertyValue>& xBitmap,
363 : bool /*bInvert*/ ) SAL_OVERRIDE
364 : {
365 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask received two properties",
366 0 : (sal_Int32) 3, xBitmap.getLength() );
367 0 : CPPUNIT_ASSERT_MESSAGE( "drawMask got URL param",
368 0 : xBitmap[0].Name == "URL" );
369 0 : CPPUNIT_ASSERT_MESSAGE( "drawMask got InputStream param",
370 0 : xBitmap[1].Name == "InputStream" );
371 0 : }
372 :
373 1 : virtual void drawImage(const uno::Sequence<beans::PropertyValue>& xBitmap ) SAL_OVERRIDE
374 : {
375 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage received two properties",
376 1 : (sal_Int32) 3, xBitmap.getLength() );
377 2 : CPPUNIT_ASSERT_MESSAGE( "drawImage got URL param",
378 1 : xBitmap[0].Name == "URL" );
379 2 : CPPUNIT_ASSERT_MESSAGE( "drawImage got InputStream param",
380 1 : xBitmap[1].Name == "InputStream" );
381 1 : m_bImageSeen = true;
382 1 : }
383 :
384 0 : virtual void drawColorMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap,
385 : const uno::Sequence<uno::Any>& /*xMaskColors*/ ) SAL_OVERRIDE
386 : {
387 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage received two properties",
388 0 : (sal_Int32) 3, xBitmap.getLength() );
389 0 : CPPUNIT_ASSERT_MESSAGE( "drawColorMaskedImage got URL param",
390 0 : xBitmap[0].Name == "URL" );
391 0 : CPPUNIT_ASSERT_MESSAGE( "drawColorMaskedImage got InputStream param",
392 0 : xBitmap[1].Name == "InputStream" );
393 0 : }
394 :
395 0 : virtual void drawMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap,
396 : const uno::Sequence<beans::PropertyValue>& xMask,
397 : bool /*bInvertMask*/) SAL_OVERRIDE
398 : {
399 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #1",
400 0 : (sal_Int32) 3, xBitmap.getLength() );
401 0 : CPPUNIT_ASSERT_MESSAGE( "drawMaskedImage got URL param #1",
402 0 : xBitmap[0].Name == "URL" );
403 0 : CPPUNIT_ASSERT_MESSAGE( "drawMaskedImage got InputStream param #1",
404 0 : xBitmap[1].Name == "InputStream" );
405 :
406 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #2",
407 0 : (sal_Int32) 3, xMask.getLength() );
408 0 : CPPUNIT_ASSERT_MESSAGE( "drawMaskedImage got URL param #2",
409 0 : xMask[0].Name == "URL" );
410 0 : CPPUNIT_ASSERT_MESSAGE( "drawMaskedImage got InputStream param #2",
411 0 : xMask[1].Name == "InputStream" );
412 0 : }
413 :
414 0 : virtual void drawAlphaMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap,
415 : const uno::Sequence<beans::PropertyValue>& xMask) SAL_OVERRIDE
416 : {
417 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #1",
418 0 : (sal_Int32) 3, xBitmap.getLength() );
419 0 : CPPUNIT_ASSERT_MESSAGE( "drawAlphaMaskedImage got URL param #1",
420 0 : xBitmap[0].Name == "URL" );
421 0 : CPPUNIT_ASSERT_MESSAGE( "drawAlphaMaskedImage got InputStream param #1",
422 0 : xBitmap[1].Name == "InputStream" );
423 :
424 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #2",
425 0 : (sal_Int32) 3, xMask.getLength() );
426 0 : CPPUNIT_ASSERT_MESSAGE( "drawAlphaMaskedImage got URL param #2",
427 0 : xMask[0].Name == "URL" );
428 0 : CPPUNIT_ASSERT_MESSAGE( "drawAlphaMaskedImage got InputStream param #2",
429 0 : xMask[1].Name == "InputStream" );
430 0 : }
431 :
432 0 : virtual void setTextRenderMode( sal_Int32 ) SAL_OVERRIDE
433 : {
434 0 : }
435 :
436 : typedef std::unordered_map<sal_Int32,FontAttributes> IdToFontMap;
437 : typedef std::unordered_map<FontAttributes,sal_Int32,FontAttrHash> FontToIdMap;
438 :
439 : typedef std::vector<GraphicsContext> GraphicsContextStack;
440 :
441 : sal_Int32 m_nNextFontId;
442 : IdToFontMap m_aIdToFont;
443 : FontToIdMap m_aFontToId;
444 :
445 : GraphicsContextStack m_aGCStack;
446 : geometry::RealSize2D m_aPageSize;
447 : geometry::RealRectangle2D m_aHyperlinkBounds;
448 : OUString m_aURI;
449 : OUStringBuffer m_aTextOut;
450 : sal_Int32 m_nNumPages;
451 : bool m_bPageEnded;
452 : bool m_bRedCircleSeen;
453 : bool m_bGreenStrokeSeen;
454 : bool m_bDashedLineSeen;
455 : bool m_bImageSeen;
456 : };
457 :
458 9 : class PDFITest : public test::BootstrapFixture
459 : {
460 : public:
461 1 : void testXPDFParser()
462 : {
463 1 : boost::shared_ptr<TestSink> pSink( new TestSink() );
464 2 : CPPUNIT_ASSERT(
465 : pdfi::xpdf_ImportFromFile(
466 : getURLFromSrc("/sdext/source/pdfimport/test/testinput.pdf"),
467 : pSink,
468 : uno::Reference< task::XInteractionHandler >(),
469 : OUString(),
470 1 : getComponentContext() ) );
471 1 : pSink->check();
472 1 : }
473 :
474 1 : void testOdfDrawExport()
475 : {
476 1 : pdfi::PDFIRawAdaptor aAdaptor( OUString(), getComponentContext() );
477 1 : aAdaptor.setTreeVisitorFactory( createDrawTreeVisitorFactory() );
478 :
479 2 : OUString tempFileURL;
480 1 : CPPUNIT_ASSERT( osl::File::createTempFile( NULL, NULL, &tempFileURL ) == osl::File::E_None );
481 1 : osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists
482 2 : CPPUNIT_ASSERT_MESSAGE("Exporting to ODF",
483 : aAdaptor.odfConvert( getURLFromSrc("/sdext/source/pdfimport/test/testinput.pdf"),
484 : new OutputWrap(tempFileURL),
485 1 : NULL ));
486 2 : osl::File::remove( tempFileURL );
487 1 : }
488 :
489 1 : void testOdfWriterExport()
490 : {
491 1 : pdfi::PDFIRawAdaptor aAdaptor( OUString(), getComponentContext() );
492 1 : aAdaptor.setTreeVisitorFactory( createWriterTreeVisitorFactory() );
493 :
494 2 : OUString tempFileURL;
495 1 : CPPUNIT_ASSERT( osl::File::createTempFile( NULL, NULL, &tempFileURL ) == osl::File::E_None );
496 1 : osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists
497 2 : CPPUNIT_ASSERT_MESSAGE("Exporting to ODF",
498 : aAdaptor.odfConvert( getURLFromSrc("/sdext/source/pdfimport/test/testinput.pdf"),
499 : new OutputWrap(tempFileURL),
500 1 : NULL ));
501 2 : osl::File::remove( tempFileURL );
502 1 : }
503 :
504 2 : CPPUNIT_TEST_SUITE(PDFITest);
505 1 : CPPUNIT_TEST(testXPDFParser);
506 1 : CPPUNIT_TEST(testOdfWriterExport);
507 1 : CPPUNIT_TEST(testOdfDrawExport);
508 5 : CPPUNIT_TEST_SUITE_END();
509 : };
510 :
511 : }
512 :
513 1 : CPPUNIT_TEST_SUITE_REGISTRATION(PDFITest);
514 :
515 4 : CPPUNIT_PLUGIN_IMPLEMENT();
516 :
517 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|