44 PDFIProcessor::PDFIProcessor(
const uno::Reference< task::XStatusIndicator >& xStat ,
45 css::uno::Reference< css::uno::XComponentContext >
const & xContext) :
51 m_pCurElement(nullptr),
56 m_xStatusIndicator( xStat )
80 GraphicsContextStack::value_type
const a(
m_aGCStack.back());
121 SAL_WARN(
"sdext.pdfimport",
"PDFIProcessor::setMiterLimit(): not supported by ODF");
158 FontToIdMap::const_iterator it =
m_aFontToId.find( aChangedFont );
170 void PDFIProcessor::setTextRenderMode( sal_Int32 i_nMode )
174 IdToFontMap::iterator it = m_aIdToFont.find( rGC.
FontId );
175 if( it != m_aIdToFont.end() )
176 setFont( it->second );
190 void PDFIProcessor::processGlyphLine()
192 if (m_GlyphsList.empty())
195 double spaceDetectBoundary = 0.0;
200 OUString& glyph =
i.getGlyph();
203 if (!glyph.isEmpty())
206 if ((ch == 0x20) || (ch == 0xa0))
208 double spaceWidth =
i.getWidth();
209 spaceDetectBoundary = spaceWidth * 0.5;
215 if (spaceDetectBoundary == 0.0)
217 double avgGlyphWidth = 0.0;
219 avgGlyphWidth +=
i.getWidth();
220 avgGlyphWidth /= m_GlyphsList.size();
221 spaceDetectBoundary = avgGlyphWidth * 0.2;
225 m_GlyphsList[0].getCurElement(),
226 getGCId(m_GlyphsList[0].getGC()));
227 frame->
ZOrder = m_nNextZOrder++;
229 frame->
FontSize = getFont(m_GlyphsList[0].getGC().FontId).size;
232 for (
size_t i = 0;
i < m_GlyphsList.size();
i++)
234 bool prependSpace =
false;
237 getGCId(m_GlyphsList[
i].getGC()),
238 m_GlyphsList[
i].getGC().FontId);
241 text->
x = m_GlyphsList[0].getGC().Transformation.get(0, 2);
242 text->
y = m_GlyphsList[0].getGC().Transformation.get(1, 2);
250 double spaceSize = m_GlyphsList[
i].getPrevSpaceWidth();
251 prependSpace = spaceSize > spaceDetectBoundary;
254 text->
Text.append(
" ");
255 text->
Text.append(m_GlyphsList[
i].getGlyph());
258 m_GlyphsList.clear();
261 void PDFIProcessor::drawGlyphs(
const OUString& rGlyphs,
262 const geometry::RealRectangle2D& rRect,
263 const geometry::Matrix2D& rFontMatrix,
269 rFontMatrix.m00, rFontMatrix.m01, 0.0,
270 rFontMatrix.m10, rFontMatrix.m11, 0.0);
271 fontMatrix.
scale(fontSize, fontSize);
275 totalTextMatrix1.
translate(rRect.X1, rRect.Y1);
276 totalTextMatrix2.
translate(rRect.X2, rRect.Y2);
279 corrMatrix.
scale(1.0, -1.0);
281 totalTextMatrix1 = totalTextMatrix1 * corrMatrix;
282 totalTextMatrix2 = totalTextMatrix2 * corrMatrix;
293 offsetMatrix1 *= invPrevMatrix;
294 offsetMatrix2 *= invMatrix;
296 double charWidth = offsetMatrix2.
get(0, 2);
297 double prevSpaceWidth = offsetMatrix1.
get(0, 2) - prevCharWidth;
299 if ((totalTextMatrix1.
get(0, 0) != prevTextMatrix.get(0, 0)) ||
300 (totalTextMatrix1.
get(0, 1) != prevTextMatrix.get(0, 1)) ||
301 (totalTextMatrix1.
get(1, 0) != prevTextMatrix.get(1, 0)) ||
302 (totalTextMatrix1.
get(1, 1) != prevTextMatrix.get(1, 1)) ||
303 (offsetMatrix1.
get(0, 2) < 0.0) ||
304 (prevSpaceWidth > prevCharWidth * 1.3) ||
312 m_GlyphsList.push_back(aGlyph);
314 prevCharWidth = charWidth;
315 prevTextMatrix = totalTextMatrix1;
318 void PDFIProcessor::endText()
322 m_pCurElement = pText->
Parent;
325 void PDFIProcessor::setupImage(
ImageId nImage)
330 double fRotate, fShearX;
333 const sal_Int32 nGCId = getGCId(rGC);
334 FrameElement* pFrame = ElementFactory::createFrameElement( m_pCurElement, nGCId );
335 ImageElement* pImageElement = ElementFactory::createImageElement( pFrame, nGCId, nImage );
336 pFrame->
x = pImageElement->
x = aTranslation.
getX();
337 pFrame->
y = pImageElement->
y = aTranslation.
getY();
338 pFrame->
w = pImageElement->
w = aScale.
getX();
339 pFrame->
h = pImageElement->
h = aScale.
getY();
340 pFrame->
ZOrder = m_nNextZOrder++;
350 void PDFIProcessor::drawMask(
const uno::Sequence<beans::PropertyValue>& xBitmap,
354 setupImage( m_aImages.addImage(xBitmap) );
357 void PDFIProcessor::drawImage(
const uno::Sequence<beans::PropertyValue>& xBitmap )
359 setupImage( m_aImages.addImage(xBitmap) );
362 void PDFIProcessor::drawColorMaskedImage(
const uno::Sequence<beans::PropertyValue>& xBitmap,
363 const uno::Sequence<uno::Any>& )
366 setupImage( m_aImages.addImage(xBitmap) );
369 void PDFIProcessor::drawMaskedImage(
const uno::Sequence<beans::PropertyValue>& xBitmap,
370 const uno::Sequence<beans::PropertyValue>& ,
374 setupImage( m_aImages.addImage(xBitmap) );
377 void PDFIProcessor::drawAlphaMaskedImage(
const uno::Sequence<beans::PropertyValue>& xBitmap,
378 const uno::Sequence<beans::PropertyValue>& )
382 setupImage( m_aImages.addImage(xBitmap) );
386 void PDFIProcessor::strokePath(
const uno::Reference< rendering::XPolyPolygon2D >& rPath )
397 pPoly->
ZOrder = m_nNextZOrder++;
400 void PDFIProcessor::fillPath(
const uno::Reference< rendering::XPolyPolygon2D >& rPath )
411 pPoly->
ZOrder = m_nNextZOrder++;
414 void PDFIProcessor::eoFillPath(
const uno::Reference< rendering::XPolyPolygon2D >& rPath )
425 pPoly->
ZOrder = m_nNextZOrder++;
428 void PDFIProcessor::intersectClip(
const uno::Reference< rendering::XPolyPolygon2D >& rPath)
435 if( aCurClip.
count() )
441 void PDFIProcessor::intersectEoClip(
const uno::Reference< rendering::XPolyPolygon2D >& rPath)
448 if( aCurClip.
count() )
454 void PDFIProcessor::hyperLink(
const geometry::RealRectangle2D& rBounds,
455 const OUString& rURI )
457 if( !rURI.isEmpty() )
460 &m_pCurPage->Hyperlinks,
462 pLink->
x = rBounds.X1;
463 pLink->
y = rBounds.Y1;
464 pLink->
w = rBounds.X2-rBounds.X1;
465 pLink->
h = rBounds.Y2-rBounds.Y1;
471 IdToFontMap::const_iterator it = m_aIdToFont.find( nFontId );
472 if( it == m_aIdToFont.end() )
473 it = m_aIdToFont.find( 0 );
480 auto it = m_aGCToId.find( rGC );
481 if( it != m_aGCToId.end() )
485 m_aGCToId.insert({rGC, m_nNextGCId});
486 m_aIdToGC.insert({m_nNextGCId, rGC});
496 auto it = m_aIdToGC.find( nGCId );
497 if( it == m_aIdToGC.end() )
498 it = m_aIdToGC.find( 0 );
502 void PDFIProcessor::endPage()
505 if( m_xStatusIndicator.is()
507 && m_pCurPage->PageNumber == m_nPages
509 m_xStatusIndicator->end();
512 void PDFIProcessor::startPage(
const geometry::RealSize2D& rSize )
519 sal_Int32 nNextPageNr = m_pCurPage ? m_pCurPage->PageNumber+1 : 1;
520 if( m_xStatusIndicator.is() )
522 if( nNextPageNr == 1 )
523 startIndicator(
" " );
524 m_xStatusIndicator->setValue( nNextPageNr );
526 m_pCurPage = ElementFactory::createPageElement(m_pDocument.get(), nNextPageNr);
527 m_pCurElement = m_pCurPage;
528 m_pCurPage->w = rSize.Width;
529 m_pCurPage->h = rSize.Height;
538 #if OSL_DEBUG_LEVEL > 0
539 m_pDocument->emitStructure( 0 );
545 startIndicator(
" " );
546 m_pDocument->visitedBy( *optimizingVisitor, std::list<std::unique_ptr<Element>>::const_iterator());
548 #if OSL_DEBUG_LEVEL > 0
549 m_pDocument->emitStructure( 0 );
558 m_pDocument->visitedBy( *finalizingVisitor, std::list<std::unique_ptr<Element>>::const_iterator() );
566 #define OASIS_STR "urn:oasis:names:tc:opendocument:xmlns:"
567 aProps[
"xmlns:office" ] =
OASIS_STR "office:1.0" ;
568 aProps[
"xmlns:style" ] =
OASIS_STR "style:1.0" ;
569 aProps[
"xmlns:text" ] =
OASIS_STR "text:1.0" ;
570 aProps[
"xmlns:svg" ] =
OASIS_STR "svg-compatible:1.0" ;
571 aProps[
"xmlns:table" ] =
OASIS_STR "table:1.0" ;
572 aProps[
"xmlns:draw" ] =
OASIS_STR "drawing:1.0" ;
573 aProps[
"xmlns:fo" ] =
OASIS_STR "xsl-fo-compatible:1.0" ;
574 aProps[
"xmlns:xlink"] =
"http://www.w3.org/1999/xlink";
575 aProps[
"xmlns:dc"] =
"http://purl.org/dc/elements/1.1/";
576 aProps[
"xmlns:number"] =
OASIS_STR "datastyle:1.0" ;
577 aProps[
"xmlns:presentation"] =
OASIS_STR "presentation:1.0" ;
578 aProps[
"xmlns:math"] =
"http://www.w3.org/1998/Math/MathML";
579 aProps[
"xmlns:form"] =
OASIS_STR "form:1.0" ;
580 aProps[
"xmlns:script"] =
OASIS_STR "script:1.0" ;
581 aProps[
"xmlns:dom"] =
"http://www.w3.org/2001/xml-events";
582 aProps[
"xmlns:xforms"] =
"http://www.w3.org/2002/xforms";
583 aProps[
"xmlns:xsd"] =
"http://www.w3.org/2001/XMLSchema";
584 aProps[
"xmlns:xsi"] =
"http://www.w3.org/2001/XMLSchema-instance";
585 aProps[
"office:version" ] =
"1.0";
590 aStyles.
emit( aContext, *aEmittingVisitor );
592 m_pDocument->visitedBy( *aEmittingVisitor, std::list<std::unique_ptr<Element>>::const_iterator() );
597 void PDFIProcessor::startIndicator(
const OUString& rText )
600 if( !m_xStatusIndicator.is() )
603 sal_Int32
nLength = rText.getLength();
604 OUStringBuffer
aStr( nLength*2 );
606 for(
int i = 0;
i < nLength;
i++ )
613 aStr.append( nElements );
617 aStr.append( pText[
i] );
619 m_xStatusIndicator->start( aStr.makeStringAndClear(), nElements );
622 void PDFIProcessor::endIndicator()
624 if( m_xStatusIndicator.is() )
625 m_xStatusIndicator->end();
628 static bool lr_tb_sort( std::unique_ptr<Element>
const & pLeft, std::unique_ptr<Element>
const & pRight )
639 double fudge_factor_left = 0.0, fudge_factor_right = 0.0;
640 if( dynamic_cast< TextElement* >(pLeft.get()) )
641 fudge_factor_left = 0.1;
642 if (dynamic_cast< TextElement* >(pRight.get()))
643 fudge_factor_right = 0.1;
646 double lower_boundary_left = pLeft->y + std::max(pLeft->h, 0.0) - fabs(pLeft->h) * fudge_factor_left;
647 double lower_boundary_right = pRight->y + std::max(pRight->h, 0.0) - fabs(pRight->h) * fudge_factor_right;
648 double upper_boundary_left = pLeft->y + std::min(pLeft->h, 0.0);
649 double upper_boundary_right = pRight->y + std::min(pRight->h, 0.0);
652 if( lower_boundary_left < upper_boundary_right )
656 if( lower_boundary_right < upper_boundary_left )
660 double left_boundary_left = pLeft->y + std::min(pLeft->w, 0.0);
661 double left_boundary_right = pRight->y + std::min(pRight->w, 0.0);
662 double right_boundary_left = pLeft->y + std::max(pLeft->w, 0.0);
663 double right_boundary_right = pRight->y + std::max(pRight->w, 0.0);
669 if( right_boundary_left < left_boundary_right )
673 if( right_boundary_right < left_boundary_left )
678 if( pLeft->x < pRight->x )
680 if( pRight->x < pLeft->x )
682 if( pLeft->y < pRight->y )
688 void PDFIProcessor::sortElements(
Element* pEle)
699 OUString PDFIProcessor::mirrorString(
const OUString& i_rString )
701 const sal_Int32 nLen = i_rString.getLength();
702 OUStringBuffer aMirror( nLen );
708 const sal_uInt32 nCodePoint = i_rString.iterateCodePoints( &i );
713 return aMirror.makeStringAndClear();
css::rendering::ARGBColor LineColor
std::unordered_map< OUString, OUString > PropertyMap
#define PDFI_OUTDEV_RESOLUTION
virtual void beginTag(const char *pTag, const PropertyMap &rProperties)=0
Open up a tag with the given properties.
Main entry from the parser.
sal_UCS4 GetMirroredChar(sal_UCS4 nChar)
virtual void setFillColor(const css::rendering::ARGBColor &rColor) override
B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon &rCandidate, const B2DPolyPolygon &rClip, bool bInside, bool bStroke, size_t *pPointLimit)
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
virtual void pushState() override
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
exports com.sun.star. frame
css::rendering::ARGBColor FillColor
std::vector< double > DashArray
virtual void setLineWidth(double) override
exports com.sun.star. text
virtual std::shared_ptr< ElementTreeVisitor > createOptimizingVisitor(PDFIProcessor &) const =0
Create visitor that combines tree nodes.
std::list< std::unique_ptr< Element > > Children
virtual void setStrokeColor(const css::rendering::ARGBColor &rColor) override
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
basegfx::B2DHomMatrix Transformation
virtual void setPageNum(sal_Int32 nNumPages) override
Total number of pages for upcoming document.
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
void scale(double fX, double fY)
void transform(const basegfx::B2DHomMatrix &rMatrix)
virtual void setMiterLimit(double) override
Tree manipulation factory.
virtual void setLineJoin(sal_Int8) override
virtual void setLineCap(sal_Int8) override
std::shared_ptr< ElementTreeVisitor > ElementTreeVisitorSharedPtr
GraphicsContext & getGC()
void updateGeometryWith(const Element *pMergeFrom)
Union element geometry with given element.
virtual void setTransformation(const css::geometry::AffineMatrix2D &rMatrix) override
GraphicsContext & getCurrentContext()
virtual void setFlatness(double) override
void emit(EmitContext &rContext, ElementTreeVisitor &rContainedElemVisitor)
void translate(double fX, double fY)
virtual std::shared_ptr< ElementTreeVisitor > createStyleCollectingVisitor(StyleContainer &, PDFIProcessor &) const =0
Create visitor that prepares style info.
GraphicsContextStack m_aGCStack
virtual std::shared_ptr< ElementTreeVisitor > createEmittingVisitor(EmitContext &) const =0
Create visitor that emits tree to an output target.
virtual void popState() override
#define SAL_WARN(area, stream)
virtual void setLineDash(const css::uno::Sequence< double > &dashes, double start) override
virtual void setFont(const FontAttributes &rFont) override
static bool lr_tb_sort(std::unique_ptr< Element > const &pLeft, std::unique_ptr< Element > const &pRight)
virtual void endTag(const char *pTag)=0
Close previously opened tag.
const uno::Reference< uno::XComponentContext > m_xContext