include/vcl/filter/SvmReader.hxx | 39 ++++ vcl/Library_vcl.mk | 1 vcl/qa/cppunit/svm/svmtest.cxx | 5 vcl/source/filter/svm/SvmReader.cxx | 334 ++++++++++++++++++++++++++++++++++++ 4 files changed, 378 insertions(+), 1 deletion(-)
New commits: commit 960d8c227bf39c66b5366f6024635ee317c6b314 Author: panoskorovesis <panoskorove...@outlook.com> AuthorDate: Wed Jun 30 09:57:27 2021 +0300 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Jul 5 08:55:09 2021 +0200 Create Separate SvmReader class Add a new class to handle MetaAcion.Read() at vcl/source/filter/svm/ Modified svmtest.cxx to use the new Read() method. Change-Id: I617cb8fe14704e1303c866261ceb695238f04234 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118143 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/vcl/filter/SvmReader.hxx b/include/vcl/filter/SvmReader.hxx new file mode 100644 index 000000000000..229fb3ca1d36 --- /dev/null +++ b/include/vcl/filter/SvmReader.hxx @@ -0,0 +1,39 @@ +/* -*- 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 . + */ + +#pragma once + +#include <memory> +#include <vcl/gdimtf.hxx> + +class SvStream; + +class VCL_DLLPUBLIC SvmReader +{ +private: + SvStream& mrStream; + +public: + SvmReader(SvStream& rIStm); + + SvStream& Read(GDIMetaFile& rMetaFile, ImplMetaReadData* pData = nullptr); + rtl::Reference<MetaAction> MetaActionHandler(ImplMetaReadData* pData); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 65b6cd8cc96e..d3f1adcd9b37 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -454,6 +454,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/jpeg/JpegReader \ vcl/source/filter/jpeg/JpegWriter \ vcl/source/filter/jpeg/JpegTransform \ + vcl/source/filter/svm/SvmReader \ vcl/source/filter/wmf/emfwr \ vcl/source/filter/wmf/wmf \ vcl/source/filter/wmf/wmfexternal \ diff --git a/vcl/qa/cppunit/svm/svmtest.cxx b/vcl/qa/cppunit/svm/svmtest.cxx index 0f2523ea3c46..7a1f4b8f0dba 100644 --- a/vcl/qa/cppunit/svm/svmtest.cxx +++ b/vcl/qa/cppunit/svm/svmtest.cxx @@ -22,6 +22,7 @@ #include <vcl/pngwrite.hxx> #include <tools/fract.hxx> #include <vcl/metaact.hxx> +#include <vcl/filter/SvmReader.hxx> #include <salhelper/simplereferenceobject.hxx> #include <bitmap/BitmapWriteAccess.hxx> @@ -328,7 +329,9 @@ GDIMetaFile SvmTest::writeAndReadStream(GDIMetaFile& rMetaFile, std::u16string_v aStream.Seek(STREAM_SEEK_TO_BEGIN); GDIMetaFile aResultMetafile; - aResultMetafile.Read(aStream); + SvmReader aReader(aStream); + aResultMetafile.Clear(); + aReader.Read(aResultMetafile); return aResultMetafile; } diff --git a/vcl/source/filter/svm/SvmReader.cxx b/vcl/source/filter/svm/SvmReader.cxx new file mode 100644 index 000000000000..e8455ea4de33 --- /dev/null +++ b/vcl/source/filter/svm/SvmReader.cxx @@ -0,0 +1,334 @@ +/* -*- 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 . + */ + +#include <vcl/filter/SvmReader.hxx> +#include <sal/log.hxx> +#include <tools/stream.hxx> +#include <tools/vcompat.hxx> +#include <vcl/TypeSerializer.hxx> +#include <vcl/gdimtf.hxx> +#include <vcl/metaact.hxx> + +#include <svmconverter.hxx> + +namespace +{ +class DepthGuard +{ +private: + ImplMetaReadData& m_rData; + rtl_TextEncoding m_eOrigCharSet; + +public: + DepthGuard(ImplMetaReadData& rData, SvStream const& rIStm) + : m_rData(rData) + , m_eOrigCharSet(m_rData.meActualCharSet) + { + ++m_rData.mnParseDepth; + m_rData.meActualCharSet = rIStm.GetStreamCharSet(); + } + bool TooDeep() const { return m_rData.mnParseDepth > 1024; } + ~DepthGuard() + { + --m_rData.mnParseDepth; + m_rData.meActualCharSet = m_eOrigCharSet; + } +}; +} + +SvmReader::SvmReader(SvStream& rIStm) + : mrStream(rIStm) +{ +} + +SvStream& SvmReader::Read(GDIMetaFile& rMetaFile, ImplMetaReadData* pData) +{ + if (mrStream.GetError()) + { + SAL_WARN("vcl.gdi", "Stream error: " << mrStream.GetError()); + return mrStream; + } + + sal_uLong nStmPos = mrStream.Tell(); + SvStreamEndian nOldFormat = mrStream.GetEndian(); + + mrStream.SetEndian(SvStreamEndian::LITTLE); + + try + { + char aId[7]; + aId[0] = 0; + aId[6] = 0; + mrStream.ReadBytes(aId, 6); + if (!strcmp(aId, "VCLMTF")) + { + // new format + sal_uInt32 nStmCompressMode = 0; + sal_uInt32 nCount = 0; + std::unique_ptr<VersionCompatRead> pCompat(new VersionCompatRead(mrStream)); + + mrStream.ReadUInt32(nStmCompressMode); + TypeSerializer aSerializer(mrStream); + MapMode aMapMode; + aSerializer.readMapMode(aMapMode); + rMetaFile.SetPrefMapMode(aMapMode); + Size aSize; + aSerializer.readSize(aSize); + rMetaFile.SetPrefSize(aSize); + mrStream.ReadUInt32(nCount); + + pCompat.reset(); // destructor writes stuff into the header + + std::unique_ptr<ImplMetaReadData> xReadData; + if (!pData) + { + xReadData.reset(new ImplMetaReadData); + pData = xReadData.get(); + } + DepthGuard aDepthGuard(*pData, mrStream); + + if (aDepthGuard.TooDeep()) + throw std::runtime_error("too much recursion"); + + for (sal_uInt32 nAction = 0; (nAction < nCount) && !mrStream.eof(); nAction++) + { + rtl::Reference<MetaAction> pAction = MetaActionHandler(pData); + if (pAction) + { + if (pAction->GetType() == MetaActionType::COMMENT) + { + MetaCommentAction* pCommentAct + = static_cast<MetaCommentAction*>(pAction.get()); + + if (pCommentAct->GetComment() == "EMF_PLUS") + rMetaFile.UseCanvas(true); + } + rMetaFile.AddAction(pAction); + } + } + } + else + { + mrStream.Seek(nStmPos); + SVMConverter(mrStream, rMetaFile); + } + } + catch (...) + { + SAL_WARN("vcl", "GDIMetaFile exception during load"); + mrStream.SetError(SVSTREAM_FILEFORMAT_ERROR); + }; + + // check for errors + if (mrStream.GetError()) + { + rMetaFile.Clear(); + mrStream.Seek(nStmPos); + } + + mrStream.SetEndian(nOldFormat); + return mrStream; +} + +rtl::Reference<MetaAction> SvmReader::MetaActionHandler(ImplMetaReadData* pData) +{ + rtl::Reference<MetaAction> pAction; + sal_uInt16 nTmp = 0; + mrStream.ReadUInt16(nTmp); + MetaActionType nType = static_cast<MetaActionType>(nTmp); + + switch (nType) + { + case MetaActionType::NONE: + pAction = new MetaAction; + break; + case MetaActionType::PIXEL: + pAction = new MetaPixelAction; + break; + case MetaActionType::POINT: + pAction = new MetaPointAction; + break; + case MetaActionType::LINE: + pAction = new MetaLineAction; + break; + case MetaActionType::RECT: + pAction = new MetaRectAction; + break; + case MetaActionType::ROUNDRECT: + pAction = new MetaRoundRectAction; + break; + case MetaActionType::ELLIPSE: + pAction = new MetaEllipseAction; + break; + case MetaActionType::ARC: + pAction = new MetaArcAction; + break; + case MetaActionType::PIE: + pAction = new MetaPieAction; + break; + case MetaActionType::CHORD: + pAction = new MetaChordAction; + break; + case MetaActionType::POLYLINE: + pAction = new MetaPolyLineAction; + break; + case MetaActionType::POLYGON: + pAction = new MetaPolygonAction; + break; + case MetaActionType::POLYPOLYGON: + pAction = new MetaPolyPolygonAction; + break; + case MetaActionType::TEXT: + pAction = new MetaTextAction; + break; + case MetaActionType::TEXTARRAY: + pAction = new MetaTextArrayAction; + break; + case MetaActionType::STRETCHTEXT: + pAction = new MetaStretchTextAction; + break; + case MetaActionType::TEXTRECT: + pAction = new MetaTextRectAction; + break; + case MetaActionType::TEXTLINE: + pAction = new MetaTextLineAction; + break; + case MetaActionType::BMP: + pAction = new MetaBmpAction; + break; + case MetaActionType::BMPSCALE: + pAction = new MetaBmpScaleAction; + break; + case MetaActionType::BMPSCALEPART: + pAction = new MetaBmpScalePartAction; + break; + case MetaActionType::BMPEX: + pAction = new MetaBmpExAction; + break; + case MetaActionType::BMPEXSCALE: + pAction = new MetaBmpExScaleAction; + break; + case MetaActionType::BMPEXSCALEPART: + pAction = new MetaBmpExScalePartAction; + break; + case MetaActionType::MASK: + pAction = new MetaMaskAction; + break; + case MetaActionType::MASKSCALE: + pAction = new MetaMaskScaleAction; + break; + case MetaActionType::MASKSCALEPART: + pAction = new MetaMaskScalePartAction; + break; + case MetaActionType::GRADIENT: + pAction = new MetaGradientAction; + break; + case MetaActionType::GRADIENTEX: + pAction = new MetaGradientExAction; + break; + case MetaActionType::HATCH: + pAction = new MetaHatchAction; + break; + case MetaActionType::WALLPAPER: + pAction = new MetaWallpaperAction; + break; + case MetaActionType::CLIPREGION: + pAction = new MetaClipRegionAction; + break; + case MetaActionType::ISECTRECTCLIPREGION: + pAction = new MetaISectRectClipRegionAction; + break; + case MetaActionType::ISECTREGIONCLIPREGION: + pAction = new MetaISectRegionClipRegionAction; + break; + case MetaActionType::MOVECLIPREGION: + pAction = new MetaMoveClipRegionAction; + break; + case MetaActionType::LINECOLOR: + pAction = new MetaLineColorAction; + break; + case MetaActionType::FILLCOLOR: + pAction = new MetaFillColorAction; + break; + case MetaActionType::TEXTCOLOR: + pAction = new MetaTextColorAction; + break; + case MetaActionType::TEXTFILLCOLOR: + pAction = new MetaTextFillColorAction; + break; + case MetaActionType::TEXTLINECOLOR: + pAction = new MetaTextLineColorAction; + break; + case MetaActionType::OVERLINECOLOR: + pAction = new MetaOverlineColorAction; + break; + case MetaActionType::TEXTALIGN: + pAction = new MetaTextAlignAction; + break; + case MetaActionType::MAPMODE: + pAction = new MetaMapModeAction; + break; + case MetaActionType::FONT: + pAction = new MetaFontAction; + break; + case MetaActionType::PUSH: + pAction = new MetaPushAction; + break; + case MetaActionType::POP: + pAction = new MetaPopAction; + break; + case MetaActionType::RASTEROP: + pAction = new MetaRasterOpAction; + break; + case MetaActionType::Transparent: + pAction = new MetaTransparentAction; + break; + case MetaActionType::FLOATTRANSPARENT: + pAction = new MetaFloatTransparentAction; + break; + case MetaActionType::EPS: + pAction = new MetaEPSAction; + break; + case MetaActionType::REFPOINT: + pAction = new MetaRefPointAction; + break; + case MetaActionType::COMMENT: + pAction = new MetaCommentAction; + break; + case MetaActionType::LAYOUTMODE: + pAction = new MetaLayoutModeAction; + break; + case MetaActionType::TEXTLANGUAGE: + pAction = new MetaTextLanguageAction; + break; + + default: + { + VersionCompatRead aCompat(mrStream); + } + break; + } + + if (pAction) + pAction->Read(mrStream, pData); + + return pAction; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits