44 PDFIProcessor::PDFIProcessor(
const uno::Reference< task::XStatusIndicator >& xStat ,
45 css::uno::Reference< css::uno::XComponentContext >
const & xContext) :
51 m_pCurElement(nullptr),
62 m_xStatusIndicator( xStat )
86 GraphicsContextStack::value_type
const a(
m_aGCStack.back());
127 SAL_WARN(
"sdext.pdfimport",
"PDFIProcessor::setMiterLimit(): not supported by ODF");
151 FontToIdMap::const_iterator it =
m_aFontToId.find( aChangedFont );
163 void PDFIProcessor::setTextRenderMode( sal_Int32 i_nMode )
167 IdToFontMap::iterator it = m_aIdToFont.find( rGC.
FontId );
168 if( it != m_aIdToFont.end() )
169 setFont( it->second );
183 void PDFIProcessor::processGlyphLine()
185 if (m_GlyphsList.empty())
188 double spaceDetectBoundary = 0.0;
193 OUString& glyph =
i.getGlyph();
196 if (!glyph.isEmpty())
199 if ((ch == 0x20) || (ch == 0xa0))
201 double spaceWidth =
i.getWidth();
202 spaceDetectBoundary = spaceWidth * 0.5;
208 if (spaceDetectBoundary == 0.0)
210 double avgGlyphWidth = 0.0;
212 avgGlyphWidth +=
i.getWidth();
213 avgGlyphWidth /= m_GlyphsList.size();
214 spaceDetectBoundary = avgGlyphWidth * 0.2;
218 m_GlyphsList[0].getCurElement(),
219 getGCId(m_GlyphsList[0].getGC()));
220 frame->
ZOrder = m_nNextZOrder++;
222 frame->
FontSize = getFont(m_GlyphsList[0].getGC().FontId).size;
225 for (
size_t i = 0;
i < m_GlyphsList.size();
i++)
227 bool prependSpace =
false;
230 getGCId(m_GlyphsList[
i].getGC()),
231 m_GlyphsList[
i].getGC().FontId);
234 text->
x = m_GlyphsList[0].getGC().Transformation.get(0, 2);
235 text->
y = m_GlyphsList[0].getGC().Transformation.get(1, 2);
243 double spaceSize = m_GlyphsList[
i].getPrevSpaceWidth();
244 prependSpace = spaceSize > spaceDetectBoundary;
247 text->
Text.append(
" ");
248 text->
Text.append(m_GlyphsList[
i].getGlyph());
251 m_GlyphsList.clear();
254 void PDFIProcessor::drawGlyphs(
const OUString& rGlyphs,
255 const geometry::RealRectangle2D& rRect,
256 const geometry::Matrix2D& rFontMatrix,
262 rFontMatrix.m00, rFontMatrix.m01, 0.0,
263 rFontMatrix.m10, rFontMatrix.m11, 0.0);
264 fontMatrix.
scale(fontSize, fontSize);
268 totalTextMatrix1.
translate(rRect.X1, rRect.Y1);
269 totalTextMatrix2.
translate(rRect.X2, rRect.Y2);
272 corrMatrix.
scale(1.0, -1.0);
274 totalTextMatrix1 = totalTextMatrix1 * corrMatrix;
275 totalTextMatrix2 = totalTextMatrix2 * corrMatrix;
286 offsetMatrix1 *= invPrevMatrix;
287 offsetMatrix2 *= invMatrix;
289 double charWidth = offsetMatrix2.
get(0, 2);
290 double prevSpaceWidth = offsetMatrix1.
get(0, 2) - prevCharWidth;
292 if ((totalTextMatrix1.
get(0, 0) != prevTextMatrix.get(0, 0)) ||
293 (totalTextMatrix1.
get(0, 1) != prevTextMatrix.get(0, 1)) ||
294 (totalTextMatrix1.
get(1, 0) != prevTextMatrix.get(1, 0)) ||
295 (totalTextMatrix1.
get(1, 1) != prevTextMatrix.get(1, 1)) ||
296 (offsetMatrix1.
get(0, 2) < 0.0) ||
297 (prevSpaceWidth > prevCharWidth * 1.3) ||
305 m_GlyphsList.push_back(aGlyph);
307 prevCharWidth = charWidth;
308 prevTextMatrix = totalTextMatrix1;
311 void PDFIProcessor::endText()
315 m_pCurElement = pText->
Parent;
318 void PDFIProcessor::setupImage(
ImageId nImage)
323 double fRotate, fShearX;
326 const sal_Int32 nGCId = getGCId(rGC);
327 FrameElement* pFrame = ElementFactory::createFrameElement( m_pCurElement, nGCId );
328 ImageElement* pImageElement = ElementFactory::createImageElement( pFrame, nGCId, nImage );
329 pFrame->
x = pImageElement->
x = aTranslation.
getX();
330 pFrame->
y = pImageElement->
y = aTranslation.
getY();
331 pFrame->
w = pImageElement->
w = aScale.
getX();
332 pFrame->
h = pImageElement->
h = aScale.
getY();
333 pFrame->
ZOrder = m_nNextZOrder++;
343 void PDFIProcessor::drawMask(
const uno::Sequence<beans::PropertyValue>& xBitmap,
347 setupImage( m_aImages.addImage(xBitmap) );
350 void PDFIProcessor::drawImage(
const uno::Sequence<beans::PropertyValue>& xBitmap )
352 setupImage( m_aImages.addImage(xBitmap) );
355 void PDFIProcessor::drawColorMaskedImage(
const uno::Sequence<beans::PropertyValue>& xBitmap,
356 const uno::Sequence<uno::Any>& )
359 setupImage( m_aImages.addImage(xBitmap) );
362 void PDFIProcessor::drawMaskedImage(
const uno::Sequence<beans::PropertyValue>& xBitmap,
363 const uno::Sequence<beans::PropertyValue>& ,
367 setupImage( m_aImages.addImage(xBitmap) );
370 void PDFIProcessor::drawAlphaMaskedImage(
const uno::Sequence<beans::PropertyValue>& xBitmap,
371 const uno::Sequence<beans::PropertyValue>& )
375 setupImage( m_aImages.addImage(xBitmap) );
379 void PDFIProcessor::strokePath(
const uno::Reference< rendering::XPolyPolygon2D >& rPath )
390 pPoly->
ZOrder = m_nNextZOrder++;
393 void PDFIProcessor::fillPath(
const uno::Reference< rendering::XPolyPolygon2D >& rPath )
404 pPoly->
ZOrder = m_nNextZOrder++;
407 void PDFIProcessor::eoFillPath(
const uno::Reference< rendering::XPolyPolygon2D >& rPath )
418 pPoly->
ZOrder = m_nNextZOrder++;
421 void PDFIProcessor::intersectClip(
const uno::Reference< rendering::XPolyPolygon2D >& rPath)
428 if( aCurClip.
count() )
434 void PDFIProcessor::intersectEoClip(
const uno::Reference< rendering::XPolyPolygon2D >& rPath)
441 if( aCurClip.
count() )
447 void PDFIProcessor::hyperLink(
const geometry::RealRectangle2D& rBounds,
448 const OUString& rURI )
450 if( !rURI.isEmpty() )
453 &m_pCurPage->Hyperlinks,
455 pLink->
x = rBounds.X1;
456 pLink->
y = rBounds.Y1;
457 pLink->
w = rBounds.X2-rBounds.X1;
458 pLink->
h = rBounds.Y2-rBounds.Y1;
464 IdToFontMap::const_iterator it = m_aIdToFont.find( nFontId );
465 if( it == m_aIdToFont.end() )
466 it = m_aIdToFont.find( 0 );
473 auto it = m_aGCToId.find( rGC );
474 if( it != m_aGCToId.end() )
478 m_aGCToId.insert({rGC, m_nNextGCId});
479 m_aIdToGC.insert({m_nNextGCId, rGC});
489 auto it = m_aIdToGC.find( nGCId );
490 if( it == m_aIdToGC.end() )
491 it = m_aIdToGC.find( 0 );
495 void PDFIProcessor::endPage()
498 if( m_xStatusIndicator.is()
500 && m_pCurPage->PageNumber == m_nPages
502 m_xStatusIndicator->end();
505 void PDFIProcessor::startPage(
const geometry::RealSize2D& rSize )
512 sal_Int32 nNextPageNr = m_pCurPage ? m_pCurPage->PageNumber+1 : 1;
513 if( m_xStatusIndicator.is() )
515 if( nNextPageNr == 1 )
516 startIndicator(
" " );
517 m_xStatusIndicator->setValue( nNextPageNr );
519 m_pCurPage = ElementFactory::createPageElement(m_pDocument.get(), nNextPageNr);
520 m_pCurElement = m_pCurPage;
521 m_pCurPage->w = rSize.Width;
522 m_pCurPage->h = rSize.Height;
531 #if OSL_DEBUG_LEVEL > 0
532 m_pDocument->emitStructure( 0 );
538 startIndicator(
" " );
539 m_pDocument->visitedBy( *optimizingVisitor, std::list<std::unique_ptr<Element>>::const_iterator());
541 #if OSL_DEBUG_LEVEL > 0
542 m_pDocument->emitStructure( 0 );
551 m_pDocument->visitedBy( *finalizingVisitor, std::list<std::unique_ptr<Element>>::const_iterator() );
559 #define OASIS_STR "urn:oasis:names:tc:opendocument:xmlns:"
560 aProps[
"xmlns:office" ] =
OASIS_STR "office:1.0" ;
561 aProps[
"xmlns:style" ] =
OASIS_STR "style:1.0" ;
562 aProps[
"xmlns:text" ] =
OASIS_STR "text:1.0" ;
563 aProps[
"xmlns:svg" ] =
OASIS_STR "svg-compatible:1.0" ;
564 aProps[
"xmlns:table" ] =
OASIS_STR "table:1.0" ;
565 aProps[
"xmlns:draw" ] =
OASIS_STR "drawing:1.0" ;
566 aProps[
"xmlns:fo" ] =
OASIS_STR "xsl-fo-compatible:1.0" ;
567 aProps[
"xmlns:xlink"] =
"http://www.w3.org/1999/xlink";
568 aProps[
"xmlns:dc"] =
"http://purl.org/dc/elements/1.1/";
569 aProps[
"xmlns:number"] =
OASIS_STR "datastyle:1.0" ;
570 aProps[
"xmlns:presentation"] =
OASIS_STR "presentation:1.0" ;
571 aProps[
"xmlns:math"] =
"http://www.w3.org/1998/Math/MathML";
572 aProps[
"xmlns:form"] =
OASIS_STR "form:1.0" ;
573 aProps[
"xmlns:script"] =
OASIS_STR "script:1.0" ;
574 aProps[
"xmlns:dom"] =
"http://www.w3.org/2001/xml-events";
575 aProps[
"xmlns:xforms"] =
"http://www.w3.org/2002/xforms";
576 aProps[
"xmlns:xsd"] =
"http://www.w3.org/2001/XMLSchema";
577 aProps[
"xmlns:xsi"] =
"http://www.w3.org/2001/XMLSchema-instance";
578 aProps[
"office:version" ] =
"1.0";
583 aStyles.
emit( aContext, *aEmittingVisitor );
585 m_pDocument->visitedBy( *aEmittingVisitor, std::list<std::unique_ptr<Element>>::const_iterator() );
590 void PDFIProcessor::startIndicator(
const OUString& rText )
593 if( !m_xStatusIndicator.is() )
596 sal_Int32
nLength = rText.getLength();
597 OUStringBuffer
aStr( nLength*2 );
599 for(
int i = 0;
i < nLength;
i++ )
606 aStr.append( nElements );
610 aStr.append( pText[
i] );
612 m_xStatusIndicator->start( aStr.makeStringAndClear(), nElements );
615 void PDFIProcessor::endIndicator()
617 if( m_xStatusIndicator.is() )
618 m_xStatusIndicator->end();
621 static bool lr_tb_sort( std::unique_ptr<Element>
const & pLeft, std::unique_ptr<Element>
const & pRight )
632 double fudge_factor_left = 0.0, fudge_factor_right = 0.0;
633 if( dynamic_cast< TextElement* >(pLeft.get()) )
634 fudge_factor_left = 0.1;
635 if (dynamic_cast< TextElement* >(pRight.get()))
636 fudge_factor_right = 0.1;
639 double lower_boundary_left = pLeft->y + std::max(pLeft->h, 0.0) - fabs(pLeft->h) * fudge_factor_left;
640 double lower_boundary_right = pRight->y + std::max(pRight->h, 0.0) - fabs(pRight->h) * fudge_factor_right;
641 double upper_boundary_left = pLeft->y + std::min(pLeft->h, 0.0);
642 double upper_boundary_right = pRight->y + std::min(pRight->h, 0.0);
645 if( lower_boundary_left < upper_boundary_right )
649 if( lower_boundary_right < upper_boundary_left )
653 double left_boundary_left = pLeft->y + std::min(pLeft->w, 0.0);
654 double left_boundary_right = pRight->y + std::min(pRight->w, 0.0);
655 double right_boundary_left = pLeft->y + std::max(pLeft->w, 0.0);
656 double right_boundary_right = pRight->y + std::max(pRight->w, 0.0);
662 if( right_boundary_left < left_boundary_right )
666 if( right_boundary_right < left_boundary_left )
671 if( pLeft->x < pRight->x )
673 if( pRight->x < pLeft->x )
675 if( pLeft->y < pRight->y )
681 void PDFIProcessor::sortElements(
Element* pEle)
692 OUString PDFIProcessor::mirrorString(
const OUString& i_rString )
694 const sal_Int32 nLen = i_rString.getLength();
695 OUStringBuffer aMirror( nLen );
701 const sal_uInt32 nCodePoint = i_rString.iterateCodePoints( &i );
706 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
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon &rCandidate, const B2DPolyPolygon &rClip, bool bInside, bool bStroke)
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