Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

util_math.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                           util.cpp  -  description
00009                              -------------------
00010     begin                : Fri Sep 14 2001
00011     copyright            : (C) 2001 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 "util_math.h"
00025 #include <QBitmap>
00026 #include <QFile>
00027 #include <QFileInfo>
00028 #include <QDir>
00029 #include <QCheckBox>
00030 #include <QWidget>
00031 #include <QPixmap>
00032 #include <QList>
00033 #include <QByteArray>
00034 #include <QPolygon>
00035 #include <QImageReader>
00036 
00037 #include <algorithm>
00038 #include "scconfig.h"
00039 
00040 #include "commonstrings.h"
00041 #include <QProcess>
00042 #include "scmessagebox.h"
00043 #include "scpixmapcache.h"
00044 #include "scpaths.h"
00045 
00046 extern "C"
00047 {
00048 #define XMD_H           // shut JPEGlib up
00049 #if defined(Q_OS_UNIXWARE)
00050 #  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
00051 #endif
00052 #include <jpeglib.h>
00053 #include <jerror.h>
00054 #undef HAVE_STDLIB_H
00055 #ifdef const
00056 #  undef const          // remove crazy C hackery in jconfig.h
00057 #endif
00058 }
00059 
00060 #include "pageitem.h"
00061 #include "scribus.h"
00062 #include "scribusdoc.h"
00063 #include "scribusview.h"
00064 /*#include <ft2build.h>
00065 #include FT_FREETYPE_H
00066 #include FT_OUTLINE_H
00067 #include FT_GLYPH_H
00068 */
00069 #include <zlib.h>
00070 
00071 
00072 using namespace std;
00073 
00074 
00075 
00076 uint getDouble(QString in, bool raw)
00077 {
00078     QByteArray bb(4, ' ');
00079     if (raw)
00080     {
00081         // Qt4
00082 /*      bb[3] = static_cast<uchar>(QChar(in.at(0)));
00083         bb[2] = static_cast<uchar>(QChar(in.at(1)));
00084         bb[1] = static_cast<uchar>(QChar(in.at(2)));
00085         bb[0] = static_cast<uchar>(QChar(in.at(3)));*/
00086         bb = bb.insert(3, in.at(0));
00087         bb = bb.insert(2, in.at(1));
00088         bb = bb.insert(1, in.at(2));
00089         bb = bb.insert(0, in.at(3));
00090     }
00091     else
00092     {
00093         // Qt4
00094 //      bb[0] = static_cast<uchar>(QChar(in.at(0)));
00095 //      bb[1] = static_cast<uchar>(QChar(in.at(1)));
00096 //      bb[2] = static_cast<uchar>(QChar(in.at(2)));
00097 //      bb[3] = static_cast<uchar>(QChar(in.at(3)));
00098         bb = bb.insert(0, in.at(0));
00099         bb = bb.insert(1, in.at(1));
00100         bb = bb.insert(2, in.at(2));
00101         bb = bb.insert(3, in.at(3));
00102     }
00103     uint ret;
00104     ret = bb[0] & 0xff;
00105     ret |= (bb[1] << 8) & 0xff00;
00106     ret |= (bb[2] << 16) & 0xff0000;
00107     ret |= (bb[3] << 24) & 0xff000000;
00108     return ret;
00109 }
00110 
00111 QPolygon RegularPolygon(double w, double h, uint c, bool star, double factor, double rota)
00112 {
00113     uint cx = star ? c * 2 : c;
00114     double seg = 360.0 / cx;
00115     double sc = rota + 180.0;
00116     double di = factor;
00117     int mx = 0;
00118     int my = 0;
00119     QPolygon pts(cx);
00120     for (uint x = 0; x < cx; ++x)
00121     {
00122         sc = seg * x + 180.0 + rota;
00123         if (star)
00124         {
00125             double wf = x % 2 == 0 ? w / 2.0 : w / 2.0 * di;
00126             double hf = x % 2 == 0 ? h / 2.0 : h / 2.0 * di;
00127             mx = qRound(sin(sc / 180.0 * M_PI) * (wf) + (w/2.0));
00128             my = qRound(cos(sc / 180.0 * M_PI) * (hf) + (h/2.0));
00129         }
00130         else
00131         {
00132             mx = qRound(sin(sc / 180.0 * M_PI) * (w/2.0) + (w/2.0));
00133             my = qRound(cos(sc / 180.0 * M_PI) * (h/2.0) + (h/2.0));
00134         }
00135         pts.setPoint(x, mx, my);
00136     }
00137     return pts;
00138 }
00139 
00140 FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota)
00141 {
00142     uint cx = star ? c * 2 : c;
00143     double seg = 360.0 / cx;
00144     double sc = rota + 180.0;
00145     double di = factor;
00146     double mx = 0;
00147     double my = 0;
00148     FPointArray pts(cx);
00149     for (uint x = 0; x < cx; ++x)
00150     {
00151         sc = seg * x + 180.0 + rota;
00152         if (star)
00153         {
00154             double wf = x % 2 == 0 ? w / 2.0 : w / 2.0 * di;
00155             double hf = x % 2 == 0 ? h / 2.0 : h / 2.0 * di;
00156             mx = sin(sc / 180.0 * M_PI) * (wf) + (w/2.0);
00157             my = cos(sc / 180.0 * M_PI) * (hf) + (h/2.0);
00158         }
00159         else
00160         {
00161             mx = sin(sc / 180.0 * M_PI) * (w/2.0) + (w/2.0);
00162             my = cos(sc / 180.0 * M_PI) * (h/2.0) + (h/2.0);
00163         }
00164         pts.setPoint(x, mx, my);
00165     }
00166     return pts;
00167 }
00168 
00169 QList<QPainterPath> decomposePath(QPainterPath &path)
00170 {
00171     QList<QPainterPath> ret;
00172     ret.clear();
00173     QPainterPath part;
00174     part = QPainterPath();
00175     bool first = true;
00176     for (int i = 0; i < path.elementCount(); ++i)
00177     {
00178         const QPainterPath::Element &elm = path.elementAt(i);
00179         if ((first) && (elm.type != QPainterPath::MoveToElement))
00180             part.moveTo(elm.x, elm.y);
00181         switch (elm.type)
00182         {
00183             case QPainterPath::MoveToElement:
00184                 if (!first)
00185                 {
00186                     ret.append(part);
00187                     part = QPainterPath();
00188                 }
00189                 first = false;
00190                 part.moveTo(elm.x, elm.y);
00191                 break;
00192             case QPainterPath::LineToElement:
00193                 part.lineTo(elm.x, elm.y);
00194                 break;
00195             case QPainterPath::CurveToElement:
00196                 part.cubicTo(elm.x, elm.y, path.elementAt(i+1).x, path.elementAt(i+1).y, path.elementAt(i+2).x, path.elementAt(i+2).y );
00197                 break;
00198             default:
00199                 break;
00200         }
00201     }
00202     if (!part.isEmpty())
00203         ret.append(part);
00204     return ret;
00205 }
00206 
00207 
00208 
00209 FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
00210 {
00211     if (lineStart == lineEnd)
00212         return FPoint(lineStart.x(), lineStart.y());
00213     
00214     // move lineStart to Origin
00215     p -= FPoint(lineStart.x(), lineStart.y());
00216     lineEnd -= lineStart;
00217     // calc dot product
00218     double lineLengthSquare = lineEnd.x() * lineEnd.x() + lineEnd.y() * lineEnd.y();
00219     double partOfLine = p.x() * lineEnd.x() + p.y() * lineEnd.y() / lineLengthSquare;
00220     // return point on line
00221     return FPoint(lineStart.x() + partOfLine * lineEnd.x(), lineStart.y() + partOfLine * lineEnd.y());
00222 }
00223 
00224 
00225 QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
00226 {
00227     QPolygon cli, outa;
00228     Segs.clear();
00229     if (ina.size() > 3)
00230     {
00231         for (uint poi=0; poi<ina.size()-3; poi += 4)
00232         {
00233             if (ina.point(poi).x() > 900000) // && cli.size() > 0)
00234             {
00235 //              outa << cli.point(cli.size()-1);
00236                 Segs.append(outa.size());
00237                 continue;
00238             }
00239             FPoint a1 = ina.point(poi);
00240             FPoint a2 = ina.point(poi+1);
00241             FPoint a3 = ina.point(poi+3);
00242             FPoint a4 = ina.point(poi+2);
00243             QPainterPath Bez;
00244             Bez.moveTo(a1.x(), a1.y());
00245             Bez.cubicTo(a2.x(), a2.y(), a3.x(), a3.y(), a4.x(), a4.y());
00246             cli = Bez.toFillPolygon().toPolygon();
00247             if (cli.size() > 1)
00248                 outa.putPoints(outa.size(), cli.size()-2, cli);
00249             else
00250                 outa << QPoint(qRound(a4.x()), qRound(a4.y()));
00251         }
00252 //      if (cli.size() > 0)
00253 //          outa << cli.point(cli.size()-1);
00254     }
00255     return outa;
00256 }
00257 
00258 FPoint getMaxClipF(FPointArray* Clip)
00259 {
00260     FPoint np, rp;
00261     double mx = 0;
00262     double my = 0;
00263     uint clipSize=Clip->size();
00264     for (uint c = 0; c < clipSize; ++c)
00265     {
00266         np = Clip->point(c);
00267         if (np.x() > 900000)
00268             continue;
00269         if (np.x() > mx)
00270             mx = np.x();
00271         if (np.y() > my)
00272             my = np.y();
00273     }
00274     rp.setXY(mx, my);
00275     return rp;
00276 }
00277 
00278 FPoint getMinClipF(FPointArray* Clip)
00279 {
00280     FPoint np, rp;
00281     double mx = 99999;
00282     double my = 99999;
00283     uint clipSize=Clip->size();
00284     for (uint c = 0; c < clipSize; ++c)
00285     {
00286         np = Clip->point(c);
00287         if (np.x() > 900000)
00288             continue;
00289         if (np.x() < mx)
00290             mx = np.x();
00291         if (np.y() < my)
00292             my = np.y();
00293     }
00294     rp.setXY(mx, my);
00295     return rp;
00296 }
00297 
00298 
00299 bool compareDouble(double a, double b)
00300 {
00301     if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
00302     {
00303         long al = static_cast<long>(10000 * a);
00304         long bl = static_cast<long>(10000 * b);
00305         return al == bl;
00306     }
00307     return a == b;
00308 }
00309 
00310 
00311 double constrainAngle(double angle, double constrain)
00312 {
00313     double newAngle=angle;
00314     double constrainTo=constrain;
00315     if (newAngle<0.0)
00316         newAngle+=360.0;
00317     newAngle=qRound(angle/constrainTo)*constrainTo;
00318     if (newAngle==360.0)
00319         newAngle=0.0;
00320     return newAngle;
00321 }
00322 
00323 double getRotationFromMatrix(QMatrix& matrix, double def)
00324 {
00325     double value = def;
00326     double norm = sqrt(fabs(matrix.det()));
00327     if (norm > 0.0000001)
00328     {
00329         double m11 = matrix.m11() / norm;
00330         double m12 = matrix.m12() / norm;
00331         double m21 = matrix.m21() / norm;
00332         double m22 = matrix.m22() / norm;
00333         if (fabs(m11) <= 1.0 && fabs(m12) <= 1.0 && fabs(m21) <= 1.0 && fabs(m22) <= 1.0)
00334         {
00335             QMatrix mat(m11, m12, m21, m22, 0, 0);
00336             if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
00337             {
00338                 double ac = acos(mat.m11());
00339                 value = (mat.m21() >= 0.0) ? ac : (-ac);
00340             }
00341         }
00342     }
00343     return value;
00344 }
00345 
Created with personalized Doxygen. This is documentation for GPL software Scribus - Open Source Desktop Publishing.