You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/filters/karbon/wmf/wmfexport.cpp

264 lines
6.7 KiB

/* This file is part of the KDE project
* Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <config.h>
#include <tqdom.h>
#include <tqcstring.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <KoFilterChain.h>
#include <KoStore.h>
#include <KoStoreDevice.h>
#include "vdocument.h"
#include "vcolor.h"
#include "vcomposite.h"
#include "vdashpattern.h"
#include "vdocument.h"
#include "vlayer.h"
#include "vpath.h"
#include "vsegment.h"
#include "vfill.h"
#include "vstroke.h"
#include "vtext.h"
#include "vflattencmd.h"
#include "wmfexport.h"
#include "kowmfwrite.h"
/*
TODO: bs.wmf stroke in red with MSword and in brown with Kword ??
*/
typedef KGenericFactory<WmfExport, KoFilter> WmfExportFactory;
K_EXPORT_COMPONENT_FACTORY( libwmfexport, WmfExportFactory( "kofficefilters" ) )
WmfExport::WmfExport( KoFilter *, const char *, const TQStringList&) :
KoFilter()
{
}
WmfExport::~WmfExport()
{
}
KoFilter::ConversionStatus WmfExport::convert( const TQCString& from, const TQCString& to )
{
if( to != "image/x-wmf" || from != "application/x-karbon" ) {
return KoFilter::NotImplemented;
}
KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read );
if( !storeIn ) {
return KoFilter::StupidError;
}
// open Placeable Wmf file
mWmf = new KoWmfWrite( m_chain->outputFile() );
if( !mWmf->begin() ) {
delete mWmf;
return KoFilter::WrongFormat;
}
TQDomDocument domIn;
domIn.setContent( storeIn );
TQDomElement docNode = domIn.documentElement();
// Load the document.
mDoc = new VDocument;
mDoc->load( docNode );
// Process the document.
mDoc->accept( *this );
mWmf->end();
delete mWmf;
delete mDoc;
return KoFilter::OK;
}
void WmfExport::visitVDocument( VDocument& document ) {
int width;
int height;
mDoc = &document;
mListPa.setAutoDelete( true );
// resolution
mDpi = 1000;
width = (int)(POINT_TO_INCH( document.width() ) * mDpi);
height = (int)(POINT_TO_INCH( document.height() ) * mDpi);
mWmf->setDefaultDpi( mDpi );
mWmf->setWindow( 0, 0, width, height );
if ( (document.width() != 0) && (document.height() != 0) ) {
mScaleX = (double)width / document.width();
mScaleY = (double)height / document.height();
}
// Export layers.
VVisitor::visitVDocument( document );
}
void WmfExport::visitVPath( VPath& composite ) {
TQPen pen;
TQBrush brush;
getPen( pen, composite.stroke() );
getBrush( brush, composite.fill() );
VVisitor::visitVPath( composite );
if ( mListPa.count() > 0 ) {
mWmf->setPen( pen );
if( (brush.style() == TQt::NoBrush)
&& (mListPa.count() == 1) ) {
mWmf->drawPolyline( *mListPa.first() );
}
else {
mWmf->setBrush( brush );
if ( mListPa.count() == 1 ) {
mWmf->drawPolygon( *mListPa.first() );
}
else {
// combined path
mWmf->drawPolyPolygon( mListPa );
}
}
}
mListPa.clear();
}
// Export segment.
void WmfExport::visitVSubpath( VSubpath& path ) {
VSubpath *newPath;
VSubpathIterator itr( path );
VFlattenCmd cmd( 0L, INCH_TO_POINT(0.3 / (double)mDpi) );
TQPointArray *pa = new TQPointArray( path.count() );
int nbrPoint=0; // number of points in the path
for( ; itr.current(); ++itr ) {
VSegment *segment= itr.current();
if (segment->isCurve()) {
newPath = new VSubpath( mDoc );
// newPath duplicate the list of curve
newPath->moveTo( itr.current()->prev()->knot() );
newPath->append( itr.current()->clone() );
while( itr.current()->next() ) {
if ( itr.current()->next()->isCurve() ) {
newPath->append( itr.current()->next()->clone() );
}
else {
break;
}
++itr;
}
// flatten the curve
cmd.visit( *newPath );
// adjust the number of points
pa->resize( pa->size() + newPath->count() - 2 );
// Ommit the first segment and insert points
newPath->first();
while( newPath->next() ) {
pa->setPoint( nbrPoint++, coordX( newPath->current()->knot().x() ),
coordY( newPath->current()->knot().y() ) );
}
delete newPath;
} else if (segment->isLine()) {
pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ),
coordY( itr.current()->knot().y() ) );
} else if (segment->isBegin()) {
// start a new polygon
pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ),
coordY( itr.current()->knot().y() ) );
}
}
// adjust the number of points
if ( nbrPoint > 1 ) {
pa->resize( nbrPoint );
mListPa.append( pa );
}
else {
delete pa;
// TODO: check why we have empty path
kdDebug() << "WmfExport::visitVSubpath : Empty path ?" << endl;
}
}
void WmfExport::visitVText( VText& text ) {
// TODO: export text
visitVSubpath( text.basePath() );
}
void WmfExport::getBrush( TQBrush& brush, const VFill *fill ) {
if( (fill->type() == VFill::solid) || (fill->type() == VFill::grad)
|| (fill->type() == VFill::patt) ) {
if ( fill->color().opacity() < 0.1 ) {
brush.setStyle( TQt::NoBrush );
}
else {
brush.setStyle( TQt::SolidPattern );
brush.setColor( fill->color() );
}
}
else {
brush.setStyle( TQt::NoBrush );
}
}
void WmfExport::getPen( TQPen& pen, const VStroke *stroke ) {
if( (stroke->type() == VStroke::solid) || (stroke->type() == VStroke::grad)
|| (stroke->type() == VStroke::patt) ) {
// TODO : Dash pattern.
if ( stroke->lineCap() == VStroke::capRound ) {
pen.setCapStyle( TQt::RoundCap );
}
else {
pen.setCapStyle( TQt::SquareCap );
}
pen.setStyle( TQt::SolidLine );
pen.setColor( stroke->color() );
pen.setWidth( coordX( stroke->lineWidth() ) );
}
else {
pen.setStyle( TQt::NoPen );
}
}
#include <wmfexport.moc>