/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
if (pProgrInfo)
{
pProgrInfo->ReportActions(nActionsToReport);
nActionsToReport = 0;
}
// MapMode scaling
MapScaling();
// To calculate the progress meter, we use GetActionSize()*3. // However, maTmpList has a lower entry count limit than GetActionSize(), // so the actions that were assumed were too much have to be re-added. // nActionsToReport = (rMtf.GetActionSize() - maTmpList.size()) * 2;
// announce all currently unannounced rescales if (pProgrInfo)
{
pProgrInfo->ReportRescales(nActionsToReport);
pProgrInfo->SetInsertCount(maTmpList.size());
}
nActionsToReport = 0;
// insert all objects cached in aTmpList now into rOL from nInsPos
nInsPos = std::min(nInsPos, rOL.GetObjCount());
for (rtl::Reference<SdrObject>& pObj : maTmpList)
{
rOL.NbcInsertObject(pObj.get(), nInsPos);
nInsPos++;
if (pProgrInfo)
{
nActionsToReport++;
if (nActionsToReport >= 32) // update all 32 actions
{
pProgrInfo->ReportInserts(nActionsToReport);
nActionsToReport = 0;
}
}
}
// report all remaining inserts for the last time if (pProgrInfo)
{
pProgrInfo->ReportInserts(nActionsToReport);
}
if (pSdrTextObj && pSdrTextObj->HasText())
{ // all text objects are created from ImportText and have no line or fill attributes, so // it is okay to concentrate on the text itself while (true)
{ const basegfx::B2DPolyPolygon aTextContour(pSdrTextObj->TakeContour()); const basegfx::B2DRange aTextRange(aTextContour.getB2DRange()); const basegfx::B2DRange aClipRange(maClip.getB2DRange());
// no overlap -> completely outside if (!aClipRange.overlaps(aTextRange))
{
pObj.clear(); break;
}
// when the clip is a rectangle fast check for inside is possible if (basegfx::utils::isRectangle(maClip) && aClipRange.isInside(aTextRange))
{ // completely inside ClipRect break;
}
// here text needs to be clipped; to do so, convert to SdrObjects with polygons // and add these recursively. Delete original object, do not add in this run
rtl::Reference<SdrObject> pConverted = pSdrTextObj->ConvertToPolyObj(true, true);
pObj.clear(); if (pConverted)
{ // recursively add created conversion; per definition this shall not // contain further SdrTextObjs. Visit only non-group objects
SdrObjListIter aIter(*pConverted, SdrIterMode::DeepNoGroups);
// work with clones; the created conversion may contain group objects // and when working with the original objects the loop itself could // break and the cleanup later would be pretty complicated (only delete group // objects, are these empty, ...?) while (aIter.IsMore())
{
SdrObject* pCandidate = aIter.Next();
OSL_ENSURE(pCandidate && dynamic_cast<SdrObjGroup*>(pCandidate) == nullptr, "SdrObjListIter with SdrIterMode::DeepNoGroups error (!)");
rtl::Reference<SdrObject> pNewClone(
pCandidate->CloneSdrObject(pCandidate->getSdrModelFromSdrObject()));
if (!aBitmapEx.IsEmpty())
{ // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used constdouble fScaleX(aBitmapEx.GetSizePixel().Width()
/ (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0)); constdouble fScaleY(
aBitmapEx.GetSizePixel().Height()
/ (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
basegfx::B2DRange aPixel(aNewRange);
basegfx::B2DHomMatrix aTrans;
// #i111954# check object for visibility // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj bool bVisible(false);
if (pObj->HasLineStyle())
{
bVisible = true;
}
if (!bVisible && pObj->HasFillStyle())
{
bVisible = true;
}
if (!bVisible)
{
SdrTextObj* pTextObj = DynCastSdrTextObj(pObj.get());
if (pTextObj && pTextObj->HasText())
{
bVisible = true;
}
}
if (!bVisible)
{
SdrGrafObj* pGrafObj = dynamic_cast<SdrGrafObj*>(pObj.get());
if (pGrafObj)
{ // this may be refined to check if the graphic really is visible. It // is here to ensure that graphic objects without fill, line and text // get created
bVisible = true;
}
}
if (bVisible)
{
maTmpList.push_back(pObj);
if (dynamic_cast<SdrPathObj*>(pObj.get()))
{ constbool bClosed(pObj->IsClosedObj());
const vcl::pdf::PDFPageObjectType ePageObjectType = pPageObject->getType(); switch (ePageObjectType)
{ case vcl::pdf::PDFPageObjectType::Text:
ImportText(pPageObject, pTextPage, nPageObjectIndex); break; case vcl::pdf::PDFPageObjectType::Path:
ImportPath(pPageObject, nPageObjectIndex); break; case vcl::pdf::PDFPageObjectType::Image:
ImportImage(pPageObject, nPageObjectIndex); break; case vcl::pdf::PDFPageObjectType::Shading:
SAL_WARN("sd.filter", "Got page object SHADING: " << nPageObjectIndex); break; case vcl::pdf::PDFPageObjectType::Form:
ImportForm(pPageObject, pTextPage, nPageObjectIndex); break; default:
SAL_WARN("sd.filter", "Unknown PDF page object #" << nPageObjectIndex << " of type: "
<< static_cast<int>(ePageObjectType)); break;
}
}
void ImpSdrPdfImport::ImportForm(std::unique_ptr<vcl::pdf::PDFiumPageObject> const& pPageObject,
std::unique_ptr<vcl::pdf::PDFiumTextPage> const& pTextPage, int/*nPageObjectIndex*/)
{ // Get the form matrix to perform correct translation/scaling of the form sub-objects. const basegfx::B2DHomMatrix aOldMatrix = maCurrentMatrix;
maCurrentMatrix = pPageObject->getMatrix();
constint nCount = pPageObject->getFormObjectCount(); for (int nIndex = 0; nIndex < nCount; ++nIndex)
{ auto pFormObject = pPageObject->getFormObject(nIndex);
ImportPdfObject(pFormObject, pTextPage, -1);
}
// Restore the old one.
maCurrentMatrix = aOldMatrix;
}
Color aTextColor(COL_TRANSPARENT); bool bFill = false; bool bUse = true; switch (pPageObject->getTextRenderMode())
{ case vcl::pdf::PDFTextRenderMode::Fill: case vcl::pdf::PDFTextRenderMode::FillClip: case vcl::pdf::PDFTextRenderMode::FillStroke: case vcl::pdf::PDFTextRenderMode::FillStrokeClip:
bFill = true; break; case vcl::pdf::PDFTextRenderMode::Stroke: case vcl::pdf::PDFTextRenderMode::StrokeClip: case vcl::pdf::PDFTextRenderMode::Unknown: break; case vcl::pdf::PDFTextRenderMode::Invisible: case vcl::pdf::PDFTextRenderMode::Clip:
bUse = false; break;
} if (bUse)
{
Color aColor = bFill ? pPageObject->getFillColor() : pPageObject->getStrokeColor(); if (aColor != COL_TRANSPARENT)
aTextColor = aColor.GetRGBColor();
}
if (aTextColor != mpVD->GetTextColor())
{
mpVD->SetTextColor(aTextColor);
mbFntDirty = true;
}
void ImpSdrPdfImport::InsertTextObject(const Point& rPos, const Size& rSize, const OUString& rStr)
{ // calc text box size, add 5% to make it fit safely
if (aFont.GetAverageFontWidth())
{
pText->ClearMergedItem(SDRATTR_TEXT_AUTOGROWWIDTH);
pText->SetMergedItem(makeSdrTextAutoGrowHeightItem(false)); // don't let the margins eat the space needed for the text
pText->SetMergedItem(SdrTextFitToSizeTypeItem(drawing::TextFitToSizeType_ALLLINES));
} else
{
pText->SetMergedItem(makeSdrTextAutoGrowWidthItem(true));
}
void ImpSdrPdfImport::ImportImage(std::unique_ptr<vcl::pdf::PDFiumPageObject> const& pPageObject, int/*nPageObjectIndex*/)
{
std::unique_ptr<vcl::pdf::PDFiumBitmap> bitmap = pPageObject->getImageBitmap(); if (!bitmap)
{
SAL_WARN("sd.filter", "Failed to get IMAGE"); return;
}
const vcl::pdf::PDFBitmapType format = bitmap->getFormat(); if (format == vcl::pdf::PDFBitmapType::Unknown)
{
SAL_WARN("sd.filter", "Failed to get IMAGE format"); return;
}
rtl::Reference<SdrGrafObj> pGraf = new SdrGrafObj(*mpModel, Graphic(aBitmap), aRect);
// This action is not creating line and fill, set directly, do not use SetAttributes(..)
pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
InsertObj(pGraf.get());
}
void ImpSdrPdfImport::ImportPath(std::unique_ptr<vcl::pdf::PDFiumPageObject> const& pPageObject, int/*nPageObjectIndex*/)
{ auto aPathMatrix = pPageObject->getMatrix();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.