kpresenter

ATFInterpreter.cpp

00001 // -*- Mode: c++-mode; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
00002 /* This file is part of the KDE project
00003    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "ATFInterpreter.h"
00022 
00023 #include <qvaluestack.h>
00024 #include <qfile.h>
00025 
00026 const char ATFInterpreter::PNT_BG[]   = "POINT {";
00027 const char ATFInterpreter::X_BG[]     = "X {";
00028 const char ATFInterpreter::Y_BG[]     = "Y {";
00029 const char ATFInterpreter::ATTR_BG[]  = "ATTRIB {";
00030 const char ATFInterpreter::END[]       = "}";
00031 
00032 // fields
00033 const int ATFInterpreter::ST_WIDTH    = 1;
00034 const int ATFInterpreter::ST_HEIGHT   = 2;
00035 const int ATFInterpreter::ST_VARIABLE = 3;
00036 const int ATFInterpreter::ST_NUMBER   = 4;
00037 const int ATFInterpreter::ST_OPERATOR = 5;
00038 
00039 // operators
00040 const char ATFInterpreter::OP_EQUAL   = '=';
00041 const char ATFInterpreter::OP_PLUS    = '+';
00042 const char ATFInterpreter::OP_MINUS   = '-';
00043 const char ATFInterpreter::OP_MULT    = '*';
00044 const char ATFInterpreter::OP_DIV     = '/';
00045 const char ATFInterpreter::COMMENT    = '#';
00046 
00047 // allowed variables
00048 const char ATFInterpreter::VAR_1      = 'a';
00049 const char ATFInterpreter::VAR_2      = 'b';
00050 const char ATFInterpreter::VAR_3      = 'c';
00051 const char ATFInterpreter::VAR_4      = 'd';
00052 const char ATFInterpreter::VAR_5      = 'e';
00053 const char ATFInterpreter::VAR_6      = 'f';
00054 const char ATFInterpreter::VAR_X      = 'x';
00055 const char ATFInterpreter::VAR_Y      = 'y';
00056 const char ATFInterpreter::VAR_VARIA  = 'v';
00057 const char ATFInterpreter::VAR_PW     = 'p';
00058 const char ATFInterpreter::VAR_W      = 'w';
00059 const char ATFInterpreter::VAR_H      = 'h';
00060 
00061 // level (depth) of the syntax
00062 const int ATFInterpreter::LEVEL_NULL  = 0;
00063 const int ATFInterpreter::LEVEL_POINT = 1;
00064 const int ATFInterpreter::LEVEL_X     = 2;
00065 const int ATFInterpreter::LEVEL_Y     = 3;
00066 const int ATFInterpreter::LEVEL_ATTR  = 4;
00067 
00068 // numbers
00069 const char ATFInterpreter::NUM_0      = '0';
00070 const char ATFInterpreter::NUM_1      = '1';
00071 const char ATFInterpreter::NUM_2      = '2';
00072 const char ATFInterpreter::NUM_3      = '3';
00073 const char ATFInterpreter::NUM_4      = '4';
00074 const char ATFInterpreter::NUM_5      = '5';
00075 const char ATFInterpreter::NUM_6      = '6';
00076 const char ATFInterpreter::NUM_7      = '7';
00077 const char ATFInterpreter::NUM_8      = '8';
00078 const char ATFInterpreter::NUM_9      = '9';
00079 
00080 /******************************************************************/
00081 /* class ATFInterpreter                                           */
00082 /******************************************************************/
00083 
00084 /*====================== constructor =============================*/
00085 ATFInterpreter::ATFInterpreter() {
00086 }
00087 
00088 /*======================= destrcutor =============================*/
00089 ATFInterpreter::~ATFInterpreter()
00090 {
00091     coordList.setAutoDelete(true);
00092     attrLs.setAutoDelete( true );
00093 }
00094 
00095 void ATFInterpreter::load(const QString & fileName)
00096 {
00097     QString line;
00098     QFile ptA(fileName);
00099 
00100     coordList.clear();
00101     lines.clear();
00102 
00103     if (ptA.open(IO_ReadOnly))
00104     {
00105         while (!ptA.atEnd())
00106         {
00107             ptA.readLine(line,255);
00108             lines.append(line.simplifyWhiteSpace());
00109         }
00110         ptA.close();
00111         interpret();
00112     }
00113 }
00114 
00115 QPointArray ATFInterpreter::getPointArray(int wid,int heig)
00116 {
00117     unsigned int px = 0,py = 0,a = 0,b = 0,c = 0,d = 0,e = 0,f = 0;
00118     unsigned int tmp = 0,num = 0;
00119     bool calc = false,res = false;
00120     char op = OP_EQUAL,var = VAR_1;
00121     QPtrList<Sign> slp;
00122     QPointArray pntArray(coordList.count());
00123 
00124     if (!coordList.isEmpty())
00125     {
00126         for (coordPtr=coordList.first();coordPtr != 0;coordPtr=coordList.next())
00127         {
00128             for (unsigned int i = 1; i<= 14; i++)
00129             {
00130                 switch (i)
00131                 {
00132                 case 1: slp = coordPtr->pntX.var1; break;
00133                 case 2: slp = coordPtr->pntX.var2; break;
00134                 case 3: slp = coordPtr->pntX.var3; break;
00135                 case 4: slp = coordPtr->pntX.var4; break;
00136                 case 5: slp = coordPtr->pntX.var5; break;
00137                 case 6: slp = coordPtr->pntX.var6; break;
00138                 case 7: slp = coordPtr->pntX.result; break;
00139                 case 8: slp = coordPtr->pntY.var1; break;
00140                 case 9: slp = coordPtr->pntY.var2; break;
00141                 case 10: slp = coordPtr->pntY.var3; break;
00142                 case 11: slp = coordPtr->pntY.var4; break;
00143                 case 12: slp = coordPtr->pntY.var5; break;
00144                 case 13: slp = coordPtr->pntY.var6; break;
00145                 case 14: slp = coordPtr->pntY.result; break;
00146                 }
00147                 if (!slp.isEmpty())
00148                 {
00149                     tmp = 0;
00150                     for (signPtr=slp.first();signPtr != 0;signPtr=slp.next())
00151                     {
00152                         switch (signPtr->type)
00153                         {
00154                         case ST_WIDTH: { num = wid; calc = true; res = false;} break;
00155                         case ST_HEIGHT: { num = heig; calc = true; res = false;} break;
00156                         case ST_OPERATOR: { op = signPtr->op; calc = false; res = false;} break;
00157                         case ST_VARIABLE: { var = signPtr->var; calc = false; res = true;} break;
00158                         case ST_NUMBER: { num = signPtr->num; calc = true; res = false;} break;
00159                         }
00160                         if (calc)
00161                         {
00162                             switch (op)
00163                             {
00164                             case OP_EQUAL: tmp = num; break;
00165                             case OP_PLUS: tmp += num; break;
00166                             case OP_MINUS: tmp -= num; break;
00167                             case OP_MULT: tmp *= num; break;
00168                             case OP_DIV: tmp /= num; break;
00169                             }
00170                         }
00171                         else if (res)
00172                         {
00173                             switch (var)
00174                             {
00175                             case VAR_1: num = a; break;
00176                             case VAR_2: num = b; break;
00177                             case VAR_3: num = c; break;
00178                             case VAR_4: num = d; break;
00179                             case VAR_5: num = e; break;
00180                             case VAR_6: num = f; break;
00181                             }
00182                             switch (op)
00183                             {
00184                             case OP_EQUAL: tmp = num; break;
00185                             case OP_PLUS: tmp += num; break;
00186                             case OP_MINUS: tmp -= num; break;
00187                             case OP_MULT: tmp *= num; break;
00188                             case OP_DIV: tmp /= num; break;
00189                             }
00190                         }
00191                     }
00192                     if (i == 1 || i == 8) a = tmp;
00193                     if (i == 2 || i == 9) b = tmp;
00194                     if (i == 3 || i == 10) c = tmp;
00195                     if (i == 4 || i == 11) d = tmp;
00196                     if (i == 5 || i == 12) e = tmp;
00197                     if (i == 6 || i == 13) f = tmp;
00198                     if (i == 7) px = tmp;
00199                     if (i == 14) py = tmp;
00200                 }
00201             }
00202             pntArray.setPoint(coordList.at(),px,py);
00203         }
00204     }
00205     return pntArray;
00206 }
00207 
00208 QPtrList<ATFInterpreter::AttribList> ATFInterpreter::getAttribList()
00209 {
00210     if(!attrLs.isEmpty())
00211         return attrLs;
00212 
00213     AttribList *attribPtr;
00214 
00215     if (!coordList.isEmpty())
00216     {
00217         for (coordPtr=coordList.first();coordPtr != 0;coordPtr=coordList.next())
00218         {
00219             attribPtr = new AttribList;
00220             attribPtr->isVariable = coordPtr->isVariable;
00221             attribPtr->pwDiv = coordPtr->pwDiv;
00222             attrLs.append(attribPtr);
00223         }
00224     }
00225     attrLs.setAutoDelete(true);
00226     return attrLs;
00227 }
00228 
00229 void ATFInterpreter::interpret()
00230 {
00231     QValueStack<int> level;
00232     Value value;
00233     bool v = false;
00234     int pw = 1;
00235     CoordStruct coord;
00236     AttribStruct attrib;
00237 
00238     level.push(LEVEL_NULL);
00239 
00240     for (QStringList::Iterator it=lines.begin(); it!=lines.end(); ++it)
00241     {
00242         if (!(*it).isEmpty() && (*it).at(0) != COMMENT)
00243         {
00244             if (level.top() == LEVEL_NULL)
00245             {
00246                 if ((*it) == PNT_BG)
00247                 {
00248                     coordPtr = new Coord;
00249                     level.push(LEVEL_POINT);
00250                 }
00251             }
00252             else if (level.top() == LEVEL_POINT)
00253             {
00254                 if ((*it) == X_BG)
00255                     level.push(LEVEL_X);
00256                 else if ((*it) == Y_BG)
00257                     level.push(LEVEL_Y);
00258                 else if ((*it) == ATTR_BG)
00259                     level.push(LEVEL_ATTR);
00260                 else if ((*it) == QString(END))
00261                 {
00262                     level.pop();
00263                     coordList.append(coordPtr);
00264                 }
00265             }
00266             else if (level.top() == LEVEL_X || level.top() == LEVEL_Y || level.top() == LEVEL_ATTR)
00267             {
00268                 switch (((*it).at(0)).latin1())
00269                 {
00270                 case VAR_1:
00271                 {
00272                     coord.a = (*it);
00273                     value.var1 = getVar(*it);
00274                 } break;
00275                 case VAR_2:
00276                 {
00277                     coord.b = (*it);
00278                     value.var2 = getVar(*it);
00279                 } break;
00280                 case VAR_3:
00281                 {
00282                     coord.c = (*it);
00283                     value.var3 = getVar(*it);
00284                 } break;
00285                 case VAR_4:
00286                 {
00287                     coord.d = (*it);
00288                     value.var4 = getVar(*it);
00289                 } break;
00290                 case VAR_5:
00291                 {
00292                     coord.e = (*it);
00293                     value.var5 = getVar(*it);
00294                 } break;
00295                 case VAR_6:
00296                 {
00297                     coord.f = (*it);
00298                     value.var6 = getVar(*it);
00299                 } break;
00300                 case VAR_X: case VAR_Y:
00301                 {
00302                     coord.result = (*it);
00303                     value.result = getVar(*it);
00304                 } break;
00305                 case VAR_VARIA:
00306                 {
00307                     if ((*it).find('0') != -1) v = false;
00308                     else v = true;
00309                     attrib.isVariable = (*it);
00310                 } break;
00311                 case VAR_PW:
00312                 {
00313                     pw = 1; pw = ((*it).at(4)).latin1() - 48;
00314                     attrib.pwDiv = (*it);
00315                 } break;
00316                 case '}':
00317                 {
00318                     switch (level.top())
00319                     {
00320                     case LEVEL_X:
00321                     {
00322                         coordPtr->pntX = value;
00323                         coord.a = QString::null;
00324                         coord.b = QString::null;
00325                         coord.c = QString::null;
00326                         coord.d = QString::null;
00327                         coord.e = QString::null;
00328                         coord.f = QString::null;
00329                         coord.result = QString::null;
00330                     } break;
00331                     case LEVEL_Y:
00332                     {
00333                         coordPtr->pntY = value;
00334                         coord.a = QString::null;
00335                         coord.b = QString::null;
00336                         coord.c = QString::null;
00337                         coord.d = QString::null;
00338                         coord.e = QString::null;
00339                         coord.f = QString::null;
00340                         coord.result = QString::null;
00341                     } break;
00342                     case LEVEL_ATTR:
00343                     {
00344                         coordPtr->isVariable = v;
00345                         coordPtr->pwDiv = pw;
00346                         pw = 1;
00347                         v = false;
00348                         attrib.isVariable = QString::null;
00349                         attrib.pwDiv = 1;
00350                     } break;
00351                     }
00352                     level.pop();
00353                 } break;
00354                 }
00355             }
00356         }
00357     }
00358 }
00359 
00360 QPtrList<ATFInterpreter::Sign> ATFInterpreter::getVar(const QString &s)
00361 {
00362     QPtrList<Sign> list;
00363 
00364     for (unsigned int i=1; i<s.length(); ++i)
00365     {
00366         if(s.at(i)==' ')
00367             continue;
00368         signPtr = new Sign;
00369         switch (s.at(i).latin1())
00370         {
00371         case VAR_W: signPtr->type = ST_WIDTH; break;
00372         case VAR_H: signPtr->type = ST_HEIGHT; break;
00373         case VAR_1:
00374         {
00375             signPtr->type = ST_VARIABLE;
00376             signPtr->var = VAR_1;
00377         } break;
00378         case VAR_2:
00379         {
00380             signPtr->type = ST_VARIABLE;
00381             signPtr->var = VAR_2;
00382         } break;
00383         case VAR_3:
00384         {
00385             signPtr->type = ST_VARIABLE;
00386             signPtr->var = VAR_3;
00387         } break;
00388         case VAR_4:
00389         {
00390             signPtr->type = ST_VARIABLE;
00391             signPtr->var = VAR_4;
00392         } break;
00393         case VAR_5:
00394         {
00395             signPtr->type = ST_VARIABLE;
00396             signPtr->var = VAR_5;
00397         } break;
00398         case VAR_6:
00399         {
00400             signPtr->type = ST_VARIABLE;
00401             signPtr->var = VAR_6;
00402         } break;
00403         case OP_EQUAL:
00404         {
00405             signPtr->type = ST_OPERATOR;
00406             signPtr->op = OP_EQUAL;
00407         } break;
00408         case OP_PLUS:
00409         {
00410             signPtr->type = ST_OPERATOR;
00411             signPtr->op = OP_PLUS;
00412         } break;
00413         case OP_MINUS:
00414         {
00415             signPtr->type = ST_OPERATOR;
00416             signPtr->op = OP_MINUS;
00417         } break;
00418         case OP_DIV:
00419         {
00420             signPtr->type = ST_OPERATOR;
00421             signPtr->op = OP_DIV;
00422         } break;
00423         case OP_MULT:
00424         {
00425             signPtr->type = ST_OPERATOR;
00426             signPtr->op = OP_MULT;
00427         } break;
00428         case NUM_0: case NUM_1: case NUM_2: case NUM_3: case NUM_4:
00429         case NUM_5: case NUM_6: case NUM_7: case NUM_8: case NUM_9:
00430         {
00431             signPtr->type = ST_NUMBER;
00432             if (s.length() - 1 > i)
00433             {
00434                 switch (s.at(i+1).latin1())
00435                 {
00436                 case NUM_0: case NUM_1: case NUM_2: case NUM_3: case NUM_4:
00437                 case NUM_5: case NUM_6: case NUM_7: case NUM_8: case NUM_9:
00438                 {
00439                     signPtr->num = (s.at(i).latin1() - 48) * 10 + s.at(i+1).latin1() - 48;
00440                     i++;
00441                 } break;
00442                 default:
00443                     signPtr->num = s.at(i).latin1() - 48; break;
00444                 }
00445             }
00446             else
00447                 signPtr->num = s.at(i).latin1() - 48;
00448         } break;
00449         }
00450         list.append(signPtr);
00451     }
00452     return list;
00453 }
KDE Home | KDE Accessibility Home | Description of Access Keys