Commit 40bc23c3 authored by Jan Hambrecht's avatar Jan Hambrecht

Implemented writing off pattern fill style. This requiered special

handling because the actual pattern images had to be written too.
So the KoShapeSavingContext now has functions to add the pixmaps and
write them later to the odf store. I added a helper class 
KoShapeStyleWriter for handling the shape style adding and writing of
the office:styles styles for convienience. Added a new StyleFillImage
style type to KoGenStyle for fill-image styles.


svn path=/trunk/koffice/; revision=694516
parent 614fc3ec
......@@ -74,6 +74,7 @@ set(flake_SRCS
KoShapeBorderRegistry.cpp
KoLineBorder.cpp
KoLineBorderFactory.cpp
KoShapeStyleWriter.cpp
commands/KoShapeGroupCommand.cpp
commands/KoShapeAlignCommand.cpp
commands/KoShapeBackgroundCommand.cpp
......
......@@ -36,11 +36,11 @@
#include "KoViewConverter.h"
#include "KoLineBorder.h"
#include "ShapeDeleter_p.h"
#include "KoShapeStyleWriter.h"
#include <KoXmlReader.h>
#include <KoXmlWriter.h>
#include <KoXmlNS.h>
#include <KoGenStyles.h>
#include <KoGenStyle.h>
#include <KoUnit.h>
#include <KoOasisStyles.h>
......@@ -636,22 +636,10 @@ QString KoShape::style( KoShapeSavingContext &context ) const
{
b->fillStyle( style, context );
}
QBrush bg( background() );
switch ( bg.style() )
{
case Qt::NoBrush:
style.addProperty( "draw:fill","none" );
break;
default:
KoOasisStyles::saveOasisFillStyle( style, context.mainStyles(), bg );
break;
}
if ( context.isSet( KoShapeSavingContext::AutoStyleInStyleXml ) ) {
style.setAutoStyleInStylesDotXml( true );
}
KoShapeStyleWriter styleWriter( context );
return context.mainStyles().lookup( style, context.isSet( KoShapeSavingContext::PresentationShape ) ? "pr" : "gr" );
return styleWriter.addFillStyle( style, background() );
}
bool KoShape::loadOdfAttributes( const KoXmlElement & element, KoShapeLoadingContext &context, int attributes )
......@@ -747,7 +735,7 @@ KoShapeBorderModel * KoShape::loadOdfStroke( const KoXmlElement & element, KoSha
if( styleStack.hasProperty( KoXmlNS::draw, "stroke" ) )
stroke = styleStack.property( KoXmlNS::draw, "stroke" );
}
else if( element.hasAttributeNS( KoXmlNS::draw, "style-name" ) )
else if( element.hasAttributeNS( KoXmlNS::presentation, "style-name" ) )
{
// fill the style stack with the shapes style
context.koLoadingContext().fillStyleStack( element, KoXmlNS::presentation, "style-name", "presentation" );
......@@ -761,7 +749,7 @@ KoShapeBorderModel * KoShape::loadOdfStroke( const KoXmlElement & element, KoSha
QPen pen = KoOasisStyles::loadOasisStrokeStyle( styleStack, stroke, context.koLoadingContext().oasisStyles() );
KoLineBorder * border = new KoLineBorder();
border->setLineWidth( pen.width() );
border->setLineWidth( pen.widthF() );
border->setColor( pen.color() );
border->setJoinStyle( pen.joinStyle() );
border->setLineStyle( pen.style(), pen.dashPattern() );
......
......@@ -25,6 +25,10 @@
#include <KoGenStyles.h>
#include <KoSavingContext.h>
#include <KoXmlWriter.h>
#include <KoStore.h>
#include <KoStoreDevice.h>
#include <kmimetype.h>
KoShapeSavingContext::KoShapeSavingContext( KoXmlWriter &xmlWriter, KoSavingContext &context )
: m_xmlWriter( &xmlWriter )
......@@ -111,3 +115,41 @@ void KoShapeSavingContext::saveLayerSet( KoXmlWriter * xmlWriter ) const
}
xmlWriter->endElement(); // draw:layer-set
}
QString KoShapeSavingContext::addImageForSaving( const QPixmap &pixmap )
{
QString filename = "Pictures/image" + QTime::currentTime().toString( "_hh_mm_ss_zzz.png" );
if( m_pixmaps.contains( filename ) )
{
int i = 1;
while( m_pixmaps.contains( filename + QString("_%1").arg( i ) ) )
i++;
filename += QString("_%1").arg( i );
}
m_pixmaps[filename] = pixmap;
return filename;
}
bool KoShapeSavingContext::saveImages( KoStore * store, KoXmlWriter * manifestWriter ) const
{
QString fileName("/tmp/temp.png");
// Find the mimetype only by the extension, not by file content (as the file is empty!)
const QString mimetype( KMimeType::findByPath( fileName, 0 ,true )->name() );
QMapIterator<QString, QPixmap> i( m_pixmaps );
while( i.hasNext() )
{
i.next();
if( store->open( i.key() ) )
{
KoStoreDevice dev(store);
if ( ! i.value().save(&dev, "PNG" ) )
return false; // e.g. bad image?
if ( !store->close() )
return false; // e.g. disk full
manifestWriter->addManifestEntry( i.key(), mimetype );
}
}
return true;
}
......@@ -33,6 +33,8 @@ class KoXmlWriter;
class KoSavingContext;
class KoGenStyles;
class KoShapeLayer;
class QPixmap;
class KoStore;
/**
* The set of data for the ODF file format used during saving of a shape.
......@@ -144,11 +146,24 @@ public:
*/
void saveLayerSet( KoXmlWriter * xmlWriter ) const;
/**
* Adds a pixmap for saving into the Pictures subfolder within the odf file
* @param pixmap the pixmap to save
* @return the filename of the pixmap to refer to
*/
QString addImageForSaving( const QPixmap &pixmap );
/**
* Saves images added with addImageForSaving to the store
*/
bool saveImages( KoStore *store, KoXmlWriter* manifestWriter ) const;
private:
KoXmlWriter *m_xmlWriter;
KoShapeSavingOptions m_savingOptions;
QMap<const KoShape *, QString> m_drawIds;
QList<const KoShapeLayer*> m_layers;
QMap<QString, QPixmap> m_pixmaps;
int m_drawId;
KoSavingContext &m_context;
......
/* This file is part of the KDE project
Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "KoShapeStyleWriter.h"
#include "KoShapeSavingContext.h"
#include "KoShape.h"
#include "KoShapeBorderModel.h"
#include <KoXmlWriter.h>
#include <KoGenStyle.h>
#include <KoGenStyles.h>
#include <KoOasisStyles.h>
KoShapeStyleWriter::KoShapeStyleWriter( KoShapeSavingContext &context )
: m_context( context )
{
}
QString KoShapeStyleWriter::addFillStyle( KoGenStyle &style, const QBrush &fill )
{
switch ( fill.style() )
{
case Qt::NoBrush:
style.addProperty( "draw:fill","none" );
break;
// the pattern style needs special handling regarding the saving of
// the pattern texture, os we handle that here
case Qt::TexturePattern:
style.addProperty( "draw:fill","bitmap" );
style.addProperty( "draw:fill-image-name", savePatternStyle( style, fill ) );
break;
default:
KoOasisStyles::saveOasisFillStyle( style, m_context.mainStyles(), fill );
break;
}
if ( m_context.isSet( KoShapeSavingContext::AutoStyleInStyleXml ) ) {
style.setAutoStyleInStylesDotXml( true );
}
return m_context.mainStyles().lookup( style, m_context.isSet( KoShapeSavingContext::PresentationShape ) ? "pr" : "gr" );
}
QString KoShapeStyleWriter::savePatternStyle( KoGenStyle &style, const QBrush &brush )
{
QPixmap texture = brush.texture();
QMatrix matrix = brush.matrix();
QSize size = texture.size();
style.addProperty( "style:repeat", "repeat" );
style.addProperty( "draw:fill-image-ref-point-x", QString("%1%").arg( matrix.dx()/size.width() * 100.0 ) );
style.addProperty( "draw:fill-image-ref-point-y", QString("%1%").arg( matrix.dy()/size.height() * 100.0 ) );
//style.addAttribute( "draw:fill-image-height", texture.height() );
//style.addAttribute( "draw:fill-image-width", texture.width() );
KoGenStyle patternStyle( KoGenStyle::StyleFillImage /*no family name*/ );
patternStyle.addAttribute( "xlink:show", "embed" );
patternStyle.addAttribute( "xlink:actuate", "onLoad" );
patternStyle.addAttribute( "xlink:type", "simple" );
patternStyle.addAttribute( "xlink:href", m_context.addImageForSaving( texture ) );
return m_context.mainStyles().lookup( patternStyle, "picture" );
}
void KoShapeStyleWriter::writeOfficeStyles( KoXmlWriter* styleWriter )
{
KoGenStyles & mainStyles = m_context.mainStyles();
Q3ValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::StyleGradientLinear );
Q3ValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
for( ; it != styles.end() ; ++it )
(*it).style->writeStyle( styleWriter, mainStyles, "svg:linearGradient", (*it).name, 0, true, true /*add draw:name*/);
styles = mainStyles.styles( KoGenStyle::StyleGradientRadial );
it = styles.begin();
for( ; it != styles.end() ; ++it )
(*it).style->writeStyle( styleWriter, mainStyles, "svg:radialGradient", (*it).name, 0, true, true /*add draw:name*/);
styles = mainStyles.styles( KoGenStyle::StyleStrokeDash );
it = styles.begin();
for( ; it != styles.end() ; ++it )
(*it).style->writeStyle( styleWriter, mainStyles, "draw:stroke-dash", (*it).name, 0, true, true /*add draw:name*/);
styles = mainStyles.styles( KoGenStyle::StyleFillImage );
it = styles.begin();
for( ; it != styles.end() ; ++it )
(*it).style->writeStyle( styleWriter, mainStyles, "draw:fill-image", (*it).name, 0, true, true /*add draw:name*/);
}
/* This file is part of the KDE project
Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
#ifndef KOSHAPESTYLEWRITER_H
#define KOSHAPESTYLEWRITER_H
#include <flake_export.h>
#include <QtCore/QString>
class KoShapeSavingContext;
class KoGenStyle;
class KoXmlWriter;
class QBrush;
/// A helper class for writing the shape styles to ODF.
class FLAKE_EXPORT KoShapeStyleWriter
{
public:
/// Creates a new shape style writer working on the given saving context
KoShapeStyleWriter( KoShapeSavingContext &context );
/**
* Writes the style of the brush using the internal saving context
* @param style the style to write to
* @param fill the fill style to save
* @return the name of the saved style
*/
QString addFillStyle( KoGenStyle &style, const QBrush &brush );
/**
* Writes the office:styles from the internal saving context to the given xml writer.
*
* Writes styles like gradients, stroke-dash or fill-images. The office:styles tag
* has to be opened and closed outside to allow other office:styles to be written.
*
* @param styleWriter the xml writer used for writing the styles
*/
void writeOfficeStyles( KoXmlWriter* styleWriter );
private:
/// Saves pattern style
QString savePatternStyle( KoGenStyle &style, const QBrush &brush );
KoShapeSavingContext & m_context; ///< the shape saving context the styles are added to
};
#endif // KOSHAPESTYLEWRITER_H
......@@ -66,6 +66,7 @@ public:
StyleGradient = 18, ///< draw:gradient as in 14.14.1 odf spec
StyleGradientLinear = 19, ///< linear svg:gradient as in 14.14.2 odf spec
StyleGradientRadial = 20, ///< radial svg:gradient as in 14.14.2 odf spec
StyleFillImage = 21, ///< fill image as in 14.14.4 odf spec
StyleFirstCustom = 2500 }; ///< the first style for applications to use
/**
......
......@@ -1430,9 +1430,6 @@ void KoOasisStyles::saveOasisFillStyle( KoGenStyle &styleFill, KoGenStyles& main
styleFill.addProperty( "draw:fill","gradient" );
styleFill.addProperty( "draw:fill-gradient-name", saveOasisGradientStyle( mainStyles, brush ) );
break;
case Qt::TexturePattern:
// TODO
break;
default: //otherstyle
styleFill.addProperty( "draw:fill","hatch" );
styleFill.addProperty( "draw:fill-hatch-name", saveOasisHatchStyle( mainStyles, brush ) );
......@@ -1544,6 +1541,11 @@ QBrush KoOasisStyles::loadOasisGradientStyle( const KoStyleStack &styleStack, co
if( e->namespaceURI() == KoXmlNS::draw && e->localName() == "gradient" )
{
// FIXME seems like oo renders the gradient start stop color at the center of the
// radial gradient, and the start color at the radius of the radial gradient
// whereas it is not mentioned in the spec how it should be rendered
// note that svg defines that exactly as the opposite as oo does
// so what should we do?
QString type = e->attributeNS( KoXmlNS::draw, "style", QString() );
if( type == "radial" )
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment