summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/frmfmt.hxx6
-rw-r--r--sw/qa/extras/htmlexport/htmlexport.cxx67
-rw-r--r--sw/source/core/layout/paintfrm.cxx8
-rw-r--r--sw/source/filter/html/README42
-rw-r--r--sw/source/filter/html/htmlflywriter.cxx7
-rw-r--r--sw/source/filter/html/wrthtml.cxx8
-rw-r--r--sw/source/filter/html/wrthtml.hxx3
7 files changed, 133 insertions, 8 deletions
diff --git a/sw/inc/frmfmt.hxx b/sw/inc/frmfmt.hxx
index d1146b8a736b..36333d4e8525 100644
--- a/sw/inc/frmfmt.hxx
+++ b/sw/inc/frmfmt.hxx
@@ -116,7 +116,7 @@ public:
/// Creates the views.
virtual void MakeFrames();
- virtual Graphic MakeGraphic( ImageMap* pMap = nullptr );
+ virtual Graphic MakeGraphic( ImageMap* pMap = nullptr, const std::optional<Size>& rTargetDPI = std::nullopt );
/** @return the IMapObject defined at format (Fly)
in the ImageMap at position Point.
@@ -212,7 +212,7 @@ public:
SwAnchoredObject* GetAnchoredObj() const;
- virtual Graphic MakeGraphic( ImageMap* pMap = nullptr ) override;
+ virtual Graphic MakeGraphic( ImageMap* pMap = nullptr, const std::optional<Size>& rTargetDPI = std::nullopt ) override;
virtual bool GetInfo( SfxPoolItem& rInfo ) const override;
@@ -388,7 +388,7 @@ public:
Reset delete marks. */
virtual void MakeFrames() override;
- virtual Graphic MakeGraphic( ImageMap* pMap = nullptr ) override;
+ virtual Graphic MakeGraphic( ImageMap* pMap = nullptr, const std::optional<Size>& rTargetDPI = std::nullopt ) override;
virtual SwFrameFormat::tLayoutDir GetLayoutDir() const override;
virtual void SetLayoutDir( const SwFrameFormat::tLayoutDir _eLayoutDir ) override;
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 1f5182ac6e4c..8642b5baa4f5 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -40,6 +40,7 @@
#include <svtools/htmlcfg.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <comphelper/processfactory.hxx>
+#include <vcl/graphicfilter.hxx>
#include <swmodule.hxx>
#include <swdll.hxx>
@@ -270,6 +271,7 @@ class SwHtmlDomExportTest : public SwModelTestBase, public HtmlTestTools
public:
/// Get the .ole path, assuming maTempFile is an XHTML export result.
OUString GetOlePath();
+ OUString GetPngPath();
/// Parse the ole1 data out of an RTF fragment URL.
void ParseOle1FromRtfUrl(const OUString& rRtfUrl, SvMemoryStream& rOle1);
/// Export using the C++ HTML export filter, with xhtmlns=reqif-xhtml.
@@ -292,6 +294,22 @@ OUString SwHtmlDomExportTest::GetOlePath()
return aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
}
+OUString SwHtmlDomExportTest::GetPngPath()
+{
+ SvMemoryStream aStream;
+ HtmlExportTest::wrapFragment(maTempFile, aStream);
+ xmlDocUniquePtr pDoc = parseXmlStream(&aStream);
+ CPPUNIT_ASSERT(pDoc);
+ OUString aPngPath = getXPath(
+ pDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "data");
+ OUString aPngSuffix(".png");
+ CPPUNIT_ASSERT(aPngPath.endsWith(aPngSuffix));
+ INetURLObject aUrl(maTempFile.GetURL());
+ aUrl.setBase(aPngPath.subView(0, aPngPath.getLength() - aPngSuffix.getLength()));
+ aUrl.setExtension(u"png");
+ return aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+}
+
void SwHtmlDomExportTest::ParseOle1FromRtfUrl(const OUString& rRtfUrl, SvMemoryStream& rOle1)
{
SvMemoryStream aRtf;
@@ -1734,6 +1752,55 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifEmbedShapeAsPNG)
OUString::number(aPixelSize.getWidth()));
}
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifEmbedShapeAsPNGCustomDPI)
+{
+ // Given a document with a shape:
+ loadURL("private:factory/swriter", nullptr);
+ uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(
+ xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+ xShape->setSize(awt::Size(7145, 5240));
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ xDrawPageSupplier->getDrawPage()->add(xShape);
+ Size aSystemDPI(
+ Application::GetDefaultDevice()->LogicToPixel(Size(1, 1), MapMode(MapUnit::MapInch)));
+ sal_Int32 nDPI = aSystemDPI.getWidth() * 2;
+
+ // When exporting to XHTML:
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aStoreProperties = {
+ comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
+ comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")),
+ comphelper::makePropertyValue("ShapeDPI", nDPI),
+ };
+ xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
+
+ // Then make sure the shape is embedded as a PNG:
+ SvMemoryStream aStream;
+ HtmlExportTest::wrapFragment(maTempFile, aStream);
+ xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+ CPPUNIT_ASSERT(pXmlDoc);
+ assertXPath(pXmlDoc, "//reqif-xhtml:p/reqif-xhtml:object", "type", "image/png");
+
+ // Then check the pixel size of the shape:
+ Size aPixelSize(Application::GetDefaultDevice()->LogicToPixel(Size(7145, 5240),
+ MapMode(MapUnit::Map100thMM)));
+ tools::Long nPNGWidth = aPixelSize.getWidth() * 2;
+ OUString aPngUrl = GetPngPath();
+ SvFileStream aFileStream(aPngUrl, StreamMode::READ);
+ GraphicDescriptor aDescriptor(aFileStream, nullptr);
+ aDescriptor.Detect(/*bExtendedInfo=*/true);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 540
+ // - Actual : 270
+ // i.e. setting a double DPI didn't result in larger pixel width of the PNG.
+ CPPUNIT_ASSERT_EQUAL(nPNGWidth, aDescriptor.GetSizePixel().getWidth());
+
+ // Then make sure the shape's logic size (in CSS pixels) don't change:
+ assertXPath(pXmlDoc, "//reqif-xhtml:p/reqif-xhtml:object", "width",
+ OUString::number(aPixelSize.getWidth()));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index e74de064a9b6..4a9eb647bbd6 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -7441,12 +7441,12 @@ void SetOutDevAndWin( SwViewShell *pSh, OutputDevice *pO,
pSh->mpOpt->SetZoom( nZoom );
}
-Graphic SwFrameFormat::MakeGraphic( ImageMap* )
+Graphic SwFrameFormat::MakeGraphic( ImageMap*, const std::optional<Size>& /*rTargetDPI*/ )
{
return Graphic();
}
-Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap )
+Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap, const std::optional<Size>& /*rTargetDPI*/ )
{
Graphic aRet;
//search any Fly!
@@ -7553,7 +7553,7 @@ Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap )
return aRet;
}
-Graphic SwDrawFrameFormat::MakeGraphic( ImageMap* )
+Graphic SwDrawFrameFormat::MakeGraphic( ImageMap*, const std::optional<Size>& rTargetDPI )
{
Graphic aRet;
SwDrawModel* pMod = getIDocumentDrawModelAccess().GetDrawModel();
@@ -7563,7 +7563,7 @@ Graphic SwDrawFrameFormat::MakeGraphic( ImageMap* )
SdrView aView( *pMod );
SdrPageView *pPgView = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
aView.MarkObj( pObj, pPgView );
- aRet = aView.GetMarkedObjBitmapEx();
+ aRet = aView.GetMarkedObjBitmapEx(/*bNoVDevIfOneBmpMarked=*/false, rTargetDPI);
aView.HideSdrPage();
}
return aRet;
diff --git a/sw/source/filter/html/README b/sw/source/filter/html/README
new file mode 100644
index 000000000000..7b16fb0838a3
--- /dev/null
+++ b/sw/source/filter/html/README
@@ -0,0 +1,42 @@
+This filter is used when the "HTML (StarWriter)" filter is invoked.
+
+Import options:
+
+- FilterOptions: string
+
+ - xhtmlns=reqif-xhtml: actives the ReqIF mode
+
+- AllowedRTFOLEMimeTypes: sequence<string>
+
+ In case an (UNO) client wants to limit the accepted set of MIME types for
+ OLE objects in ReqIF mode, that's possible via this parameter.
+
+ Any MIME type is accepted by default.
+
+Export options:
+
+- FilterOptions: string
+
+ - SkipImages: skips images
+
+ - SkipHeaderFooter: skips the header and footer
+
+ - EmbedImages: inlines images
+
+ - XHTML: activates the XHTML mode
+
+ - xhtmlns=reqif-xhtml: actives the ReqIF mode
+
+- RTFOLEMimeType: string
+
+ Defines what MIME type to use for OLE objects in ReqIF mode, defaults to text/rtf.
+
+- ExportImagesAsOLE: boolean
+
+ Defines if images should be exported as OLE objects or bitmaps, defaults to
+ false.
+
+- ShapeDPI: long (32bit signed int)
+
+ Defines a custom DPI when converting vector shapes to bitmaps, defaults to
+ the system DPI (96 when not on HiDPI).
diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx
index 8f6608097f07..5dc8d69360c8 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -1804,7 +1804,12 @@ static Writer & OutHTML_FrameFormatAsImage( Writer& rWrt, const SwFrameFormat& r
return rWrt;
ImageMap aIMap;
- Graphic aGraphic( const_cast<SwFrameFormat &>(rFrameFormat).MakeGraphic( &aIMap ) );
+ std::optional<Size> aDPI;
+ if (rHTMLWrt.m_nShapeDPI.has_value())
+ {
+ aDPI.emplace(*rHTMLWrt.m_nShapeDPI, *rHTMLWrt.m_nShapeDPI);
+ }
+ Graphic aGraphic( const_cast<SwFrameFormat &>(rFrameFormat).MakeGraphic( &aIMap, aDPI ) );
if (rHTMLWrt.mbReqIF)
{
diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx
index dfd03a5360f2..d6880d407842 100644
--- a/sw/source/filter/html/wrthtml.cxx
+++ b/sw/source/filter/html/wrthtml.cxx
@@ -208,6 +208,14 @@ void SwHTMLWriter::SetupFilterOptions(SfxMedium& rMedium)
{
it->second >>= m_bExportImagesAsOLE;
}
+
+ it = aStoreMap.find("ShapeDPI");
+ if (it != aStoreMap.end())
+ {
+ sal_Int32 nVal{};
+ it->second >>= nVal;
+ m_nShapeDPI.emplace(nVal);
+ }
}
void SwHTMLWriter::SetupFilterOptions(const OUString& rFilterOptions)
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index cc84b39f1e65..340c1a0a81dc 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -414,6 +414,9 @@ public:
/// ReqIF mode: export images as OLE objects.
bool m_bExportImagesAsOLE = false;
+ /// DPI used when exporting a vector shape as a bitmap.
+ std::optional<sal_Int32> m_nShapeDPI;
+
/// Construct an instance of SwHTMLWriter and optionally give it
/// the filter options directly, which can also be set via SetupFilterOptions().
explicit SwHTMLWriter( const OUString& rBaseURL, const OUString& rFilterOptions = "" );