--- /dev/null
+#include "../../../include/freenet/captcha/alternatecaptcha2.h"\r
+\r
+#include <Poco/Path.h>\r
+#include <Poco/DirectoryIterator.h>\r
+\r
+#include <cmath>\r
+#include <vector>\r
+\r
+#ifdef ALTERNATE_CAPTCHA\r
+\r
+AlternateCaptcha2::AlternateCaptcha2()\r
+{\r
+ AlternateCaptchaFonts fonts;\r
+ m_fonts=fonts.Fonts();\r
+}\r
+\r
+void AlternateCaptcha2::Generate()\r
+{\r
+ std::string puzzlestring=GenerateRandomString(6);\r
+ std::vector<int> fontnums(puzzlestring.size(),0);\r
+ \r
+ m_solution.clear();\r
+ m_puzzle.clear();\r
+ \r
+ FreeImage::Bitmap bigbmp(300,300,32);\r
+ bigbmp.SetTransparent();\r
+\r
+ // get total width of text\r
+ int textwidth=0;\r
+ for(int i=0; i<puzzlestring.size(); i++)\r
+ {\r
+ fontnums[i]=rand()%m_fonts.size();\r
+ textwidth+=m_fonts[fontnums[i]].Char(puzzlestring[i]).Width();\r
+ }\r
+\r
+ RGBQUAD white;\r
+ white.rgbRed=255;\r
+ white.rgbGreen=255;\r
+ white.rgbBlue=255;\r
+ white.rgbReserved=255;\r
+ int numlines=(rand()%3)+2;\r
+ for(int i=0; i<numlines; i++)\r
+ {\r
+ int x1=rand()%150;\r
+ int y1=(rand()%100)+100;\r
+ int x2=(rand()%150)+150;\r
+ int y2=(rand()%100)+100;\r
+ bigbmp.Line(x1,y1,x2,y2,white);\r
+ bigbmp.Line(x1+1,y1,x2+1,y2,white);\r
+ }\r
+ \r
+ // draw the text on the bigbmp centered\r
+ int currentx=150-(textwidth/2);\r
+ for(int i=0; i<puzzlestring.size(); i++)\r
+ {\r
+ FreeImage::Bitmap charbmp=m_fonts[fontnums[i]].Char(puzzlestring[i]);\r
+ bigbmp.BlitTrans(charbmp,currentx,150-(charbmp.Height()/2),0,0,charbmp.Width(),charbmp.Height());\r
+ currentx+=m_fonts[fontnums[i]].Char(puzzlestring[i]).Width();//+1;\r
+ }\r
+ \r
+ // rotate and skew the big bitmap a few times\r
+ int lastrot=0;\r
+ int thisrot=0;\r
+ int numrots=(rand()%4)+4;\r
+ for(int i=0; i<numrots; i++)\r
+ {\r
+ thisrot=((rand()%180)-90);\r
+ bigbmp.Rotate(-lastrot+thisrot,0,0,150,150);\r
+ int offset=rand()%10000;\r
+ float freq=3.0+(float(rand()%7000)/1000.0);\r
+ float amp=1.0+(float(rand()%1000)/500.0);\r
+ for(int y=0; y<bigbmp.Height(); y++)\r
+ {\r
+ double shift=sin((double)(y+offset)/freq)*amp;\r
+ bigbmp.HorizontalOffset(y,shift);\r
+ }\r
+ lastrot=thisrot;\r
+ }\r
+\r
+ // rotate the big bitmap back to (almost) horizontal\r
+ bigbmp.Rotate(-lastrot+((rand()%10)-5),0,0,150,150);\r
+\r
+ // grab the center of the big bitmap as the final bitmap\r
+ FreeImage::Bitmap bmp(110,50,32);\r
+ bmp.SetTransparent();\r
+ bmp.Blit(bigbmp,0,0,95,125,110,50,255);\r
+\r
+ m_solution.insert(m_solution.end(),puzzlestring.begin(),puzzlestring.end());\r
+ bmp.SaveToMemory("bmp",m_puzzle);\r
+\r
+}\r
+\r
+const std::string AlternateCaptcha2::GenerateRandomString(const int len)\r
+{\r
+ // no l,1 O,0 because they look too much alike\r
+ static std::string chars="abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789@#";\r
+ std::string temp="";\r
+ for(int i=0; i<len; i++)\r
+ {\r
+ temp+=chars[rand()%chars.size()];\r
+ }\r
+ return temp;\r
+}\r
+\r
+const bool AlternateCaptcha2::GetPuzzle(std::vector<unsigned char> &puzzle)\r
+{\r
+ puzzle=m_puzzle;\r
+ return true;\r
+}\r
+\r
+const bool AlternateCaptcha2::GetSolution(std::vector<unsigned char> &solution)\r
+{\r
+ solution=m_solution;\r
+ return true;\r
+}\r
+\r
+#endif // ALTERNATE_CAPTCHA\r