00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _WORD_DRAW_H_
00014 #define _WORD_DRAW_H_
00015
00016 #include "AImage.h"
00017 #include "PDFgraphing.h"
00018 #include "Word.h"
00019 #include <fstream>
00020 #include <string>
00021
00022 const int ssConst = 20;
00023
00024
00025
00026
00028
00029
00030 class WordDraw
00031 {
00032 public:
00033 WordDraw( int n, const Word& w, bool draw_grid = true ):
00034 ss( ssConst ),
00035
00036 N(n),
00037 betBraids(0),
00038 theLength( 0 )
00039 {
00040 theImage = new CImage( w.length()*(ssConst+1) + 1 , n*(ssConst+1) + 1 );
00041
00042 for (int i=0;i<theImage->getWidth();i++)
00043 for (int j=0;j<theImage->getHeight();j++){
00044 theImage->setRedPixel(i,j,255);
00045 theImage->setBluePixel(i,j,255);
00046 theImage->setGreenPixel(i,j,255);
00047 }
00048
00049 drawCompressedBraid( w );
00050
00051 if (draw_grid){
00052 for (int i=0;i<=(theLength+1)*(ss+1);i+=(ss+1))
00053 drawVerticalGrid( i, (i/(ss+1) % 10 ? 220 :0) );
00054 for (int i=0;i<theImage->getHeight();i+=(ss+1))
00055 drawHorizontalGrid( i );
00056 }
00057
00058 }
00059
00060 WordDraw( int n, const list<Word>& w, bool draw_grid = true ):
00061 ss( ssConst ),
00062
00063 N(n),
00064 betBraids(20),
00065 theLength( 0 )
00066 {
00067 int max_length = 0;
00068 for (list<Word>::const_iterator I=w.begin();I!=w.end();I++)
00069 if (max_length < I->length())
00070 max_length = I->length();
00071
00072 int one_braid_width = n*(6+1)+1;
00073 theImage = new CImage( max_length*(ssConst+1) + 1 , w.size()*one_braid_width + 1 + (w.size()-1)*betBraids );
00074
00075 for (int i=0;i<theImage->getWidth();i++)
00076 for (int j=0;j<theImage->getHeight();j++){
00077 theImage->setRedPixel(i,j,255);
00078 theImage->setBluePixel(i,j,255);
00079 theImage->setGreenPixel(i,j,255);
00080 }
00081
00082 int i_offset=0;
00083 for (list<Word>::const_iterator I=w.begin();I!=w.end();I++,i_offset+=one_braid_width+betBraids)
00084 drawCompressedBraid( *I, i_offset );
00085
00086 if (draw_grid){
00087 for (int i=0;i<=(theLength+1)*(ss+1);i+=(ss+1))
00088 drawVerticalGrid( i , ( i/(ss+1) % 10 ? 220 : 0 ));
00089
00090 i_offset=one_braid_width;
00091 for (int i=0;i<theImage->getHeight();i+=(ss+1)){
00092 if ( i >= i_offset){
00093 i+=betBraids-ss;
00094 i_offset+=one_braid_width+betBraids;
00095 }
00096 drawHorizontalGrid( i );
00097 }
00098 }
00099
00100 }
00101 ~WordDraw() { delete theImage; }
00102 void saveTo( const string& f_name ) {theImage->saveTo(f_name);}
00103
00104 private:
00105
00106
00107
00108
00109
00110
00111
00112
00113 void drawCompressedBraid( const Word& theWord, int vert_offset = 0){
00114 vector<int> positions(N+2,-1);
00115
00116 int i=0;
00117 for (ConstWordIterator wI=theWord.begin();wI!=theWord.end();wI++,i++){
00118 Generator g = *wI;
00119 int absg = abs(g);
00120 int pos = max(positions[absg],max(positions[absg-1],positions[absg+1])) + 1;
00121 drawGenerator( g,pos,vert_offset );
00122 positions[absg] = pos;
00123 if (theLength < pos) theLength = pos;
00124 }
00125
00126 }
00127
00128 void drawGenerator( Generator g, int pos, int vert_offset ){
00129 for (int iss=0;iss<ss;iss++)
00130 for (int jss=0;jss<ss;jss++)
00131 if ( g > 0 ){
00132 theImage->setRedPixel( pos*ss + iss + pos+1, vert_offset+ g + (g - 1)*ss + jss,168);
00133 theImage->setBluePixel( pos*ss + iss + pos+1, vert_offset+ g + (g - 1)*ss + jss,168);
00134 theImage->setGreenPixel( pos*ss + iss + pos+1, vert_offset+g + (g - 1)*ss + jss,168);
00135 } else {
00136 int ag = abs(g);
00137 theImage->setRedPixel( pos*ss +iss + pos+1, vert_offset+ ag + (ag-1)*ss + jss,0);
00138 theImage->setBluePixel( pos*ss +iss + pos+1, vert_offset+ ag + (ag-1)*ss + jss,0);
00139 theImage->setGreenPixel( pos*ss +iss + pos+1,vert_offset+ ag + (ag-1)*ss + jss,0);
00140 }
00141 }
00142
00143 void drawVerticalGrid( int vpos, int color){
00144
00145 for (int i=0;i<theImage->getHeight();i+=2){
00146 theImage->setRedPixel( vpos, i,color);
00147 theImage->setBluePixel( vpos, i, color );
00148 theImage->setGreenPixel( vpos, i, color );
00149 }
00150 }
00151
00152 void drawHorizontalGrid( int hpos){
00153 for (int i=0;i<=(theLength+1)*(ss+1);i+=2){
00154 theImage->setRedPixel( i, hpos,220);
00155 theImage->setBluePixel( i, hpos, 220 );
00156 theImage->setGreenPixel( i, hpos, 220 );
00157 }
00158 }
00159
00160
00161 int N;
00162 CImage* theImage;
00163 int ss;
00164 int theLength;
00165 int betBraids;
00166 };
00167
00168
00169
00170
00171
00172
00173
00174 class RGB
00175 {
00176 public:
00177 RGB(double r, double g, double b): R(r), G(g), B(b) {}
00178 RGB(double gray ): R(gray),G(gray),B(gray) {}
00179
00180
00181 double R;
00182 double G;
00183 double B;
00184 };
00185
00186
00188 class BraidDrawPDF
00189 {
00190 public:
00191
00193
00197 BraidDrawPDF( int n, string t = string() ):
00198 ss( ssConst ),
00199
00200 N(n),
00201 betBraids(0),
00202 theLength( 0 ),
00203 theTitle( t ),
00204 useCircle( false )
00205 {
00206 }
00207
00208 ~BraidDrawPDF() { }
00209
00211 void draw( const Word& w) {
00212
00213 pdf_out.newPage();
00214 drawCompressedBraid( w );
00215
00216 }
00217
00218
00220 void save( const char* f ){
00221 pdf_out.save(f);
00222 }
00223
00225 void setSS(int new_ss ) { ss = new_ss; }
00226
00227
00228 private:
00229
00230 void drawGrid( int nP, int sN) {
00231 for (int i=PDFPage::lMargin();i<=PDFPage::lMargin()+PDFPage::mWidth();i+=(ss))
00232 pdf_out.addObject( nP , new udPDFPageObjectVertLine( i, stripPosition( sN ),tableWidth(), 0.9, true ) );
00233 for (int i=stripPosition( sN );i<stripPosition( sN + 1);i+=(ss))
00234 pdf_out.addObject( nP , new udPDFPageObjectHorizLine( PDFPage::lMargin() ,i,PDFPage::mWidth(), 0.9, true ) );
00235
00236
00237 pdf_out.addObject( nP , new udPDFPageObjectRect(PDFPage::lMargin() , stripPosition( sN + 1) - ss, PDFPage::mWidth(), ss, 0.95, 0.95 ) );
00238
00239
00240
00241 pdf_out.addObject( nP , new udPDFPageObjectText( PDFPage::lMargin() , PDFPage::tMargin() + 10 , theTitle ) );
00242
00243 }
00244
00245 int tableWidth() const { return N*(ss);}
00246
00247 int stripPosition(int i){return i*tableWidth() + i*ss + PDFPage::tMargin() + (theTitle.length() > 0 ? 20 : 0) ;}
00248
00249
00250
00251
00252 private:
00253
00254 void drawCompressedBraid( const Word& theWord, int vert_offset = 0){
00255 vector<int> positions(N+2,-1);
00256
00257
00258
00259 cout << "Positions in page: " << posInPage() << endl;
00260 cout << "Stripes per page : " << stripesInPage() << endl;
00261
00262 int i=0;
00263 int maxSN = 0;
00264 int maxPage = 0;
00265 for (ConstWordIterator wI=theWord.begin();wI!=theWord.end();wI++,i++){
00266 Generator g = *wI;
00267 int absg = abs(g);
00268 int pos = max(positions[absg],max(positions[absg-1],positions[absg+1])) + 1;
00269
00270
00271 if ( maxSN < int(pos / posInPage()) ){
00272 drawGrid(maxPage,maxSN % stripesInPage() );
00273 maxSN = int(pos / posInPage());
00274
00275 }
00276 if ( maxPage < maxSN / stripesInPage() ){
00277 pdf_out.newPage();
00278 maxPage++;
00279
00280
00281 }
00282
00283 positions[absg] = pos;
00284 if (theLength < pos) theLength = pos;
00285
00286 drawGenerator( g,pos,vert_offset );
00287
00288
00289 }
00290 drawGrid(maxPage,maxSN % stripesInPage() );
00291 }
00292
00293 int posInPage() const { return PDFPage::mWidth() / (ss); }
00294 int stripesInPage() const { return PDFPage::mHeight() / ((N+1)*(ss)); }
00295
00296 void drawGenerator( Generator g, int pos, int vert_offset ){
00297
00298 int sPos = pos % posInPage();
00299
00300 int pN = getPageStrip( pos ).first;
00301 int sN = getPageStrip( pos ).second;
00302 int new_vert_offset = stripPosition(sN);
00303
00304 if ( g > 0 ){
00305 if (useCircle)
00306 pdf_out.addObject( pN , new udPDFPageObjectCircle(PDFPage::lMargin() + sPos*ss + double(ss)/2.0 , new_vert_offset + (g-1)*(ss) + double(ss)/2.0, double(ss)/2.0, 0.9, 0.5 ) );
00307 else
00308 pdf_out.addObject( pN , new udPDFPageObjectSquare(PDFPage::lMargin() + sPos*ss , new_vert_offset + (g-1)*(ss), ss, 0.9, 0.5 ) );
00309
00310 } else {
00311 int ag = abs(g);
00312 if (useCircle)
00313 pdf_out.addObject( pN , new udPDFPageObjectCircle(PDFPage::lMargin() + sPos*ss + double(ss)/2.0, new_vert_offset + (ag-1)*(ss)+double(ss)/2.0, double(ss)/2.0, 0.9, 0 ) );
00314 else
00315 pdf_out.addObject( pN , new udPDFPageObjectSquare(PDFPage::lMargin() + sPos*ss, new_vert_offset + (ag-1)*(ss), ss, 0.9, 0 ) );
00316 }
00317 }
00318
00319 pair<int,int> getPageStrip( int pos ) const {
00320 int totSN = pos / posInPage();
00321 int pN = totSN / stripesInPage();
00322 int sN = totSN % stripesInPage();
00323
00324
00325
00326 return pair<int,int>(pN,sN);
00327 }
00328
00329
00330 int N;
00331 PDFStructure pdf_out;
00332 int ss;
00333 int theLength;
00334 int betBraids;
00335 bool useCircle;
00336 string theTitle;
00337 };
00338 #endif