summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-06-04 15:58:01 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-06-04 18:03:10 +0200
commit04716690f6c5193f15868bc71e7d17c53e085a54 (patch)
tree3bab71a0ff00553023b4fab9635dc37e7b235bd5 /sw
parent5ffcf2fa69aa6c79b07b1cf04c8cf6c85c5f6b83 (diff)
sw HTML export: allow custom DPI for the bitmaps of shapes
But leave the CSS pixel size of them unchanged in the HTML markup. Also add some documentation on the various options, so one doesn't have to dig them out from testcases. Change-Id: I6c6ee4e9c98d674f44e7c5835f2e6a6737e13f34 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116722 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
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 = "" );