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 :
10 : #include <config_folders.h>
11 :
12 : #include <stdio.h>
13 : #include <string.h>
14 : #include <stdlib.h>
15 :
16 : #include <boost/shared_ptr.hpp>
17 : #include <boost/weak_ptr.hpp>
18 :
19 : #define LOK_USE_UNSTABLE_API
20 : #include <LibreOfficeKit/LibreOfficeKit.h>
21 :
22 : #include <tools/errinf.hxx>
23 : #include <osl/file.hxx>
24 : #include <osl/process.h>
25 : #include <rtl/strbuf.hxx>
26 : #include <rtl/bootstrap.hxx>
27 : #include <cppuhelper/bootstrap.hxx>
28 : #include <comphelper/processfactory.hxx>
29 :
30 : #include <com/sun/star/beans/XPropertySet.hpp>
31 : #include <com/sun/star/frame/XModel.hpp>
32 : #include <com/sun/star/frame/Desktop.hpp>
33 : #include <com/sun/star/frame/XStorable.hpp>
34 : #include <com/sun/star/lang/Locale.hpp>
35 : #include <com/sun/star/lang/XComponent.hpp>
36 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 : #include <com/sun/star/ucb/XContentProvider.hpp>
38 : #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
39 :
40 : #include <vcl/svapp.hxx>
41 : #include <tools/resmgr.hxx>
42 : #include <vcl/graphicfilter.hxx>
43 : #include <vcl/sysdata.hxx>
44 : #include <vcl/virdev.hxx>
45 : #include <vcl/ITiledRenderable.hxx>
46 : #include <unotools/syslocaleoptions.hxx>
47 : #include <unotools/mediadescriptor.hxx>
48 : #include <osl/module.hxx>
49 :
50 : #include <salinst.hxx>
51 :
52 : // Tiled Rendering is Linux only for now.
53 : #if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS)
54 : // And let's also grab the SvpSalInstance and SvpSalVirtualDevice
55 : #include <headless/svpinst.hxx>
56 : #include <headless/svpvd.hxx>
57 :
58 : #include <basebmp/bitmapdevice.hxx>
59 : #endif
60 :
61 : using namespace css;
62 : using namespace vcl;
63 : using namespace utl;
64 :
65 : using namespace boost;
66 :
67 : struct LibLODocument_Impl;
68 : struct LibLibreOffice_Impl;
69 :
70 : static LibLibreOffice_Impl *gImpl = NULL;
71 160 : static weak_ptr< LibreOfficeKitClass > gOfficeClass;
72 160 : static weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass;
73 :
74 : typedef struct
75 : {
76 : const char *extn;
77 : const char *filterName;
78 : } ExtensionMap;
79 :
80 : // We need a shared_array for passing into the BitmapDevice (via
81 : // VirtualDevice.SetOutputSizePixelScaleOffsetAndBuffer which goes via the
82 : // SvpVirtualDevice, ending up in the basebmp BitmapDevice. However as we're
83 : // given the array externally we can't delete it, and hence need to override
84 : // shared_array's default of deleting its pointer.
85 : template<typename T>
86 : struct NoDelete
87 : {
88 0 : void operator()(T* /* p */) {}
89 : };
90 :
91 : static const ExtensionMap aWriterExtensionMap[] =
92 : {
93 : { "doc", "MS Word 97" },
94 : { "docx", "MS Word 2007 XML" },
95 : { "fodt", "OpenDocument Text Flat XML" },
96 : { "html", "HTML (StarWriter)" },
97 : { "odt", "writer8" },
98 : { "ott", "writer8_template" },
99 : { "pdf", "writer_pdf_Export" },
100 : { "txt", "Text" },
101 : { "xhtml", "XHTML Writer File" },
102 : { NULL, NULL }
103 : };
104 :
105 : static const ExtensionMap aCalcExtensionMap[] =
106 : {
107 : { "csv", "Text - txt - csv (StarCalc)" },
108 : { "fods", "OpenDocument Spreadsheet Flat XML" },
109 : { "html", "HTML (StarCalc)" },
110 : { "ods", "calc8" },
111 : { "ots", "calc8_template" },
112 : { "pdf", "calc_pdf_Export" },
113 : { "xhtml", "XHTML Calc File" },
114 : { "xls", "MS Excel 97" },
115 : { "xlsx", "Calc MS Excel 2007 XML" },
116 : { NULL, NULL }
117 : };
118 :
119 : static const ExtensionMap aImpressExtensionMap[] =
120 : {
121 : { "fodp", "OpenDocument Presentation Flat XML" },
122 : { "html", "impress_html_Export" },
123 : { "odg", "impress8_draw" },
124 : { "odp", "impress8" },
125 : { "otp", "impress8_template" },
126 : { "pdf", "impress_pdf_Export" },
127 : { "potm", "Impress MS PowerPoint 2007 XML Template" },
128 : { "pot", "MS PowerPoint 97 Vorlage" },
129 : { "pptx", "Impress MS PowerPoint 2007 XML" },
130 : { "pps", "MS PowerPoint 97 Autoplay" },
131 : { "ppt", "MS PowerPoint 97" },
132 : { "svg", "impress_svg_Export" },
133 : { "swf", "impress_flash_Export" },
134 : { "xhtml", "XHTML Impress File" },
135 : { NULL, NULL }
136 : };
137 :
138 : static const ExtensionMap aDrawExtensionMap[] =
139 : {
140 : { "odg", "draw8" },
141 : { "fodg", "draw_ODG_FlatXML" },
142 : { "html", "draw_html_Export" },
143 : { "svg", "draw_svg_Export" },
144 : { "swf", "draw_flash_Export" },
145 : { "xhtml", "XHTML Draw File" },
146 : { "vdx", "draw_Visio_Document" },
147 : { "vsd", "draw_Visio_Document" },
148 : { "vsdm", "draw_Visio_Document" },
149 : { "vsdx", "draw_Visio_Document" },
150 : { "pub", "draw_Publisher_Document" },
151 : { "cdr", "draw_CorelDraw_Document" },
152 : { "wpg", "draw_WordPerfect_Graphics" },
153 : { NULL, NULL }
154 : };
155 :
156 0 : static OUString getUString(const char* pString)
157 : {
158 0 : if (pString == NULL)
159 0 : return OUString();
160 :
161 0 : OString sString(pString, strlen(pString));
162 0 : return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
163 : }
164 :
165 : // Try to convert a relative URL to an absolute one
166 0 : static OUString getAbsoluteURL(const char* pURL)
167 : {
168 0 : OUString aURL( getUString( pURL ) );
169 0 : OUString sAbsoluteDocUrl, sWorkingDir, sDocPathUrl;
170 :
171 : // FIXME: this would appear to kill non-file URLs.
172 0 : osl_getProcessWorkingDir(&sWorkingDir.pData);
173 0 : osl::FileBase::getFileURLFromSystemPath( aURL, sDocPathUrl );
174 0 : osl::FileBase::getAbsoluteFileURL(sWorkingDir, sDocPathUrl, sAbsoluteDocUrl);
175 :
176 0 : return sAbsoluteDocUrl;
177 : }
178 :
179 : extern "C"
180 : {
181 :
182 : static void doc_destroy(LibreOfficeKitDocument* pThis);
183 : static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* pUrl, const char* pFormat, const char* pFilterOptions);
184 : static LibreOfficeKitDocumentType doc_getDocumentType(LibreOfficeKitDocument* pThis);
185 : static int doc_getParts(LibreOfficeKitDocument* pThis);
186 : static int doc_getPart(LibreOfficeKitDocument* pThis);
187 : static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart);
188 : static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart);
189 : static void doc_setPartMode(LibreOfficeKitDocument* pThis, LibreOfficeKitPartMode ePartMode);
190 : void doc_paintTile(LibreOfficeKitDocument* pThis,
191 : unsigned char* pBuffer,
192 : const int nCanvasWidth, const int nCanvasHeight,
193 : int* pRowStride,
194 : const int nTilePosX, const int nTilePosY,
195 : const int nTileWidth, const int nTileHeight);
196 : static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
197 : long* pWidth,
198 : long* pHeight);
199 :
200 : struct LibLODocument_Impl : public _LibreOfficeKitDocument
201 : {
202 : uno::Reference<css::lang::XComponent> mxComponent;
203 : shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
204 :
205 0 : LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent) :
206 0 : mxComponent( xComponent )
207 : {
208 0 : if (!(m_pDocumentClass = gDocumentClass.lock()))
209 : {
210 0 : m_pDocumentClass.reset(new LibreOfficeKitDocumentClass);
211 :
212 0 : m_pDocumentClass->nSize = sizeof(LibreOfficeKitDocument);
213 :
214 0 : m_pDocumentClass->destroy = doc_destroy;
215 0 : m_pDocumentClass->saveAs = doc_saveAs;
216 0 : m_pDocumentClass->getDocumentType = doc_getDocumentType;
217 0 : m_pDocumentClass->getParts = doc_getParts;
218 0 : m_pDocumentClass->getPart = doc_getPart;
219 0 : m_pDocumentClass->setPart = doc_setPart;
220 0 : m_pDocumentClass->getPartName = doc_getPartName;
221 0 : m_pDocumentClass->setPartMode = doc_setPartMode;
222 0 : m_pDocumentClass->paintTile = doc_paintTile;
223 0 : m_pDocumentClass->getDocumentSize = doc_getDocumentSize;
224 :
225 0 : gDocumentClass = m_pDocumentClass;
226 : }
227 0 : pClass = m_pDocumentClass.get();
228 0 : }
229 :
230 0 : ~LibLODocument_Impl()
231 0 : {
232 0 : mxComponent->dispose();
233 0 : }
234 : };
235 :
236 0 : static void doc_destroy(LibreOfficeKitDocument *pThis)
237 : {
238 0 : LibLODocument_Impl *pDocument = static_cast<LibLODocument_Impl*>(pThis);
239 0 : delete pDocument;
240 0 : }
241 :
242 : static void lo_destroy (LibreOfficeKit* pThis);
243 : static int lo_initialize (LibreOfficeKit* pThis, const char* pInstallPath);
244 : static LibreOfficeKitDocument* lo_documentLoad (LibreOfficeKit* pThis, const char* pURL);
245 : static char * lo_getError (LibreOfficeKit* pThis);
246 :
247 0 : struct LibLibreOffice_Impl : public _LibreOfficeKit
248 : {
249 : OUString maLastExceptionMsg;
250 : shared_ptr< LibreOfficeKitClass > m_pOfficeClass;
251 :
252 0 : LibLibreOffice_Impl()
253 0 : {
254 0 : if(!(m_pOfficeClass = gOfficeClass.lock())) {
255 0 : m_pOfficeClass.reset(new LibreOfficeKitClass);
256 0 : m_pOfficeClass->nSize = sizeof(LibreOfficeKitClass);
257 :
258 0 : m_pOfficeClass->destroy = lo_destroy;
259 0 : m_pOfficeClass->documentLoad = lo_documentLoad;
260 0 : m_pOfficeClass->getError = lo_getError;
261 :
262 0 : gOfficeClass = m_pOfficeClass;
263 : }
264 :
265 0 : pClass = m_pOfficeClass.get();
266 0 : }
267 : };
268 :
269 : namespace
270 : {
271 :
272 0 : ITiledRenderable* getTiledRenderable(LibreOfficeKitDocument* pThis)
273 : {
274 0 : LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
275 0 : return dynamic_cast<ITiledRenderable*>(pDocument->mxComponent.get());
276 : }
277 :
278 : } // anonymous namespace
279 :
280 : // Wonder global state ...
281 160 : static uno::Reference<css::uno::XComponentContext> xContext;
282 160 : static uno::Reference<css::lang::XMultiServiceFactory> xSFactory;
283 160 : static uno::Reference<css::lang::XMultiComponentFactory> xFactory;
284 :
285 0 : static LibreOfficeKitDocument* lo_documentLoad(LibreOfficeKit* pThis, const char* pURL)
286 : {
287 0 : LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
288 :
289 0 : OUString aURL = getAbsoluteURL(pURL);
290 :
291 0 : SolarMutexGuard aGuard;
292 :
293 0 : uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext);
294 :
295 0 : pLib->maLastExceptionMsg = "";
296 :
297 : try
298 : {
299 0 : uno::Reference<lang::XComponent> xComponent;
300 0 : xComponent = xComponentLoader->loadComponentFromURL(
301 : aURL, OUString("_blank"), 0,
302 0 : uno::Sequence<css::beans::PropertyValue>());
303 :
304 0 : if (xComponent.is())
305 0 : return new LibLODocument_Impl(xComponent);
306 : else
307 0 : pLib->maLastExceptionMsg = "unknown load failure";
308 :
309 : }
310 0 : catch (const uno::Exception& exception)
311 : {
312 0 : pLib->maLastExceptionMsg = exception.Message;
313 : }
314 :
315 0 : return NULL;
316 : }
317 :
318 0 : static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const char* pFormat, const char* pFilterOptions)
319 : {
320 0 : LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
321 :
322 0 : OUString sFormat = getUString(pFormat);
323 0 : OUString aURL = getAbsoluteURL(sUrl);
324 :
325 : try
326 : {
327 : const ExtensionMap* pMap;
328 :
329 0 : switch (doc_getDocumentType(pThis))
330 : {
331 : case LOK_DOCTYPE_SPREADSHEET:
332 0 : pMap = (const ExtensionMap*) aCalcExtensionMap;
333 0 : break;
334 : case LOK_DOCTYPE_PRESENTATION:
335 0 : pMap = (const ExtensionMap*) aImpressExtensionMap;
336 0 : break;
337 : case LOK_DOCTYPE_DRAWING:
338 0 : pMap = (const ExtensionMap*) aDrawExtensionMap;
339 0 : break;
340 : case LOK_DOCTYPE_TEXT:
341 0 : pMap = (const ExtensionMap*) aWriterExtensionMap;
342 0 : break;
343 : case LOK_DOCTYPE_OTHER:
344 : default:
345 0 : return false;
346 : }
347 :
348 0 : if (pFormat == NULL)
349 : {
350 : // sniff from the extension
351 0 : sal_Int32 idx = aURL.lastIndexOf(".");
352 0 : if( idx > 0 )
353 : {
354 0 : sFormat = aURL.copy( idx + 1 );
355 : }
356 : else
357 : {
358 0 : gImpl->maLastExceptionMsg = "input filename without a suffix";
359 0 : return false;
360 : }
361 : }
362 :
363 0 : OUString aFilterName;
364 0 : for (sal_Int32 i = 0; pMap[i].extn; ++i)
365 : {
366 0 : if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[i].extn))
367 : {
368 0 : aFilterName = getUString(pMap[i].filterName);
369 0 : break;
370 : }
371 : }
372 0 : if (aFilterName.isEmpty())
373 : {
374 0 : gImpl->maLastExceptionMsg = "no output filter found for provided suffix";
375 0 : return false;
376 : }
377 :
378 0 : OUString aFilterOptions = getUString(pFilterOptions);
379 :
380 0 : MediaDescriptor aSaveMediaDescriptor;
381 0 : aSaveMediaDescriptor["Overwrite"] <<= sal_True;
382 0 : aSaveMediaDescriptor["FilterName"] <<= aFilterName;
383 0 : aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS()] <<= aFilterOptions;
384 :
385 0 : uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
386 0 : xStorable->storeToURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
387 :
388 0 : return true;
389 : }
390 0 : catch (const uno::Exception& exception)
391 : {
392 0 : gImpl->maLastExceptionMsg = "exception: " + exception.Message;
393 : }
394 0 : return false;
395 : }
396 :
397 0 : static LibreOfficeKitDocumentType doc_getDocumentType (LibreOfficeKitDocument* pThis)
398 : {
399 0 : LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
400 :
401 : try
402 : {
403 0 : uno::Reference<frame::XModel> xDocument(pDocument->mxComponent, uno::UNO_QUERY_THROW);
404 0 : uno::Sequence<beans::PropertyValue> aSequence = xDocument->getArgs();
405 :
406 0 : MediaDescriptor aMediaDescriptor(aSequence);
407 0 : OUString sPropertyName = MediaDescriptor::PROP_DOCUMENTSERVICE();
408 0 : OUString aDocumentService = aMediaDescriptor.getUnpackedValueOrDefault(sPropertyName, OUString());
409 :
410 0 : if (aDocumentService.isEmpty())
411 : {
412 0 : gImpl->maLastExceptionMsg = "unknown document type";
413 0 : return LOK_DOCTYPE_OTHER;
414 : }
415 :
416 0 : if (aDocumentService == "com.sun.star.sheet.SpreadsheetDocument")
417 : {
418 0 : return LOK_DOCTYPE_SPREADSHEET;
419 : }
420 0 : else if (aDocumentService == "com.sun.star.presentation.PresentationDocument")
421 : {
422 0 : return LOK_DOCTYPE_PRESENTATION;
423 : }
424 0 : else if (aDocumentService == "com.sun.star.drawing.DrawingDocument")
425 : {
426 0 : return LOK_DOCTYPE_DRAWING;
427 : }
428 0 : else if (aDocumentService == "com.sun.star.text.TextDocument")
429 : {
430 0 : return LOK_DOCTYPE_TEXT;
431 : }
432 : else
433 : {
434 0 : gImpl->maLastExceptionMsg = "unknown document mapping";
435 0 : }
436 : }
437 0 : catch (const uno::Exception& exception)
438 : {
439 0 : gImpl->maLastExceptionMsg = "exception: " + exception.Message;
440 : }
441 0 : return LOK_DOCTYPE_OTHER;
442 : }
443 :
444 0 : static int doc_getParts (LibreOfficeKitDocument* pThis)
445 : {
446 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
447 0 : if (!pDoc)
448 : {
449 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
450 0 : return 0;
451 : }
452 :
453 0 : return pDoc->getParts();
454 : }
455 :
456 0 : static int doc_getPart (LibreOfficeKitDocument* pThis)
457 : {
458 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
459 0 : if (!pDoc)
460 : {
461 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
462 0 : return 0;
463 : }
464 :
465 0 : return pDoc->getPart();
466 : }
467 :
468 0 : static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart)
469 : {
470 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
471 0 : if (!pDoc)
472 : {
473 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
474 0 : return;
475 : }
476 :
477 0 : SolarMutexGuard aGuard;
478 0 : pDoc->setPart( nPart );
479 : }
480 :
481 0 : static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart)
482 : {
483 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
484 0 : if (!pDoc)
485 : {
486 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
487 0 : return 0;
488 : }
489 :
490 0 : OUString sName = pDoc->getPartName( nPart );
491 0 : OString aString = OUStringToOString(sName, RTL_TEXTENCODING_UTF8);
492 0 : char* pMemory = (char*) malloc(aString.getLength() + 1);
493 0 : strcpy(pMemory, aString.getStr());
494 0 : return pMemory;
495 :
496 : }
497 :
498 0 : static void doc_setPartMode(LibreOfficeKitDocument* pThis,
499 : LibreOfficeKitPartMode ePartMode)
500 : {
501 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
502 0 : if (!pDoc)
503 : {
504 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
505 0 : return;
506 : }
507 :
508 0 : SolarMutexGuard aGuard;
509 :
510 0 : int nCurrentPart = pDoc->getPart();
511 :
512 0 : pDoc->setPartMode(ePartMode);
513 :
514 : // We need to make sure the internal state is updated, just changing the mode
515 : // might not update the relevant shells (i.e. impress will keep rendering the
516 : // previous mode unless we do this).
517 : // TODO: we might want to do this within the relevant components rather than
518 : // here, but that's also dependent on how we implement embedded object
519 : // rendering I guess?
520 : // TODO: we could be clever and e.g. set to 0 when we change to/from
521 : // embedded object mode, and not when changing between slide/notes/combined
522 : // modes?
523 0 : if ( nCurrentPart < pDoc->getParts() )
524 : {
525 0 : pDoc->setPart( nCurrentPart );
526 : }
527 : else
528 : {
529 0 : pDoc->setPart( 0 );
530 0 : }
531 : }
532 :
533 0 : void doc_paintTile (LibreOfficeKitDocument* pThis,
534 : unsigned char* pBuffer,
535 : const int nCanvasWidth, const int nCanvasHeight,
536 : int* pRowStride,
537 : const int nTilePosX, const int nTilePosY,
538 : const int nTileWidth, const int nTileHeight)
539 : {
540 : SAL_INFO( "lok.tiledrendering", "paintTile: painting [" << nTileWidth << "x" << nTileHeight <<
541 : "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<
542 : nCanvasWidth << "x" << nCanvasHeight << "]px" );
543 :
544 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
545 0 : if (!pDoc)
546 : {
547 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
548 0 : return;
549 : }
550 :
551 0 : SolarMutexGuard aGuard;
552 :
553 : #if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS)
554 0 : ImplSVData* pSVData = ImplGetSVData();
555 0 : SvpSalInstance* pSalInstance = static_cast< SvpSalInstance* >(pSVData->mpDefInst);
556 0 : pSalInstance->setBitCountFormatMapping( 32, ::basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA );
557 :
558 0 : VirtualDevice aDevice(0, (sal_uInt16)32);
559 0 : boost::shared_array< sal_uInt8 > aBuffer( pBuffer, NoDelete< sal_uInt8 >() );
560 : aDevice.SetOutputSizePixelScaleOffsetAndBuffer(
561 : Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(),
562 0 : aBuffer, true );
563 :
564 : pDoc->paintTile(aDevice, nCanvasWidth, nCanvasHeight,
565 0 : nTilePosX, nTilePosY, nTileWidth, nTileHeight);
566 :
567 0 : SvpSalVirtualDevice* pSalDev = static_cast< SvpSalVirtualDevice* >(aDevice.getSalVirtualDevice());
568 0 : basebmp::BitmapDeviceSharedPtr pBmpDev = pSalDev->getBitmapDevice();
569 :
570 0 : *pRowStride = pBmpDev->getScanlineStride();
571 : #else
572 : (void) pBuffer;
573 : (void) nCanvasWidth;
574 : (void) nCanvasHeight;
575 : (void) pRowStride;
576 : (void) nTilePosX;
577 : (void) nTilePosY;
578 : (void) nTileWidth;
579 : (void) nTileHeight;
580 : #endif
581 : }
582 :
583 0 : static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
584 : long* pWidth,
585 : long* pHeight)
586 : {
587 0 : ITiledRenderable* pDoc = getTiledRenderable(pThis);
588 0 : if (pDoc)
589 : {
590 0 : Size aDocumentSize = pDoc->getDocumentSize();
591 0 : *pWidth = aDocumentSize.Width();
592 0 : *pHeight = aDocumentSize.Height();
593 : }
594 : else
595 : {
596 0 : gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
597 : }
598 0 : }
599 :
600 0 : static char* lo_getError (LibreOfficeKit *pThis)
601 : {
602 0 : LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
603 0 : OString aString = OUStringToOString(pLib->maLastExceptionMsg, RTL_TEXTENCODING_UTF8);
604 0 : char* pMemory = (char*) malloc(aString.getLength() + 1);
605 0 : strcpy(pMemory, aString.getStr());
606 0 : return pMemory;
607 : }
608 :
609 0 : static void force_c_locale(void)
610 : {
611 : // force locale (and resource files loaded) to en-US
612 0 : OUString aLangISO("en-US");
613 0 : LanguageTag aLocale(aLangISO);
614 0 : ResMgr::SetDefaultLocale(aLocale);
615 0 : SvtSysLocaleOptions aLocalOptions;
616 0 : aLocalOptions.SetLocaleConfigString(aLangISO);
617 0 : aLocalOptions.SetUILocaleConfigString(aLangISO);
618 0 : }
619 :
620 0 : static void aBasicErrorFunc(const OUString& rError, const OUString& rAction)
621 : {
622 0 : OStringBuffer aBuffer("Unexpected dialog: ");
623 0 : aBuffer.append(OUStringToOString(rAction, RTL_TEXTENCODING_ASCII_US));
624 0 : aBuffer.append(" Error: ");
625 0 : aBuffer.append(OUStringToOString(rError, RTL_TEXTENCODING_ASCII_US));
626 :
627 0 : fprintf(stderr, "Unexpected basic error dialog '%s'\n", aBuffer.getStr());
628 0 : }
629 :
630 0 : static void initialize_uno(const OUString &aAppProgramURL)
631 : {
632 0 : rtl::Bootstrap::setIniFilename(aAppProgramURL + "/" SAL_CONFIGFILE("soffice"));
633 :
634 0 : xContext = cppu::defaultBootstrap_InitialComponentContext();
635 0 : fprintf(stderr, "Uno initialized %d\n", xContext.is());
636 0 : xFactory = xContext->getServiceManager();
637 0 : xSFactory = uno::Reference<lang::XMultiServiceFactory>(xFactory, uno::UNO_QUERY_THROW);
638 0 : comphelper::setProcessServiceFactory(xSFactory);
639 :
640 : // set UserInstallation to user profile dir in test/user-template
641 : // rtl::Bootstrap aDefaultVars;
642 : // aDefaultVars.set(OUString("UserInstallation"), aAppProgramURL + "../registry" );
643 : // configmgr setup ?
644 0 : }
645 :
646 0 : static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath)
647 : {
648 : (void) pThis;
649 :
650 : static bool bInitialized = false;
651 0 : if (bInitialized)
652 0 : return 1;
653 :
654 0 : if (!pAppPath)
655 0 : return 0;
656 :
657 0 : OUString aAppPath;
658 0 : if (pAppPath)
659 : {
660 0 : aAppPath = OUString(pAppPath, strlen(pAppPath), RTL_TEXTENCODING_UTF8);
661 : }
662 : else
663 : {
664 : ::osl::Module::getUrlFromAddress( reinterpret_cast< oslGenericFunction >(lo_initialize),
665 0 : aAppPath);
666 : }
667 :
668 0 : OUString aAppURL;
669 0 : if (osl::FileBase::getFileURLFromSystemPath(aAppPath, aAppURL) != osl::FileBase::E_None)
670 0 : return 0;
671 :
672 : try
673 : {
674 : // If we've set up the command args elsewhere then we cannot do it
675 : // again (as an assert will fire), this will be the case e.g.
676 : // for unit tests (and possibly if UNO is being used in addition
677 : // to LOK in an external program).
678 0 : if (!osl_areCommandArgsSet())
679 : {
680 0 : osl_setCommandArgs(0, NULL);
681 : }
682 0 : initialize_uno(aAppURL);
683 0 : force_c_locale();
684 :
685 : // Force headless
686 0 : rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
687 0 : InitVCL();
688 0 : Application::EnableHeadlessMode(true);
689 :
690 0 : ErrorHandler::RegisterDisplay(aBasicErrorFunc);
691 :
692 0 : fprintf(stderr, "initialized\n");
693 0 : bInitialized = true;
694 : }
695 0 : catch (css::uno::Exception& exception)
696 : {
697 : fprintf(stderr, "bootstrapping exception '%s'\n",
698 0 : OUStringToOString(exception.Message, RTL_TEXTENCODING_UTF8).getStr());
699 : }
700 0 : return bInitialized;
701 : }
702 :
703 0 : SAL_DLLPUBLIC_EXPORT LibreOfficeKit *libreofficekit_hook(const char* install_path)
704 : {
705 0 : if (!gImpl)
706 : {
707 0 : fprintf(stderr, "create libreoffice object\n");
708 0 : gImpl = new LibLibreOffice_Impl();
709 0 : if (!lo_initialize(gImpl, install_path))
710 : {
711 0 : lo_destroy(gImpl);
712 : }
713 : }
714 0 : return static_cast<LibreOfficeKit*>(gImpl);
715 : }
716 :
717 0 : static void lo_destroy(LibreOfficeKit *pThis)
718 : {
719 0 : LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
720 0 : delete pLib;
721 0 : gImpl = NULL;
722 0 : }
723 :
724 480 : }
725 :
726 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|