// alico_image.h - AlicompImage( mm, iPower0, iPower1, 640, 480 ...); /*** #define _IMAGE_WIDTH_SMALL 450 #include // ------------------- GD components #include "gd.h" #include "gdfontg.h" #include "gdfontl.h" #include "gdfontmb.h" #include "gdfonts.h" #include "gdfontt.h" #include //#include "aligwl.h" // see below ***/ #include /***** //void f_line( gdImagePtr& im, int iY0, int iY, int iX1, int iX2 ) { int f_clr( gdImagePtr& im, int x, int pMin, int pMax ) { // P1 < x < P2 : min/max //// Colors: 450 -> 450/4 // Colors: 450 -> 450/9 = 50 int xP; double iR, iG,iB, dP; // Note: Here iR, iG, iB - double ! int ddY; int iC; //dP = 450. / (double)(pMax - pMin); // Colors per power unit //dP = 400. / (double)(pMax - pMin); // Colors per power unit dP = 550. / (double)(pMax - pMin); // Colors per power unit iR=0.; iG=0.; iB =0.; xP = (int)(dP * (x - pMin)); //xP -= (xP % 9 ); // Reduce colors to 450/9 = 50 xP -= (xP % 8 ); // Reduce colors to 400/8 = 50 xP -= (xP % 11 ); // Reduce colors to 400/8 = 50 ddY = xP; if( ddY < 200 ) { iR = ddY * 0.5; iR+= 155.; if( iR < 0 ) iR = 0.; // ? *** } else { //+if( ddY < 400 ) { iR = 255; // 200 - 250 if( ddY <= 250 ) { //iG = ddY - 200; iG = (ddY - 200) * 2; // 0 - 100 // 250 - 400 } else { iG = 100 + (ddY - 250.) * 0.5; } } iC = gdImageColorResolve( im , (int)iR, (int)iG, (int)iB ); return iC; // ----------------------------------------------------- } int f_clrBlue( gdImagePtr& im, int x, int pMin, int pMax ) { // P1 < x <= P2 : min/max // - Colors: 350 -> 350/7 = 50 // Colors: 300 -> 300/6 = 50 int xP; double iR, iG,iB, dP; // Note: Here iR, iG, iB - double ! (multiply) int ddY; int iC; //dP = 350. / (double)(pMax - pMin); // Colors per unit dP = 300. / (double)(pMax - pMin); // Colors per unit iR=0.; iG=0.; iB =0.; xP = (int)(dP * (x - pMin)); //xP -= (xP % 7 ); // Reduce colors to 50 xP -= (xP % 6 ); // Reduce colors to 50 ddY = xP; // <= 240 iR = 100.; // 5 iG = 240. - ddY; // 240 - 160 = 80 iB = 255.; //// > 240 //if( ddY > 240 ) { //if( ddY > 120 && ddY <=180 ) { if( ddY > 160 && ddY <=180 ) { //iG = 120. - (ddY - 120.)*2.; //120 -> 0 iG =80. - (ddY - 160.)*4.; //80 -> 0 } else if( ddY > 180 ) { iG = 0.; //iB = 145. + (350. - (double)ddY); //iB = 135. + (300. - (double)ddY); // 255 -> 135 iB = 75. + (300. - (double)ddY) * 1.5; // 255 -> 135 } iC = gdImageColorResolve( im , (int)iR, (int)iG, (int)iB ); return iC; } int f_clrGreen( gdImagePtr& im, int x, int pMin, int pMax ) { // P1 < x <= P2 : min/max // Colors: 150 -> 150/3 = 50 int xP; double iR, iG,iB, dP; // Note: Here iR, iG, iB - double ! (multiply) int ddY; int iC; dP = 150. / (double)(pMax - pMin); // Colors per unit iR=0.; iG=0.; iB =0.; xP = (int)(dP * (x - pMin)); xP -= (xP % 3 ); // Reduce colors to 50 ddY = xP; // <= 240 iR = 185. - ddY; //*0.5; iG = 240. - ddY; iB = 185. - ddY; //*0.5; iC = gdImageColorResolve( im , (int)iR, (int)iG, (int)iB ); return iC; } // Moved right/left legends // iWk2 += f_moveLeg( im_out, iWk2, iWk2 + iL*2, iYleg, 'R', 50, sAlgo1, brown, dorange ); // iWk2 += iL; // // ty = 'R' or 'L' or 'B' int f_moveLeg( gdImagePtr& im, int iX1, int iX2, int iYleg, const char ty, int iMax, const char *sAlgo1, int brown, int dorange ) { int iL = (int)((double)(iX2 - iX1) * 0.5); int i, iC, iMin = 0, iWk2 = iX1; if( iMax == 0 ) iMax = 1; //gdImageFilledRectangle(im_out, iWk2 , iYleg+2, iWk2 + iL*2, iYleg + 12, blue ); //gdImageFilledRectangle(im_out, iWk2+iL, iYleg+2, iWk2 + iL*2, iYleg + 12, dblue ); // tst //bool bTest = true; bool bTest = false; if( bTest && ty == 'R' ) iX1 = 65; double dStep = ((double)iX2 - (double)iX1 + 1.) / (double)iMax; // tst if( bTest && ty == 'L' ) dStep = ( 600. - (double)iX1 + 1.) / (double)iMax; //for( i = 0; i < iMax; ++i ) { for( i = 1; i <= iMax; ++i ) { if( ty == 'R' ) iC = f_clrBlue( im, i, 0, iMax + 1 ); // + 1 ! *** else iC = f_clrGreen( im, i, 0, iMax + 1 ); gdImageFilledRectangle(im, iX1 + (double)(i - 1)*dStep , iYleg+2, iX1 + (double)i*dStep - 1, iYleg + 12, iC ); } // Offset number //gdImageString(im, gdFontTiny, iWk2+iL*0.5, iYleg + 12, // (unsigned char*)"1", brown ); //gdImageString(im, gdFontTiny, iWk2+iL*1.5, iYleg + 12, // (unsigned char*)"2", brown ); //double dOff = (double)iL * 2. / ((double)iMax*2.); double dOff = (double)iL / (double)iMax; int dOff1 = dOff - 3, dOff2; if( dOff1 < 0 ) dOff1 = 0; char buf10[10]; sprintf( buf10, "%d\0", iMax ); dOff2 = iL*2 - (int)(dOff + (double)strlen( buf10 ) * 2.4 ); // * 2.5 if( ty != 'B' ) { gdImageString(im, gdFontTiny, iWk2 + dOff1, iYleg + 12, (unsigned char*)"1", brown ); gdImageString(im, gdFontTiny, iWk2 + dOff2, iYleg + 12, (unsigned char*)buf10, brown ); } iWk2 += (iL*2 + 3); //tst if( bTest && ty == 'L' ) return iWk2; gdImageString(im, gdFontSmall, iWk2, iYleg , (unsigned char*)sAlgo1, dorange ); if( ty != 'B' ) { // Offset 'offset' gdImageString(im, gdFontTiny, iWk2+5, iYleg + 12, (unsigned char*)"offset", brown ); } iWk2 += (strlen(sAlgo1)*6 + 6); if( ty == 'R' ) { gdImageString(im, gdFontSmall, iWk2, iYleg , (unsigned char*)"moved right", brown ); iWk2 += 11*6; // ty = 'L' } else { gdImageString(im, gdFontSmall, iWk2, iYleg , (unsigned char*)"moved left", brown ); iWk2 += 10*6; } return iWk2; } int f_colWeightLeg( gdImagePtr& im, int iX1, int iX2, int iYleg, string& sSy, int brown ) { int iL = (int)((double)(iX2 - iX1) * 0.5); int i, iC, iMin = 0, iMax = sSy.length(), iWk2 = iX1; if( iMax == 0 ) iMax = 1; //gdImageFilledRectangle(im_out, iWk2 , iYleg+2, iWk2 + iL*2, iYleg + 12, blue ); //gdImageFilledRectangle(im_out, iWk2+iL, iYleg+2, iWk2 + iL*2, iYleg + 12, dblue ); // tst //bool bTest = true; bool bTest = false; if( bTest ) iMax = 50; double dStep = ((double)iX2 - (double)iX1 + 1.) / (double)iMax; // tst if( bTest ) dStep = ( 600. - (double)iX1 + 1.) / (double)iMax; char buf1[2]; buf1[0] = ' '; buf1[1] = 0; for( i = 1; i <= iMax; ++i ) { iC = f_clr( im, iMax - i + 1, 0, iMax + 1 ); // + 1 ! *** gdImageFilledRectangle(im, iX1 + (double)(i - 1)*dStep , iYleg+2, iX1 + (double)i*dStep - 1, iYleg + 12, iC ); if( bTest ) continue; // <---------- buf1[0] = sSy[i - 1]; gdImageString(im, gdFontTiny, iX1 + (double)(i - 0.5)*dStep - 3, iYleg + 12, (unsigned char*)buf1, brown ); } iWk2 += (iL*2 + 3); if( bTest ) return iWk2; gdImageString(im, gdFontSmall, iWk2, iYleg , (unsigned char*)"column weight", brown ); iWk2 += (7*6 + 6); return iWk2; } int f_1stN( int iL ) { // iL = seq len; returns: 1st N to plot if( iL <= 20 ) return 1; // 14 24 34 44 54 64 74 84 94 int a[] = { -1, 1, 2, 2, 4, 4, 5, 5, 5, 5 }; int iB = (int)log10( iL ); // 310: 2,... int i, iFactor=1, iR, i1st; for( i = 0; i < iB; i++ ) iFactor *= 10; // 100 i1st = iL / iFactor; // 3 iR = (int)((a[i1st] * iFactor) * 0.1); // 2 * 10 = 20 - 1st N and up to 20 points max return iR; } // Display seq name // ty = 0 - std, 1 - tiny, 2 - two cols // name length = 10 (12 - tiny) void f_outSeqName( gdImagePtr& im, int i, string& sName, int dX1, int iY, int ty, int iC, int iC2, int iC3 ) { char buf20[20]; int iWk, iL0 = 10; string sWk; if( ty > 0 ) iL0 = 12; iWk = sName.length(); if( iWk > iL0 ) { iWk = iL0; sWk = sName.substr(0,iL0); cout << " - tranc: iL0 = " << iL0 << ", name len = " << sWk.length() << endl; } else { sWk = sName; } cout << " - name len = " << sWk.length() << endl; //sprintf( buf6, "%s\0", (sWk.substr(0,10)).c_str() ); sprintf( buf20, "%s\0", sWk.c_str() ); if( ty < 1 ) { gdImageString(im, gdFontSmall, dX1 - 4 - iWk*6, iY, (unsigned char*)buf20, iC ); } else if( ty < 2 ){ gdImageString(im, gdFontTiny, dX1 - 4 - iWk*5, iY, (unsigned char*)buf20, iC ); // Two cols: } else { //cout << " - i = " << i << endl; gdImageString(im, gdFontTiny, dX1 - 4 - iWk*5 - (i % 2 == 0 ? 0 : iL0 * 5 + 3), iY - 2, (unsigned char*)buf20, i % 2 == 0 ? iC : iC2 ) ; if( i % 2 != 0 ) { //gdImageDashedLine(im, dX1 - 4 - iL0*5 + 2, iY + 2, dX1 - 4, iY + 2, iC3 ); gdImageLine(im, dX1 - 4 - iL0*5 + 2, iY + 2, dX1 - 4, iY + 2, iC3 ); } } } *****/ // ------------------------------------------------------------------- void f_outSameUnpaired( gdImagePtr& im, int iX02, int iY01, int iY02, bool bUnpair, int iGB, int brown ) { if( bUnpair ) { gdImageString(im, gdFontSmall, //(int)((double)(iX01 + iX02 ) * 0.5 - 5.* 4.), iX02 - 6*8 - 4 , (int)((double)(iY01 + iY02 ) * 0.5 - 7.), // tiny = - 2 (unsigned char*)"unpaired", brown ); } else if( iGB == 0 ) { gdImageString(im, gdFontSmall, //(int)((double)(iX01 + iX02 ) * 0.5 - 5.* 2.), iX02 - 6*4 - 4 , (int)((double)(iY01 + iY02 ) * 0.5 - 7.), (unsigned char*)"same", brown ); } } void f_outCompType( gdImagePtr& im, int iX02, int iY01, int iY02, char cCompType, int brown ) { if( cCompType == ' ' ) return; // --------> offsets available char buf10[11]; if( cCompType == 's' ) sprintf( buf10, "same\0" ); else if( cCompType == 'u' ) //sprintf( buf10, "unpaired\0" ); sprintf( buf10, "single\0" ); else //if( cCompType == 'm' ) sprintf( buf10, "mismatch\0" ); gdImageString(im, gdFontSmall, iX02 - 6*strlen(buf10) - 4 , (int)((double)(iY01 + iY02 ) * 0.5 - 7.), // tiny = - 2 (unsigned char*)buf10, brown ); } //void f_oneSeqComp( im_out, mOff, dX1 +ddX1 +1, dY1_wk, iW - dX2 - ddX2 - 1, dY2_wk ); char f_oneSeqComp( gdImagePtr& im, ImageOptions& cfg, mOffDef& mOff0, int iX01, int iY01, int iX02, int iY02, int iMaxClr, int iMinClr //int iMisPos //, int iSeqLen ) { //+cout << "*** f_oneSeqComp. Size = " << mOff0.size() << endl; char cAliCompType = ' '; // 's', 'u', 'm' - same/unpaired/mismatch // Alex // typedef multimap< int, OffsetDescr, less, alloc > mOffDef2; typedef multimap< int, OffsetDescr, less > mOffDef2; mOffDef2 mOff; mOffDef::iterator iiM; OffsetDescr oDescr0, oDescr; //int green = gdImageColorResolve( im, 0, 100, 0); //++int dgreen = gdImageColorResolve( im, 0, 159, 0); int dgreen = gdImageColorResolve( im, 105, 165, 105); //++int blue = gdImageColorResolve( im, 0, 0, 255); //int blue = gdImageColorResolve( im, 100, 240, 255); int blue = gdImageColorResolve( im, 100, 165, 255); //int grey = gdImageColorResolve( im, 222, 222, 222); int brown = gdImageColorResolve( im, 102, 51, 0); //int brown = gdImageColorResolve( im, 152, 101, 0); int white2 = gdImageColorResolve( im, 247, 250, 255); //int unpaired = gdImageColorResolve( im, 240, 200, 0); //int unpaired = gdImageColorResolve( im, 250, 211, 233); int pos0, pos, ddx0, iX1, iX2, iSeqLen, iC; char ty0; bool bUnpair = false; int iBlue = 0, iGreen = 0; // get last pos: iiM = mOff0.end(); iiM--; // always 'e' iSeqLen = (*iiM).first; // Get 1st item: iiM = mOff0.begin(); pos0 = (*iiM).first; oDescr0 = (*iiM).second; ty0 = oDescr0.ty; ddx0 = oDescr0.ddx; for( ++iiM; iiM != mOff0.end(); ++iiM ) { pos = (*iiM).first; //+cout << " - pos " << pos0 << ", " << pos << endl; // Add to another map //if( ty0 == 'g' || ty0 == 'd' ) { // Unpaired (pos = -1 to be the 1st ) if( ty0 == 'u' || ty0 == 'm' ) { // unpaired/mismatch bUnpair = true; cAliCompType = ty0; oDescr0.x1 = 0; // starting from 0 oDescr0.x2 = iSeqLen; mOff.insert( mOffDef2::value_type( (const int) -1, oDescr0 ) ); // Paired } else if( ty0 != '0' ) { if( ty0 != 'd' || ddx0 != 0 ) { // ('d' & 0) same as '0' oDescr0.x1 = pos0; // starting from 0 oDescr0.x2 = pos; // - 1; *** next to the last: // to plot to start of the next pos ! mOff.insert( mOffDef2::value_type( (const int) abs( ddx0 ), oDescr0 ) ); } } pos0 = pos; oDescr0 = (*iiM).second; ty0 = oDescr0.ty; ddx0 = oDescr0.ddx; /** if( ty0 == 'e' ) { iSeqLen = pos; // + 1; // ******** ? //break; } **/ } if( mOff.empty() ) { // only 'same' ? //+f_outSameUnpaired( im, iX02, iY01, iY02, bUnpair, 0, brown ); if( cAliCompType == ' ' ) //&& (iGreen + iBlue) == 0 ) cAliCompType = 's'; // same return cAliCompType; // ------------------------------> } //bool bUnpair = false; // *** see above //int iBlue =0, iGreen = 0; for( iiM = mOff.begin(); iiM != mOff.end(); ++iiM ) { oDescr = (*iiM).second; iX1 = (double)(iX02 - iX01) * (double)oDescr.x1 / (double)iSeqLen + (double)iX01; iX2 = (double)(iX02 - iX01) * (double)oDescr.x2 / (double)iSeqLen + (double)iX01; //+cout << " - x1/2 = " << oDescr.x1 << ", " << oDescr.x2 << endl; //+cout << " - X1/2 = " << iX1 << ", " << iX2 << endl; //++if( oDescr.ddx < 0 ) { //++ iC = dgreen; //} else if( oDescr.ddx == 0 ) { // gap if( oDescr.ty == 'd' ) { if( oDescr.ddx > 0 ) { //iC = blue; iC = f_clrBlue( im, oDescr.ddx, iMinClr, iMaxClr ); ++iBlue; } else if( oDescr.ddx < 0 ) { iC = f_clrGreen( im, -oDescr.ddx, iMinClr, iMaxClr ); //dgreen; ++iGreen; } } else if( oDescr.ty == 'g' ) { // gap iC = cfg.gapColor; //white2; //brown; //grey; } else if( oDescr.ty == 'u' || oDescr.ty == 'm' ) { iC = cfg.unpairColor; bUnpair = true; //cout << "***unpairColor" << endl; } if( oDescr.ty == 'g' ) { // gap double dWk = (double)( iY02 - iY01 ) * 0.25; if( dWk < 1. ) dWk = 1.; gdImageFilledRectangle( im , iX1, iY01+(int)dWk, iX2, iY02 - (int)dWk, iC ); // ? } else { gdImageFilledRectangle( im , iX1, iY01+1, iX2, iY02 - 1, iC ); // ? } } // 'same/unpaired' - Small font /** if( bUnpair ) { gdImageString(im, gdFontSmall, //(int)((double)(iX01 + iX02 ) * 0.5 - 5.* 4.), iX02 - 6*8 - 4 , (int)((double)(iY01 + iY02 ) * 0.5 - 7.), // tiny = - 2 (unsigned char*)"unpaired", brown ); } else if( (iGreen + iBlue) == 0 ) { gdImageString(im, gdFontSmall, //(int)((double)(iX01 + iX02 ) * 0.5 - 5.* 2.), iX02 - 6*4 - 4 , (int)((double)(iY01 + iY02 ) * 0.5 - 7.), (unsigned char*)"same", brown ); } **/ //+f_outSameUnpaired( im, iX02, iY01, iY02, bUnpair, iGreen + iBlue, brown ); // 'same/unpaired' - Tiny font // . . . // 'same/unpaired' - Tiny font/two cols // . . . if( cAliCompType == ' ' && (iGreen + iBlue) == 0 ) cAliCompType = 's'; // same return cAliCompType; } void f_outMisMark( gdImagePtr& im, ImageOptions& image_cfg, int iP, int iLen, int iX1, int iY1, int iX2, int iY2, int iC, int red ) { int iX, dX = 5; //10; if( iLen == 0 ) return; // -----------> ? double dWk = (double)(iX2 - iX1 +1 ) * (double)(iP - 1) / (double)iLen + 0.5; iX = iX1 + (int)dWk; if( iX + dX > iX2 ) // adjust at end iX = iX2 - dX; gdImageFilledRectangle( im, iX, iY1, iX + dX, iY2 , iC ); gdImageRectangle ( im, iX, iY1, iX + dX, iY2 , red ); } //AlicompImage( vANames, vOffs, image_cfg, "lact1.png", sTit, sAlgo1, sAlgo2 ); //void AlicompImage( vSNamesDef& vSNames , vOffsDef& vOffs, void AlicompImage( Align& oAli, ImageOptions& image_cfg, const char *sFName, const char *sTit , const char *sAlgo1, const char *sAlgo2 ) { vSNamesDef& vSNames = *(oAli.pSNames); vOffsDef& vOffs = *(oAli.pOffs); int iW=image_cfg.iW, iH = image_cfg.iH; cout << "*** AlicompIma W/H: " << iW << ", " << iH << endl; // Seq len: mOffDef mOff = vOffs[0]; mOffDef::iterator iiM; mOffDef::reverse_iterator irM = mOff.rbegin(); // Just to get seq len OffsetDescr oDescr = (*irM).second, oD1; int iSeqLen = (*irM).first; //iSeqLen++; // *** !!!!!!!! ???????? int nSeq = vSNames.size(); // Seq Names vector size cout << " - Seq Len = " << iSeqLen << ", Number of Seqs = " << nSeq << endl; //bool bColWeight = true, bMoveLeft = true, bMoveRight = true; bool bColWeight = true, bMoveLeft = false, bMoveRight = false; bool bMismatch = false; //+string& sWL = *(oAli.pWeightLine); // *NIK rejected * 15.06.2001 int i, j=0, iWk, iWk2, dX_wk, dY_wk, dY1_wk, dY2_wk, iC; // iWk1, //+if( sWL.length() < 1 ) // *NIK rejected //+ bColWeight = false; // Moved left/right ? for( i = 0; i < nSeq; ++i ) { mOff = vOffs[i]; for( iiM = mOff.begin(); iiM != mOff.end(); ++iiM ) { oD1 = (*iiM).second; if( oD1.ty = 'd' ) { if( oD1.ddx > 0 ) bMoveRight = true; else if( oD1.ddx < 0 ) bMoveLeft = true; } } } if( bMoveRight ) cout << " -- Move Right" << endl; if( bMoveLeft ) cout << " -- Move Left" << endl; FILE *out; gdImagePtr im_out; // Color indexes int white; int blue, lblue; int red; int green, dgreen; int white2, lwhite, lwhite2, brown, brown2; int gray, lgray, vlgray, black; //+int i, j=0, iWk, iWk1, iWk2, dX_wk, dY_wk, dY1_wk, dY2_wk, iC; //++int iW=800, iH=480; int dX1, dX2, dY1, dY2, ddX1, ddX2, ddY2; //int dSP1, dSP2; // pixels in one space double dSP1, dSP2; // pixels in one space double dYLim0 = 6., dYLim1 = 11.;// 0 - go to two cols of names, 1 - go tiny font int SN1 = 10 ; //, SN2 ; // 1st numbers int SL1 , SL2 ; // len in dSN units double xP; //, yP; // Factor; N -> pixels double dWk, d_dY, iYwei; //int iX1, iX2; string sWk; // Offsets: //dX1 = 32; dX2 = 32; dY1 = 16; dY2 = 16 + 16 + 16 ; //16; //+dX1 = 42; dX2 = 22; dY1 = 16; dY2 = 8 + 16 + 16 + 16 ; //16; dX1 = 42; dX2 = 22; dY1 = 26; dY2 = 8 + 16 + 16; // + 16 ; //16; ddX1 = ddX2 = 0; //7; ****************** // Small font iWk = 7; // 7*6 = 42 - at least to place "weight" // max seq name for( i = 0; i < nSeq; ++i ) { if( (iWk2 = vSNames[i].length()) > iWk ) iWk = iWk2; } if( iWk > 10 ) // 10 letters in a name at most iWk = 10; dX1 = 10 + iWk * 6; dY1 += 16; // Upper scale dY1 += 2; // Subtitle //dY2 -= 16; // Weight line moved inside // MoveLeft at Bottom: if( bColWeight == true && bMoveLeft == true && bMoveRight == true ) dY2 +=(11+1); int dY_WL = image_cfg.WLwidth, iLegLineGap = 4; //7; // WL - bottom if( image_cfg.WLtype == 0 ) { ddY2 = 0; dY2 += (image_cfg.WLwidth+iLegLineGap*3); // + 4 * 3 = 12 iYwei = iH - dY2 + 15; //ddY2; // WL-inside } else if( image_cfg.WLtype != 0 ) { // == 1 ) { //ddY2 = 7+4; // Weight line space // +2 ***13.06.2001 ddY2 = image_cfg.WLwidth+4; // Weight line space // +2 ***13.06.2001 iYwei = iH - dY2 - dY_WL; //ddY2; // inside } //- ddY2 = 7; //SN2 = f_1stN( wSeq2.len() ); SL2 = nSeq; //(int)(wSeq2.len() / SN2) + 1; //dSP2 = (int)((double)(iH - dY1 - dY2) / SL2 + 0.5); //+dSP2 = (double)(iH - dY1 - dY2) / SL2; // + 0.5; dSP2 = (double)(iH - dY1 - dY2 - ddY2) / SL2; // + 0.5; // +wei line cout << "--- dSP2(Y) = " << dSP2 << endl; if( dSP2 < dYLim0 ) dX1 += dX1; //SL1 = 17; SL2 = 17; //dSP1 = 34; dSP2 = 26; //xP = 3.4; //yP = 2.6; SN1 = f_1stN( iSeqLen ); SL1 = (int)(iSeqLen / SN1); // + 1; //++ if( SL1 * SN1 < iSeqLen ) //++ SL1++; //dSP1 = (int)((double)(iW - dX1 - dX2) / SL1 + 0.5); //+dSP1 = (double)(iW - dX1 - dX2 - ddX1 - ddX2 ) / SL1; dSP1 = (double)(iW - dX1 - dX2 - ddX1 - ddX2 ) * SN1/ iSeqLen; xP = (double)dSP1 / SN1; //yP = (double)dSP2 / SN2; /***** // Tune dX2, dY1 a little: dY1 = iH - dY2 - SL2 * dSP2; dX2 = iW - dX1 - SL1 * dSP1; #ifdef _TRACE cout << " -- SL1 (17) = " << SL1 << ", dSP1 (34) = " << dSP1 << ", xP (?3.4) = " << xP << endl; cout << " -- SL2 (17) = " << SL2 << ", dSP2 (26) = " << dSP2 << ", yP (?2.6) = " << yP << endl; #endif *****/ //+char buf100[100]; // Create output image im_out = gdImageCreate( iW, iH ); int yellow = gdImageColorResolve( im_out, 255, 190, 0 ); int orange = gdImageColorResolve( im_out, 255, 100, 0 ); int dorange= gdImageColorResolve( im_out, 160, 70, 0 ); int dgray = gdImageColorAllocate(im_out, 180, 180, 180); int dblue = gdImageColorAllocate(im_out, 0, 0, 170); int unpaired = gdImageColorResolve( im_out, 250, 211, 233); int mismark = gdImageColorResolve( im_out, 230, 190, 211); //int lblack = gdImageColorResolve( im_out, 150, 150, 150); int lblack = gdImageColorResolve( im_out, 140, 140, 140); //int lblack = gdImageColorResolve( im_out, 110, 110, 110); white = gdImageColorAllocate(im_out , 255, 255, 255); white2 = gdImageColorAllocate(im_out, 247, 250, 255); //pwhite = gdImageColorAllocate(im_out2, 255, 255, 127); // Set transparent color. //gdImageColorTransparent(im_out , white); red = gdImageColorAllocate(im_out , 255, 0, 0); green = gdImageColorAllocate(im_out , 0, 255, 0); //dgreen= gdImageColorAllocate(im_out , 0, 100, 0); dgreen= gdImageColorAllocate(im_out , 0, 159, 0); blue = gdImageColorAllocate(im_out , 0, 0, 255); lblue = gdImageColorAllocate(im_out , 185, 215, 255); //lblue = gdImageColorAllocate(im_out , 100, 150, 200); brown = gdImageColorAllocate(im_out , 102, 51, 0); black = gdImageColorAllocate(im_out, 0, 0, 0); brown2 = gdImageColorAllocate(im_out, 7, 0, 0); gray = gdImageColorAllocate(im_out, 200, 200, 200); lgray = gdImageColorAllocate(im_out, 222, 222, 222); vlgray = gdImageColorAllocate(im_out, 250, 250, 250); lwhite = gdImageColorAllocate(im_out, 255, 250, 245); //lwhite2= gdImageColorAllocate(im_out, 255, 249, 232); //lwhite2= gdImageColorAllocate(im_out, 255, 240, 230); //lwhite2= gdImageColorAllocate(im_out, 247, 255, 255); lwhite2= gdImageColorAllocate(im_out, 247, 247, 255); gdImageFilledRectangle( im_out , 0, 0, iW - 1, iH - 1, white); // ? // internal gdImageFilledRectangle( im_out , dX1, dY1, iW - dX2, iH - dY2, lwhite ); //white2); for( i = 0; i < 5; i++ ) { //iWk = 41 - i*5; // 0 = lgray 31 iWk = 50 - i*5; // 0 = lgray 31 iC = gdImageColorAllocate(im_out, 255 - iWk, 255 - iWk, 255 - iWk); gdImageLine(im_out, 1+i, 1+i, iW - i, 1+i, iC); gdImageLine(im_out, 1+i, 1+i, 1+i , iH - i, iC); } gdImageFilledRectangle(im_out, 1+i, 1+i, iW - i , dY1 - 1, iC ); gdImageFilledRectangle(im_out, 1+i, 1+i, dX1 - 1, iH - i, iC ); int iC2 = iC; // Light gray at right-lower: gdImageLine(im_out, iW - 1, iH - 1, iW - 1, 1 , gray); gdImageLine(im_out, iW - 1, iH - 1, 1 , iH - 1, gray); gdImageFilledRectangle(im_out, iW - dX2 + 1, dY1, iW - i, iH - i, iC2); gdImageFilledRectangle(im_out, dX1 , iH - dY2 + 1 ,iW - i, iH - i, iC2); // White lines: (..dark lines see below) gdImageLine(im_out, dX1 - 1 , dY1 - 1 , iW - dX2 + 1, dY1 - 1 , white); gdImageLine(im_out, dX1 - 1 , dY1 - 1 , dX1 - 1 , iH - dY2 + 1, white); gdImageLine(im_out, dX1 - 2 , dY1 - 2 , iW - dX2 + 2, dY1 - 2 , white); gdImageLine(im_out, dX1 - 2 , dY1 - 2 , dX1 - 2 , iH - dY2 + 2, white); gdImageLine(im_out, dX1 - 3 , dY1 - 2 , dX1 - 3 , iH - dY2 + 2, white); // Left-upper black frame: gdImageLine(im_out, 0, 0, iW - 1, 0, black); gdImageLine(im_out, 0, 0, 0 , iH - 1, black); char buf6[7]; image_cfg.gapColor = lblack; //lblack; //gray; //lgray; //gray image_cfg.unpairColor = unpaired; //lgray; //gray // Weight line: //#define _ALIG_WL_ORDERED #include "aligwl.h" //#undef _ALIG_WL_ORDERED /***** int iYwei = iH - dY2 - ddY2; // inside //gdImageString(im_out, gdFontTiny, dX1 - 5*11 - 4, iYwei - 2, // (unsigned char*)"weight line", dorange ); //brown ); gdImageString(im_out, gdFontTiny, dX1 - 5*6 - 4, iYwei - 2, (unsigned char*)"weight", dorange ); //brown ); //gdImageFilledRectangle(im_out, dX1 + 1, iYwei, iW - dX2 - 1, iH - dY2 - 1, white2 ); //gdImageFilledRectangle(im_out, dX1 + 1+20, iYwei, dX1 + 1+50, iH - dY2 - 1, yellow ); //gdImageFilledRectangle(im_out, dX1 + 1+51, iYwei, dX1 + 1+100, iH - dY2 - 1, red ); //gdImageFilledRectangle(im_out, dX1 + 1+150, iYwei, dX1 + 1+200, iH - dY2 - 1, dorange ); //bool bColWeight = true; //string sWL; //string& sWL = *(oAli.pWeightLine); //nph-malign: //sWL = ".*+.+**.*.**.+.+.+++.+++*+*+.*+*+.+++.+*+++*+.*+..*.....+.++.**....++++***+**+.*"; //ClustalW: //sWL = " :: ::* * ** : : :..* * : * . .. *: .. : .::: ** *"; int iSy; //double dWL = ((double)(iW - dX1 - dX2 ) + 1.) / (double)(iSeqLen - 1); // *** -1 double dWL = ((double)(iW - dX1 - dX2 ) ) / (double)iSeqLen; //cout << " ** sWL len = " << sWL.length() << " dWL = " << dWL << endl; //cout << " - last pos iW - dX2 = " << iW - dX2 << ", dX1 + i*dWL = " << dX1 + 80*dWL << endl; for( i = 0; i < sWL.length(); ++i ) { if( i >= iSeqLen ) break; // ---------> iSy = 4; // ' ' - blank if( sWL[i] == '.' ) iSy = 3; if( sWL[i] == ':' ) iSy = 2; if( sWL[i] == '+' ) iSy = 2; if( sWL[i] == '*' ) iSy = 1; iC = f_clr( im_out, iSy, 0, 5 ); gdImageFilledRectangle(im_out, dX1 + (double)i * dWL + 1, iYwei, dX1 + (double)(i+1.) * dWL, iH - dY2 - 1, iC ); } *****/ // Find min/max offset and set max clr: int iMaxClr = 0, iMinClr = iSeqLen, iMinOff, iMaxOff; for( i = 0; i < nSeq; ++i ) { mOff = vOffs[i]; for( iiM = mOff.begin(); iiM != mOff.end(); ++iiM ) { oDescr = (*iiM).second; iWk = abs(oDescr.ddx); if( iWk > iMaxClr ) iMaxClr = iWk; // max if( iWk < iMinClr && iWk > 0 ) iMinClr = iWk; // min } } cout << " -- Max ddx = " << iMaxClr << ", min ddx = " << iMinClr << endl; iMinOff = iMinClr; // ? iMaxOff = iMaxClr; // ? --iMinClr; ++iMaxClr; // to be not very deep if( image_cfg.offType == 0 ) // abs iMinClr = 0; // Force at list two color at legend //+if( iMaxClr < 3 ) //+ iMaxClr = 3; if( (iMaxClr - iMinClr) < 3 ) ++iMaxClr; // X-lines: //+dY_wk = iH - dY2 - (int)dSP2; // + X_year; //dY_wk = iH - dY2 - (int)dSP2 - ddY2; // +wei line d_dY = 0.12 * dSP2; d_dY = 0; // ********************** //dY1_wk = iH - dY2 - (int)(dSP2 + d_dY); //dY2_wk = iH - dY2 - d_dY; // Alex // vector< char, alloc > vComp( nSeq, ' ' ); // 's' - same, 'u' - unpaired, 'm' - mismatch vector< char > vComp( nSeq, ' ' ); // 's' - same, 'u' - unpaired, 'm' - mismatch for( i = 1; i <= nSeq; i++ ) { //+dWk = (double)(iH - dY2) - dSP2 * (double)i; dWk = (double)(iH - dY2) - dSP2 * (double)i - (double)ddY2; // wei inside dY_wk = (int)dWk; dY1_wk = (int)( (double)(iH - dY2) - dSP2 * (double)i + d_dY - (double)ddY2); dY2_wk = (int)( (double)(iH - dY2) - dSP2 * (double)(i - 1) - d_dY - (double)ddY2); //cout << " - dY_wk = " << dY_wk << endl; // *** See also after Y-lines ! iC = lgray; if( i % 2 == 0 ) iC = lblue; //iWk2 = 0; //gdImageDashedLine(im_out, dX1, dY_wk, iW - dX2, dY_wk, iC); if( i % 2 == 0 ) { gdImageFilledRectangle( im_out , dX1 +ddX1 +1, dY1_wk, iW - dX2 - ddX2 - 1, dY2_wk, white ); } if( i % 2 == 0 || i == 1) { gdImageRectangle ( im_out , dX1 +ddX1 +1, dY1_wk, iW - dX2 - ddX2 - 1, dY2_wk, gray ); //brown ); } // lgray a little tune.. if( i % 2 > 0 ) { //|| i == 1) { gdImageLine ( im_out , dX1 +ddX1+1, dY2_wk + 1, iW - dX2 - ddX2 - 1, dY2_wk + 1, lgray ); gdImageLine ( im_out , dX1 +ddX1+1, dY2_wk - 1, iW - dX2 - ddX2 - 1, dY2_wk - 1, lgray ); } mOff = vOffs[nSeq - i]; vComp[nSeq - i] = f_oneSeqComp( im_out, image_cfg, mOff, dX1 +ddX1 +1, dY1_wk, iW - dX2 - ddX2 - 1, dY2_wk, iMaxClr, iMinClr ); // Mark mismatch pos iWk = (*oAli.pMisPos)[nSeq - i]; if( iWk > -1 ) { bMismatch = true; // for legend f_outMisMark( im_out, image_cfg, iWk, iSeqLen, dX1 +ddX1 +1, dY1_wk+2, iW - dX2 - ddX2 - 1, dY2_wk - 1, mismark, red ); } //** sWk = vSNames[nSeq - i]; /** iWk = sWk.length(); if( iWk > 10 ) { iWk = 10; sWk.substr(0,10); } sprintf( buf6, "%s\0", (sWk.substr(0,10)).c_str() ); //gdImageString(im_out, gdFontSmall, 7, dY1_wk, gdImageString(im_out, gdFontSmall, dX1 - 4 - iWk*6, dY1_wk, (unsigned char*)buf6, brown2 ); **/ f_outSeqName( im_out, i, sWk, dX1, dY1_wk, ( dSP2 < dYLim1 ? (dSP2 < dYLim0 ? 2 : 1) : 0 ), brown2, brown, gray ); // type = 0 - std, 1 - tiny, 2 - two cols //** / if( i % 2 == 0 ) { //|| i == 1) { gdImageLine ( im_out , dX1 +ddX1 +1, dY2_wk, iW - dX2 - ddX2 - 1, dY2_wk, black); //gray ); //brown ); } else { gdImageLine ( im_out , dX1 +ddX1 +1, dY2_wk, iW - dX2 - ddX2 - 1, dY2_wk, white ); //gray ); //brown ); } //dY_wk -= dSP2; } // Y-lines: dX_wk = dX1 + ddX1 + (int)dSP1 ; // + X_year; // 1st SEQ //for( i = 1; i < SL1; i++ ) { for( i = 1; i <= SL1; i++ ) { //-for( i = 0; i <= SL1; i++ ) { iC = lgray; if( i % 2 == 0 ) iC = lblue; iWk2 = 0; //+if( ( i + 1 ) % 2 == 0 ) { //+ gdImageFilledRectangle( im_out , dX_wk - dSP1 +1, dY1+1, dX_wk - 1, //+ iH - dY2 - 1, lwhite2); // transporent? //+} gdImageDashedLine(im_out, dX_wk, dY1, dX_wk, iH - dY2, iC ); if( i % 2 == 0 ) { sprintf( buf6, "%d\0", i*SN1); gdImageString(im_out, gdFontSmall, dX_wk - 6, dY1 - 16, (unsigned char*)buf6, brown2 ); gdImageString(im_out, gdFontSmall, dX_wk - 6, iH - dY2, //dY1 + 6, (unsigned char*)buf6, brown2 ); //(unsigned char*)"20", brown2 ); f_scaleStroke( im_out, 'u', dX_wk, dY1 ); // - 1 ); f_scaleStroke( im_out, 'd', dX_wk, iH - dY2 + 1 ); } if( i == 1 ) { gdImageString(im_out, gdFontSmall, dX1, dY1 - 16, (unsigned char*)"1", brown2 ); gdImageString(im_out, gdFontSmall, dX1, iH - dY2, //dY1 + 6, (unsigned char*)"1", brown2 ); } //+gdImageLine(im_out, dX_wk, dY1, dX_wk, iH - dY2, iC); //dX_wk += dSP1; dWk = (double)dX1 + ddX1 + dSP1 * (double)(i+1); dX_wk = (int)dWk; } // (After Y-lines!) // Comparison result types at right: for( i = 1; i <= nSeq; i++ ) { dWk = (double)(iH - dY2) - dSP2 * (double)i - (double)ddY2; // wei inside dY1_wk = (int)( (double)(iH - dY2) - dSP2 * (double)i + d_dY - (double)ddY2); dY2_wk = (int)( (double)(iH - dY2) - dSP2 * (double)(i - 1) - d_dY - (double)ddY2); f_outCompType( im_out, iW - dX2 - ddX2 - 1, dY1_wk, dY2_wk, vComp[nSeq - i], brown ); } //cout << " - Lines" << endl; // ..white lines see above gdImageLine(im_out, dX1 , dY1 , iW - dX2, dY1, brown); gdImageLine(im_out, dX1 , dY1 , dX1 , iH - dY2, brown); gdImageLine(im_out, dX1 , iH - dY2, iW - dX2, iH - dY2, brown); gdImageLine(im_out, iW - dX2, dY1, iW - dX2, iH - dY2, brown); // Legends: //+int iL, iYleg = iH - dY2 + 16 + 16; int iL, iYleg = iH - dY2 + 14; // wei inside int iLG; // gap between legends = iL (iL/2) if( image_cfg.WLtype == 0 ) // wei at bottom iYleg = (iYwei + dY_WL + iLegLineGap*3 ); gdImageString(im_out, gdFontSmall, dX1, iYleg , (unsigned char*)"Legends: ", brown ); // + 11 * 6 iWk = iYleg + 5; iL = 25; //dSP1; // * 2; // *** 25*2 =50 colors iLG = iL; if( iW <= 600 ) //400 ) iLG = iL/2; iWk2 = dX1 + 9*6 + iLG; int iWk2_0 = iWk2; // for 'same' gdImageFilledRectangle(im_out, iWk2, iYleg+2, iWk2 + iL/2, iYleg + 12, image_cfg.gapColor ); //dgray ); //image_cfg.gapColor ); iWk2 += (iL/2 + 3); gdImageString(im_out, gdFontSmall, iWk2, iYleg , (unsigned char*)"gap", brown ); // + 11 * 6 iWk2 += (iLG + 3*6); // Moved right /*** gdImageFilledRectangle(im_out, iWk2 , iYleg+2, iWk2 + iL*2, iYleg + 12, blue ); gdImageFilledRectangle(im_out, iWk2+iL, iYleg+2, iWk2 + iL*2, iYleg + 12, dblue ); // Offset number gdImageString(im_out, gdFontTiny, iWk2+iL*0.5, iYleg + 12, (unsigned char*)"1", brown ); gdImageString(im_out, gdFontTiny, iWk2+iL*1.5, iYleg + 12, (unsigned char*)"2", brown ); iWk2 += (iL*2 + 3); gdImageString(im_out, gdFontSmall, iWk2, iYleg , (unsigned char*)sAlgo1, dorange ); // Offset 'offset' gdImageString(im_out, gdFontTiny, iWk2, iYleg + 12, (unsigned char*)"offset", brown ); iWk2 += (strlen(sAlgo1)*6 + 6); gdImageString(im_out, gdFontSmall, iWk2, iYleg , (unsigned char*)"moved right", brown ); iWk2 += (iL + 11*6); ***/ int iWk22; if( bMoveRight ) { iWk22 = f_moveLeg( im_out, iWk2, iWk2 + iL*2, iYleg, 'R', iMaxClr - 1, iMinClr + 1, sAlgo1, brown, dorange ); } //iWk2 += iL; if( bMoveLeft ) { if( bColWeight && bMoveRight ) { // B - bottom iWk2 = f_moveLeg( im_out, iWk2, iWk2 + iL*2, iYleg+18, 'B', iMaxClr - 1, iMinClr + 1, sAlgo1, brown, dorange ); iWk2 = iWk22 + iLG; // 'same' rect - only when moveLeft&Right&Weight. gdImageFilledRectangle(im_out, iWk2_0, iYleg+18, iWk2_0 + iL/2, iYleg + 28, white ); gdImageRectangle (im_out, iWk2_0, iYleg+18, iWk2_0 + iL/2, iYleg + 28, image_cfg.gapColor ); //iWk2 += (iL/2 + 3); gdImageString(im_out, gdFontSmall, iWk2_0 + (iL/2 + 3), iYleg + 16, (unsigned char*)"same", brown ); // + 11 * 6 } else { if( bMoveRight ) { iWk2 = iWk22 + iLG; } iWk2 = f_moveLeg( im_out, iWk2, iWk2 + iL*2, iYleg, 'L', iMaxClr - 1, iMinClr + 1, sAlgo1, brown, dorange ); iWk2 += iLG; } } else if( bMoveRight ) { iWk2 = iWk22 + iLG; } if( bColWeight ) { //+iWk2 = f_colWeightLeg( im_out, iWk2, iWk2 + iL*2, iYleg, *(oAli.pWLlegends), brown ); iWk2 = f_colWeightLeg( im_out, iWk2, iWk2 + iL*2, iYleg, iWLceil, oAli.WeightLineMax, brown ); iWk2 += iLG; } if( bMismatch ) { gdImageFilledRectangle(im_out, iWk2, iYleg+2, iWk2 + iL/2, iYleg + 12, mismark ); gdImageRectangle (im_out, iWk2, iYleg+2, iWk2 + iL/2, iYleg + 12, red ); iWk2 += (iL/2 + 3); gdImageString(im_out, gdFontSmall, iWk2, iYleg , (unsigned char*)"mismatch", brown ); // + 11 * 6 iWk2 += (iLG + 8*6); } /** // Moved left gdImageFilledRectangle(im_out, iWk2 , iYleg+2, iWk2 + iL*2, iYleg + 12, green ); gdImageFilledRectangle(im_out, iWk2+iL, iYleg+2, iWk2 + iL*2, iYleg + 12, dgreen ); // Offset number gdImageString(im_out, gdFontTiny, iWk2+iL*0.5, iYleg + 12, (unsigned char*)"1", brown ); gdImageString(im_out, gdFontTiny, iWk2+iL*1.5, iYleg + 12, (unsigned char*)"2", brown ); iWk2 += (iL*2 + 3); gdImageString(im_out, gdFontSmall, iWk2, iYleg , (unsigned char*)sAlgo1, dorange ); // Offset 'offset' gdImageString(im_out, gdFontTiny, iWk2, iYleg + 12, (unsigned char*)"offset", brown ); iWk2 += (strlen(sAlgo1)*6 + 6); gdImageString(im_out, gdFontSmall, iWk2, iYleg , (unsigned char*)"moved left", brown ); iWk2 += (iL + 10*6); **/ /***** if( iPmin < P0 ) { // ..lgray iWk = iH - dY2 + 16 + 16 + 5+2; for( i = 0; i < 2; iWk++, i++ ) { gdImageLine(im_out, iWk2, iWk, iWk2 + iL, iWk, gray ); //lgray); } //+gdImageLine(im_out, iWk2, iWk, iWk2 + iL, iWk, gray); // underline iWk2 += (iL + 3); if( Pdrop > 0 ) sprintf( buf100, "%.1f <= noise < %.1f ", double(Pdrop*0.1), double(P0*0.1) ); else sprintf( buf100, "noise less than %.1f ", double(P0*0.1) ); buf100[25] = 0; gdImageString(im_out, gdFontSmall, iWk2, iH - dY2 + 16 + 16 , (unsigned char*)buf100, brown ); // + 11 * 6 "power less than 3" } // Opts: //gdImageStringUp(im_out, gdFontTiny, iW - 16, iH - dY2 - 2, gdImageStringUp(im_out, gdFontTiny, iW - 17, iH - dY2 - 2, (unsigned char*)sOpt, brown ); // wm_name *****/ // Title char *subTit = "Comparison of two alignments"; char *subTit2 = "with same sequences"; if( strlen(sTit) < 1 ) { gdImageString(im_out, gdFontGiant, (int)((double)(iW - 9*strlen(subTit) - dX1 - dX2) * 0.5 + dX1), 5, //7, (unsigned char*)subTit, brown ); gdImageString(im_out, gdFontTiny, (int)((double)(iW - 5*strlen(subTit2) - dX1 - dX2) * 0.5 + dX1) , 5+15, (unsigned char*)subTit2, brown ); } else { //gdImageString(im_out, gdFontGiant, (int)((double)(iW - 9*strlen(sTit)) * 0.5) , 5, gdImageString(im_out, gdFontGiant, (int)((double)(iW - 9*strlen(sTit) - dX1 - dX2) * 0.5 + dX1) , 5, (unsigned char*)sTit, brown ); gdImageString(im_out, gdFontTiny, (int)((double)(iW - 5*strlen(subTit) - dX1 - dX2) * 0.5 + dX1) , 5+15, (unsigned char*)subTit, brown ); } // Algo gdImageString(im_out, gdFontMediumBold, 5, 4, (unsigned char*)sAlgo1, dorange ); gdImageString(im_out, gdFontSmall, 5+strlen(sAlgo1)*7+6, 4, //+7, 4 (unsigned char*)"alignment", brown ); gdImageString(im_out, gdFontTiny, 5, 15, (unsigned char*)"versus", brown ); gdImageString(im_out, gdFontTiny, 5+5*6+5, 15, (unsigned char*)sAlgo2, brown2 ); // red ); //dgreen ); /***** iWk = iW - 92; gdImageString(im_out, gdFontTiny, iWk, 4, (unsigned char*)"Power thresholds:", brown ); //+sprintf( buf100, "%.1f, %.1f, and %.1f \0", //***08.01.01 //+ double(Pdrop*0.1), double(P0*0.1), double(P1*0.1) ); sprintf( buf100, " %.1f, and %.1f \0", double(Pdrop*0.1), double(P0*0.1) ); //buf100[40] = 0; gdImageString(im_out, gdFontTiny, iWk, 11, (unsigned char*)buf100, brown ); // Check if empty: if( mm.empty() ) { gdImageString(im_out, gdFontGiant, (int)((iW - 9.*30.) * 0.5) , (int)(iH * 0.4), // (unsigned char*)"DOTHELIX MOTIFS' COLLECTION MAP", red ); (unsigned char*)" NO MOTIFS ARE FOUND.", red ); gdImageString(im_out, gdFontGiant, (int)((iW - 9.*30.) * 0.5) , (int)(iH * 0.4)+40, (unsigned char*)" TRY SMALLER THRESHOLDS.", red ); } *****/ out = fopen( sFName, "wb"); // Write PNG gdImagePng(im_out , out); fclose(out); gdImageDestroy(im_out); /***/ } // EOF