Warning, file /office/calligra/filters/karbon/wmf/WmfExport.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2003 thierry lorthiois (lorthioist@wanadoo.fr)
0003  * SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #include "WmfExport.h"
0009 #include <WmfWriter.h>
0010 
0011 #include <KarbonDocument.h>
0012 #include <KarbonPart.h>
0013 
0014 #include <kpluginfactory.h>
0015 
0016 #include <KoFilterChain.h>
0017 #include <KoShapeStroke.h>
0018 #include <KoShape.h>
0019 #include <KoShapeContainer.h>
0020 #include <KoColorBackground.h>
0021 #include <KoGradientBackground.h>
0022 #include <KoPatternBackground.h>
0023 #include <KoUnit.h>
0024 #include <KoPAPageBase.h>
0025 #include <KoPageLayout.h>
0026 
0027 #include <algorithm>
0028 
0029 #include <QPainterPath>
0030 
0031 /*
0032 TODO: bs.wmf stroke in red with MSword and in brown with Words ??
0033 */
0034 
0035 K_PLUGIN_FACTORY_WITH_JSON(WmfExportFactory, "calligra_filter_karbon2wmf.json",
0036                registerPlugin<WmfExport>();)
0037 
0038 
0039 
0040 WmfExport::WmfExport(QObject*parent, const QVariantList&) :
0041         KoFilter(parent)
0042 {
0043 }
0044 
0045 WmfExport::~WmfExport()
0046 {
0047 }
0048 
0049 KoFilter::ConversionStatus WmfExport::convert(const QByteArray& from, const QByteArray& to)
0050 {
0051     if (to != "image/x-wmf" || from != "application/vnd.oasis.opendocument.graphics")
0052         return KoFilter::NotImplemented;
0053 
0054     KoDocument * doc = m_chain->inputDocument();
0055     if (! doc)
0056         return KoFilter::ParsingError;
0057 
0058     KarbonDocument * karbonPart = dynamic_cast<KarbonDocument*>(doc);
0059     if (! karbonPart)
0060         return KoFilter::WrongFormat;
0061 
0062     // open Placeable Wmf file
0063     mWmf = new Libwmf::WmfWriter(m_chain->outputFile());
0064     if (!mWmf->begin()) {
0065         delete mWmf;
0066         return KoFilter::WrongFormat;
0067     }
0068 
0069     paintDocument(karbonPart);
0070 
0071     mWmf->end();
0072 
0073     delete mWmf;
0074 
0075     return KoFilter::OK;
0076 }
0077 
0078 void WmfExport::paintDocument(KarbonDocument* document)
0079 {
0080     KoPAPageBase *page = document->pages().value(0);
0081     if (!page) {
0082         return;
0083     }
0084     // resolution
0085     mDpi = 1000;
0086 
0087     const KoPageLayout &layout = page->pageLayout();
0088     QSizeF pageSize(layout.width, layout.height);
0089     int width = static_cast<int>(POINT_TO_INCH(pageSize.width()) * mDpi);
0090     int height = static_cast<int>(POINT_TO_INCH(pageSize.height()) * mDpi);
0091 
0092     mWmf->setDefaultDpi(mDpi);
0093     mWmf->setWindow(0, 0, width, height);
0094 
0095     if ((pageSize.width() != 0) && (pageSize.height() != 0)) {
0096         mScaleX = static_cast<double>(width) / pageSize.width();
0097         mScaleY = static_cast<double>(height) / pageSize.height();
0098     }
0099 
0100     QList<KoShape*> shapes = page->shapes();
0101     std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
0102 
0103     // Export layers.
0104     foreach(KoShape * shape, shapes) {
0105         if (dynamic_cast<KoShapeContainer*>(shape))
0106             continue;
0107         paintShape(shape);
0108     }
0109 }
0110 
0111 void WmfExport::paintShape(KoShape * shape)
0112 {
0113     QList<QPolygonF> subpaths = shape->outline().toFillPolygons(shape->absoluteTransformation(0));
0114 
0115     if (! subpaths.count())
0116         return;
0117 
0118     QList<QPolygon> polygons;
0119     foreach(const QPolygonF & subpath, subpaths) {
0120         QPolygon p;
0121         uint pointCount = subpath.count();
0122         for (uint i = 0; i < pointCount; ++i)
0123             p.append(QPoint(coordX(subpath[i].x()), coordY(subpath[i].y())));
0124 
0125         polygons.append(p);
0126     }
0127     mWmf->setPen(getPen(shape->stroke()));
0128 
0129     if (polygons.count() == 1 && ! shape->background())
0130         mWmf->drawPolyline(polygons.first());
0131     else {
0132         QBrush fill(Qt::NoBrush);
0133         QSharedPointer<KoColorBackground>  cbg = qSharedPointerDynamicCast<KoColorBackground>(shape->background());
0134         if (cbg)
0135             fill = QBrush(cbg->color(), cbg->style());
0136         QSharedPointer<KoGradientBackground>  gbg = qSharedPointerDynamicCast<KoGradientBackground>(shape->background());
0137         if (gbg) {
0138             fill = QBrush(*gbg->gradient());
0139             fill.setTransform(gbg->transform());
0140         }
0141         QSharedPointer<KoPatternBackground>  pbg = qSharedPointerDynamicCast<KoPatternBackground>(shape->background());
0142         if (pbg) {
0143             fill.setTextureImage(pbg->pattern());
0144             fill.setTransform(pbg->transform());
0145         }
0146         mWmf->setBrush(fill);
0147         if (polygons.count() == 1)
0148             mWmf->drawPolygon(polygons.first());
0149         else
0150             mWmf->drawPolyPolygon(polygons);
0151     }
0152 }
0153 
0154 QPen WmfExport::getPen(const KoShapeStrokeModel * stroke)
0155 {
0156     const KoShapeStroke * lineStroke = dynamic_cast<const KoShapeStroke*>(stroke);
0157     if (! lineStroke)
0158         return QPen(Qt::NoPen);
0159 
0160     QPen pen(lineStroke->lineStyle());
0161     if (pen.style() > Qt::SolidLine)
0162         pen.setDashPattern(lineStroke->lineDashes());
0163 
0164     pen.setColor(lineStroke->color());
0165     pen.setCapStyle(lineStroke->capStyle());
0166     pen.setJoinStyle(lineStroke->joinStyle());
0167     pen.setWidthF(coordX(lineStroke->lineWidth()));
0168     pen.setMiterLimit(lineStroke->miterLimit());
0169 
0170     return pen;
0171 }
0172 
0173 int WmfExport::coordX(double left)
0174 {
0175     return (int)(left * mScaleX);
0176 }
0177 
0178 int WmfExport::coordY(double top)
0179 {
0180     return (int)(top * mScaleY);
0181 }
0182 
0183 #include <WmfExport.moc>
0184