diff options
Diffstat (limited to 'svtools/source/filter/filter.cxx')
-rw-r--r-- | svtools/source/filter/filter.cxx | 203 |
1 files changed, 136 insertions, 67 deletions
diff --git a/svtools/source/filter/filter.cxx b/svtools/source/filter/filter.cxx index 7065c89e0618..4db83cce97b9 100644 --- a/svtools/source/filter/filter.cxx +++ b/svtools/source/filter/filter.cxx @@ -1,30 +1,21 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. +/* + * This file is part of the LibreOffice project. * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. + * 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/. * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). + * This file incorporates work covered by the following license notice: * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ + * 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 <osl/mutex.hxx> #include <comphelper/processfactory.hxx> @@ -35,7 +26,7 @@ #include <vcl/salctype.hxx> #include <vcl/pngread.hxx> #include <vcl/pngwrite.hxx> -#include <vcl/svgread.hxx> +#include <vcl/svgdata.hxx> #include <vcl/virdev.hxx> #include <vcl/svapp.hxx> #include <osl/file.hxx> @@ -70,6 +61,7 @@ #include <rtl/bootstrap.hxx> #include <rtl/instance.hxx> #include <rtl/logfile.hxx> +#include <vcl/metaact.hxx> #include <vector> #include "SvFilterOptionsDialog.hxx" @@ -665,38 +657,97 @@ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtensio } //--------------------------- SVG ------------------------------------ - if( !bTest || ( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) ) + if( !bTest ) { - bSomethingTested=sal_True; + // check for Xml + if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<?xml", 256, 5 ) // is it xml + && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"version", 256, 7 )) // does it have a version (required for xml) + { + bool bIsSvg(false); - // just a simple test for the extension - if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) - return sal_True; + // check for DOCTYPE svg combination + if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"DOCTYPE", 256, 7 ) // 'DOCTYPE' is there + && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"svg", 256, 3 )) // 'svg' is there + { + bIsSvg = true; + } - sal_uLong nSize = ( nStreamLen > 1024 ) ? 1024 : nStreamLen; - std::vector<sal_uInt8> aBuf(nSize); + // check for svg element in 1st 256 bytes + if(!bIsSvg && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg' + { + bIsSvg = true; + } - rStream.Seek( nStreamPos ); - rStream.Read( &aBuf[0], nSize ); + if(!bIsSvg) + { + // it's a xml, look for '<svg' in full file. Should not happen too + // often since the tests above will handle most cases, but can happen + // with Svg files containing big comment headers or Svg as the host + // language + const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen); + sal_uInt8* pBuf = new sal_uInt8[nSize]; - // read the first 1024 bytes & check a few magic string - // constants (heuristically) - sal_Int8 aMagic1[] = {'<', 's', 'v', 'g'}; - if( std::search(aBuf.begin(), aBuf.end(), - aMagic1, aMagic1+SAL_N_ELEMENTS(aMagic1)) != aBuf.end() ) - { - rFormatExtension = rtl::OUString("SVG"); - return sal_True; - } + rStream.Seek(nStreamPos); + rStream.Read(pBuf, nSize); + + if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg' + { + bIsSvg = true; + } - sal_Int8 aMagic2[] = {'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ', 's', 'v', 'g'}; - if( std::search(aBuf.begin(), aBuf.end(), - aMagic2, aMagic2+SAL_N_ELEMENTS(aMagic2)) != aBuf.end() ) + delete[] pBuf; + } + + if(bIsSvg) + { + rFormatExtension = OUString( "SVG" ); + return sal_True; + } + } + else { - rFormatExtension = rtl::OUString("SVG"); - return sal_True; + // #119176# Svg files which have no xml header at all have shown up, + // detect those, too + bool bIsSvg(false); + + // check for svg element in 1st 256 bytes + if(ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg' + { + bIsSvg = true; + } + + if(!bIsSvg) + { + // look for '<svg' in full file. Should not happen too + // often since the tests above will handle most cases, but can happen + // with Svg files containing big comment headers or Svg as the host + // language + const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen); + sal_uInt8* pBuf = new sal_uInt8[nSize]; + + rStream.Seek(nStreamPos); + rStream.Read(pBuf, nSize); + + if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg' + { + bIsSvg = true; + } + + delete[] pBuf; + } + + if(bIsSvg) + { + rFormatExtension = OUString( "SVG" ); + return sal_True; + } } } + else if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) + { + bSomethingTested = sal_True; + return sal_True; + } //--------------------------- TGA ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) ) @@ -1560,18 +1611,38 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, if( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); - vcl::SVGReader aSVGReader( rIStream ); - GDIMetaFile aSVGMtf; + const sal_uInt32 nStmPos(rIStream.Tell()); + const sal_uInt32 nStmLen(rIStream.Seek(STREAM_SEEK_TO_END) - nStmPos); + bool bOkay(false); - if( 0 == aSVGReader.Read( aSVGMtf ).GetActionSize() ) + if(nStmLen) { - nStatus = GRFILTER_FILTERERROR; + SvgDataArray aNewData(new sal_uInt8[nStmLen]); + + rIStream.Seek(nStmPos); + rIStream.Read(aNewData.get(), nStmLen); + + if(!rIStream.GetError()) + { + SvgDataPtr aSvgDataPtr( + new SvgData( + aNewData, + nStmLen, + rPath)); + + rGraphic = Graphic(aSvgDataPtr); + bOkay = true; + } } - else + + if(bOkay) { - rGraphic = Graphic( aSVGMtf ); eLinkType = GFX_LINK_TYPE_NATIVE_SVG; } + else + { + nStatus = GRFILTER_FILTERERROR; + } } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) ) { @@ -1930,7 +2001,7 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& aMTF.SetPrefSize( aGraphic.GetPrefSize() ); aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() ); } - aMTF.Write( rOStm, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC ); + aMTF.Write( rOStm ); if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } @@ -2047,24 +2118,22 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& } else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) ) { - sal_Bool bDone = sal_False; + bool bDone(false); // do we have a native SVG RenderGraphic, whose data can be written directly? - if( ( GRAPHIC_GDIMETAFILE == eType ) && aGraphic.IsRenderGraphic() ) + const SvgDataPtr aSvgDataPtr(rGraphic.getSvgData()); + + if(aSvgDataPtr.get() && aSvgDataPtr->getSvgDataArrayLength()) { - const ::vcl::RenderGraphic aRenderGraphic( aGraphic.GetRenderGraphic() ); + rOStm.Write(aSvgDataPtr->getSvgDataArray().get(), aSvgDataPtr->getSvgDataArrayLength()); - if( aRenderGraphic.GetGraphicDataLength() && - aRenderGraphic.GetGraphicDataMimeType().equalsIgnoreAsciiCase( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) ) ) ) + if( rOStm.GetError() ) { - rOStm.Write( aRenderGraphic.GetGraphicData().get(), - aRenderGraphic.GetGraphicDataLength() ); - - if( rOStm.GetError() ) - { - nStatus = GRFILTER_IOERROR; - } + nStatus = GRFILTER_IOERROR; + } + else + { + bDone = true; } } |