--- /dev/null
+#include "../../../include/freenet/captcha/alternatecaptcha1.h"\r
+\r
+#include <Poco/Path.h>\r
+#include <Poco/DirectoryIterator.h>\r
+\r
+#include <cmath>\r
+\r
+#ifdef ALTERNATE_CAPTCHA\r
+\r
+bool AlternateCaptcha1::m_fontsloaded(false);\r
+std::vector<FreeImage::Font> AlternateCaptcha1::m_fonts;\r
+\r
+AlternateCaptcha1::AlternateCaptcha1()\r
+{\r
+ if(m_fontsloaded==false)\r
+ {\r
+ FreeImage_Initialise(true);\r
+ LoadFonts();\r
+ m_fontsloaded=true;\r
+ }\r
+}\r
+\r
+void AlternateCaptcha1::Generate()\r
+{\r
+ std::string puzzlestring=GenerateRandomString(5);\r
+ FreeImage::Bitmap tempchar(50,50,32);\r
+ tempchar.SetTransparent();\r
+ FreeImage::Bitmap bmp(110,50,32);\r
+ bmp.SetTransparent();\r
+\r
+ m_solution.clear();\r
+ m_puzzle.clear();\r
+\r
+ // draw the text\r
+ if(m_fonts.size()>0)\r
+ {\r
+ for(int i=0; i<puzzlestring.size(); i++)\r
+ {\r
+ RGBQUAD black;\r
+ black.rgbRed=0;\r
+ black.rgbGreen=0;\r
+ black.rgbBlue=0;\r
+ int xoffset=(i*20)-(5+(rand()%5));\r
+ int yoffset=(rand()%20)-10;\r
+ int fontnum=rand()%m_fonts.size();\r
+ FreeImage::Bitmap charbmp=m_fonts[fontnum].Char(puzzlestring[i]);\r
+\r
+ tempchar.SetTransparent();\r
+ tempchar.ClearTransparent();\r
+ tempchar.BlitTrans(charbmp,25-(charbmp.Width()/2),25-(charbmp.Height()/2),0,0,charbmp.Width(),charbmp.Height());\r
+ tempchar.Rotate((rand()%60)-30,0,0,25,25);\r
+\r
+ bmp.BlitTrans(tempchar,xoffset,yoffset,0,0,50,50);\r
+ }\r
+ }\r
+\r
+ //place some random lines\r
+ RGBQUAD white;\r
+ white.rgbRed=255;\r
+ white.rgbGreen=255;\r
+ white.rgbBlue=255;\r
+ white.rgbReserved=255;\r
+ int numlines=(rand()%5)+10;\r
+ for(int i=0; i<numlines; i++)\r
+ {\r
+ // draw 4 short lines very close to each other\r
+ int x1[4];\r
+ int y1[4];\r
+ int x2[4];\r
+ int y2[4];\r
+\r
+ x1[0]=rand()%bmp.Width();\r
+ y1[0]=rand()%bmp.Height();\r
+ x2[0]=x1[0]+(rand()%40)-20;\r
+ y2[0]=y1[0]+(rand()%40)-20;\r
+\r
+ for(int i=1; i<4; i++)\r
+ {\r
+ x1[i]=x1[i-1]+rand()%3-1;\r
+ y1[i]=y1[i-1]+rand()%3-1;\r
+ x2[i]=x2[i-1]+rand()%3-1;\r
+ y2[i]=y2[i-1]+rand()%3-1;\r
+ }\r
+\r
+ for(int i=0; i<4; i++)\r
+ {\r
+ bmp.Line(x1[i],y1[i],x2[i],y2[i],white);\r
+ }\r
+ }\r
+\r
+ int offset=rand()%10000;\r
+ for(int y=0; y<bmp.Height(); y++)\r
+ {\r
+ double shift=sin((double)(y+offset)/3.0);\r
+ bmp.HorizontalOffset(y,shift);\r
+ }\r
+\r
+ m_solution.clear();\r
+ m_solution.insert(m_solution.end(),puzzlestring.begin(),puzzlestring.end());\r
+ m_puzzle.clear();\r
+ bmp.SaveToMemory("bmp",m_puzzle);\r
+\r
+}\r
+\r
+const std::string AlternateCaptcha1::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 AlternateCaptcha1::GetPuzzle(std::vector<unsigned char> &puzzle)\r
+{\r
+ puzzle=m_puzzle;\r
+ return true;\r
+}\r
+\r
+const bool AlternateCaptcha1::GetSolution(std::vector<unsigned char> &solution)\r
+{\r
+ solution=m_solution;\r
+ return true;\r
+}\r
+\r
+void AlternateCaptcha1::LoadFonts()\r
+{\r
+ FreeImage::Bitmap bmp;\r
+ Poco::Path path("fonts");\r
+ Poco::DirectoryIterator di(path);\r
+ Poco::DirectoryIterator end;\r
+\r
+ while(di!=end)\r
+ {\r
+ if(di.name().find("bmp")!=std::string::npos)\r
+ {\r
+ bmp.Load("bmp",di.path().toString());\r
+ m_fonts.push_back(FreeImage::Font(bmp));\r
+ }\r
+ ++di;\r
+ }\r
+\r
+}\r
+\r
+#endif // ALTERNATE_CAPTCHA\r