diff -r 000000000000 -r 42188c7ea2d9 Orb/Doxygen/src/formula.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orb/Doxygen/src/formula.cpp Thu Jan 21 17:29:01 2010 +0000 @@ -0,0 +1,320 @@ +/****************************************************************************** + * + * + * Copyright (C) 1997-2008 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#include +#include + +#include "qtbc.h" +#include +#include +#include +#include + +#include "formula.h" +#include "image.h" +#include "util.h" +#include "message.h" +#include "config.h" +#include "portable.h" +#include "index.h" +#include "doxygen.h" + +Formula::Formula(const char *text) +{ + static int count=0; + number = count++; + form=text; +} + +Formula::~Formula() +{ +} + +int Formula::getId() +{ + return number; +} + +void FormulaList::generateBitmaps(const char *path) +{ + int x1,y1,x2,y2; + QDir d(path); + // store the original directory + if (!d.exists()) { err("Error: Output dir %s does not exist!\n",path); exit(1); } + QCString oldDir = convertToQCString(QDir::currentDirPath()); + // go to the html output directory (i.e. path) + QDir::setCurrent(d.absPath()); + QDir thisDir; + // generate a latex file containing one formula per page. + QCString texName="_formulas.tex"; + QList pagesToGenerate; + pagesToGenerate.setAutoDelete(TRUE); + FormulaListIterator fli(*this); + Formula *formula; + QFile f(texName); + bool formulaError=FALSE; + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + if (Config_getBool("LATEX_BATCHMODE")) t << "\\batchmode" << endl; + t << "\\documentclass{article}" << endl; + t << "\\usepackage{epsfig}" << endl; // for those who want to include images + const char *s=Config_getList("EXTRA_PACKAGES").first(); + while (s) + { + t << "\\usepackage{" << s << "}\n"; + s=Config_getList("EXTRA_PACKAGES").next(); + } + t << "\\pagestyle{empty}" << endl; + t << "\\begin{document}" << endl; + int page=0; + for (fli.toFirst();(formula=fli.current());++fli) + { + QCString resultName; + resultName.sprintf("form_%d.png",formula->getId()); + // only formulas for which no image exists are generated + QFileInfo fi(resultName); + if (!fi.exists()) + { + // we force a pagebreak after each formula + t << formula->getFormulaText() << endl << "\\pagebreak\n\n"; + pagesToGenerate.append(new int(page)); + } + Doxygen::indexList.addImageFile(resultName); + page++; + } + t << "\\end{document}" << endl; + f.close(); + } + if (pagesToGenerate.count()>0) // there are new formulas + { + //printf("Running latex...\n"); + //system("latex _formulas.tex /dev/null"); + QCString latexCmd = Config_getString("LATEX_CMD_NAME"); + if (latexCmd.isEmpty()) latexCmd="latex"; + if (portable_system(latexCmd,"_formulas.tex")!=0) + { + err("Problems running latex. Check your installation or look " + "for typos in _formulas.tex and check _formulas.log!\n"); + formulaError=TRUE; + //return; + } + //printf("Running dvips...\n"); + QListIterator pli(pagesToGenerate); + int *pagePtr; + int pageIndex=1; + for (;(pagePtr=pli.current());++pli,++pageIndex) + { + int pageNum=*pagePtr; + msg("Generating image form_%d.png for formula\n",pageNum); + char dviArgs[4096]; + QCString formBase; + formBase.sprintf("_form%d",pageNum); + // run dvips to convert the page with number pageIndex to an + // encapsulated postscript. + sprintf(dviArgs,"-q -D 600 -E -n 1 -p %d -o %s.eps _formulas.dvi", + pageIndex,formBase.data()); + if (portable_system("dvips",dviArgs)!=0) + { + err("Problems running dvips. Check your installation!\n"); + return; + } + // now we read the generated postscript file to extract the bounding box + QFileInfo fi(formBase+".eps"); + if (fi.exists()) + { + QCString eps = fileToString(formBase+".eps"); + int i=eps.find("%%BoundingBox:"); + if (i!=-1) + { + sscanf(eps.data()+i,"%%%%BoundingBox:%d %d %d %d",&x1,&y1,&x2,&y2); + } + else + { + err("Error: Couldn't extract bounding box!\n"); + } + } + // next we generate a postscript file which contains the eps + // and displays it in the right colors and the right bounding box + f.setName(formBase+".ps"); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "1 1 1 setrgbcolor" << endl; // anti-alias to white background + t << "newpath" << endl; + t << "-1 -1 moveto" << endl; + t << (x2-x1+2) << " -1 lineto" << endl; + t << (x2-x1+2) << " " << (y2-y1+2) << " lineto" << endl; + t << "-1 " << (y2-y1+2) << " lineto" <50) zoomFactor=10; + scaleFactor *= zoomFactor/10.0; + int gx = (((int)((x2-x1)*scaleFactor))+3)&~2; + int gy = (((int)((y2-y1)*scaleFactor))+3)&~2; + // Then we run ghostscript to convert the postscript to a pixmap + // The pixmap is a truecolor image, where only black and white are + // used. + + char gsArgs[4096]; + sprintf(gsArgs,"-q -g%dx%d -r%dx%dx -sDEVICE=ppmraw " + "-sOutputFile=%s.pnm -dNOPAUSE -dBATCH -- %s.ps", + gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72), + formBase.data(),formBase.data() + ); + if (portable_system(portable_ghostScriptCommand(),gsArgs)!=0) + { + err("Problem running ghostscript %s %s. Check your installation!\n",portable_ghostScriptCommand(),gsArgs); + return; + } + f.setName(formBase+".pnm"); + uint imageX=0,imageY=0; + // we read the generated image again, to obtain the pixel data. + if (f.open(IO_ReadOnly)) + { + QTextStream t(&f); + QCString s; + if (!t.eof()) + s=t.readLine(); + if (s.length()<2 || s.left(2)!="P6") + err("Error: ghostscript produced an illegal image format!"); + else + { + // assume the size if after the first line that does not start with + // # excluding the first line of the file. + while (!t.eof() && (s=t.readLine()) && !s.isEmpty() && s.at(0)=='#') { } + sscanf(s,"%d %d",&imageX,&imageY); + } + if (imageX>0 && imageY>0) + { + //printf("Converting image...\n"); + char *data = new char[imageX*imageY*3]; // rgb 8:8:8 format + uint i,x,y,ix,iy; + f.readBlock(data,imageX*imageY*3); + Image srcImage(imageX,imageY), + filteredImage(imageX,imageY), + dstImage(imageX/4,imageY/4); + uchar *ps=srcImage.getData(); + // convert image to black (1) and white (0) index. + for (i=0;igetId() << ":" << formula->getFormulaText() << endl; + } + f.close(); + } + // reset the directory to the original location. + QDir::setCurrent(oldDir); +} + + +#ifdef FORMULA_TEST +int main() +{ + FormulaList fl; + fl.append(new Formula("$x^2$")); + fl.append(new Formula("$y^2$")); + fl.append(new Formula("$\\sqrt{x_0^2+x_1^2+x_2^2}$")); + fl.generateBitmaps("dest"); + return 0; +} +#endif