summaryrefslogtreecommitdiff
path: root/svtools/source/filter/filter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/filter/filter.cxx')
-rw-r--r--svtools/source/filter/filter.cxx203
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;
}
}