Back to index

scribus-ng  1.3.4.dfsg+svn20071115
svgexplugin.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************
00008                           svgexplugin.cpp  -  description
00009                              -------------------
00010     begin                : Sun Aug 3 08:00:00 CEST 2002
00011     copyright            : (C) 2002 by Franz Schmid
00012     email                : Franz.Schmid@altmuehlnet.de
00013  ***************************************************************************/
00014 
00015 /***************************************************************************
00016  *                                                                         *
00017  *   This program is free software; you can redistribute it and/or modify  *
00018  *   it under the terms of the GNU General Public License as published by  *
00019  *   the Free Software Foundation; either version 2 of the License, or     *
00020  *   (at your option) any later version.                                   *
00021  *                                                                         *
00022  ***************************************************************************/
00023 
00024 #include <qfile.h>
00025 #include <qtextstream.h>
00026 
00027 #include "svgexplugin.h"
00028 
00029 #include "scconfig.h"
00030 #include "cmsettings.h"
00031 #include "commonstrings.h"
00032 #include "customfdialog.h"
00033 #include "scribuscore.h"
00034 #include "page.h"
00035 #include "scgzfile.h"
00036 #include "prefsmanager.h"
00037 #include "prefsfile.h"
00038 #include "prefscontext.h"
00039 #include "scmessagebox.h"
00040 #include "util.h"
00041 #include "customfdialog.h"
00042 #include "sctextstruct.h"
00043 #include "guidemanager.h"
00044 #include "sccolorengine.h"
00045 
00046 int svgexplugin_getPluginAPIVersion()
00047 {
00048        return PLUGIN_API_VERSION;
00049 }
00050 
00051 ScPlugin* svgexplugin_getPlugin()
00052 {
00053        SVGExportPlugin* plug = new SVGExportPlugin();
00054        Q_CHECK_PTR(plug);
00055        return plug;
00056 }
00057 
00058 void svgexplugin_freePlugin(ScPlugin* plugin)
00059 {
00060        SVGExportPlugin* plug = dynamic_cast<SVGExportPlugin*>(plugin);
00061        Q_ASSERT(plug);
00062        delete plug;
00063 }
00064 
00065 SVGExportPlugin::SVGExportPlugin() : ScActionPlugin()
00066 {
00067        // Set action info in languageChange, so we only have to do
00068        // it in one place.
00069        languageChange();
00070 }
00071 
00072 SVGExportPlugin::~SVGExportPlugin() {};
00073 
00074 void SVGExportPlugin::languageChange()
00075 {
00076        // Note that we leave the unused members unset. They'll be initialised
00077        // with their default ctors during construction.
00078        // Action name
00079        m_actionInfo.name = "ExportAsSVG";
00080        // Action text for menu, including accel
00081        m_actionInfo.text = tr("Save as &SVG...");
00082        // Menu
00083        m_actionInfo.menu = "FileExport";
00084        m_actionInfo.enabledOnStartup = true;
00085 }
00086 
00087 const QString SVGExportPlugin::fullTrName() const
00088 {
00089        return QObject::tr("SVG Export");
00090 }
00091 
00092 const ScActionPlugin::AboutData* SVGExportPlugin::getAboutData() const
00093 {
00094        AboutData* about = new AboutData;
00095        about->authors = "Franz Schmid <franz@scribus.info>";
00096        about->shortDescription = tr("Exports SVG Files");
00097        about->description = tr("Exports the current page into an SVG file.");
00098        about->license = "GPL";
00099        Q_CHECK_PTR(about);
00100        return about;
00101 }
00102 
00103 void SVGExportPlugin::deleteAboutData(const AboutData* about) const
00104 {
00105        Q_ASSERT(about);
00106        delete about;
00107 }
00108 
00109 bool SVGExportPlugin::run(ScribusDoc* doc, QString filename)
00110 {
00111        Q_ASSERT(filename.isEmpty());
00112        QString fileName;
00113        if (doc!=0)
00114        {
00115               PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("svgex");
00116               QString wdir = prefs->get("wdir", ".");
00117               CustomFDialog *openDia = new CustomFDialog(doc->scMW(), wdir, QObject::tr("Save as"), QObject::tr("SVG-Images (*.svg *.svgz);;All Files (*)"), fdCompressFile);
00118               openDia->setSelection(getFileNameByPage(doc, doc->currentPage()->pageNr(), "svg"));
00119               openDia->setExtension("svg");
00120               openDia->setZipExtension("svgz");
00121               if (openDia->exec())
00122               {
00123                      if (openDia->SaveZip->isChecked())
00124                             openDia->handleCompress();
00125                      fileName = openDia->selectedFile();
00126               }
00127               delete openDia;
00128 
00129               if (!fileName.isEmpty())
00130               {
00131                      prefs->set("wdir", fileName.left(fileName.findRev("/")));
00132                      QFile f(fileName);
00133                      if (f.exists())
00134                      {
00135                             int exit=ScMessageBox::warning(doc->scMW(), CommonStrings::trWarning,
00136                                    QObject::tr("Do you really want to overwrite the File:\n%1 ?").arg(fileName),
00137                                    CommonStrings::trYes,
00138                                    CommonStrings::trNo,
00139                                    0, 0, 1);
00140                             if (exit != 0)
00141                                    return true;
00142                      }
00143                      SVGExPlug *dia = new SVGExPlug(doc);
00144                      dia->doExport(fileName);
00145                      delete dia;
00146               }
00147               else
00148                      return true;
00149        }
00150        return true;
00151 }
00152 
00153 SVGExPlug::SVGExPlug( ScribusDoc* doc )
00154 {
00155        m_Doc=doc;
00156        m_View=m_Doc->view();
00157        m_ScMW=m_Doc->scMW();
00158 }
00159 
00160 bool SVGExPlug::doExport( QString fName )
00161 {
00162 #ifdef USECAIRO
00163        Page *Seite = m_Doc->currentPage();
00164        int clipx = static_cast<int>(Seite->xOffset());
00165        int clipy = static_cast<int>(Seite->yOffset());
00166        int clipw = qRound(Seite->width());
00167        int cliph = qRound(Seite->height());
00168        double sca = m_View->scale();
00169        double cx = m_Doc->minCanvasCoordinate.x();
00170        double cy = m_Doc->minCanvasCoordinate.y();
00171        m_Doc->minCanvasCoordinate = FPoint(0, 0);
00172        bool frs = m_Doc->guidesSettings.framesShown;
00173        bool ctrls = m_Doc->guidesSettings.showControls;
00174        m_Doc->guidesSettings.framesShown = false;
00175        m_Doc->guidesSettings.showControls = false;
00176        m_View->setScale(1.0);
00177        m_View->previewMode = true;
00178        ScPainter *painter = new ScPainter(fName, clipw, cliph, 1.0, 0);
00179        painter->clear(m_Doc->papColor);
00180        painter->translate(-clipx, -clipy);
00181        painter->setFillMode(ScPainter::Solid);
00182        m_View->DrawMasterItems(painter, Seite, QRect(clipx, clipy, clipw, cliph));
00183        m_View->DrawPageItems(painter, QRect(clipx, clipy, clipw, cliph));
00184        painter->end();
00185        m_Doc->guidesSettings.framesShown = frs;
00186        m_Doc->guidesSettings.showControls = ctrls;
00187        m_View->setScale(sca);
00188        delete painter;
00189        m_View->previewMode = false;
00190        m_Doc->minCanvasCoordinate = FPoint(cx, cy);
00191 #else
00192        QDomDocument docu("svgdoc");
00193        QString vo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00194        QString st = "<svg></svg>";
00195        docu.setContent(st);
00196        QDomElement elem = docu.documentElement();
00197        elem.setAttribute("width", FToStr(m_Doc->pageWidth)+"pt");
00198        elem.setAttribute("height", FToStr(m_Doc->pageHeight)+"pt");
00199        elem.setAttribute("xmlns", "http://www.w3.org/2000/svg");
00200        elem.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");
00201        Page *Seite;
00202        GradCount = 0;
00203        ClipCount = 0;
00204        Seite = m_Doc->MasterPages.at(m_Doc->MasterNames[m_Doc->currentPage()->MPageNam]);
00205        ProcessPage(Seite, &docu, &elem);
00206        Seite = m_Doc->currentPage();
00207        ProcessPage(Seite, &docu, &elem);
00208        if(fName.right(2) == "gz")
00209        {
00210               // zipped saving
00211               ScGzFile gzf(fName, docu.toString().utf8());
00212               if (!gzf.write(vo))
00213                      return false;
00214        }
00215        else
00216        {
00217               QFile f(fName);
00218               if(!f.open(IO_WriteOnly))
00219                      return false;
00220               QTextStream s(&f);
00221               QString wr = vo;
00222               wr += docu.toString();
00223               QCString utf8wr = wr.utf8();
00224               s.writeRawBytes(utf8wr.data(), utf8wr.length());
00225               f.close();
00226        }
00227 #endif
00228        return true;
00229 }
00230 
00231 #ifndef USECAIRO
00232 void SVGExPlug::ProcessPage(Page *Seite, QDomDocument *docu, QDomElement *elem)
00233 {
00234        QString tmp, trans, fill, stroke, strokeW, strokeLC, strokeLJ, strokeDA, gradi, Clipi, chx;
00235        int d;
00236        ScText *hl;
00237        int Lnr = 0;
00238        struct Layer ll;
00239        ll.isPrintable = false;
00240        ll.LNr = 0;
00241        QDomElement ob, gr, tp, tp2, defi, grad;
00242        QDomText tp1;
00243        PageItem *Item;
00244        gradi = "Grad";
00245        Clipi = "Clip";
00246        QPtrList<PageItem> Items;
00247        Page* SavedAct = m_Doc->currentPage();
00248        m_Doc->setCurrentPage(Seite);
00249        if (Seite->pageName().isEmpty())
00250               Items = m_Doc->DocItems;
00251        else
00252               Items = m_Doc->MasterItems;
00253        for (uint la = 0; la < m_Doc->Layers.count(); la++)
00254               {
00255               Level2Layer(m_Doc, &ll, Lnr);
00256               if (ll.isPrintable)
00257                      {
00258                      for(uint j = 0; j < Items.count(); ++j)
00259                      {
00260                             Item = Items.at(j);
00261                             if (Item->LayerNr != ll.LNr)
00262                                    continue;
00263                             double x = Seite->xOffset();
00264                             double y = Seite->yOffset();
00265                             double w = Seite->width();
00266                             double h = Seite->height();
00267                             double x2 = Item->BoundingX;
00268                             double y2 = Item->BoundingY;
00269                             double w2 = Item->BoundingW;
00270                             double h2 = Item->BoundingH;
00271                             if (!( QMAX( x, x2 ) <= QMIN( x+w, x2+w2 ) && QMAX( y, y2 ) <= QMIN( y+h, y2+h2 )))
00272                                    continue;
00273                             if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
00274                             {
00275                                    fill = "fill:"+SetFarbe(Item->fillColor(), Item->fillShade())+";";
00276                                    if (Item->GrType != 0)
00277                                    {
00278                                           defi = docu->createElement("defs");
00279                                           if ((Item->GrType == 5) || (Item->GrType == 7))
00280                                                  grad = docu->createElement("radialGradient");
00281                                           else
00282                                                  grad = docu->createElement("linearGradient");
00283                                           grad.setAttribute("id", gradi+IToStr(GradCount));
00284                                           grad.setAttribute("gradientUnits", "userSpaceOnUse");
00285                                           switch (Item->GrType)
00286                                           {
00287                                                  case 1:
00288                                                         grad.setAttribute("x1", "0");
00289                                                         grad.setAttribute("y1", FToStr(Item->height() / 2));
00290                                                         grad.setAttribute("x2", FToStr(Item->width()));
00291                                                         grad.setAttribute("y2", FToStr(Item->height() / 2));
00292                                                         break;
00293                                                  case 2:
00294                                                         grad.setAttribute("x1", FToStr(Item->width()/ 2));
00295                                                         grad.setAttribute("y1", "0");
00296                                                         grad.setAttribute("x2", FToStr(Item->width()/ 2));
00297                                                         grad.setAttribute("y2", FToStr(Item->height()));
00298                                                         break;
00299                                                  case 3:
00300                                                         grad.setAttribute("x1", "0");
00301                                                         grad.setAttribute("y1", "0");
00302                                                         grad.setAttribute("x2", FToStr(Item->width()));
00303                                                         grad.setAttribute("y2", FToStr(Item->height()));
00304                                                         break;
00305                                                  case 4:
00306                                                         grad.setAttribute("x1", "0");
00307                                                         grad.setAttribute("y1", FToStr(Item->height()));
00308                                                         grad.setAttribute("x2", FToStr(Item->width()));
00309                                                         grad.setAttribute("y2", "0");
00310                                                         break;
00311                                                  case 5:
00312                                                         grad.setAttribute("r", FToStr(QMAX(Item->width() / 2, Item->height() / 2)));
00313                                                         grad.setAttribute("cx", FToStr(Item->width() / 2));
00314                                                         grad.setAttribute("cy", FToStr(Item->height() / 2));
00315                                                         break;
00316                                                  case 6:
00317                                                         grad.setAttribute("x1", FToStr(Item->GrStartX));
00318                                                         grad.setAttribute("y1", FToStr(Item->GrStartY));
00319                                                         grad.setAttribute("x2", FToStr(Item->GrEndX));
00320                                                         grad.setAttribute("y2", FToStr(Item->GrEndY));
00321                                                         break;
00322                                                  case 7:
00323                                                         grad.setAttribute("r", FToStr(QMAX(Item->width() / 2, Item->height() / 2)));
00324                                                         grad.setAttribute("cx", FToStr(Item->GrStartX));
00325                                                         grad.setAttribute("cy", FToStr(Item->GrStartY));
00326                                                         break;
00327                                           }
00328                                           QPtrVector<VColorStop> cstops = Item->fill_gradient.colorStops();
00329                                           for (uint cst = 0; cst < Item->fill_gradient.Stops(); ++cst)
00330                                           {
00331                                                  QDomElement itcl = docu->createElement("stop");
00332                                                  itcl.setAttribute("offset", FToStr(cstops.at(cst)->rampPoint*100)+"%");
00333                                                  itcl.setAttribute("stop-opacity", FToStr(cstops.at(cst)->opacity));
00334                                                  itcl.setAttribute("stop-color", SetFarbe(cstops.at(cst)->name, cstops.at(cst)->shade));
00335                                                  grad.appendChild(itcl);
00336                                           }
00337                                           defi.appendChild(grad);
00338                                           fill = "fill:url(#"+gradi+IToStr(GradCount)+");";
00339                                           GradCount++;
00340                                    }
00341                                    if (Item->fillRule)
00342                                           fill += " fill-rule:evenodd;";
00343                                    else
00344                                           fill += " fill-rule:nonzero;";
00345                                    if (Item->fillTransparency() != 0)
00346                                           fill += " fill-opacity:"+FToStr(1.0 - Item->fillTransparency())+";";
00347                             }
00348                             else
00349                                    fill = "fill:none;";
00350                             if (Item->lineColor() != CommonStrings::None)
00351                             {
00352                                    stroke = "stroke:"+SetFarbe(Item->lineColor(), Item->lineShade())+";";
00353                                    if (Item->lineTransparency() != 0)
00354                                           stroke += " stroke-opacity:"+FToStr(1.0 - Item->lineTransparency())+";";
00355                             }
00356                             else
00357                                    stroke = "stroke:none;";
00358                             trans = "translate("+FToStr(Item->xPos()-Seite->xOffset())+", "+FToStr(Item->yPos()-Seite->yOffset())+")";
00359                             if (Item->rotation() != 0)
00360                                    trans += " rotate("+FToStr(Item->rotation())+")";
00361                             strokeW = "stroke-width:"+FToStr(Item->lineWidth())+"pt;";
00362                             strokeLC = "stroke-linecap:";
00363                             switch (Item->PLineEnd)
00364                             {
00365                                    case Qt::FlatCap:
00366                                           strokeLC += "butt;";
00367                                           break;
00368                                    case Qt::SquareCap:
00369                                           strokeLC += "square;";
00370                                           break;
00371                                    case Qt::RoundCap:
00372                                           strokeLC += "round;";
00373                                           break;
00374                                    default:
00375                                           strokeLC += "butt;";
00376                                           break;
00377                             }
00378                             strokeLJ = "stroke-linejoin:";
00379                             switch (Item->PLineJoin)
00380                             {
00381                                    case Qt::MiterJoin:
00382                                           strokeLJ += "miter;";
00383                                           break;
00384                                    case Qt::BevelJoin:
00385                                           strokeLJ += "bevel;";
00386                                           break;
00387                                    case Qt::RoundJoin:
00388                                           strokeLJ += "round;";
00389                                           break;
00390                                    default:
00391                                           strokeLJ += "miter;";
00392                                           break;
00393                             }
00394                             strokeDA = "stroke-dasharray:";
00395                             if (Item->DashValues.count() != 0)
00396                             {
00397                                    QValueList<double>::iterator it;
00398                                    for ( it = Item->DashValues.begin(); it != Item->DashValues.end(); ++it )
00399                                    {
00400                                           strokeDA += IToStr(static_cast<int>(*it))+" ";
00401                                    }
00402                                    strokeDA += "; stroke-dashoffset:"+IToStr(static_cast<int>(Item->DashOffset))+";";
00403                             }
00404                             else
00405                             {
00406                                    QString Dt = FToStr(QMAX(2*Item->lineWidth(), 1));
00407                                    QString Da = FToStr(QMAX(6*Item->lineWidth(), 1));
00408                                    switch (Item->PLineArt)
00409                                    {
00410                                           case Qt::SolidLine:
00411                                                  strokeDA += "none;";
00412                                                  break;
00413                                           case Qt::DashLine:
00414                                                  strokeDA += Da+","+Dt+";";
00415                                                  break;
00416                                           case Qt::DotLine:
00417                                                  strokeDA += Dt+";";
00418                                                  break;
00419                                           case Qt::DashDotLine:
00420                                                  strokeDA += Da+","+Dt+","+Dt+","+Dt+";";
00421                                                  break;
00422                                           case Qt::DashDotDotLine:
00423                                                  strokeDA += Da+","+Dt+","+Dt+","+Dt+","+Dt+","+Dt+";";
00424                                                  break;
00425                                           default:
00426                                                  strokeDA += "none;";
00427                                                  break;
00428                                           }
00429                             }
00430                             gr = docu->createElement("g");
00431                             gr.setAttribute("transform", trans);
00432                             if (!Item->asTextFrame())
00433                             {
00434                                    if (Item->NamedLStyle.isEmpty())
00435                                    {
00436                                           if (Item->asPathText())
00437                                                  gr.setAttribute("style", "fill:none; "+stroke+" "+strokeW+" "+strokeLC+" "+strokeLJ+" "+strokeDA);
00438                                           else
00439                                                  gr.setAttribute("style", fill+" "+stroke+" "+strokeW+" "+strokeLC+" "+strokeLJ+" "+strokeDA);
00440                                    }
00441                             }
00442                             switch (Item->itemType())
00443                             {
00444                             /* Item types 3 and 1 are OBSOLETE: CR 2005-02-06
00445                             case 1:
00446                             case 3:
00447                             */
00448                             case PageItem::Polygon:
00449                                           if (Item->NamedLStyle.isEmpty())
00450                                           {
00451                                                  ob = docu->createElement("path");
00452                                                  ob.setAttribute("d", SetClipPath(Item)+"Z");
00453                                           }
00454                                           else
00455                                           {
00456                                                  ob = docu->createElement("path");
00457                                                  ob.setAttribute("d", SetClipPath(Item)+"Z");
00458                                                  ob.setAttribute("style", fill);
00459                                                  gr.appendChild(ob);
00460                                                  multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
00461                                                  for (int it = ml.size()-1; it > -1; it--)
00462                                                  {
00463                                                         if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
00464                                                         {
00465                                                                ob = docu->createElement("path");
00466                                                                ob.setAttribute("d", SetClipPath(Item)+"Z");
00467                                                                ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
00468                                                                gr.appendChild(ob);
00469                                                         }
00470                                                  }
00471                                           }
00472                                    break;
00473                             case PageItem::ImageFrame:
00474                                           if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
00475                                           {
00476                                                  ob = docu->createElement("path");
00477                                                  ob.setAttribute("d", SetClipPath(Item)+"Z");
00478                                                  ob.setAttribute("style", fill);
00479                                                  gr.appendChild(ob);
00480                                           }
00481                                           if ((Item->PicAvail) && (!Item->Pfile.isEmpty()))
00482                                           {
00483                                                  ob = docu->createElement("clipPath");
00484                                                  ob.setAttribute("id", Clipi+IToStr(ClipCount));
00485                                                  ob.setAttribute("clipPathUnits", "userSpaceOnUse");
00486                                                  ob.setAttribute("clip-rule", "evenodd");
00487                                                  QDomElement cl = docu->createElement("path");
00488                                                  if (Item->imageClip.size() != 0)
00489                                                         cl.setAttribute("d", SetClipPathImage(Item)+"Z");
00490                                                  else
00491                                                         cl.setAttribute("d", SetClipPath(Item)+"Z");
00492                                                  ob.appendChild(cl);
00493                                                  gr.appendChild(ob);
00494                                                  ScImage img;
00495                                                  CMSettings cms(m_Doc, Item->IProfile, Item->IRender);
00496                                                  img.LoadPicture(Item->Pfile, cms, Item->UseEmbedded, true, ScImage::RGBProof, 72);
00497                                                  img.applyEffect(Item->effectsInUse, m_Doc->PageColors, true);
00498                                                  QFileInfo fi = QFileInfo(Item->Pfile);
00499                                                  img.qImage().save(fi.baseName()+".png", "PNG");
00500                                                  ob = docu->createElement("image");
00501                                                  ob.setAttribute("clip-path", "url(#"+Clipi+IToStr(ClipCount)+")");
00502                                                  ob.setAttribute("xlink:href", fi.baseName()+".png");
00503                                                  ob.setAttribute("x", "0pt");
00504                                                  ob.setAttribute("y", "0pt");
00505                                                  ob.setAttribute("width", FToStr(Item->width())+"pt");
00506                                                  ob.setAttribute("height", FToStr(Item->height())+"pt");
00507                                                  ClipCount++;
00508                                                  gr.appendChild(ob);
00509                                           }
00510                                           if (Item->NamedLStyle.isEmpty())
00511                                           {
00512                                                  ob = docu->createElement("path");
00513                                                  ob.setAttribute("d", SetClipPath(Item)+"Z");
00514                                                  ob.setAttribute("style", "fill:none; "+stroke+" "+strokeW+" "+strokeLC+" "+strokeLJ+" "+strokeDA);
00515                                           }
00516                                           else
00517                                           {
00518                                                  multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
00519                                                  for (int it = ml.size()-1; it > -1; it--)
00520                                                  {
00521                                                         if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
00522                                                         {
00523                                                                ob = docu->createElement("path");
00524                                                                ob.setAttribute("d", SetClipPath(Item)+"Z");
00525                                                                ob.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
00526                                                                gr.appendChild(ob);
00527                                                         }
00528                                                  }
00529                                           }
00530                                    break;
00531                             case PageItem::PolyLine:
00532                                           if (Item->NamedLStyle.isEmpty())
00533                                           {
00534                                                  ob = docu->createElement("path");
00535                                                  ob.setAttribute("d", SetClipPath(Item));
00536                                           }
00537                                           else
00538                                           {
00539                                                  multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
00540                                                  for (int it = ml.size()-1; it > -1; it--)
00541                                                  {
00542                                                         if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
00543                                                         {
00544                                                                ob = docu->createElement("path");
00545                                                                ob.setAttribute("d", SetClipPath(Item));
00546                                                                ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
00547                                                                gr.appendChild(ob);
00548                                                         }
00549                                                  }
00550                                           }
00551                                    break;
00552                             case PageItem::TextFrame:
00553                                           if ((Item->fillColor() != CommonStrings::None) || (Item->GrType != 0))
00554                                           {
00555                                                  ob = docu->createElement("path");
00556                                                  ob.setAttribute("d", SetClipPath(Item)+"Z");
00557                                                  ob.setAttribute("style", fill);
00558                                                  gr.appendChild(ob);
00559                                           }
00560                                           ob = docu->createElement("text");
00561                                           for (d = 0; d < Item->itemText.length() && ! Item->frameDisplays(d); ++d)
00562                                                  ;
00563                                           for (; d < Item->itemText.length() && Item->frameDisplays(d); ++d)
00564                                           {
00565                                                  hl = Item->itemText.item(d);
00566                                                  if ((hl->ch == QChar(13)) || (hl->ch == QChar(10)) || (hl->ch == QChar(9)) || (hl->ch == QChar(28)))
00567                                                         continue;
00568                                                  if (hl->glyph.yoffset == 0)
00569                                                         break;
00570                                                  if (hl->ch == QChar(29))
00571                                                         chx = " ";
00572                                                  else
00573                                                         chx = hl->ch;
00574                                                  tp = docu->createElement("tspan");
00575                                                  tp.setAttribute("x", FToStr(hl->glyph.xoffset)+"pt");
00576                                                  tp.setAttribute("y", FToStr(hl->glyph.yoffset)+"pt");
00577                                                  SetTextProps(&tp, hl);
00578                                                  tp1 = docu->createTextNode(chx);
00579                                                  tp.appendChild(tp1);
00580                                                  ob.appendChild(tp);
00581                                           }
00582                                    break;
00583                             case PageItem::Line:
00584                                           if (Item->NamedLStyle.isEmpty())
00585                                           {
00586                                                  ob = docu->createElement("path");
00587                                                  ob.setAttribute("d", "M 0 0 L "+FToStr(Item->width())+" 0");
00588                                           }
00589                                           else
00590                                           {
00591                                                  multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
00592                                                  for (int it = ml.size()-1; it > -1; it--)
00593                                                  {
00594                                                         if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
00595                                                         {
00596                                                                ob = docu->createElement("path");
00597                                                                ob.setAttribute("d", "M 0 0 L "+FToStr(Item->width())+" 0");
00598                                                                ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
00599                                                                gr.appendChild(ob);
00600                                                         }
00601                                                  }
00602                                           }
00603                                    break;
00604                             case PageItem::PathText:
00605                                           if (Item->PoShow)
00606                                           {
00607                                                  if (Item->NamedLStyle.isEmpty())
00608                                                  {
00609                                                         ob = docu->createElement("path");
00610                                                         ob.setAttribute("d", SetClipPath(Item));
00611                                                         gr.appendChild(ob);
00612                                                  }
00613                                                  else
00614                                                  {
00615                                                         multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
00616                                                         for (int it = ml.size()-1; it > -1; it--)
00617                                                         {
00618                                                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
00619                                                                {
00620                                                                       ob = docu->createElement("path");
00621                                                                       ob.setAttribute("d", SetClipPath(Item));
00622                                                                       ob.setAttribute("style", GetMultiStroke(&ml[it], Item));
00623                                                                       gr.appendChild(ob);
00624                                                                }
00625                                                         }
00626                                                  }
00627                                           }
00628                                           ob = docu->createElement("text");
00629                                           for (d = 0; d < Item->itemText.length() && !Item->frameDisplays(d); ++d)
00630                                                  ;
00631                                           for (; d < Item->itemText.length() && Item->frameDisplays(d); ++d)
00632                                           {
00633                                                  hl = Item->itemText.item(d);
00634                                                  if ((hl->ch == QChar(13)) || (hl->ch == QChar(10)) || (hl->ch == QChar(9)) || (hl->ch == QChar(25)) || (hl->ch == QChar(28)))
00635                                                         continue;
00636                                                  if (hl->ch == QChar(29))
00637                                                         chx = " ";
00638                                                  else
00639                                                         chx = hl->ch;
00640                                                  tp = docu->createElement("tspan");
00641                                                  tp.setAttribute("x", FToStr(hl->PtransX)+"pt");
00642                                                  tp.setAttribute("y", FToStr(hl->PtransY)+"pt");
00643                                                  tp.setAttribute("rotate", hl->PRot);
00644                                                  tp2 = docu->createElement("tspan");
00645                                                  tp2.setAttribute("dx", FToStr(hl->glyph.xoffset)+"pt");
00646                                                  tp2.setAttribute("dy", FToStr(hl->glyph.yoffset)+"pt");
00647                                                  SetTextProps(&tp2, hl);
00648                                                  tp1 = docu->createTextNode(chx);
00649                                                  tp2.appendChild(tp1);
00650                                                  tp.appendChild(tp2);
00651                                                  ob.appendChild(tp);
00652                                           }
00653                                    break;
00654                             default:
00655                                    break;
00656                             }
00657                             if (Item->GrType != 0)
00658                                    elem->appendChild(defi);
00659                             gr.appendChild(ob);
00660                             elem->appendChild(gr);
00661                      }
00662               }
00663               Lnr++;
00664        }
00665        m_Doc->setCurrentPage(SavedAct);
00666 }
00667 
00668 QString SVGExPlug::SetClipPath(PageItem *ite)
00669 {
00670        QString tmp = "";
00671        FPoint np, np1, np2;
00672        bool nPath = true;
00673        if (ite->PoLine.size() > 3)
00674               {
00675               for (uint poi=0; poi<ite->PoLine.size()-3; poi += 4)
00676                      {
00677                      if (ite->PoLine.point(poi).x() > 900000)
00678                             {
00679                             tmp += "Z ";
00680                             nPath = true;
00681                             continue;
00682                             }
00683                      if (nPath)
00684                             {
00685                             np = ite->PoLine.point(poi);
00686                             tmp += "M"+FToStr(np.x())+" "+FToStr(np.y())+" ";
00687                             nPath = false;
00688                             }
00689                      np = ite->PoLine.point(poi+1);
00690                      tmp += "C"+FToStr(np.x())+" "+FToStr(np.y())+" ";
00691                      np1 = ite->PoLine.point(poi+3);
00692                      tmp += FToStr(np1.x())+" "+FToStr(np1.y())+" ";
00693                      np2 = ite->PoLine.point(poi+2);
00694                      tmp += FToStr(np2.x())+" "+FToStr(np2.y())+" ";
00695                      }
00696               }
00697        return tmp;
00698 }
00699 
00700 QString SVGExPlug::SetClipPathImage(PageItem *ite)
00701 {
00702        QString tmp = "";
00703        FPoint np, np1, np2;
00704        bool nPath = true;
00705        if (ite->imageClip.size() > 3)
00706               {
00707               for (uint poi=0; poi<ite->imageClip.size()-3; poi += 4)
00708                      {
00709                      if (ite->imageClip.point(poi).x() > 900000)
00710                             {
00711                             tmp += "Z ";
00712                             nPath = true;
00713                             continue;
00714                             }
00715                      if (nPath)
00716                             {
00717                             np = ite->imageClip.point(poi);
00718                             tmp += "M"+FToStr(np.x())+" "+FToStr(np.y())+" ";
00719                             nPath = false;
00720                             }
00721                      np = ite->imageClip.point(poi+1);
00722                      tmp += "C"+FToStr(np.x())+" "+FToStr(np.y())+" ";
00723                      np1 = ite->imageClip.point(poi+3);
00724                      tmp += FToStr(np1.x())+" "+FToStr(np1.y())+" ";
00725                      np2 = ite->imageClip.point(poi+2);
00726                      tmp += FToStr(np2.x())+" "+FToStr(np2.y())+" ";
00727                      }
00728               }
00729        return tmp;
00730 }
00731 
00732 QString SVGExPlug::FToStr(double c)
00733 {
00734        QString cc;
00735        return cc.setNum(c);
00736 }
00737 
00738 QString SVGExPlug::IToStr(int c)
00739 {
00740        QString cc;
00741        return cc.setNum(c);
00742 }
00743 
00744 void SVGExPlug::SetTextProps(QDomElement *tp, ScText *hl)
00745 {
00746        int chst = hl->effects() & 127;
00747        if (hl->fillColor() != CommonStrings::None)
00748               tp->setAttribute("fill", SetFarbe(hl->fillColor(), hl->fillShade()));
00749        else
00750               tp->setAttribute("fill", "none");
00751        if ((hl->strokeColor() != CommonStrings::None) && (chst & 4))
00752               {
00753               tp->setAttribute("stroke", SetFarbe(hl->strokeColor(), hl->strokeShade()));
00754               tp->setAttribute("stroke-width", FToStr(hl->font().strokeWidth(hl->fontSize() / 10.0))+"pt");
00755               }
00756        else
00757               tp->setAttribute("stroke", "none");
00758        tp->setAttribute("font-size", (hl->fontSize() / 10.0));
00759        tp->setAttribute("font-family", hl->font().family());
00760        if (chst != 0)
00761               {
00762               if (chst & 64)
00763                      tp->setAttribute("font-variant", "small-caps");
00764               if (chst & 32)
00765                      tp->setAttribute("font-weight", "bold");
00766               if (chst & 16)
00767                      tp->setAttribute("text-decoration", "line-through");
00768               if (chst & 8)
00769                      tp->setAttribute("text-decoration", "underline");
00770               }
00771 }
00772 
00773 QString SVGExPlug::SetFarbe(QString farbe, int shad)
00774 {
00775        const ScColor& col = m_Doc->PageColors[farbe];
00776        return ScColorEngine::getShadeColorProof(col, m_Doc, shad).name();
00777 }
00778 
00779 QString SVGExPlug::GetMultiStroke(struct SingleLine *sl, PageItem *Item)
00780 {
00781        QString tmp = "fill:none; ";
00782        tmp += "stroke:"+SetFarbe(sl->Color, sl->Shade)+"; ";
00783        if (Item->fillTransparency() != 0)
00784               tmp += " stroke-opacity:"+FToStr(1.0 - Item->fillTransparency())+"; ";
00785        tmp += "stroke-width:"+FToStr(sl->Width)+"pt; ";
00786        tmp += "stroke-linecap:";
00787        switch (static_cast<PenCapStyle>(sl->LineEnd))
00788               {
00789               case Qt::FlatCap:
00790                      tmp += "butt;";
00791                      break;
00792               case Qt::SquareCap:
00793                      tmp += "square;";
00794                      break;
00795               case Qt::RoundCap:
00796                      tmp += "round;";
00797                      break;
00798               default:
00799                      tmp += "butt;";
00800                      break;
00801               }
00802        tmp += " stroke-linejoin:";
00803        switch (static_cast<PenJoinStyle>(sl->LineJoin))
00804               {
00805               case Qt::MiterJoin:
00806                      tmp += "miter;";
00807                      break;
00808               case Qt::BevelJoin:
00809                      tmp += "bevel;";
00810                      break;
00811               case Qt::RoundJoin:
00812                      tmp += "round;";
00813                      break;
00814               default:
00815                      tmp += "miter;";
00816                      break;
00817               }
00818        tmp += " stroke-dasharray:";
00819        QString Dt = FToStr(QMAX(2*sl->Width, 1));
00820        QString Da = FToStr(QMAX(6*sl->Width, 1));
00821        switch (static_cast<PenStyle>(sl->Dash))
00822               {
00823               case Qt::SolidLine:
00824                      tmp += "none;";
00825                      break;
00826               case Qt::DashLine:
00827                      tmp += Da+","+Dt+";";
00828                      break;
00829               case Qt::DotLine:
00830                      tmp += Dt+";";
00831                      break;
00832               case Qt::DashDotLine:
00833                      tmp += Da+","+Dt+","+Dt+","+Dt+";";
00834                      break;
00835               case Qt::DashDotDotLine:
00836                      tmp += Da+","+Dt+","+Dt+","+Dt+","+Dt+","+Dt+";";
00837                      break;
00838               default:
00839                      tmp += "none;";
00840                      break;
00841               }
00842        return tmp;
00843 }
00844 #endif
00845 
00846 SVGExPlug::~SVGExPlug()
00847 {
00848 }
00849 
00850 #include "svgexplugin.moc"