/* -*- 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 #include #include #include #include #include #include #include #include #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_uInt64 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 (mrStream.good() && !strcmp(aId, "VCLMTF")) { // new format sal_uInt32 nStmCompressMode = 0; sal_uInt32 nCount = 0; std::unique_ptr 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 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 pAction = MetaActionHandler(pData); if (pAction) { if (pAction->GetType() == MetaActionType::COMMENT) { MetaCommentAction* pCommentAct = static_cast(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 SvmReader::MetaActionHandler(ImplMetaReadData* pData) { rtl::Reference pAction; sal_uInt16 nTmp = 0; mrStream.ReadUInt16(nTmp); MetaActionType nType = static_cast(nTmp); switch (nType) { case MetaActionType::NONE: return DefaultHandler(); case MetaActionType::PIXEL: return PixelHandler(); case MetaActionType::POINT: return PointHandler(); case MetaActionType::LINE: return LineHandler(); case MetaActionType::RECT: return RectHandler(); case MetaActionType::ROUNDRECT: return RoundRectHandler(); case MetaActionType::ELLIPSE: return EllipseHandler(); case MetaActionType::ARC: return ArcHandler(); case MetaActionType::PIE: return PieHandler(); case MetaActionType::CHORD: return ChordHandler(); case MetaActionType::POLYLINE: return PolyLineHandler(); case MetaActionType::POLYGON: return PolygonHandler(); case MetaActionType::POLYPOLYGON: return PolyPolygonHandler(); case MetaActionType::TEXT: return TextHandler(pData); case MetaActionType::TEXTARRAY: return TextArrayHandler(pData); case MetaActionType::STRETCHTEXT: return StretchTextHandler(pData); case MetaActionType::TEXTRECT: return TextRectHandler(pData); case MetaActionType::TEXTLINE: return TextLineHandler(); case MetaActionType::BMP: return BmpHandler(); case MetaActionType::BMPSCALE: return BmpScaleHandler(); case MetaActionType::BMPSCALEPART: return BmpScalePartHandler(); case MetaActionType::BMPEX: return BmpExHandler(); case MetaActionType::BMPEXSCALE: return BmpExScaleHandler(); case MetaActionType::BMPEXSCALEPART: return BmpExScalePartHandler(); case MetaActionType::MASK: return MaskHandler(); case MetaActionType::MASKSCALE: return MaskScaleHandler(); case MetaActionType::MASKSCALEPART: return MaskScalePartHandler(); case MetaActionType::GRADIENT: return GradientHandler(); case MetaActionType::GRADIENTEX: return GradientExHandler(); case MetaActionType::HATCH: return HatchHandler(); case MetaActionType::WALLPAPER: return WallpaperHandler(); case MetaActionType::CLIPREGION: return ClipRegionHandler(); case MetaActionType::ISECTRECTCLIPREGION: return ISectRectClipRegionHandler(); case MetaActionType::ISECTREGIONCLIPREGION: return ISectRegionClipRegionHandler(); case MetaActionType::MOVECLIPREGION: return MoveClipRegionHandler(); case MetaActionType::LINECOLOR: return LineColorHandler(); case MetaActionType::FILLCOLOR: return FillColorHandler(); case MetaActionType::TEXTCOLOR: return TextColorHandler(); case MetaActionType::TEXTFILLCOLOR: return TextFillColorHandler(); case MetaActionType::TEXTLINECOLOR: return TextLineColorHandler(); case MetaActionType::OVERLINECOLOR: return OverlineColorHandler(); case MetaActionType::TEXTALIGN: return TextAlignHandler(); case MetaActionType::MAPMODE: return MapModeHandler(); case MetaActionType::FONT: return FontHandler(pData); case MetaActionType::PUSH: return PushHandler(); case MetaActionType::POP: return PopHandler(); case MetaActionType::RASTEROP: return RasterOpHandler(); case MetaActionType::Transparent: return TransparentHandler(); case MetaActionType::FLOATTRANSPARENT: return FloatTransparentHandler(pData); case MetaActionType::EPS: return EPSHandler(); case MetaActionType::REFPOINT: return RefPointHandler(); case MetaActionType::COMMENT: return CommentHandler(); case MetaActionType::LAYOUTMODE: return LayoutModeHandler(); case MetaActionType::TEXTLANGUAGE: return TextLanguageHandler(); default: { VersionCompatRead aCompat(mrStream); } break; } return pAction; } void SvmReader::ReadColor(Color& rColor) { sal_uInt32 nTmp(0); mrStream.ReadUInt32(nTmp); rColor = ::Color(ColorTransparency, nTmp); } rtl::Reference SvmReader::LineColorHandler() { rtl::Reference pAction(new MetaLineColorAction); VersionCompatRead aCompat(mrStream); Color aColor; ReadColor(aColor); bool aBool(false); mrStream.ReadCharAsBool(aBool); pAction->SetSetting(aBool); pAction->SetColor(aColor); return pAction; } rtl::Reference SvmReader::FillColorHandler() { rtl::Reference pAction(new MetaFillColorAction); VersionCompatRead aCompat(mrStream); Color aColor; ReadColor(aColor); bool aBool(false); mrStream.ReadCharAsBool(aBool); pAction->SetColor(aColor); pAction->SetSetting(aBool); return pAction; } rtl::Reference SvmReader::RectHandler() { rtl::Reference pAction(new MetaRectAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRectangle; aSerializer.readRectangle(aRectangle); pAction->SetRect(aRectangle); return pAction; } rtl::Reference SvmReader::PointHandler() { rtl::Reference pAction(new MetaPointAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); pAction->SetPoint(aPoint); return pAction; } rtl::Reference SvmReader::PixelHandler() { rtl::Reference pAction(new MetaPixelAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); Color aColor; ReadColor(aColor); pAction->SetPoint(aPoint); pAction->SetColor(aColor); return pAction; } rtl::Reference SvmReader::LineHandler() { rtl::Reference pAction(new MetaLineAction); VersionCompatRead aCompat(mrStream); // Version 1 TypeSerializer aSerializer(mrStream); Point aPoint; Point aEndPoint; aSerializer.readPoint(aPoint); aSerializer.readPoint(aEndPoint); pAction->SetStartPoint(aPoint); pAction->SetEndPoint(aEndPoint); // Version 2 if (aCompat.GetVersion() >= 2) { LineInfo aLineInfo; ReadLineInfo(mrStream, aLineInfo); pAction->SetLineInfo(aLineInfo); } return pAction; } rtl::Reference SvmReader::RoundRectHandler() { rtl::Reference pAction(new MetaRoundRectAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRectangle; aSerializer.readRectangle(aRectangle); sal_uInt32 HorzRound(0); sal_uInt32 VertRound(0); mrStream.ReadUInt32(HorzRound).ReadUInt32(VertRound); pAction->SetRect(aRectangle); pAction->SetHorzRound(HorzRound); pAction->SetVertRound(VertRound); return pAction; } rtl::Reference SvmReader::EllipseHandler() { rtl::Reference pAction(new MetaEllipseAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRectangle; aSerializer.readRectangle(aRectangle); pAction->SetRect(aRectangle); return pAction; } rtl::Reference SvmReader::ArcHandler() { rtl::Reference pAction(new MetaArcAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRectangle; aSerializer.readRectangle(aRectangle); Point aPoint; aSerializer.readPoint(aPoint); Point aEndPoint; aSerializer.readPoint(aEndPoint); pAction->SetRect(aRectangle); pAction->SetStartPoint(aPoint); pAction->SetEndPoint(aEndPoint); return pAction; } rtl::Reference SvmReader::PieHandler() { rtl::Reference pAction(new MetaPieAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRectangle; aSerializer.readRectangle(aRectangle); Point aPoint; aSerializer.readPoint(aPoint); Point aEndPoint; aSerializer.readPoint(aEndPoint); pAction->SetRect(aRectangle); pAction->SetStartPoint(aPoint); pAction->SetEndPoint(aEndPoint); return pAction; } rtl::Reference SvmReader::ChordHandler() { rtl::Reference pAction(new MetaChordAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRectangle; aSerializer.readRectangle(aRectangle); Point aPoint; aSerializer.readPoint(aPoint); Point aEndPoint; aSerializer.readPoint(aEndPoint); pAction->SetRect(aRectangle); pAction->SetStartPoint(aPoint); pAction->SetEndPoint(aEndPoint); return pAction; } rtl::Reference SvmReader::PolyLineHandler() { rtl::Reference pAction(new MetaPolyLineAction); VersionCompatRead aCompat(mrStream); // Version 1 tools::Polygon aPolygon; ReadPolygon(mrStream, aPolygon); // Version 2 if (aCompat.GetVersion() >= 2) { LineInfo aLineInfo; ReadLineInfo(mrStream, aLineInfo); pAction->SetLineInfo(aLineInfo); } if (aCompat.GetVersion() >= 3) { sal_uInt8 bHasPolyFlags(0); mrStream.ReadUChar(bHasPolyFlags); if (bHasPolyFlags) aPolygon.Read(mrStream); } pAction->SetPolygon(aPolygon); return pAction; } rtl::Reference SvmReader::PolygonHandler() { rtl::Reference pAction(new MetaPolygonAction); VersionCompatRead aCompat(mrStream); tools::Polygon aPolygon; ReadPolygon(mrStream, aPolygon); // Version 1 if (aCompat.GetVersion() >= 2) // Version 2 { sal_uInt8 bHasPolyFlags(0); mrStream.ReadUChar(bHasPolyFlags); if (bHasPolyFlags) aPolygon.Read(mrStream); } pAction->SetPolygon(aPolygon); return pAction; } rtl::Reference SvmReader::PolyPolygonHandler() { rtl::Reference pAction(new MetaPolyPolygonAction); VersionCompatRead aCompat(mrStream); tools::PolyPolygon aPolyPolygon; ReadPolyPolygon(mrStream, aPolyPolygon); // Version 1 if (aCompat.GetVersion() < 2) // Version 2 { pAction->SetPolyPolygon(aPolyPolygon); return pAction; } sal_uInt16 nNumberOfComplexPolygons(0); mrStream.ReadUInt16(nNumberOfComplexPolygons); const size_t nMinRecordSize = sizeof(sal_uInt16); const size_t nMaxRecords = mrStream.remainingSize() / nMinRecordSize; if (nNumberOfComplexPolygons > nMaxRecords) { SAL_WARN("vcl.gdi", "Parsing error: " << nMaxRecords << " max possible entries, but " << nNumberOfComplexPolygons << " claimed, truncating"); nNumberOfComplexPolygons = nMaxRecords; } for (sal_uInt16 i = 0; i < nNumberOfComplexPolygons; ++i) { sal_uInt16 nIndex(0); mrStream.ReadUInt16(nIndex); tools::Polygon aPoly; aPoly.Read(mrStream); if (nIndex >= aPolyPolygon.Count()) { SAL_WARN("vcl.gdi", "svm contains polygon index " << nIndex << " outside possible range " << aPolyPolygon.Count()); continue; } aPolyPolygon.Replace(aPoly, nIndex); } pAction->SetPolyPolygon(aPolyPolygon); return pAction; } rtl::Reference SvmReader::TextHandler(const ImplMetaReadData* pData) { rtl::Reference pAction(new MetaTextAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); OUString aStr = mrStream.ReadUniOrByteString(pData->meActualCharSet); sal_uInt16 nTmpIndex(0); mrStream.ReadUInt16(nTmpIndex); sal_uInt16 nTmpLen(0); mrStream.ReadUInt16(nTmpLen); pAction->SetPoint(aPoint); if (aCompat.GetVersion() >= 2) // Version 2 aStr = read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream); if (nTmpIndex > aStr.getLength()) { SAL_WARN("vcl.gdi", "inconsistent offset"); nTmpIndex = aStr.getLength(); } if (nTmpLen > aStr.getLength() - nTmpIndex) { SAL_WARN("vcl.gdi", "inconsistent len"); nTmpLen = aStr.getLength() - nTmpIndex; } pAction->SetIndex(nTmpIndex); pAction->SetLen(nTmpLen); pAction->SetText(aStr); return pAction; } rtl::Reference SvmReader::TextArrayHandler(const ImplMetaReadData* pData) { rtl::Reference pAction(new MetaTextArrayAction); std::vector aArray; VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); pAction->SetPoint(aPoint); OUString aStr = mrStream.ReadUniOrByteString(pData->meActualCharSet); pAction->SetText(aStr); sal_uInt16 nTmpIndex(0); mrStream.ReadUInt16(nTmpIndex); sal_uInt16 nTmpLen(0); mrStream.ReadUInt16(nTmpLen); sal_Int32 nAryLen(0); mrStream.ReadInt32(nAryLen); if (nTmpLen > aStr.getLength() - nTmpIndex) { SAL_WARN("vcl.gdi", "inconsistent offset and len"); pAction->SetIndex(0); pAction->SetLen(aStr.getLength()); return pAction; } pAction->SetIndex(nTmpIndex); pAction->SetLen(nTmpLen); if (nAryLen) { // #i9762#, #106172# Ensure that DX array is at least mnLen entries long if (nTmpLen >= nAryLen) { try { aArray.resize(nTmpLen); sal_Int32 i; sal_Int32 val(0); for (i = 0; i < nAryLen; i++) { mrStream.ReadInt32(val); aArray[i] = val; } // #106172# setup remainder for (; i < nTmpLen; i++) aArray[i] = 0; } catch (std::bad_alloc&) { } } else { return pAction; } } if (aCompat.GetVersion() >= 2) // Version 2 { aStr = read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream); pAction->SetText(aStr); if (nTmpLen > aStr.getLength() - nTmpIndex) { SAL_WARN("vcl.gdi", "inconsistent offset and len"); pAction->SetIndex(0); pAction->SetLen(aStr.getLength()); aArray.clear(); } } if (!aArray.empty()) pAction->SetDXArray(std::move(aArray)); return pAction; } rtl::Reference SvmReader::StretchTextHandler(const ImplMetaReadData* pData) { rtl::Reference pAction(new MetaStretchTextAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); OUString aStr = mrStream.ReadUniOrByteString(pData->meActualCharSet); sal_uInt32 nTmpWidth(0); mrStream.ReadUInt32(nTmpWidth); sal_uInt16 nTmpIndex(0); mrStream.ReadUInt16(nTmpIndex); sal_uInt16 nTmpLen(0); mrStream.ReadUInt16(nTmpLen); pAction->SetPoint(aPoint); pAction->SetWidth(nTmpWidth); if (aCompat.GetVersion() >= 2) // Version 2 aStr = read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream); if (nTmpIndex > aStr.getLength()) { SAL_WARN("vcl.gdi", "inconsistent offset"); nTmpIndex = aStr.getLength(); } if (nTmpLen > aStr.getLength() - nTmpIndex) { SAL_WARN("vcl.gdi", "inconsistent len"); nTmpLen = aStr.getLength() - nTmpIndex; } pAction->SetIndex(nTmpIndex); pAction->SetLen(nTmpLen); pAction->SetText(aStr); return pAction; } rtl::Reference SvmReader::TextRectHandler(const ImplMetaReadData* pData) { rtl::Reference pAction(new MetaTextRectAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRect; aSerializer.readRectangle(aRect); OUString aStr = mrStream.ReadUniOrByteString(pData->meActualCharSet); sal_uInt16 nTmp(0); mrStream.ReadUInt16(nTmp); pAction->SetRect(aRect); pAction->SetStyle(static_cast(nTmp)); if (aCompat.GetVersion() >= 2) // Version 2 aStr = read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream); pAction->SetText(aStr); return pAction; } rtl::Reference SvmReader::TextLineHandler() { rtl::Reference pAction(new MetaTextLineAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aPos; aSerializer.readPoint(aPos); sal_Int32 nTempWidth(0); mrStream.ReadInt32(nTempWidth); pAction->SetStartPoint(aPos); pAction->SetWidth(nTempWidth); sal_uInt32 nTempStrikeout(0); mrStream.ReadUInt32(nTempStrikeout); sal_uInt32 nTempUnderline(0); mrStream.ReadUInt32(nTempUnderline); pAction->SetStrikeout(static_cast(nTempStrikeout & SAL_MAX_ENUM)); pAction->SetUnderline(static_cast(nTempUnderline & SAL_MAX_ENUM)); if (aCompat.GetVersion() >= 2) { sal_uInt32 nTempOverline(0); mrStream.ReadUInt32(nTempOverline); pAction->SetOverline(static_cast(nTempOverline & SAL_MAX_ENUM)); } return pAction; } rtl::Reference SvmReader::BmpHandler() { rtl::Reference pAction(new MetaBmpAction); VersionCompatRead aCompat(mrStream); Bitmap aBmp; ReadDIB(aBmp, mrStream, true); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); pAction->SetBitmap(aBmp); pAction->SetPoint(aPoint); return pAction; } namespace { void sanitizeNegativeSizeDimensions(Size& rSize) { if (rSize.Width() < 0) { SAL_WARN("vcl.gdi", "sanitizeNegativeSizeDimensions: negative width"); rSize.setWidth(0); } if (rSize.Height() < 0) { SAL_WARN("vcl.gdi", "sanitizeNegativeSizeDimensions: negative height"); rSize.setHeight(0); } } } rtl::Reference SvmReader::BmpScaleHandler() { rtl::Reference pAction(new MetaBmpScaleAction); VersionCompatRead aCompat(mrStream); Bitmap aBmp; ReadDIB(aBmp, mrStream, true); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); Size aSz; aSerializer.readSize(aSz); sanitizeNegativeSizeDimensions(aSz); pAction->SetBitmap(aBmp); pAction->SetPoint(aPoint); pAction->SetSize(aSz); return pAction; } rtl::Reference SvmReader::BmpScalePartHandler() { rtl::Reference pAction(new MetaBmpScalePartAction); VersionCompatRead aCompat(mrStream); Bitmap aBmp; ReadDIB(aBmp, mrStream, true); TypeSerializer aSerializer(mrStream); Point aDestPoint; aSerializer.readPoint(aDestPoint); Size aDestSize; aSerializer.readSize(aDestSize); Point aSrcPoint; aSerializer.readPoint(aSrcPoint); Size aSrcSize; aSerializer.readSize(aSrcSize); pAction->SetBitmap(aBmp); pAction->SetDestPoint(aDestPoint); pAction->SetDestSize(aDestSize); pAction->SetSrcPoint(aSrcPoint); pAction->SetSrcSize(aSrcSize); return pAction; } rtl::Reference SvmReader::BmpExHandler() { rtl::Reference pAction(new MetaBmpExAction); VersionCompatRead aCompat(mrStream); BitmapEx aBmpEx; ReadDIBBitmapEx(aBmpEx, mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); pAction->SetPoint(aPoint); pAction->SetBitmapEx(aBmpEx); return pAction; } rtl::Reference SvmReader::BmpExScaleHandler() { rtl::Reference pAction(new MetaBmpExScaleAction); VersionCompatRead aCompat(mrStream); BitmapEx aBmpEx; ReadDIBBitmapEx(aBmpEx, mrStream); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); Size aSize; aSerializer.readSize(aSize); sanitizeNegativeSizeDimensions(aSize); pAction->SetBitmapEx(aBmpEx); pAction->SetPoint(aPoint); pAction->SetSize(aSize); return pAction; } rtl::Reference SvmReader::BmpExScalePartHandler() { rtl::Reference pAction(new MetaBmpExScalePartAction); VersionCompatRead aCompat(mrStream); BitmapEx aBmpEx; ReadDIBBitmapEx(aBmpEx, mrStream); TypeSerializer aSerializer(mrStream); Point aDstPoint; aSerializer.readPoint(aDstPoint); Size aDstSize; aSerializer.readSize(aDstSize); Point aSrcPoint; aSerializer.readPoint(aSrcPoint); Size aSrcSize; aSerializer.readSize(aSrcSize); pAction->SetBitmapEx(aBmpEx); pAction->SetDestPoint(aDstPoint); pAction->SetDestSize(aDstSize); pAction->SetSrcPoint(aSrcPoint); pAction->SetSrcSize(aSrcSize); return pAction; } rtl::Reference SvmReader::MaskHandler() { rtl::Reference pAction(new MetaMaskAction); VersionCompatRead aCompat(mrStream); Bitmap aBmp; ReadDIB(aBmp, mrStream, true); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); pAction->SetBitmap(aBmp); pAction->SetPoint(aPoint); return pAction; } rtl::Reference SvmReader::MaskScaleHandler() { rtl::Reference pAction(new MetaMaskScaleAction); VersionCompatRead aCompat(mrStream); Bitmap aBmp; ReadDIB(aBmp, mrStream, true); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); Size aSize; aSerializer.readSize(aSize); pAction->SetBitmap(aBmp); pAction->SetPoint(aPoint); pAction->SetSize(aSize); return pAction; } rtl::Reference SvmReader::MaskScalePartHandler() { rtl::Reference pAction(new MetaMaskScalePartAction); VersionCompatRead aCompat(mrStream); Bitmap aBmp; ReadDIB(aBmp, mrStream, true); Color aColor; ReadColor(aColor); TypeSerializer aSerializer(mrStream); Point aDstPt; aSerializer.readPoint(aDstPt); Size aDstSz; aSerializer.readSize(aDstSz); Point aSrcPt; aSerializer.readPoint(aSrcPt); Size aSrcSz; aSerializer.readSize(aSrcSz); pAction->SetBitmap(aBmp); pAction->SetColor(aColor); pAction->SetDestPoint(aDstPt); pAction->SetDestSize(aDstSz); pAction->SetSrcPoint(aSrcPt); pAction->SetSrcSize(aSrcSz); return pAction; } rtl::Reference SvmReader::GradientHandler() { rtl::Reference pAction(new MetaGradientAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRect; aSerializer.readRectangle(aRect); Gradient aGradient; aSerializer.readGradient(aGradient); pAction->SetRect(aRect); pAction->SetGradient(aGradient); return pAction; } rtl::Reference SvmReader::GradientExHandler() { rtl::Reference pAction(new MetaGradientExAction); VersionCompatRead aCompat(mrStream); tools::PolyPolygon aPolyPoly; ReadPolyPolygon(mrStream, aPolyPoly); TypeSerializer aSerializer(mrStream); Gradient aGradient; aSerializer.readGradient(aGradient); pAction->SetGradient(aGradient); pAction->SetPolyPolygon(aPolyPoly); return pAction; } rtl::Reference SvmReader::HatchHandler() { rtl::Reference pAction(new MetaHatchAction); VersionCompatRead aCompat(mrStream); tools::PolyPolygon aPolyPoly; ReadPolyPolygon(mrStream, aPolyPoly); Hatch aHatch; ReadHatch(mrStream, aHatch); pAction->SetPolyPolygon(aPolyPoly); pAction->SetHatch(aHatch); return pAction; } rtl::Reference SvmReader::WallpaperHandler() { rtl::Reference pAction(new MetaWallpaperAction); VersionCompatRead aCompat(mrStream); Wallpaper aWallpaper; ReadWallpaper(mrStream, aWallpaper); pAction->SetWallpaper(aWallpaper); return pAction; } rtl::Reference SvmReader::ClipRegionHandler() { rtl::Reference pAction(new MetaClipRegionAction); VersionCompatRead aCompat(mrStream); vcl::Region aRegion; ReadRegion(mrStream, aRegion); bool aClip(false); mrStream.ReadCharAsBool(aClip); pAction->SetRegion(aRegion); pAction->SetClipping(aClip); return pAction; } rtl::Reference SvmReader::ISectRectClipRegionHandler() { rtl::Reference pAction(new MetaISectRectClipRegionAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); tools::Rectangle aRect; aSerializer.readRectangle(aRect); pAction->SetRect(aRect); return pAction; } rtl::Reference SvmReader::ISectRegionClipRegionHandler() { rtl::Reference pAction(new MetaISectRegionClipRegionAction); VersionCompatRead aCompat(mrStream); vcl::Region aRegion; ReadRegion(mrStream, aRegion); pAction->SetRegion(aRegion); return pAction; } rtl::Reference SvmReader::MoveClipRegionHandler() { rtl::Reference pAction(new MetaMoveClipRegionAction); VersionCompatRead aCompat(mrStream); sal_Int32 nTmpHM(0), nTmpVM(0); mrStream.ReadInt32(nTmpHM).ReadInt32(nTmpVM); pAction->SetHorzMove(nTmpHM); pAction->SetVertMove(nTmpVM); return pAction; } rtl::Reference SvmReader::TextColorHandler() { rtl::Reference pAction(new MetaTextColorAction); VersionCompatRead aCompat(mrStream); Color aColor; ReadColor(aColor); pAction->SetColor(aColor); return pAction; } rtl::Reference SvmReader::TextFillColorHandler() { rtl::Reference pAction(new MetaTextFillColorAction); VersionCompatRead aCompat(mrStream); Color aColor; ReadColor(aColor); bool bSet(false); mrStream.ReadCharAsBool(bSet); pAction->SetColor(aColor); pAction->SetSetting(bSet); return pAction; } rtl::Reference SvmReader::TextLineColorHandler() { rtl::Reference pAction(new MetaTextLineColorAction); VersionCompatRead aCompat(mrStream); Color aColor; ReadColor(aColor); bool bSet(false); mrStream.ReadCharAsBool(bSet); pAction->SetColor(aColor); pAction->SetSetting(bSet); return pAction; } rtl::Reference SvmReader::OverlineColorHandler() { rtl::Reference pAction(new MetaOverlineColorAction); VersionCompatRead aCompat(mrStream); Color aColor; ReadColor(aColor); bool bSet(false); mrStream.ReadCharAsBool(bSet); pAction->SetColor(aColor); pAction->SetSetting(bSet); return pAction; } rtl::Reference SvmReader::TextAlignHandler() { rtl::Reference pAction(new MetaTextAlignAction); VersionCompatRead aCompat(mrStream); sal_uInt16 nTmp16(0); mrStream.ReadUInt16(nTmp16); pAction->SetTextAlign(static_cast(nTmp16)); return pAction; } rtl::Reference SvmReader::MapModeHandler() { rtl::Reference pAction(new MetaMapModeAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); MapMode aMapMode; aSerializer.readMapMode(aMapMode); pAction->SetMapMode(aMapMode); return pAction; } rtl::Reference SvmReader::FontHandler(ImplMetaReadData* pData) { rtl::Reference pAction(new MetaFontAction); VersionCompatRead aCompat(mrStream); vcl::Font aFont; ReadFont(mrStream, aFont); pData->meActualCharSet = aFont.GetCharSet(); if (pData->meActualCharSet == RTL_TEXTENCODING_DONTKNOW) pData->meActualCharSet = osl_getThreadTextEncoding(); pAction->SetFont(aFont); return pAction; } rtl::Reference SvmReader::PushHandler() { rtl::Reference pAction(new MetaPushAction); VersionCompatRead aCompat(mrStream); sal_uInt16 nTmp(0); mrStream.ReadUInt16(nTmp); pAction->SetPushFlags(static_cast(nTmp)); return pAction; } rtl::Reference SvmReader::PopHandler() { rtl::Reference pAction(new MetaPopAction); VersionCompatRead aCompat(mrStream); return pAction; } rtl::Reference SvmReader::RasterOpHandler() { rtl::Reference pAction(new MetaRasterOpAction); sal_uInt16 nTmp16(0); VersionCompatRead aCompat(mrStream); mrStream.ReadUInt16(nTmp16); pAction->SetRasterOp(static_cast(nTmp16)); return pAction; } rtl::Reference SvmReader::TransparentHandler() { rtl::Reference pAction(new MetaTransparentAction); VersionCompatRead aCompat(mrStream); tools::PolyPolygon aPolyPoly; ReadPolyPolygon(mrStream, aPolyPoly); sal_uInt16 nTransPercent(0); mrStream.ReadUInt16(nTransPercent); pAction->SetPolyPolygon(aPolyPoly); pAction->SetTransparence(nTransPercent); return pAction; } rtl::Reference SvmReader::FloatTransparentHandler(ImplMetaReadData* pData) { rtl::Reference pAction(new MetaFloatTransparentAction); VersionCompatRead aCompat(mrStream); GDIMetaFile aMtf; SvmReader aReader(mrStream); aReader.Read(aMtf, pData); TypeSerializer aSerializer(mrStream); Point aPoint; aSerializer.readPoint(aPoint); Size aSize; aSerializer.readSize(aSize); sanitizeNegativeSizeDimensions(aSize); Gradient aGradient; aSerializer.readGradient(aGradient); pAction->SetGDIMetaFile(aMtf); pAction->SetPoint(aPoint); pAction->SetSize(aSize); pAction->SetGradient(aGradient); return pAction; } rtl::Reference SvmReader::EPSHandler() { rtl::Reference pAction(new MetaEPSAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); GfxLink aGfxLink; aSerializer.readGfxLink(aGfxLink); Point aPoint; aSerializer.readPoint(aPoint); Size aSize; aSerializer.readSize(aSize); GDIMetaFile aSubst; Read(aSubst); pAction->SetLink(aGfxLink); pAction->SetPoint(aPoint); pAction->SetSize(aSize); pAction->SetSubstitute(aSubst); return pAction; } rtl::Reference SvmReader::RefPointHandler() { rtl::Reference pAction(new MetaRefPointAction); VersionCompatRead aCompat(mrStream); TypeSerializer aSerializer(mrStream); Point aRefPoint; aSerializer.readPoint(aRefPoint); bool bSet(false); mrStream.ReadCharAsBool(bSet); pAction->SetRefPoint(aRefPoint); pAction->SetSetting(bSet); return pAction; } rtl::Reference SvmReader::CommentHandler() { rtl::Reference pAction(new MetaCommentAction); VersionCompatRead aCompat(mrStream); OString aComment; aComment = read_uInt16_lenPrefixed_uInt8s_ToOString(mrStream); sal_Int32 nValue(0); sal_uInt32 nDataSize(0); mrStream.ReadInt32(nValue).ReadUInt32(nDataSize); if (nDataSize > mrStream.remainingSize()) { SAL_WARN("vcl.gdi", "Parsing error: " << mrStream.remainingSize() << " available data, but " << nDataSize << " claimed, truncating"); nDataSize = mrStream.remainingSize(); } SAL_INFO("vcl.gdi", "MetaCommentAction::Read " << aComment); std::unique_ptr pData; pData.reset(); if (nDataSize) { pData.reset(new sal_uInt8[nDataSize]); mrStream.ReadBytes(pData.get(), nDataSize); } pAction->SetComment(aComment); pAction->SetDataSize(nDataSize); pAction->SetValue(nValue); pAction->SetData(pData.get(), nDataSize); return pAction; } rtl::Reference SvmReader::LayoutModeHandler() { rtl::Reference pAction(new MetaLayoutModeAction); VersionCompatRead aCompat(mrStream); sal_uInt32 tmp(0); mrStream.ReadUInt32(tmp); pAction->SetLayoutMode(static_cast(tmp)); return pAction; } rtl::Reference SvmReader::TextLanguageHandler() { rtl::Reference pAction(new MetaTextLanguageAction); VersionCompatRead aCompat(mrStream); sal_uInt16 nTmp = 0; mrStream.ReadUInt16(nTmp); pAction->SetTextLanguage(static_cast(nTmp)); return pAction; } rtl::Reference SvmReader::DefaultHandler() { return rtl::Reference(new MetaAction); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */