29 inline double pointToPixel(
const double fPoint,
const double fResolutionDPI)
35 bool isCompatible(
SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize)
47 if (aFirstBytes[0] !=
'%' || aFirstBytes[1] !=
'P' || aFirstBytes[2] !=
'D'
48 || aFirstBytes[3] !=
'F' || aFirstBytes[4] !=
'-')
51 sal_Int32 nMajor =
o3tl::toInt32(std::string_view(reinterpret_cast<char*>(&aFirstBytes[5]), 1));
52 sal_Int32 nMinor =
o3tl::toInt32(std::string_view(reinterpret_cast<char*>(&aFirstBytes[7]), 1));
53 return !(nMajor > 1 || (nMajor == 1 && nMinor > 6));
62 bool bCompatible = isCompatible(rInStream, nPos, nSize);
81 std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
87 if (!pPdfDocument->saveWithVersion(aSaved, 16))
91 aSaved.
Seek(STREAM_SEEK_TO_BEGIN);
95 return rOutStream.
good();
102 if (!getCompatibleStream(rStream, aMemoryStream))
105 const sal_uInt32 nStreamLength = aMemoryStream.
TellEnd();
107 auto aPdfData = std::make_unique<std::vector<sal_uInt8>>(nStreamLength);
109 aMemoryStream.
Seek(STREAM_SEEK_TO_BEGIN);
110 aMemoryStream.
ReadBytes(aPdfData->data(), aPdfData->size());
114 return { std::move(aPdfData) };
131 std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = pPdfium->openDocument(pBuffer, nSize);
137 const int nPageCount = pPdfDocument->getPageCount();
140 const size_t nLastPage = std::min<int>(nPageCount, nFirstPage + nPages) - 1;
141 for (
size_t nPageIndex = nFirstPage; nPageIndex <= nLastPage; ++nPageIndex)
144 std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(nPageIndex);
149 double nPageWidthPoints = pPdfPage->getWidth();
150 double nPageHeightPoints = pPdfPage->getHeight();
151 if (pSizeHint && pSizeHint->
getX() && pSizeHint->
getY())
162 const size_t nPageWidth = std::round(pointToPixel(nPageWidthPoints, fResolutionDPI)
164 const size_t nPageHeight = std::round(pointToPixel(nPageHeightPoints, fResolutionDPI)
165 * PDF_INSERT_MAGIC_SCALE_FACTOR);
166 std::unique_ptr<vcl::pdf::PDFiumBitmap> pPdfBitmap
167 = pPdfium->createBitmap(nPageWidth, nPageHeight, 1);
171 bool bTransparent = pPdfPage->hasTransparency();
178 const sal_uInt32 nColor = bTransparent ? 0x00000000 : 0xFFFFFFFF;
179 pPdfBitmap->fillRect(0, 0, nPageWidth, nPageHeight, nColor);
180 pPdfBitmap->renderPageBitmap(pPdfDocument.get(), pPdfPage.get(), 0,
181 0, nPageWidth, nPageHeight);
190 const int nStride = pPdfBitmap->getStride();
191 std::vector<sal_uInt8> aScanlineAlpha(nPageWidth);
192 for (
size_t nRow = 0; nRow < nPageHeight; ++nRow)
197 for (
size_t nCol = 0; nCol < nPageWidth; ++nCol)
200 aScanlineAlpha[nCol] = ~pPdfLine[3];
210 rBitmaps.emplace_back(aBitmap, aMask);
214 rBitmaps.emplace_back(std::move(aBitmap));
218 return rBitmaps.size();
222 std::shared_ptr<VectorGraphicData>& rVectorGraphicData)
227 SAL_WARN(
"vcl.filter",
"ImportPDF: empty PDF data array");
239 std::shared_ptr<VectorGraphicData> pVectorGraphicData;
242 rGraphic =
Graphic(pVectorGraphicData);
256 std::vector<PDFGraphicAnnotation>
257 findAnnotations(
const std::unique_ptr<vcl::pdf::PDFiumPage>& pPage,
basegfx::B2DSize aPageSize)
259 std::vector<PDFGraphicAnnotation> aPDFGraphicAnnotations;
260 for (
int nAnnotation = 0; nAnnotation < pPage->getAnnotationCount(); nAnnotation++)
262 auto pAnnotation = pPage->getAnnotation(nAnnotation);
265 auto eSubtype = pAnnotation->getSubType();
285 OUString sDateTimeString
289 css::util::DateTime aDateTime;
290 if (!sISO8601String.isEmpty())
295 Color aColor = pAnnotation->getColor();
297 aPDFGraphicAnnotations.emplace_back();
299 auto& rPDFGraphicAnnotation = aPDFGraphicAnnotations.back();
300 rPDFGraphicAnnotation.maRectangle = rRectangleHMM;
301 rPDFGraphicAnnotation.maAuthor = sAuthor;
302 rPDFGraphicAnnotation.maText = sText;
303 rPDFGraphicAnnotation.maDateTime = aDateTime;
304 rPDFGraphicAnnotation.meSubType = eSubtype;
305 rPDFGraphicAnnotation.maColor = aColor;
309 auto const& rVertices = pAnnotation->getVertices();
310 if (!rVertices.empty())
312 auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerPolygon>();
313 rPDFGraphicAnnotation.mpMarker = pMarker;
314 for (
auto const& rVertex : rVertices)
316 auto aPoint = convertFromPDFInternalToHMM(rVertex, aPageSize);
317 pMarker->maPolygon.append(aPoint);
319 pMarker->maPolygon.setClosed(
true);
322 pMarker->maFillColor = pAnnotation->getInteriorColor();
327 auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerSquare>();
328 rPDFGraphicAnnotation.mpMarker = pMarker;
331 pMarker->maFillColor = pAnnotation->getInteriorColor();
335 auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerCircle>();
336 rPDFGraphicAnnotation.mpMarker = pMarker;
339 pMarker->maFillColor = pAnnotation->getInteriorColor();
343 auto const& rStrokesList = pAnnotation->getInkStrokes();
344 if (!rStrokesList.empty())
346 auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerInk>();
347 rPDFGraphicAnnotation.mpMarker = pMarker;
348 for (
auto const& rStrokes : rStrokesList)
351 for (
auto const& rVertex : rStrokes)
353 auto aPoint = convertFromPDFInternalToHMM(rVertex, aPageSize);
356 pMarker->maStrokes.push_back(aPolygon);
358 float fWidth = pAnnotation->getBorderWidth();
361 pMarker->maFillColor = pAnnotation->getInteriorColor();
366 size_t nCount = pAnnotation->getAttachmentPointsCount();
369 auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerHighlight>(
371 rPDFGraphicAnnotation.mpMarker = pMarker;
372 for (
size_t i = 0;
i < nCount; ++
i)
374 auto aAttachmentPoints = pAnnotation->getAttachmentPoints(i);
375 if (!aAttachmentPoints.empty())
381 = convertFromPDFInternalToHMM(aAttachmentPoints[0], aPageSize);
384 = convertFromPDFInternalToHMM(aAttachmentPoints[1], aPageSize);
387 = convertFromPDFInternalToHMM(aAttachmentPoints[3], aPageSize);
390 = convertFromPDFInternalToHMM(aAttachmentPoints[2], aPageSize);
393 pMarker->maQuads.push_back(aPolygon);
400 auto const& rLineGeometry = pAnnotation->getLineGeometry();
401 if (!rLineGeometry.empty())
403 auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerLine>();
404 rPDFGraphicAnnotation.mpMarker = pMarker;
406 auto aPoint1 = convertFromPDFInternalToHMM(rLineGeometry[0], aPageSize);
407 pMarker->maLineStart = aPoint1;
409 auto aPoint2 = convertFromPDFInternalToHMM(rLineGeometry[1], aPageSize);
410 pMarker->maLineEnd = aPoint2;
412 float fWidth = pAnnotation->getBorderWidth();
419 return aPDFGraphicAnnotations;
426 std::unique_ptr<SvStream>
xStream(
444 auto pPdfDocument = pPdfium->openDocument(pGfxLink->GetData(), pGfxLink->GetDataSize());
449 const int nPageCount = pPdfDocument->getPageCount();
453 for (
int nPageIndex = 0; nPageIndex < nPageCount; ++nPageIndex)
456 if (aPageSize.
getX() <= 0.0 || aPageSize.
getY() <= 0.0)
461 constexpr
double pointToTwipconversionRatio = 20;
469 Graphic aGraphic(pGfxLink, nPageIndex);
471 auto pPage = pPdfDocument->openPage(nPageIndex);
473 std::vector<PDFGraphicAnnotation> aPDFGraphicAnnotations
474 = findAnnotations(pPage, aPageSize);
476 rGraphics.emplace_back(std::move(aGraphic),
Size(nPageWidth, nPageHeight),
477 aPDFGraphicAnnotations);
480 return rGraphics.size();
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
size_t RenderPDFBitmaps(const void *pBuffer, int nSize, std::vector< BitmapEx > &rBitmaps, const size_t nFirstPage, int nPages, const basegfx::B2DTuple *pSizeHint)
Fills the rBitmaps vector with rendered pages.
bool ISO8601parseDateTime(std::u16string_view rString, css::util::DateTime &rDateTime)
bool importPdfVectorGraphicData(SvStream &rStream, std::shared_ptr< VectorGraphicData > &rVectorGraphicData)
Imports a PDF stream as a VectorGraphicData.
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
#define STREAM_SEEK_TO_END
sal_uInt64 Seek(sal_uInt64 nPos)
double getDefaultPdfResolutionDpi()
Get the default PDF rendering resolution in DPI.
This template handles BitmapAccess the RAII way.
virtual sal_uInt64 TellEnd() override
constexpr auto convertTwipToMm100(N n)
constexpr OStringLiteral constDictionaryKeyContents
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
Container for the binary data, whose responsibility is to manage the make it as simple as possible to...
constexpr int PDF_INSERT_MAGIC_SCALE_FACTOR
OUString convertPdfDateToISO8601(OUString const &rInput)
static std::shared_ptr< PDFium > & get()
constexpr OStringLiteral constDictionaryKeyModificationDate
#define STREAM_SEEK_TO_BEGIN
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
SvStream & WriteStream(SvStream &rStream)
const sal_uInt8 * ConstScanline
std::size_t ReadBytes(void *pData, std::size_t nSize)
constexpr auto convertPointToMm100(N n)
void setClosed(bool bNew)
constexpr OStringLiteral constDictionaryKeyTitle
size_t ImportPDFUnloaded(const OUString &rURL, std::vector< PDFGraphicResult > &rGraphics)
Import PDF as Graphic images (1 per page), but not loaded yet.
#define SAL_WARN(area, stream)
bool ImportPDF(SvStream &rStream, Graphic &rGraphic)
Imports a PDF stream into rGraphic.
constexpr OStringLiteral constDictionaryKeyInteriorColor