fpdf.cpp 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940
  1. // fpdf.cpp
  2. //
  3. #include "fpdf.h"
  4. #line 12 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  5. #define PDF_USING_ZLIB 1
  6. #define FPDF_VERSION "1.7"
  7. #include "sqlite3.h"
  8. #define pdf_vsnprintf sqlite3_ivsnprintf //vsnprintf
  9. #define pdf_snprintf sqlite3_isnprintf //snprintf
  10. #include <cstdarg>
  11. #include <cstdio>
  12. #include <cstring>
  13. #include <ctime>
  14. #include <cmath>
  15. #ifdef PDF_USING_ZLIB
  16. #include "zlib.h"
  17. #endif
  18. //#include "duma.h"
  19. #line 2285 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  20. #define M_SOF0 0xC0 // Start Of Frame N
  21. #define M_SOF1 0xC1 // N indicates which compression process
  22. #define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use
  23. #define M_SOF3 0xC3
  24. #define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers
  25. #define M_SOF6 0xC6
  26. #define M_SOF7 0xC7
  27. #define M_SOF9 0xC9
  28. #define M_SOF10 0xCA
  29. #define M_SOF11 0xCB
  30. #define M_SOF13 0xCD
  31. #define M_SOF14 0xCE
  32. #define M_SOF15 0xCF
  33. #define M_SOI 0xD8
  34. #define M_EOI 0xD9 // End Of Image (end of datastream)
  35. #define M_SOS 0xDA // Start Of Scan (begins compressed data)
  36. #define M_COM 0xFE // COMment
  37. #define M_PSEUDO 0xFFD8 // pseudo marker for start of image(byte 0)
  38. #define LZZ_INLINE inline
  39. #line 30 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  40. std::string & gzcompress (std::string & dest, std::string const & src)
  41. #line 31 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  42. {
  43. z_stream stream;
  44. int err;
  45. int nExtraChunks;
  46. size_t src_len = src.size();
  47. size_t dest_len = 2048 + src_len;
  48. dest.resize(dest_len);
  49. stream.next_in = (Bytef*)&src[0];
  50. stream.avail_in = (uInt)src_len;
  51. stream.zalloc = (alloc_func)0;
  52. stream.zfree = (free_func)0;
  53. stream.opaque = (voidpf)0;
  54. //err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
  55. err = deflateInit(&stream, Z_BEST_SPEED);
  56. if (err != Z_OK) throw "Could not initialize zstream !";
  57. nExtraChunks = 0;
  58. do
  59. {
  60. stream.next_out = (unsigned char*)&dest[0];
  61. stream.avail_out = dest_len;
  62. err = deflate(&stream, Z_FINISH);
  63. if (err == Z_STREAM_END )
  64. break;
  65. if (err != Z_OK)
  66. {
  67. deflateEnd(&stream);
  68. throw "Could not uncompress data !";
  69. }
  70. nExtraChunks += 1;
  71. }
  72. while (stream.avail_out == 0);
  73. dest.resize(stream.total_out);
  74. err = deflateEnd(&stream);
  75. if (nExtraChunks || (err != Z_OK)) throw "Could finalize zstream !";
  76. return dest;
  77. }
  78. #line 75 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  79. std::string & gzuncompress (std::string & dest, std::string const & src)
  80. #line 76 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  81. {
  82. z_stream stream;
  83. int err;
  84. int nExtraChunks;
  85. size_t src_len = src.size();
  86. size_t dest_len = 2048 + src_len*5;
  87. dest.resize(dest_len);
  88. stream.next_in = (Bytef*)&src[0];
  89. stream.avail_in = (uInt)src_len;
  90. stream.zalloc = (alloc_func)0;
  91. stream.zfree = (free_func)0;
  92. err = inflateInit(&stream);
  93. if (err != Z_OK) throw "Could not initialize zstream !";
  94. nExtraChunks = 0;
  95. do
  96. {
  97. stream.next_out = (unsigned char*)&dest[0];
  98. stream.avail_out = dest_len;
  99. err = inflate(&stream, Z_FINISH);
  100. if (err == Z_STREAM_END )
  101. break;
  102. if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
  103. err = Z_DATA_ERROR;
  104. if (err != Z_BUF_ERROR)
  105. {
  106. inflateEnd(&stream);
  107. throw "Could not uncompress data !";
  108. }
  109. nExtraChunks += 1;
  110. }
  111. while (stream.avail_out == 0);
  112. dest.resize(stream.total_out);
  113. err = inflateEnd(&stream);
  114. if (nExtraChunks || (err != Z_OK)) throw "Could finalize zstream !";
  115. return dest;
  116. }
  117. #line 132 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  118. char const * FPDF_FONTPATH = 0;
  119. #line 261 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  120. FPDF::~ FPDF ()
  121. #line 262 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  122. {
  123. font_map_t::iterator iter = m_fonts.begin();
  124. font_map_t::iterator iend = m_fonts.end();
  125. while(iter != iend)
  126. {
  127. delete iter->second;
  128. ++iter;
  129. }
  130. }
  131. #line 272 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  132. FPDF::FPDF ()
  133. #line 273 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  134. {
  135. reset(e_orientation_portrait, e_mm, e_A4);
  136. }
  137. #line 277 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  138. FPDF::FPDF (e_orientation orientation, e_units unit, e_page_sizes psize)
  139. #line 278 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  140. {
  141. reset(orientation, unit, psize);
  142. }
  143. #line 282 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  144. FPDF::FPDF (char orientation, char const * unit, char const * psize)
  145. #line 283 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  146. {
  147. e_orientation eo = orientation == 'L' ? e_orientation_landscape : e_orientation_portrait;
  148. e_units eu;
  149. e_page_sizes es;
  150. if(strcasecmp(unit, "pt")==0) eu = e_pt;
  151. else if(strcasecmp(unit, "cm")==0) eu = e_cm;
  152. else if(strcasecmp(unit, "in")==0) eu = e_in;
  153. else eu = e_mm;
  154. if(strcasecmp(psize, "a3")==0) es = e_A3;
  155. else if(strcasecmp(psize, "a5")==0) es = e_A5;
  156. else if(strcasecmp(psize, "letter")==0) es = e_Letter;
  157. else if(strcasecmp(psize, "legal")==0) es = e_Legal;
  158. else es = e_A4;
  159. reset(eo, eu, es);
  160. }
  161. #line 301 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  162. void FPDF::reset (e_orientation orientation, e_units unit, e_page_sizes psize)
  163. #line 302 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  164. {
  165. // Scale factor
  166. switch(unit)
  167. {
  168. case e_pt:
  169. m_k = 1;
  170. break;
  171. case e_mm:
  172. m_k = 72/25.4;
  173. break;
  174. case e_cm:
  175. m_k = 72/2.54;
  176. break;
  177. case e_in:
  178. m_k = 72;
  179. break;
  180. default:
  181. Error("Incorrect unit: %s", unit);
  182. }
  183. // Some checks
  184. _dochecks();
  185. // Initialization of properties
  186. m_page = 0;
  187. m_pages.clear();
  188. m_PageSizes.clear();
  189. m_offsets.clear();
  190. m_fonts.clear();
  191. m_FontFiles.clear();
  192. m_diffs.clear();
  193. m_images.clear();
  194. m_PageLinks.clear();
  195. m_links.clear();
  196. m_extgstates.clear();
  197. m_offsets.resize(3, 0);
  198. m_n = 2;
  199. m_buffer.clear();
  200. m_buffer.reserve(1024);
  201. //this->buffer = "";
  202. //this->m_pages = array();
  203. //this->PageSizes = array();
  204. m_state = 0;
  205. //this->fonts = array();
  206. //this->FontFiles = array();
  207. //this->diffs = array();
  208. //this->images = array();
  209. //this->links = array();
  210. m_InHeader = false;
  211. m_InFooter = false;
  212. m_lasth = 0;
  213. //this->FontFamily = "";
  214. //this->FontStyle = "";
  215. m_FontSizePt = 12;
  216. m_underline = false;
  217. m_DrawColor = "0 G";
  218. //m_DrawColor_rgb = {0,0,0,0};
  219. m_DrawColor_rgb.r = 0;
  220. m_DrawColor_rgb.g = 0;
  221. m_DrawColor_rgb.b = 0;
  222. m_DrawColor_rgb.t = 0;
  223. m_FillColor = "0 g";
  224. //m_FillColor_rgb = {0,0,0,0};
  225. m_FillColor_rgb = m_DrawColor_rgb;
  226. m_TextColor = "0 g";
  227. //m_TextColor_rgb = {0,0,0,0};
  228. m_TextColor_rgb = m_DrawColor_rgb;
  229. m_ColorFlag = false;
  230. m_ws = 0;
  231. // Font path
  232. if(FPDF_FONTPATH)
  233. {
  234. m_fontpath = FPDF_FONTPATH;
  235. char clast = *m_fontpath.rbegin();
  236. if(clast != '/' && clast != '\\')
  237. m_fontpath += "/";
  238. }
  239. #if 0
  240. else if(is_dir(dirname(__FILE__) + "/font"))
  241. m_fontpath = dirname(__FILE__) + "/font/";
  242. #endif
  243. else
  244. m_fontpath.clear();
  245. m_CurrentFont = 0;
  246. st_pagesize page_size;
  247. _getpagesize(page_size, psize);
  248. m_DefPageSize = page_size;
  249. m_CurPageSize = page_size;
  250. // Page orientation
  251. switch(orientation)
  252. {
  253. case e_orientation_portrait:
  254. {
  255. m_DefOrientation = e_orientation_portrait;
  256. m_w = page_size.w;
  257. m_h = page_size.h;
  258. }
  259. break;
  260. case e_orientation_landscape:
  261. {
  262. m_DefOrientation = e_orientation_landscape;
  263. m_w = page_size.h;
  264. m_h = page_size.w;
  265. }
  266. break;
  267. default:
  268. Error("Incorrect orientation: %d", orientation);
  269. }
  270. m_CurOrientation = m_DefOrientation;
  271. m_wPt = m_w * m_k;
  272. m_hPt = m_h * m_k;
  273. m_angle = 0;
  274. // Page margins (1 cm)
  275. pdf_float_t margin = 28.35/m_k;
  276. SetMargins(margin,margin);
  277. // Interior cell margin (1 mm)
  278. m_cMargin = margin/10.0;
  279. // Line width (0.2 mm)
  280. m_LineWidth = .567/m_k;
  281. // Automatic page break
  282. SetAutoPageBreak(true,2*margin);
  283. // Default display mode
  284. SetDisplayMode(e_zoom_default);
  285. m_CustomZoom = 0;
  286. // Enable compression
  287. SetCompression(true);
  288. // Set default PDF version number
  289. m_PDFVersion = "1.3";
  290. m_doubleSided=false;
  291. m_xDelta=0;
  292. m_innerMargin=10;
  293. m_outerMargin=10;
  294. m_n_js = 0;
  295. }
  296. #line 440 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  297. void FPDF::SetDoubleSided (pdf_float_t inner, pdf_float_t outer)
  298. #line 441 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  299. {
  300. if(outer != inner)
  301. {
  302. m_doubleSided=true;
  303. m_outerMargin=outer;
  304. m_innerMargin=inner;
  305. }
  306. }
  307. #line 450 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  308. void FPDF::SetMargins (pdf_float_t left, pdf_float_t top, pdf_float_t right)
  309. #line 451 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  310. {
  311. // Set left, top and right margins
  312. m_lMargin = left;
  313. m_tMargin = top;
  314. m_rMargin = (right==0.0f) ? left : right;
  315. }
  316. #line 458 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  317. void FPDF::SetLeftMargin (pdf_float_t margin)
  318. #line 459 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  319. {
  320. // Set left margin
  321. m_lMargin = margin;
  322. if(m_page > 0 && m_x < margin)
  323. m_x = margin;
  324. }
  325. #line 488 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  326. void FPDF::SetAutoPageBreak (bool b, pdf_float_t margin)
  327. #line 489 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  328. {
  329. // Set auto page break mode and triggering margin
  330. m_AutoPageBreak = b;
  331. m_bMargin = margin;
  332. m_PageBreakTrigger = m_h-margin;
  333. }
  334. #line 496 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  335. void FPDF::CheckPageBreak (pdf_float_t height)
  336. #line 497 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  337. {
  338. //If the height h would cause an overflow, add a new page immediately
  339. if(GetY()+height > m_PageBreakTrigger)
  340. AddPage(m_CurOrientation);
  341. }
  342. #line 513 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  343. void FPDF::SetDisplayMode (e_zoom_mode zoom, e_layout_mode layout)
  344. #line 514 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  345. {
  346. // Set display mode in viewer
  347. if(zoom==e_zoom_fullpage || zoom==e_zoom_fullwidth ||
  348. zoom==e_zoom_real || zoom==e_zoom_default)
  349. m_ZoomMode = zoom;
  350. else
  351. Error("Incorrect zoom display mode %d", zoom);
  352. if(layout==e_layout_single || layout==e_layout_continuous ||
  353. layout==e_layout_two || layout==e_layout_default)
  354. m_LayoutMode = layout;
  355. else
  356. Error("Incorrect layout display mode: %d", layout);
  357. }
  358. #line 528 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  359. void FPDF::SetCompression (bool compress)
  360. #line 529 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  361. {
  362. // Set page compression
  363. #ifndef PDF_USING_ZLIB
  364. m_compress = false;
  365. #else
  366. m_compress = compress;
  367. #endif
  368. }
  369. #line 538 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  370. void FPDF::SetTitle (char const * title)
  371. #line 539 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  372. {
  373. // Title of document
  374. m_title = title;
  375. }
  376. #line 544 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  377. void FPDF::SetSubject (char const * subject)
  378. #line 545 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  379. {
  380. // Subject of document
  381. m_subject = subject;
  382. }
  383. #line 550 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  384. void FPDF::SetAuthor (char const * author)
  385. #line 551 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  386. {
  387. // Author of document
  388. m_author = author;
  389. }
  390. #line 556 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  391. void FPDF::SetKeywords (char const * keywords)
  392. #line 557 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  393. {
  394. // Keywords of document
  395. m_keywords = keywords;
  396. }
  397. #line 562 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  398. void FPDF::SetCreator (char const * creator)
  399. #line 563 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  400. {
  401. // Creator of document
  402. m_creator = creator;
  403. }
  404. #line 568 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  405. void FPDF::AliasNbPages (char const * alias)
  406. #line 569 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  407. {
  408. // Define an alias for total number of pages
  409. m_AliasNbPages = alias;
  410. }
  411. #line 580 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  412. void FPDF::Error (char const * msg, ...)
  413. #line 581 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  414. {
  415. // Fatal error
  416. va_list args;
  417. va_start( args, msg );
  418. pdf_vsnprintf(m_scratch_buf, sizeof(m_scratch_buf), msg, args);
  419. va_end( args );
  420. std::string error_msg = "FPDF error: ";
  421. error_msg += m_scratch_buf;
  422. throw error_msg;
  423. }
  424. #line 598 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  425. void FPDF::Close ()
  426. #line 599 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  427. {
  428. // Terminate document
  429. if(m_state==3) return;
  430. if(m_page==0) AddPage();
  431. // Page footer
  432. m_InFooter = true;
  433. Footer();
  434. m_InFooter = false;
  435. // Close page
  436. _endpage();
  437. // Close document
  438. _enddoc();
  439. }
  440. #line 613 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  441. void FPDF::AddPage (e_orientation orientation, st_pagesize * psize)
  442. #line 614 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  443. {
  444. // Start a new page
  445. if(m_state==0) Open();
  446. std::string family = m_FontFamily;
  447. std::string style = m_FontStyle;
  448. if(m_underline) style += "U";
  449. pdf_float_t fontsize = m_FontSizePt;
  450. pdf_float_t lw = m_LineWidth;
  451. std::string dc = m_DrawColor;
  452. std::string fc = m_FillColor;
  453. std::string tc = m_TextColor;
  454. bool cf = m_ColorFlag;
  455. if(m_page > 0)
  456. {
  457. // Page footer
  458. m_InFooter = true;
  459. Footer();
  460. m_InFooter = false;
  461. // Close page
  462. _endpage();
  463. }
  464. // Start new page
  465. _beginpage(orientation,psize);
  466. // Set line cap style to square
  467. _out("2 J");
  468. // Set line width
  469. m_LineWidth = lw;
  470. _outfmt(true, "%.2f w", lw*m_k);
  471. // Set font
  472. if(!family.empty()) SetFont(family.c_str(),style.c_str(),fontsize);
  473. // Set colors
  474. m_DrawColor = dc;
  475. if(dc != "0 G") _out(dc);
  476. m_FillColor = fc;
  477. if(fc != "0 g") _out(fc);
  478. m_TextColor = tc;
  479. m_ColorFlag = cf;
  480. // Page header
  481. m_InHeader = true;
  482. Header();
  483. m_InHeader = false;
  484. // Restore line width
  485. if(m_LineWidth != lw)
  486. {
  487. m_LineWidth = lw;
  488. _outfmt(true, "%.2f w", lw*m_k);
  489. }
  490. // Restore font
  491. if(!family.empty()) SetFont(family.c_str(),style.c_str(),fontsize);
  492. // Restore colors
  493. if(m_DrawColor != dc)
  494. {
  495. m_DrawColor = dc;
  496. _out(dc);
  497. }
  498. if(m_FillColor != fc)
  499. {
  500. m_FillColor = fc;
  501. _out(fc);
  502. }
  503. m_TextColor = tc;
  504. m_ColorFlag = cf;
  505. }
  506. #line 678 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  507. void FPDF::Header ()
  508. #line 679 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  509. {}
  510. #line 683 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  511. void FPDF::Footer ()
  512. #line 684 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  513. {}
  514. #line 694 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  515. void FPDF::SetDrawColor (unsigned char r)
  516. #line 695 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  517. {
  518. // Set color for all stroking operations
  519. //m_DrawColor_rgb = {r,r,r,0};
  520. m_DrawColor_rgb.r = r;
  521. m_DrawColor_rgb.g = r;
  522. m_DrawColor_rgb.b = r;
  523. m_DrawColor_rgb.t = 0;
  524. pdf_sprintf(m_DrawColor, "%.3f G", r/255.0);
  525. if(m_page>0) _out(m_DrawColor);
  526. }
  527. #line 706 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  528. void FPDF::SetDrawColor (unsigned char r, unsigned char g, unsigned char b)
  529. #line 707 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  530. {
  531. // Set color for all stroking operations
  532. //m_DrawColor_rgb = {r,g,b,0};
  533. m_DrawColor_rgb.r = r;
  534. m_DrawColor_rgb.g = g;
  535. m_DrawColor_rgb.b = b;
  536. m_DrawColor_rgb.t = 0;
  537. pdf_sprintf(m_DrawColor, "%.3f %.3f %.3f RG", r/255.0, g/255.0, b/255.0);
  538. if(m_page>0) _out(m_DrawColor);
  539. }
  540. #line 726 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  541. void FPDF::SetFillColor (unsigned char r)
  542. #line 727 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  543. {
  544. // Set color for all filling operations
  545. //m_FillColor_rgb = {r,r,r,0};
  546. m_FillColor_rgb.r = r;
  547. m_FillColor_rgb.g = r;
  548. m_FillColor_rgb.b = r;
  549. m_FillColor_rgb.t = 0;
  550. pdf_sprintf(m_FillColor, "%.3f g", r/255.0);
  551. m_ColorFlag = (m_FillColor != m_TextColor);
  552. if(m_page>0) _out(m_FillColor);
  553. }
  554. #line 739 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  555. void FPDF::SetFillColor (unsigned char r, unsigned char g, unsigned char b)
  556. #line 740 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  557. {
  558. // Set color for all filling operations
  559. //m_FillColor_rgb = {r,g,b,0};
  560. m_FillColor_rgb.r = r;
  561. m_FillColor_rgb.g = g;
  562. m_FillColor_rgb.b = b;
  563. m_FillColor_rgb.t = 0;
  564. pdf_sprintf(m_FillColor, "%.3f %.3f %.3f rg", r/255.0, g/255.0, b/255.0);
  565. m_ColorFlag = (m_FillColor != m_TextColor);
  566. if(m_page>0) _out(m_FillColor);
  567. }
  568. #line 760 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  569. void FPDF::SetTextColor (unsigned char r)
  570. #line 761 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  571. {
  572. // Set color for text
  573. //m_TextColor_rgb = {r,r,r,0};
  574. m_TextColor_rgb.r = r;
  575. m_TextColor_rgb.g = r;
  576. m_TextColor_rgb.b = r;
  577. m_TextColor_rgb.t = 0;
  578. pdf_sprintf(m_TextColor, "%.3f g", r/255.0);
  579. m_ColorFlag = (m_FillColor != m_TextColor);
  580. }
  581. #line 772 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  582. void FPDF::SetTextColor (unsigned char r, unsigned char g, unsigned char b)
  583. #line 773 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  584. {
  585. // Set color for text
  586. //m_TextColor_rgb = {r,g,b,0};
  587. m_TextColor_rgb.r = r;
  588. m_TextColor_rgb.g = g;
  589. m_TextColor_rgb.b = b;
  590. m_TextColor_rgb.t = 0;
  591. pdf_sprintf(m_TextColor, "%.3f %.3f %.3f rg", r/255.0, g/255.0, b/255.0);
  592. m_ColorFlag = (m_FillColor != m_TextColor);
  593. }
  594. #line 796 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  595. void FPDF::SetAlpha (pdf_float_t alpha, char const * bm)
  596. #line 797 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  597. {
  598. // set alpha for stroking (CA) and non-stroking (ca) operations
  599. st_alpha_t gs;
  600. gs.alpha = alpha;
  601. gs.bm = bm ? bm : "Normal";
  602. m_extgstates.push_back(gs);
  603. _outfmt(true, "/GS%d gs", m_extgstates.size());
  604. }
  605. #line 806 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  606. pdf_float_t FPDF::GetStringWidth (char const * s)
  607. #line 807 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  608. {
  609. // Get width of a string in the current font
  610. font_width_t *cw = m_CurrentFont->font.cw;
  611. pdf_float_t w = 0.0;
  612. if(s)
  613. {
  614. while(*s)
  615. {
  616. w += cw[(unsigned char)*s++];
  617. }
  618. }
  619. return w*m_FontSize/1000.0;
  620. }
  621. #line 826 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  622. void FPDF::SetLineWidth (pdf_float_t width)
  623. #line 827 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  624. {
  625. // Set line width
  626. m_LineWidth = width;
  627. if(m_page>0) _outfmt(true, "%.2f w", width*m_k);
  628. }
  629. #line 833 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  630. void FPDF::SetDash (pdf_float_t black, pdf_float_t white)
  631. #line 834 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  632. {
  633. if(black >= 0.0f && white >= 0.0f)
  634. _outfmt(true, "[%.3f %.3f] 0 d", black*m_k, white*m_k);
  635. else
  636. _out("[] 0 d");
  637. }
  638. #line 841 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  639. void FPDF::Line (pdf_float_t x1, pdf_float_t y1, pdf_float_t x2, pdf_float_t y2)
  640. #line 842 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  641. {
  642. // Draw a line
  643. _outfmt(true, "%.2f %.2f m %.2f %.2f l S", x1*m_k,(m_h-y1)*m_k,x2*m_k,(m_h-y2)*m_k);
  644. }
  645. #line 847 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  646. void FPDF::Rect (pdf_float_t x, pdf_float_t y, pdf_float_t w, pdf_float_t h, char const * style)
  647. #line 848 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  648. {
  649. // Draw a rectangle
  650. const char *op = "S";
  651. if(style)
  652. {
  653. if(strcasecmp(style, "F") == 0) op = "f";
  654. else if( (strcasecmp(style, "FD") == 0) ||
  655. (strcasecmp(style, "DF") == 0) ) op = "B";
  656. }
  657. _outfmt(true, "%.2f %.2f %.2f %.2f re %s", x*m_k,(m_h-y)*m_k,w*m_k,-h*m_k, op);
  658. }
  659. #line 860 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  660. void FPDF::AddFont (char const * afamily, char const * astyle, char const * afile)
  661. #line 861 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  662. {
  663. // Add a TrueType, OpenType or Type1 font
  664. std::string family, style;
  665. if(afamily && afamily[0])
  666. {
  667. family = afamily;
  668. _str_tolower(family);
  669. }
  670. else
  671. {
  672. family = m_FontFamily;
  673. }
  674. if(astyle && astyle[0])
  675. {
  676. style = astyle;
  677. _str_tolower(style);
  678. }
  679. if(family=="arial") family = "helvetica";
  680. if(style=="ib") style = "bi";
  681. std::string fontkey = family + style;
  682. font_map_t::iterator iter = m_fonts.find(fontkey);
  683. if(iter != m_fonts.end()) return; //already inserted
  684. st_pdf_font_base *font;
  685. if(fontkey == "helveticai") font = new pdf_font_HelveticaOblique();
  686. else if(fontkey == "helveticab") font = new pdf_font_HelveticaBold();
  687. else if(fontkey == "helveticabi") font = new pdf_font_HelveticaBoldOblique();
  688. else if(fontkey == "times") font = new pdf_font_Times();
  689. else if(fontkey == "timesi") font = new pdf_font_TimesOblique();
  690. else if(fontkey == "timesb") font = new pdf_font_TimesBold();
  691. else if(fontkey == "timesbi") font = new pdf_font_TimesBoldOblique();
  692. else if(fontkey == "courier") font = new pdf_font_Courier();
  693. else if(fontkey == "courieri") font = new pdf_font_CourierOblique();
  694. else if(fontkey == "courierb") font = new pdf_font_CourierBold();
  695. else if(fontkey == "courierbi") font = new pdf_font_CourierBoldOblique();
  696. else if(fontkey == "symbol") font = new pdf_font_Symbol();
  697. else if(fontkey == "zapfdingbats") font = new pdf_font_ZapfDingbats();
  698. else font = new pdf_font_Helvetica();
  699. m_fonts[fontkey] = font;
  700. font->i = m_fonts.size();
  701. #if 0
  702. if(m_fonts.find(fontkey) == -1) return;
  703. st_pdf_font info = _loadfont(file);
  704. info.i = m_fonts.size()+1;
  705. if(!empty(info["diff"]))
  706. {
  707. // Search existing encodings
  708. n = array_search(info["diff"],m_diffs);
  709. if(!n)
  710. {
  711. n = count(m_diffs)+1;
  712. m_diffs[n] = info["diff"];
  713. }
  714. info["diffn"] = n;
  715. }
  716. if(!empty(info["file"]))
  717. {
  718. // Embedded font
  719. if(info["type"]=="TrueType")
  720. m_FontFiles[info["file"]] = array("length1"=>info["originalsize"]);
  721. else
  722. m_FontFiles[info["file"]] = array("length1"=>info["size1"], "length2"=>info["size2"]);
  723. }
  724. m_fonts[fontkey] = info;
  725. #endif
  726. }
  727. #line 934 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  728. void FPDF::GetFontSettings (font_settings_st & fs)
  729. #line 934 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  730. {
  731. fs.family = m_FontFamily;
  732. fs.style = m_FontStyle;
  733. fs.size = m_FontSizePt;
  734. }
  735. #line 940 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  736. void FPDF::SetFontSettings (font_settings_st & fs)
  737. #line 940 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  738. {
  739. SetFont(fs.family.c_str(), fs.style.c_str(), fs.size);
  740. }
  741. #line 944 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  742. void FPDF::SetFont (char const * afamily, char const * astyle, pdf_float_t size)
  743. #line 945 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  744. {
  745. // Select a font; size given in points
  746. std::string family, style;
  747. if(afamily && afamily[0])
  748. {
  749. family = afamily;
  750. _str_tolower(family);
  751. if(family=="arial") family = "helvetica";
  752. }
  753. else
  754. {
  755. family = m_FontFamily;
  756. }
  757. if(astyle && astyle[0])
  758. {
  759. style = astyle;
  760. _str_tolower(style);
  761. }
  762. size_t found = style.find("u");
  763. if(found != std::string::npos )
  764. {
  765. m_underline = true;
  766. style.erase(found, 1);
  767. }
  768. else
  769. m_underline = false;
  770. if(style=="ib") style = "bi";
  771. if(size==0) size = m_FontSizePt;
  772. // Test if font is already selected
  773. if(m_FontFamily==family && m_FontStyle==style && m_FontSizePt==size)
  774. return;
  775. // Test if font is already loaded
  776. std::string fontkey = family + style;
  777. font_map_t::iterator iter = m_fonts.find(fontkey);
  778. if(iter == m_fonts.end())
  779. {
  780. // Test if one of the core fonts
  781. if(isPdfFontCore(family.c_str()))
  782. {
  783. if(family=="symbol" || family=="zapfdingbats") style.clear();
  784. fontkey = family + style;
  785. iter = m_fonts.find(fontkey);
  786. if(iter == m_fonts.end()) AddFont(family.c_str(),style.c_str());
  787. }
  788. else
  789. Error("Undefined font: %s %s", family.c_str(), style.c_str());
  790. }
  791. // Select it
  792. m_FontFamily = family;
  793. m_FontStyle = style;
  794. m_FontSizePt = size;
  795. m_FontSize = size/m_k;
  796. m_CurrentFont = m_fonts[fontkey];
  797. if(m_page>0)
  798. _outfmt(true, "BT /F%d %.2f Tf ET", m_CurrentFont->i, m_FontSizePt);
  799. }
  800. #line 1003 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  801. void FPDF::SetFontSize (pdf_float_t size)
  802. #line 1004 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  803. {
  804. // Set font size in points
  805. if(m_FontSizePt==size) return;
  806. m_FontSizePt = size;
  807. m_FontSize = size/m_k;
  808. if(m_page>0)
  809. _outfmt(true, "BT /F%d %.2f Tf ET", m_CurrentFont->i, m_FontSizePt);
  810. }
  811. #line 1018 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  812. int FPDF::AddLink ()
  813. #line 1019 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  814. {
  815. // Create a new internal link
  816. int n = m_links.size();
  817. st_link link = {0,0};
  818. m_links.push_back(link);
  819. return n;
  820. }
  821. #line 1027 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  822. void FPDF::SetLink (int link, pdf_float_t y, int page)
  823. #line 1028 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  824. {
  825. // Set destination of internal link
  826. st_link &nlink = m_links[link];
  827. if(y==-1) nlink.to = m_y;
  828. if(page==-1) page = m_page;
  829. nlink.from = page;
  830. }
  831. #line 1036 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  832. void FPDF::Link (pdf_float_t x, pdf_float_t y, pdf_float_t w, pdf_float_t h, int link)
  833. #line 1037 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  834. {
  835. // Put a link on the page
  836. st_page_link pl;
  837. pl.x = x*m_k;
  838. pl.y = m_hPt-y*m_k;
  839. pl.w = w*m_k;
  840. pl.h = h*m_k;
  841. pl.link = link;
  842. m_PageLinks[m_page] = pl;
  843. }
  844. #line 1049 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  845. void FPDF::_TextBase (std::string & result, pdf_float_t x, pdf_float_t y, char const * txt)
  846. #line 1050 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  847. {
  848. // Output a string
  849. //because the format buffer is limited
  850. //we send the string separated from format
  851. if(m_ColorFlag)
  852. {
  853. result += "q " + m_TextColor + " ";
  854. }
  855. pdf_sprintf_append(result, "BT %.2f %.2f Td (", x, y);
  856. result += _escape(txt);
  857. result += ") Tj ET";
  858. if(m_underline && txt)
  859. {
  860. result += " " + _dounderline(x, y, txt);
  861. }
  862. if(m_ColorFlag) result += " Q";
  863. }
  864. #line 1070 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  865. void FPDF::Rotate (pdf_float_t angle, pdf_float_t x, pdf_float_t y)
  866. #line 1071 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  867. {
  868. if(x==-1) x=m_x;
  869. if(y==-1) y=m_y;
  870. if(m_angle!=0) _out("Q");
  871. m_angle=angle;
  872. if(angle!=0)
  873. {
  874. angle*=M_PI/180.0;
  875. pdf_float_t c=cos(angle);
  876. pdf_float_t s=sin(angle);
  877. pdf_float_t cx=x*m_k;
  878. pdf_float_t cy=(m_h-y)*m_k;
  879. _outfmt(true, "q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm",
  880. c,s,-s,c,cx,cy,-cx,-cy);
  881. }
  882. }
  883. #line 1088 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  884. void FPDF::RotatedText (pdf_float_t x, pdf_float_t y, char const * txt, pdf_float_t angle)
  885. #line 1089 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  886. {
  887. //Text rotated around its origin
  888. Rotate(angle,x,y);
  889. Text(x,y,txt);
  890. Rotate(0);
  891. }
  892. #line 1101 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  893. void FPDF::ClippingText (pdf_float_t x, pdf_float_t y, char const * txt, bool outline)
  894. #line 1102 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  895. {
  896. int op= outline ? 5 : 7;
  897. _outfmt(false, "q BT %.2f %.2f Td %d Tr (", x*m_k, (m_h-y)*m_k, op);
  898. _out(_escape(txt), false);
  899. _out(") Tj ET");
  900. }
  901. #line 1109 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  902. void FPDF::Text (pdf_float_t x, pdf_float_t y, char const * txt)
  903. #line 1110 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  904. {
  905. std::string result;
  906. _TextBase(result, x*m_k, (m_h-y)*m_k, txt);
  907. _out(result);
  908. }
  909. #line 1116 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  910. void FPDF::TextShadow (pdf_float_t x, pdf_float_t y, char const * txt, pdf_float_t displacement)
  911. #line 1118 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  912. {
  913. pdf_color_t saved_color = m_TextColor_rgb;
  914. SetTextColor(200,200,200);
  915. Text(x+displacement, y+displacement, txt);
  916. SetTextColor(saved_color);
  917. Text(x, y, txt);
  918. }
  919. #line 1126 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  920. bool FPDF::AcceptPageBreak ()
  921. #line 1127 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  922. {
  923. // Accept automatic page break or not
  924. return m_AutoPageBreak;
  925. }
  926. #line 1132 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  927. void FPDF::Cell (pdf_float_t w, pdf_float_t h, char const * txt, char const * border, int ln, char align, bool fill, int link)
  928. #line 1134 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  929. {
  930. // Output a cell
  931. std::string s;
  932. pdf_float_t k = m_k;
  933. if(m_y+h > m_PageBreakTrigger && !m_InHeader && !m_InFooter && AcceptPageBreak())
  934. {
  935. // Automatic page break
  936. pdf_float_t x = m_x;
  937. pdf_float_t ws = m_ws;
  938. if(ws>0)
  939. {
  940. m_ws = 0;
  941. _out("0 Tw");
  942. }
  943. AddPage(m_CurOrientation, &m_CurPageSize);
  944. m_x = x + m_xDelta;
  945. if(ws>0)
  946. {
  947. m_ws = ws;
  948. _outfmt(true, "%.3f Tw", ws*k);
  949. }
  950. }
  951. if(w==0)
  952. w = m_w-m_rMargin-m_x;
  953. if(fill || (border && border[0]=='1'))
  954. {
  955. pdf_sprintf(s, "%.2f %.2f %.2f %.2f re %s ", m_x*k,(m_h-m_y)*k,w*k,-h*k,
  956. fill ? ((border && border[0]=='1') ? "B" : "f") : "S");
  957. }
  958. if(border)
  959. {
  960. pdf_float_t x = m_x;
  961. pdf_float_t y = m_y;
  962. if(strchr(border,'L'))
  963. pdf_sprintf_append(s, "%.2f %.2f m %.2f %.2f l S ",x*k,(m_h-y)*k,x*k,(m_h-(y+h))*k);
  964. if(strchr(border,'T'))
  965. pdf_sprintf_append(s, "%.2f %.2f m %.2f %.2f l S ",x*k,(m_h-y)*k,(x+w)*k,(m_h-y)*k);
  966. if(strchr(border,'R'))
  967. pdf_sprintf_append(s, "%.2f %.2f m %.2f %.2f l S ",(x+w)*k,(m_h-y)*k,(x+w)*k,(m_h-(y+h))*k);
  968. if(strchr(border,'B'))
  969. pdf_sprintf_append(s, "%.2f %.2f m %.2f %.2f l S ",x*k,(m_h-(y+h))*k,(x+w)*k,(m_h-(y+h))*k);
  970. }
  971. if(txt)
  972. {
  973. pdf_float_t dx;
  974. pdf_float_t txt_width = GetStringWidth(txt);
  975. if(align=='R')
  976. dx = w-m_cMargin-txt_width;
  977. else if(align=='C')
  978. dx = (w-txt_width)/2;
  979. else
  980. dx = m_cMargin;
  981. _TextBase(s, (m_x+dx)*k, (m_h-(m_y+.5*h+.3*m_FontSize))*k, txt);
  982. if(link)
  983. Link(m_x+dx, m_y+.5*h-.5*m_FontSize, txt_width, m_FontSize, link);
  984. }
  985. if(!s.empty()) _out(s);
  986. m_lasth = h;
  987. if(ln>0)
  988. {
  989. // Go to next line
  990. m_y += h;
  991. if(ln==1) m_x = m_lMargin;
  992. }
  993. else m_x += w;
  994. }
  995. #line 1210 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  996. void FPDF::MultiCell (pdf_float_t w, pdf_float_t h, char const * txt, char const * border, char align, bool fill)
  997. #line 1212 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  998. {
  999. // Output text with automatic or explicit line breaks
  1000. font_width_t *cw = m_CurrentFont->font.cw;
  1001. if(w==0) w = m_w-m_rMargin-m_x;
  1002. pdf_float_t wmax = (w-2*m_cMargin)*1000.0/m_FontSize;
  1003. std::string stmp, s = txt ? txt : "";
  1004. _erasestrch(s, '\r');
  1005. int nb = s.size();
  1006. if(nb>0 && s[nb-1]=='\n') --nb;
  1007. std::string b, b2;
  1008. if(border)
  1009. {
  1010. if(border[0]=='1')
  1011. {
  1012. border = "LTRB";
  1013. b = "LRT";
  1014. b2 = "LR";
  1015. }
  1016. else
  1017. {
  1018. if(strchr(border,'L')) b2 += "L";
  1019. if(strchr(border,'R')) b2 += "R";
  1020. b = strchr(border,'T') ? b2+"T" : b2;
  1021. }
  1022. }
  1023. int sep = -1;
  1024. int i = 0;
  1025. int j = 0;
  1026. int l = 0;
  1027. int ns = 0;
  1028. int nl = 1;
  1029. int ls = 0;
  1030. while(i<nb)
  1031. {
  1032. // Get next character
  1033. unsigned char c = (unsigned char)s[i];
  1034. if(c=='\n')
  1035. {
  1036. // Explicit line break
  1037. if(m_ws>0)
  1038. {
  1039. m_ws = 0;
  1040. _out("0 Tw");
  1041. }
  1042. stmp = s.substr(j, i-j);
  1043. Cell(w,h,stmp,b.c_str(),2,align,fill);
  1044. ++i;
  1045. sep = -1;
  1046. j = i;
  1047. l = 0;
  1048. ns = 0;
  1049. ++nl;
  1050. if(border && nl==2) b = b2;
  1051. continue;
  1052. }
  1053. if(c==' ')
  1054. {
  1055. sep = i;
  1056. ls = l;
  1057. ++ns;
  1058. }
  1059. l += cw[c];
  1060. if(l>wmax)
  1061. {
  1062. // Automatic line break
  1063. if(sep==-1)
  1064. {
  1065. if(i==j) ++i;
  1066. if(m_ws>0)
  1067. {
  1068. m_ws = 0;
  1069. _out("0 Tw");
  1070. }
  1071. stmp = s.substr(j, i-j);
  1072. Cell(w,h,stmp,b.c_str(),2,align,fill);
  1073. }
  1074. else
  1075. {
  1076. if(align=='J')
  1077. {
  1078. m_ws = (ns>1) ? (wmax-ls)/1000.0*m_FontSize/(ns-1) : 0;
  1079. //printf("%d %f %f %d %f\n", ns, m_ws, wmax, ls, m_FontSize);
  1080. _outfmt(true, "%.3f Tw",m_ws*m_k);
  1081. }
  1082. stmp = s.substr(j, sep-j);
  1083. Cell(w,h,stmp,b.c_str(),2,align,fill);
  1084. i = sep+1;
  1085. }
  1086. sep = -1;
  1087. j = i;
  1088. l = 0;
  1089. ns = 0;
  1090. ++nl;
  1091. if(border && nl==2)
  1092. b = b2;
  1093. }
  1094. else
  1095. ++i;
  1096. }
  1097. // Last chunk
  1098. if(m_ws>0)
  1099. {
  1100. m_ws = 0;
  1101. _out("0 Tw");
  1102. }
  1103. if(border && strchr(border,'B'))
  1104. b += "B";
  1105. stmp = s.substr(j, i-j);
  1106. Cell(w,h,stmp,b.c_str(),2,align,fill);
  1107. m_x = m_lMargin;
  1108. }
  1109. #line 1331 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1110. int FPDF::CalcLines (pdf_float_t w, char const * txt)
  1111. #line 1332 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1112. {
  1113. //Computes the number of lines a MultiCell of width w will take
  1114. font_width_t *cw = m_CurrentFont->font.cw;
  1115. if(w==0) w = m_w-m_rMargin-m_x;
  1116. pdf_float_t wmax = (w-2*m_cMargin)*1000.0/m_FontSize;
  1117. std::string stmp, s = txt ? txt : "";
  1118. _erasestrch(s, '\r');
  1119. int nb = s.size();
  1120. if(nb>0 && s[nb-1]=='\n') --nb;
  1121. int sep = -1;
  1122. int i = 0;
  1123. int j = 0;
  1124. int l = 0;
  1125. int nl = 1;
  1126. while(i<nb)
  1127. {
  1128. // Get next character
  1129. unsigned char c = (unsigned char)s[i];
  1130. if(c == '\n')
  1131. {
  1132. ++i;
  1133. sep = -1;
  1134. j = i;
  1135. l = 0;
  1136. ++nl;
  1137. continue;
  1138. }
  1139. if(c == ' ') sep=i;
  1140. l += cw[c];
  1141. if(l > wmax)
  1142. {
  1143. if(sep == -1)
  1144. {
  1145. if(i == j) ++i;
  1146. }
  1147. else i = sep+1;
  1148. sep = -1;
  1149. j = i;
  1150. l = 0;
  1151. ++nl;
  1152. }
  1153. else
  1154. ++i;
  1155. }
  1156. return nl;
  1157. }
  1158. #line 1381 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1159. void FPDF::MultiCellBlt (pdf_float_t w, pdf_float_t h, char const * blt, char const * txt, char const * border, char align, bool fill)
  1160. #line 1384 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1161. {
  1162. //Get bullet width including margins
  1163. pdf_float_t blt_width = GetStringWidth(blt)+m_cMargin*2;
  1164. //Save x
  1165. pdf_float_t bak_x = m_x;
  1166. //Output bullet
  1167. Cell(blt_width, h, blt,0,' ', fill);
  1168. //Output text
  1169. MultiCell(w-blt_width, h, txt, border, align, fill);
  1170. //Restore x
  1171. m_x = bak_x;
  1172. }
  1173. #line 1401 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1174. void FPDF::ClippingRect (pdf_float_t x, pdf_float_t y, pdf_float_t w, pdf_float_t h, bool outline)
  1175. #line 1402 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1176. {
  1177. char op=outline ? 'S' : 'n';
  1178. _outfmt(true, "q %.2f %.2f %.2f %.2f re W %c",
  1179. x*m_k, (m_h-y)*m_k, w*m_k,-h*m_k, op);
  1180. }
  1181. #line 1408 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1182. void FPDF::UnsetClipping ()
  1183. #line 1409 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1184. {
  1185. _out("Q");
  1186. }
  1187. #line 1413 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1188. void FPDF::ClippedCell (pdf_float_t w, pdf_float_t h, char const * txt, char const * border, int ln, char align, bool fill, int link)
  1189. #line 1415 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1190. {
  1191. if(border || fill || m_y+h>m_PageBreakTrigger)
  1192. {
  1193. Cell(w,h,0,border,0,' ',fill);
  1194. m_x-=w;
  1195. }
  1196. ClippingRect(m_x,m_y,w,h);
  1197. Cell(w,h,txt,0,ln,align,false,link);
  1198. UnsetClipping();
  1199. }
  1200. #line 1427 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1201. void FPDF::CellFit (pdf_float_t w, pdf_float_t h, char const * txt, char const * border, int ln, char align, bool fill, int link, bool scale, bool force)
  1202. #line 1430 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1203. {
  1204. //Get string width
  1205. pdf_float_t str_width=GetStringWidth(txt);
  1206. //Calculate ratio to fit cell
  1207. if(w==0.0f) w = m_w-m_rMargin-m_x;
  1208. pdf_float_t ratio = (w-m_cMargin*2)/str_width;
  1209. bool fit = (ratio < 1 || (ratio > 1 && force));
  1210. if (fit)
  1211. {
  1212. if (scale)
  1213. {
  1214. //Calculate horizontal scaling
  1215. pdf_float_t horiz_scale=ratio*100.0;
  1216. //Set horizontal scaling
  1217. _outfmt(true, "BT %.2f Tz ET", horiz_scale);
  1218. }
  1219. else
  1220. {
  1221. //Calculate character spacing in points
  1222. // TODO (mingo2#1#): UTF-8 strlen
  1223. int txt_size = txt ? strlen(txt) : 0;
  1224. pdf_float_t char_space=(w-m_cMargin*2-str_width)/std::max(txt_size-1,1)*m_k;
  1225. //Set character spacing
  1226. _outfmt(true, "BT %.2f Tc ET", char_space);
  1227. }
  1228. //Override user alignment (since text will fill up cell)
  1229. align=' ';
  1230. }
  1231. //Pass on to Cell method
  1232. Cell(w,h,txt,border,ln,align,fill,link);
  1233. //Reset character spacing/horizontal scaling
  1234. if (fit)
  1235. {
  1236. _out("BT ", false);
  1237. _out(scale ? "100 Tz" : "0 Tc", false);
  1238. _out(" ET");
  1239. }
  1240. }
  1241. #line 1546 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1242. void FPDF::Write (pdf_float_t h, char const * txt, int link)
  1243. #line 1547 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1244. {
  1245. // Output text in flowing mode
  1246. font_width_t *cw = m_CurrentFont->font.cw;
  1247. pdf_float_t w = m_w-m_rMargin-m_x;
  1248. pdf_float_t wmax = (w-2*m_cMargin)*1000.0/m_FontSize;
  1249. std::string stmp, s = txt ? txt : "";
  1250. _erasestrch(s, '\r');
  1251. int nb = s.size();
  1252. int sep = -1;
  1253. int i = 0;
  1254. int j = 0;
  1255. int l = 0;
  1256. int nl = 1;
  1257. while(i<nb)
  1258. {
  1259. // Get next character
  1260. unsigned char c = (unsigned char)s[i];
  1261. if(c=='\n')
  1262. {
  1263. // Explicit line break
  1264. stmp = s.substr(j, i-j);
  1265. Cell(w,h,stmp,0,2,' ',0,link);
  1266. i++;
  1267. sep = -1;
  1268. j = i;
  1269. l = 0;
  1270. if(nl==1)
  1271. {
  1272. m_x = m_lMargin;
  1273. w = m_w-m_rMargin-m_x;
  1274. wmax = (w-2*m_cMargin)*1000.0/m_FontSize;
  1275. }
  1276. nl++;
  1277. continue;
  1278. }
  1279. if(c==' ') sep = i;
  1280. l += cw[c];
  1281. if(l>wmax)
  1282. {
  1283. // Automatic line break
  1284. if(sep==-1)
  1285. {
  1286. if(m_x > m_lMargin)
  1287. {
  1288. // Move to next line
  1289. m_x = m_lMargin;
  1290. m_y += h;
  1291. w = m_w-m_rMargin-m_x;
  1292. wmax = (w-2*m_cMargin)*1000.0/m_FontSize;
  1293. i++;
  1294. nl++;
  1295. continue;
  1296. }
  1297. if(i==j) i++;
  1298. stmp = s.substr(j, i-j);
  1299. Cell(w,h,stmp,0,2,' ',0,link);
  1300. }
  1301. else
  1302. {
  1303. stmp = s.substr(j, sep-j);
  1304. Cell(w,h,stmp,0,2,' ',0,link);
  1305. i = sep+1;
  1306. }
  1307. sep = -1;
  1308. j = i;
  1309. l = 0;
  1310. if(nl==1)
  1311. {
  1312. m_x = m_lMargin;
  1313. w = m_w-m_rMargin-m_x;
  1314. wmax = (w-2*m_cMargin)*1000.0/m_FontSize;
  1315. }
  1316. nl++;
  1317. }
  1318. else
  1319. i++;
  1320. }
  1321. // Last chunk
  1322. if(i!=j)
  1323. {
  1324. stmp = s.substr(j, j);
  1325. Cell(l/1000.0*m_FontSize,h,stmp,0,0,' ',0,link);
  1326. }
  1327. }
  1328. #line 1632 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1329. void FPDF::Ln (pdf_float_t h)
  1330. #line 1633 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1331. {
  1332. // Line feed; default value is last cell height
  1333. m_x = m_lMargin;
  1334. if(h==0.0) m_y += m_lasth;
  1335. else m_y += h;
  1336. }
  1337. #line 1642 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1338. void FPDF::Image (char const * image_name, unsigned char const * image_blob, size_t blob_size, pdf_float_t x, pdf_float_t y, pdf_float_t w, pdf_float_t h, char const * atype, int link)
  1339. #line 1647 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1340. {
  1341. st_image info;
  1342. // Put an image on the page
  1343. if(!image_name) Error("Image name is null !");
  1344. if(m_images.find(image_name) == m_images.end())
  1345. {
  1346. // First use of this image, get info
  1347. std::string type;
  1348. if(atype) type = atype;
  1349. if(type.empty())
  1350. {
  1351. if(image_blob)
  1352. Error("Image type was not specified: %s", image_name);
  1353. //else assume image_name is a filename
  1354. const char *pos = strrchr(image_name,'.');
  1355. if(!pos)
  1356. Error("Image file has no extension and no type was specified: %s", image_name);
  1357. type = pos+1;
  1358. }
  1359. _str_tolower(type);
  1360. if(type=="jpeg") type = "jpg";
  1361. if(type == "jpg") {
  1362. if(image_blob) _parsejpg_blob(info, image_name, image_blob, blob_size);
  1363. else _parsejpg(info, image_name);
  1364. }
  1365. else if(type == "png") {
  1366. if(image_blob) _parsepng_blob(info, image_name, image_blob, blob_size);
  1367. else _parsepng(info, image_name);
  1368. }
  1369. else Error("Unsupported image type: %s", type.c_str());
  1370. info.i = m_images.size()+1;
  1371. m_images[image_name] = info;
  1372. }
  1373. else
  1374. info = m_images[image_name];
  1375. // Automatic width and height calculation if needed
  1376. if(w==0.0 && h==0.0)
  1377. {
  1378. // Put image at 96 dpi
  1379. w = -96;
  1380. h = -96;
  1381. }
  1382. else
  1383. {
  1384. if(w==0) w = h* info.w/info.h;
  1385. else if(w<0) w = - info.w*72.0/w/m_k;
  1386. if(h==0) h = w* info.h/info.w;
  1387. else if(h<0) h = - info.h*72.0/h/m_k;
  1388. }
  1389. pdf_float_t _y, _x;
  1390. // Flowing mode
  1391. if(y==-1)
  1392. {
  1393. if(m_y+h>m_PageBreakTrigger && !m_InHeader && !m_InFooter && AcceptPageBreak())
  1394. {
  1395. // Automatic page break
  1396. pdf_float_t x2 = m_x;
  1397. AddPage(m_CurOrientation, &m_CurPageSize);
  1398. m_x = x2;
  1399. }
  1400. _y = m_y;
  1401. m_y += h;
  1402. }
  1403. else _y = y;
  1404. if(x==-1) _x = m_x;
  1405. else _x = x;
  1406. _outfmt(true, "q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q",w*m_k,h*m_k,_x*m_k,(m_h-(_y+h))*m_k,info.i);
  1407. if(link) Link(_x,_y,w,h,link);
  1408. }
  1409. #line 1719 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1410. void FPDF::Image (char const * file, pdf_float_t x, pdf_float_t y, pdf_float_t w, pdf_float_t h, char const * atype, int link)
  1411. #line 1722 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1412. {
  1413. Image(file, 0, 0, x, y, w, h, atype, link);
  1414. }
  1415. #line 1732 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1416. void FPDF::SetX (pdf_float_t x)
  1417. #line 1733 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1418. {
  1419. // Set x position
  1420. if(x>=0) m_x = x;
  1421. else m_x = m_w+x;
  1422. }
  1423. #line 1745 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1424. void FPDF::SetY (pdf_float_t y)
  1425. #line 1746 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1426. {
  1427. // Set y position and reset x
  1428. m_x = m_lMargin;
  1429. if(y>=0) m_y = y;
  1430. else m_y = m_h+y;
  1431. }
  1432. #line 1772 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1433. std::string FPDF::Output (char const * name, char dest)
  1434. #line 1773 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1435. {
  1436. // Output PDF to some destination
  1437. if(m_state<3) Close();
  1438. if(dest==' ')
  1439. {
  1440. if(!name)
  1441. {
  1442. name = "doc.pdf";
  1443. dest = 'I';
  1444. }
  1445. else
  1446. dest = 'F';
  1447. }
  1448. switch(dest)
  1449. {
  1450. #if 0
  1451. case 'I':
  1452. // Send to standard output
  1453. _checkoutput();
  1454. if(PHP_SAPI!="cli")
  1455. {
  1456. // We send to a browser
  1457. header("Content-Type: application/pdf");
  1458. header("Content-Disposition: inline; filename="".name.""");
  1459. header("Cache-Control: private, max-age=0, must-revalidate");
  1460. header("Pragma: public");
  1461. }
  1462. echo m_buffer;
  1463. break;
  1464. case 'D':
  1465. // Download file
  1466. _checkoutput();
  1467. header("Content-Type: application/x-download");
  1468. header("Content-Disposition: attachment; filename="".name.""");
  1469. header("Cache-Control: private, max-age=0, must-revalidate");
  1470. header("Pragma: public");
  1471. echo m_buffer;
  1472. break;
  1473. #endif
  1474. case 'F':
  1475. {
  1476. // Save to local file
  1477. FILE *f = fopen(name,"wb");
  1478. if(!f)
  1479. Error("Unable to create output file: %s", name);
  1480. fwrite(m_buffer.c_str(), m_buffer.size(), 1, f);
  1481. fclose(f);
  1482. }
  1483. break;
  1484. case 'S':
  1485. // Return as a string
  1486. return m_buffer;
  1487. default:
  1488. Error("Incorrect output destination: %c", dest);
  1489. }
  1490. return "";
  1491. }
  1492. #line 1831 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1493. void FPDF::RoundedRect (pdf_float_t x, pdf_float_t y, pdf_float_t w, pdf_float_t h, pdf_float_t r, char const * style)
  1494. #line 1833 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1495. {
  1496. pdf_float_t k = m_k;
  1497. pdf_float_t hp = m_h;
  1498. pdf_float_t MyArc = 4.0/3.0 * (sqrt(2) - 1);
  1499. _outfmt(true, "%.2f %.2f m",(x+r)*k,(hp-y)*k);
  1500. pdf_float_t xc = x+w-r;
  1501. pdf_float_t yc = y+r;
  1502. _outfmt(true, "%.2f %.2f l", xc*k,(hp-y)*k);
  1503. _Arc(xc + r*MyArc, yc - r, xc + r, yc - r*MyArc, xc + r, yc);
  1504. xc = x+w-r;
  1505. yc = y+h-r;
  1506. _outfmt(true, "%.2f %.2f l",(x+w)*m_k,(hp-yc)*m_k);
  1507. _Arc(xc + r, yc + r*MyArc, xc + r*MyArc, yc + r, xc, yc + r);
  1508. xc = x+r;
  1509. yc = y+h-r;
  1510. _outfmt(true, "%.2f %.2f l",xc*m_k,(hp-(y+h))*m_k);
  1511. _Arc(xc - r*MyArc, yc + r, xc - r, yc + r*MyArc, xc - r, yc);
  1512. xc = x+r;
  1513. yc = y+r;
  1514. _outfmt(true, "%.2F %.2F l",(x)*m_k,(hp-yc)*m_k);
  1515. _Arc(xc - r, yc - r*MyArc, xc - r*MyArc, yc - r, xc, yc - r);
  1516. std::string str_style = style ? style : "";
  1517. if(str_style=="F") _out("f");
  1518. else if(str_style=="FD" || str_style=="DF") _out("B");
  1519. else _out("S");
  1520. }
  1521. #line 1861 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1522. void FPDF::Circle (pdf_float_t x, pdf_float_t y, pdf_float_t r, char const * style)
  1523. #line 1862 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1524. {
  1525. Ellipse(x,y,r,r,style);
  1526. }
  1527. #line 1866 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1528. void FPDF::Ellipse (pdf_float_t x, pdf_float_t y, pdf_float_t rx, pdf_float_t ry, char const * style)
  1529. #line 1868 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1530. {
  1531. const char *op = "S";
  1532. std::string str_style = style ? style : "";
  1533. if(str_style=="F") op ="f";
  1534. else if(str_style=="FD" || str_style=="DF") op ="B";
  1535. pdf_float_t tmp = 4.0/3.0*(sqrt(2)-1);
  1536. pdf_float_t lx=tmp*rx;
  1537. pdf_float_t ly=tmp*ry;
  1538. _outfmt(true, "%.2f %.2f m %.2f %.2f %.2f %.2f %.2f %.2f c",
  1539. (x+rx)*m_k,(m_h-y)*m_k,
  1540. (x+rx)*m_k,(m_h-(y-ly))*m_k,
  1541. (x+lx)*m_k,(m_h-(y-ry))*m_k,
  1542. x*m_k,(m_h-(y-ry))*m_k);
  1543. _outfmt(true, "%.2f %.2f %.2f %.2f %.2f %.2f c",
  1544. (x-lx)*m_k,(m_h-(y-ry))*m_k,
  1545. (x-rx)*m_k,(m_h-(y-ly))*m_k,
  1546. (x-rx)*m_k,(m_h-y)*m_k);
  1547. _outfmt(true, "%.2f %.2f %.2f %.2f %.2f %.2f c",
  1548. (x-rx)*m_k,(m_h-(y+ly))*m_k,
  1549. (x-lx)*m_k,(m_h-(y+ry))*m_k,
  1550. x*m_k,(m_h-(y+ry))*m_k);
  1551. _outfmt(true, "%.2f %.2f %.2f %.2f %.2f %.2f c %s",
  1552. (x+lx)*m_k,(m_h-(y+ry))*m_k,
  1553. (x+rx)*m_k,(m_h-(y+ly))*m_k,
  1554. (x+rx)*m_k,(m_h-y)*m_k,
  1555. op);
  1556. }
  1557. #line 1896 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1558. void FPDF::IncludeJS (char const * script)
  1559. #line 1897 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1560. {
  1561. m_javascript=script;
  1562. }
  1563. #line 1908 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1564. void FPDF::_Arc (pdf_float_t x1, pdf_float_t y1, pdf_float_t x2, pdf_float_t y2, pdf_float_t x3, pdf_float_t y3)
  1565. #line 1909 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1566. {
  1567. pdf_float_t h = m_h;
  1568. _outfmt(true, "%.2f %.2f %.2f %.2f %.2f %.2f c ", x1*m_k,
  1569. (h-y1)*m_k, x2*m_k, (h-y2)*m_k, x3*m_k, (h-y3)*m_k);
  1570. }
  1571. #line 1915 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1572. std::string & FPDF::_erasestrch (std::string & str, char c)
  1573. #line 1916 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1574. {
  1575. if(!str.empty())
  1576. {
  1577. size_t size = str.size();
  1578. //int used intentionally for the case of 0nt char should be erased
  1579. for(size_t i=0; i<size; ++i)
  1580. {
  1581. if(str.at(i) == c)
  1582. {
  1583. str.erase(i, 1);
  1584. --size;
  1585. --i;
  1586. }
  1587. }
  1588. }
  1589. return str;
  1590. }
  1591. #line 1934 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1592. void FPDF::_str_tolower (std::string & str)
  1593. #line 1935 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1594. {
  1595. for(size_t i=0, size=str.size(); i < size; ++i)
  1596. {
  1597. str[i] = tolower(str[i]);
  1598. }
  1599. }
  1600. #line 1942 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1601. void FPDF::_dochecks ()
  1602. #line 1943 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1603. {}
  1604. #line 1946 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1605. void FPDF::_checkoutput ()
  1606. #line 1947 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1607. {
  1608. #if 0
  1609. if(PHP_SAPI!="cli")
  1610. {
  1611. if(headers_sent(file,line))
  1612. Error("Some data has already been output, can't send PDF file (output started at file:line)");
  1613. }
  1614. if(ob_get_length())
  1615. {
  1616. // The output buffer is not empty
  1617. if(preg_match("/^(\xEF\xBB\xBF)?\s*/",ob_get_contents()))
  1618. {
  1619. // It contains only a UTF-8 BOM and/or whitespace, let"s clean it
  1620. ob_clean();
  1621. }
  1622. else
  1623. Error("Some data has already been output, can't send PDF file");
  1624. }
  1625. #endif
  1626. }
  1627. #line 1969 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1628. FPDF::st_pagesize & FPDF::_getpagesize (st_pagesize & result, e_page_sizes size)
  1629. #line 1970 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1630. {
  1631. switch(size)
  1632. {
  1633. case e_A3:
  1634. result.w = 841.89;
  1635. result.h = 1190.55;
  1636. break;
  1637. case e_A5:
  1638. result.w = 420.94;
  1639. result.h = 595.28;
  1640. break;
  1641. case e_Letter:
  1642. result.w = 612;
  1643. result.h = 792;
  1644. break;
  1645. case e_Legal:
  1646. result.w = 612;
  1647. result.h = 1008;
  1648. break;
  1649. default:
  1650. /*case e_A4:*/
  1651. result.w = 595.28;
  1652. result.h = 841.89;
  1653. break;
  1654. }
  1655. result.w /= m_k;
  1656. result.h /=m_k;
  1657. return result;
  1658. }
  1659. #line 2001 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1660. void FPDF::_beginpage (e_orientation orientation, st_pagesize * size)
  1661. #line 2002 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1662. {
  1663. m_page++;
  1664. m_pages.resize(m_page);
  1665. m_state = 2;
  1666. m_x = m_lMargin;
  1667. m_y = m_tMargin;
  1668. m_FontFamily = "";
  1669. // Check page size and orientation
  1670. if(orientation==e_orientation_none) orientation = m_DefOrientation;
  1671. st_pagesize *psize;
  1672. if(!size) psize = &m_DefPageSize;
  1673. else psize = size;
  1674. if(orientation!=m_CurOrientation || psize->w != m_CurPageSize.w || psize->h != m_CurPageSize.h)
  1675. {
  1676. // New size or orientation
  1677. if(orientation==e_orientation_portrait)
  1678. {
  1679. m_w = psize->w;
  1680. m_h = psize->h;
  1681. }
  1682. else
  1683. {
  1684. m_w = psize->h;
  1685. m_h = psize->w;
  1686. }
  1687. m_wPt = m_w*m_k;
  1688. m_hPt = m_h*m_k;
  1689. m_PageBreakTrigger = m_h-m_bMargin;
  1690. m_CurOrientation = orientation;
  1691. m_CurPageSize = *psize;
  1692. }
  1693. if(orientation != m_DefOrientation || psize->w != m_DefPageSize.w || psize->h != m_DefPageSize.h)
  1694. {
  1695. st_pagesize ps;
  1696. ps.w = m_wPt;
  1697. ps.h = m_hPt;
  1698. m_PageSizes[m_page] = ps;
  1699. }
  1700. if ( m_doubleSided )
  1701. {
  1702. if( m_page % 2 == 0 )
  1703. {
  1704. m_xDelta=m_outerMargin - m_innerMargin;
  1705. SetLeftMargin(m_outerMargin);
  1706. SetRightMargin(m_innerMargin);
  1707. }
  1708. else
  1709. {
  1710. m_xDelta=m_innerMargin - m_outerMargin;
  1711. SetLeftMargin(m_innerMargin);
  1712. SetRightMargin(m_outerMargin);
  1713. }
  1714. m_x=m_lMargin;
  1715. m_y=m_tMargin;
  1716. }
  1717. }
  1718. #line 2081 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1719. std::string FPDF::_escape (std::string const & s)
  1720. #line 2082 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1721. {
  1722. std::string str = s;
  1723. if(!str.empty())
  1724. {
  1725. size_t size = str.size();
  1726. for(size_t i=0; i<size; ++i)
  1727. {
  1728. switch((unsigned char)str.at(i))
  1729. {
  1730. case '\\':
  1731. case '(':
  1732. case ')':
  1733. str.insert(i, "\\");
  1734. ++size;
  1735. ++i;
  1736. continue;
  1737. case '\r':
  1738. str.erase(i, 1);
  1739. --size;
  1740. continue;
  1741. //now a cheap ut82latin
  1742. case 0xE2: //euro 0xE282AC = \200
  1743. if(((unsigned char)str[i+1]) == 0x82 && ((unsigned char)str[i+2]) == 0xAC)
  1744. {
  1745. str[i] = '\\';
  1746. str[i+1] = '2';
  1747. str[i+2] = '0';
  1748. str.insert(i+3, "0");
  1749. size += 1;
  1750. i += 3;
  1751. }
  1752. continue;
  1753. case 0xC2:
  1754. str.erase(i, 1);
  1755. --size;
  1756. continue;
  1757. case 0xC3:
  1758. str.erase(i, 1);
  1759. str[i] += 64;
  1760. --size;
  1761. --i;
  1762. continue;
  1763. }
  1764. }
  1765. }
  1766. return str;
  1767. }
  1768. #line 2130 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1769. void FPDF::_textstring (std::string & result, std::string const & s)
  1770. #line 2131 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1771. {
  1772. // Format a text string
  1773. result = "(" + _escape(s) + ")";
  1774. }
  1775. #line 2171 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1776. int FPDF::substr_count (char const * str, char c)
  1777. #line 2172 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1778. {
  1779. int result = 0;
  1780. if(str)
  1781. {
  1782. while(*str)
  1783. {
  1784. if(*str++ == c) result++;
  1785. }
  1786. }
  1787. return result;
  1788. }
  1789. #line 2184 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1790. std::string FPDF::_dounderline (pdf_float_t x, pdf_float_t y, char const * txt)
  1791. #line 2185 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1792. {
  1793. // Underline text
  1794. int up = m_CurrentFont->font.up;
  1795. int ut = m_CurrentFont->font.ut;
  1796. int w = GetStringWidth(txt)+m_ws*substr_count(txt,' ');
  1797. pdf_snprintf(m_scratch_buf, sizeof(m_scratch_buf), "%.2f %.2f %.2f %.2f re f",x*m_k,(m_h-(y-up/1000.0*m_FontSize))*m_k,w*m_k,-ut/1000.0*m_FontSizePt);
  1798. return m_scratch_buf;
  1799. }
  1800. #line 2199 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1801. FPDF::blob_stream_t::~ blob_stream_t ()
  1802. #line 2199 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1803. {}
  1804. #line 2206 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1805. FPDF::blob_stream_memory_t::blob_stream_memory_t (unsigned char const * ablob, size_t asize)
  1806. #line 2206 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1807. {
  1808. blob = ablob;
  1809. size = asize;
  1810. offset = 0;
  1811. }
  1812. #line 2211 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1813. bool FPDF::blob_stream_memory_t::eof ()
  1814. #line 2211 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1815. {
  1816. return offset == size;
  1817. }
  1818. #line 2214 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1819. size_t FPDF::blob_stream_memory_t::tell ()
  1820. #line 2214 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1821. {
  1822. return offset;
  1823. }
  1824. #line 2218 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1825. size_t FPDF::blob_stream_memory_t::read (void * dest, size_t num_read)
  1826. #line 2219 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1827. {
  1828. if (offset + num_read > size)
  1829. num_read = size - offset;
  1830. memcpy ((char *)dest, blob + offset, num_read);
  1831. offset += num_read;
  1832. return num_read;
  1833. }
  1834. #line 2230 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1835. void FPDF::blob_stream_memory_t::seek (size_t to_offset, int whence)
  1836. #line 2231 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1837. {
  1838. size_t npos;
  1839. switch (whence) {
  1840. case SEEK_SET:
  1841. npos = to_offset;
  1842. break;
  1843. case SEEK_CUR:
  1844. npos = offset + to_offset;
  1845. break;
  1846. case SEEK_END:
  1847. npos = size;
  1848. break;
  1849. default:
  1850. return;
  1851. }
  1852. offset = npos > size ? size : npos;
  1853. }
  1854. #line 2257 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1855. FPDF::blob_stream_file_t::blob_stream_file_t (FILE * afp)
  1856. #line 2257 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1857. {
  1858. fp = afp;
  1859. }
  1860. #line 2260 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1861. FPDF::blob_stream_file_t::~ blob_stream_file_t ()
  1862. #line 2260 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1863. {
  1864. if(fp) fclose(fp);
  1865. }
  1866. #line 2263 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1867. bool FPDF::blob_stream_file_t::eof ()
  1868. #line 2263 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1869. {
  1870. return feof(fp);
  1871. }
  1872. #line 2266 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1873. size_t FPDF::blob_stream_file_t::tell ()
  1874. #line 2266 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1875. {
  1876. return ftell(fp);
  1877. }
  1878. #line 2270 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1879. size_t FPDF::blob_stream_file_t::read (void * dest, size_t num_read)
  1880. #line 2271 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1881. {
  1882. return fread(dest, 1, num_read, fp);
  1883. }
  1884. #line 2275 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1885. void FPDF::blob_stream_file_t::seek (size_t to_offset, int whence)
  1886. #line 2276 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1887. {
  1888. fseek(fp, to_offset, whence);
  1889. }
  1890. #line 2306 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1891. void FPDF::_parsejpg (st_image & info, blob_stream_t & fp, char const * image_name)
  1892. #line 2307 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  1893. {
  1894. bool isValid = false;
  1895. info.cs.clear();
  1896. info.pal.clear();
  1897. info.trns.clear();
  1898. info.data.clear();
  1899. std::string buf;
  1900. _readstream(buf,fp,3);
  1901. if (buf != "\xff\xd8\xff")
  1902. Error("Not a JPG image: %s", image_name);
  1903. // Extract info from a JPEG file
  1904. unsigned int marker = M_PSEUDO;
  1905. unsigned short length, ffRead = 1;
  1906. unsigned char bits = 0;
  1907. unsigned short height = 0;
  1908. unsigned short width = 0;
  1909. unsigned char channels = 0;
  1910. bool ready = false;
  1911. int lastMarker;
  1912. int commentCorrection;
  1913. int a;
  1914. while (!ready)
  1915. {
  1916. lastMarker = marker;
  1917. commentCorrection = 1;
  1918. a = 0;
  1919. // get marker byte, swallowing possible padding
  1920. if (lastMarker == M_COM && commentCorrection)
  1921. {
  1922. // some software does not count the length bytes of COM section
  1923. // one company doing so is very much envolved in JPEG... so we accept too
  1924. // by the way: some of those companies changed their code now...
  1925. commentCorrection = 2;
  1926. }
  1927. else
  1928. {
  1929. lastMarker = 0;
  1930. commentCorrection = 0;
  1931. }
  1932. if (ffRead)
  1933. {
  1934. a = 1; // already read 0xff in filetype detection
  1935. }
  1936. do
  1937. {
  1938. _readstream(buf,fp,1);
  1939. if (fp.eof())
  1940. {
  1941. marker = M_EOI; // we hit EOF
  1942. break;
  1943. }
  1944. marker = (unsigned char)buf[0];
  1945. if (lastMarker == M_COM && commentCorrection > 0)
  1946. {
  1947. if (marker != 0xFF)
  1948. {
  1949. marker = 0xff;
  1950. commentCorrection--;
  1951. }
  1952. else
  1953. {
  1954. lastMarker = M_PSEUDO; // stop skipping non 0xff for M_COM
  1955. }
  1956. }
  1957. if (++a > 10)
  1958. {
  1959. // who knows the maxim amount of 0xff? though 7
  1960. // but found other implementations
  1961. marker = M_EOI;
  1962. break;
  1963. }
  1964. }
  1965. while (marker == 0xff);
  1966. if (a < 2)
  1967. {
  1968. marker = M_EOI; // at least one 0xff is needed before marker code
  1969. }
  1970. if (lastMarker == M_COM && commentCorrection)
  1971. {
  1972. marker = M_EOI; // ah illegal: char after COM section not 0xFF
  1973. }
  1974. ffRead = 0;
  1975. switch (marker)
  1976. {
  1977. case M_SOF0:
  1978. case M_SOF1:
  1979. case M_SOF2:
  1980. case M_SOF3:
  1981. case M_SOF5:
  1982. case M_SOF6:
  1983. case M_SOF7:
  1984. case M_SOF9:
  1985. case M_SOF10:
  1986. case M_SOF11:
  1987. case M_SOF13:
  1988. case M_SOF14:
  1989. case M_SOF15:
  1990. // handle SOFn block
  1991. length = (unsigned short)_readshort(fp);
  1992. _readstream(buf, fp,1);
  1993. bits = (unsigned char)buf[0];
  1994. height = (unsigned short)_readshort(fp);
  1995. width = (unsigned short)_readshort(fp);
  1996. _readstream(buf, fp,1);
  1997. channels = (unsigned char)buf[0];
  1998. isValid = true;
  1999. ready = true;
  2000. break;
  2001. case M_SOS:
  2002. case M_EOI:
  2003. isValid = false;
  2004. ready = true;
  2005. default:
  2006. {
  2007. // anything else isn't interesting
  2008. long pos = (unsigned short) _readshort(fp);
  2009. pos = pos-2;
  2010. if (pos)
  2011. {
  2012. fp.seek(pos, SEEK_CUR );
  2013. }
  2014. }
  2015. break;
  2016. }
  2017. }
  2018. if (isValid)
  2019. {
  2020. if (channels == 3)
  2021. {
  2022. info.cs = "DeviceRGB";
  2023. }
  2024. else if(channels == 4)
  2025. {
  2026. info.cs = "DeviceCMYK";
  2027. }
  2028. else
  2029. {
  2030. info.cs = "DeviceGray";
  2031. }
  2032. info.bpc = bits;
  2033. //Read whole file
  2034. fp.seek(0, SEEK_END);
  2035. int fsize = fp.tell();
  2036. fp.seek(0, SEEK_SET);
  2037. _readstream(info.data, fp, fsize);
  2038. info.w = width;
  2039. info.h = height;
  2040. info.f = "DCTDecode";
  2041. return;
  2042. }
  2043. Error("Invalid JPG image: %s", image_name);
  2044. }
  2045. #line 2471 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2046. void FPDF::_parsejpg (st_image & info, char const * file_name)
  2047. #line 2472 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2048. {
  2049. // Extract info from a JPG file
  2050. FILE *fp = fopen(file_name,"rb");
  2051. if(!fp) Error("Can't open image file: %s", file_name);
  2052. blob_stream_file_t sf(fp);
  2053. _parsejpg(info, sf, file_name);
  2054. }
  2055. #line 2481 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2056. void FPDF::_parsejpg_blob (st_image & info, char const * image_name, unsigned char const * image_blob, size_t blob_size)
  2057. #line 2483 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2058. {
  2059. if(!image_name) Error("Image name is NULL!");
  2060. if(!image_blob) Error("Image blob is NULL!");
  2061. if(!blob_size) Error("Image blob size is zero!");
  2062. blob_stream_memory_t sm(image_blob, blob_size);
  2063. _parsejpg(info, sm, image_name);
  2064. }
  2065. #line 2491 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2066. void FPDF::_parsepng (st_image & info, char const * file_name)
  2067. #line 2492 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2068. {
  2069. // Extract info from a PNG file
  2070. FILE *fp = fopen(file_name,"rb");
  2071. if(!fp) Error("Can't open image file: %s", file_name);
  2072. blob_stream_file_t sf(fp);
  2073. _parsepngstream(info, sf, file_name);
  2074. }
  2075. #line 2502 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2076. void FPDF::_parsepng_blob (st_image & info, char const * image_name, unsigned char const * image_blob, size_t blob_size)
  2077. #line 2504 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2078. {
  2079. if(!image_name) Error("Image name is NULL!");
  2080. if(!image_blob) Error("Image blob is NULL!");
  2081. if(!blob_size) Error("Image blob size is zero!");
  2082. blob_stream_memory_t sm(image_blob, blob_size);
  2083. _parsepngstream(info, sm, image_name);
  2084. }
  2085. #line 2512 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2086. void FPDF::_getGrayImgColorAndalpha (std::string & color, std::string & alpha, std::string & line)
  2087. #line 2512 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2088. {
  2089. size_t size = line.size();
  2090. color.reserve(size);
  2091. alpha.reserve(size);
  2092. for(size_t i=0; i<size; i+=2){
  2093. color += line[i];
  2094. alpha += line[i+1];
  2095. }
  2096. }
  2097. #line 2522 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2098. void FPDF::_getRGBImgColorAndalpha (std::string & color, std::string & alpha, std::string & line)
  2099. #line 2522 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2100. {
  2101. size_t size = line.size();
  2102. color.reserve(size);
  2103. alpha.reserve(size/3);
  2104. for(size_t i=0; i<size; i+=4){
  2105. color.append(line.c_str()+i, 3);
  2106. alpha += line[i+3];
  2107. }
  2108. }
  2109. #line 2532 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2110. void FPDF::_parsepngstream (st_image & info, blob_stream_t & fp, char const * image_name)
  2111. #line 2533 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2112. {
  2113. std::string buf;
  2114. // Check signature
  2115. _readstream(buf, fp, 8);
  2116. if(buf != "\x89PNG\x0D\x0A\x1A\x0A")
  2117. Error("Not a PNG image: %s", image_name);
  2118. // Read header chunk
  2119. _readstream(buf, fp, 4);
  2120. _readstream(buf, fp, 4);
  2121. if(buf != "IHDR") Error("Incorrect PNG image: %s", image_name);
  2122. info.w = _readint(fp);
  2123. info.h = _readint(fp);
  2124. _readstream(buf, fp, 1);
  2125. info.bpc = buf[0];
  2126. if(info.bpc>8) Error("16-bit depth not supported: %s", image_name);
  2127. _readstream(buf, fp, 1);
  2128. int ct = buf[0];
  2129. if(ct==0 || ct==4) info.cs = "DeviceGray";
  2130. else if(ct==2 || ct==6) info.cs = "DeviceRGB";
  2131. else if(ct==3) info.cs = "Indexed";
  2132. else Error("Unknown color type: %s", image_name);
  2133. _readstream(buf, fp, 3);
  2134. if(buf[0]!=0)
  2135. Error("Unknown compression method: %s", image_name);
  2136. if(buf[1]!=0)
  2137. Error("Unknown filter method: %s", image_name);
  2138. if(buf[2]!=0)
  2139. Error("Interlacing not supported: %s", image_name);
  2140. _readstream(buf,fp,4);
  2141. pdf_sprintf(info.dp, "/Predictor 15 /Colors %d /BitsPerComponent %d /Columns %d",
  2142. (info.cs=="DeviceRGB" ? 3 : 1), (int)info.bpc, (int)info.w);
  2143. // Scan chunks looking for palette, transparency and image data
  2144. info.pal.clear();
  2145. info.trns.clear();
  2146. info.data.clear();
  2147. int n;
  2148. do
  2149. {
  2150. n = _readint(fp);
  2151. _readstream(buf, fp, 4);
  2152. if(buf=="PLTE")
  2153. {
  2154. // Read palette
  2155. _readstream(info.pal, fp,n);
  2156. _readstream(buf, fp, 4);
  2157. }
  2158. else if(buf=="tRNS")
  2159. {
  2160. // Read transparency info
  2161. _readstream(buf,fp,n);
  2162. if(ct==0)
  2163. {
  2164. info.trns.push_back(buf[1]);
  2165. }
  2166. else if(ct==2)
  2167. {
  2168. info.trns.push_back(buf[1]);
  2169. info.trns.push_back(buf[3]);
  2170. info.trns.push_back(buf[5]);
  2171. }
  2172. else
  2173. {
  2174. size_t pos = buf.find('\0');
  2175. if(pos!=std::string::npos)
  2176. info.trns.push_back(buf[pos]);
  2177. }
  2178. _readstream(buf,fp,4);
  2179. }
  2180. else if(buf=="IDAT")
  2181. {
  2182. // Read image data block
  2183. info.data += _readstream(buf,fp,n);
  2184. _readstream(buf, fp, 4);
  2185. }
  2186. else if(buf=="IEND")
  2187. break;
  2188. else
  2189. _readstream(buf,fp,n+4);
  2190. }
  2191. while(n);
  2192. if(info.cs=="Indexed" && info.pal.empty()) Error("Missing palette in %s", image_name);
  2193. info.f = "FlateDecode";
  2194. #ifdef PDF_USING_ZLIB
  2195. if(ct>=4)
  2196. {
  2197. // Extract alpha channel
  2198. std::string data;
  2199. gzuncompress(data, info.data);
  2200. std::string color, alpha, line;
  2201. if(ct==4)
  2202. {
  2203. // Gray image
  2204. int len = 2*info.w;
  2205. for(int i=0; i<info.h; i++)
  2206. {
  2207. int pos = (1+len)*i;
  2208. color.append(data[pos], 1);
  2209. alpha.append(data[pos], 1);
  2210. line.assign(data.c_str()+pos+1,len);
  2211. _getGrayImgColorAndalpha(color, alpha, line);
  2212. //color += preg_replace("/(.)./s","1",line);
  2213. //alpha += preg_replace("/.(.)/s","1",line);
  2214. }
  2215. }
  2216. else
  2217. {
  2218. // RGB image
  2219. int len = 4*info.w;
  2220. for(int i=0; i<info.h; i++)
  2221. {
  2222. int pos = (1+len)*i;
  2223. color.append(data[pos], 1);
  2224. alpha.append(data[pos], 1);
  2225. line.assign(data.c_str()+pos+1,len);
  2226. _getRGBImgColorAndalpha(color, alpha, line);
  2227. //color += preg_replace("/(.{3})./s","1",line);
  2228. //alpha += preg_replace("/.{3}(.)/s","1",line);
  2229. }
  2230. }
  2231. gzcompress(info.smask, alpha);
  2232. data.clear();
  2233. gzcompress(info.data, color);
  2234. if(m_PDFVersion < "1.4") m_PDFVersion = "1.4";
  2235. }
  2236. #endif
  2237. }
  2238. #line 2664 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2239. std::string & FPDF::_readstream (std::string & result, blob_stream_t & fp, size_t n)
  2240. #line 2665 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2241. {
  2242. // Read n bytes from stream
  2243. result.resize(n);
  2244. if(fp.read(&result[0], n) != n) Error("Can't read from stream !");
  2245. return result;
  2246. }
  2247. #line 2672 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2248. int FPDF::_readint (blob_stream_t & fp)
  2249. #line 2673 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2250. {
  2251. // Read a 4-byte integer from stream
  2252. std::string buf;
  2253. _readstream(buf, fp, 4);
  2254. int i = 1;
  2255. char *p = (char *)&i;
  2256. if (p[0] == 1) //LITTLE_ENDIAN
  2257. {
  2258. unsigned char c0 = buf[0], c1 = buf[1], c2 = buf[2], c3 = buf[3];
  2259. buf[0] = c3;
  2260. buf[1] = c2;
  2261. buf[2] = c1;
  2262. buf[3] = c0;
  2263. }
  2264. //else BIG_ENDIAN
  2265. return *((int*)&buf[0]);
  2266. }
  2267. #line 2691 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2268. int FPDF::_readshort (blob_stream_t & fp)
  2269. #line 2692 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2270. {
  2271. // Read a 4-byte integer from stream
  2272. std::string buf;
  2273. _readstream(buf, fp, 2);
  2274. short i = 1;
  2275. char *p = (char *)&i;
  2276. if (p[0] == 1) //LITTLE_ENDIAN
  2277. {
  2278. unsigned char c0 = buf[0], c1 = buf[1];
  2279. buf[0] = c1;
  2280. buf[1] = c0;
  2281. }
  2282. //else BIG_ENDIAN
  2283. return *((short*)&buf[0]);
  2284. }
  2285. #line 2708 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2286. void FPDF::_parsegif (std::string & file)
  2287. #line 2709 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2288. {
  2289. #if 0
  2290. // Extract info from a GIF file (via PNG conversion)
  2291. if(!function_exists("imagepng"))
  2292. Error("GD extension is required for GIF support");
  2293. if(!function_exists("imagecreatefromgif"))
  2294. Error("GD has no GIF read support");
  2295. im = imagecreatefromgif(file);
  2296. if(!im)
  2297. Error("Missing or incorrect image file: ".file);
  2298. imageinterlace(im,0);
  2299. f = @fopen("php://temp","rb+");
  2300. if(f)
  2301. {
  2302. // Perform conversion in memory
  2303. ob_start();
  2304. imagepng(im);
  2305. data = ob_get_clean();
  2306. imagedestroy(im);
  2307. fwrite(f,data);
  2308. fseek(fp, 0, SEEK_SET);
  2309. info = _parsepngstream(f,file);
  2310. fclose(f);
  2311. }
  2312. else
  2313. {
  2314. // Use temporary file
  2315. tmp = tempnam(".","gif");
  2316. if(!tmp)
  2317. Error("Unable to create a temporary file");
  2318. if(!imagepng(im,tmp))
  2319. Error("Error while saving to temporary file");
  2320. imagedestroy(im);
  2321. info = _parsepng(tmp);
  2322. unlink(tmp);
  2323. }
  2324. return info;
  2325. #endif
  2326. }
  2327. #line 2749 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2328. void FPDF::_newobj ()
  2329. #line 2750 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2330. {
  2331. // Begin a new object
  2332. m_n++;
  2333. m_offsets.push_back(m_buffer.size());
  2334. _outfmt(true, "%d 0 obj", m_n);
  2335. }
  2336. #line 2757 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2337. void FPDF::_putstream (std::string const & s)
  2338. #line 2758 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2339. {
  2340. _out("stream");
  2341. _out(s);
  2342. _out("endstream");
  2343. }
  2344. #line 2764 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2345. void FPDF::_out (char const * s, size_t size, bool nl)
  2346. #line 2765 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2347. {
  2348. // Add a line to the document
  2349. if(m_state==2)
  2350. {
  2351. std::string &str = m_pages[m_page-1];
  2352. str.append(s, size);
  2353. if(nl) str += "\n";
  2354. }
  2355. else
  2356. {
  2357. m_buffer.append(s, size);
  2358. if(nl) m_buffer += "\n";
  2359. }
  2360. }
  2361. #line 2780 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2362. std::string & FPDF::pdf_sprintf (std::string & s, char const * fmt, ...)
  2363. #line 2781 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2364. {
  2365. va_list args;
  2366. va_start( args, fmt );
  2367. int size = pdf_vsnprintf(m_scratch_buf, sizeof(m_scratch_buf), fmt, args);
  2368. va_end( args );
  2369. if(size < 0) Error("Too big string passed to sprintf %d", __LINE__);
  2370. s = m_scratch_buf;
  2371. return s;
  2372. }
  2373. #line 2791 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2374. void FPDF::pdf_sprintf_append (std::string & s, char const * fmt, ...)
  2375. #line 2792 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2376. {
  2377. va_list args;
  2378. va_start( args, fmt );
  2379. int size = pdf_vsnprintf(m_scratch_buf, sizeof(m_scratch_buf), fmt, args);
  2380. va_end( args );
  2381. if(size < 0) Error("Too big string passed to sprintf %d", __LINE__);
  2382. s += m_scratch_buf;
  2383. }
  2384. #line 2801 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2385. void FPDF::_outfmt (bool nl, char const * fmt, ...)
  2386. #line 2802 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2387. {
  2388. va_list args;
  2389. va_start( args, fmt );
  2390. int size = pdf_vsnprintf(m_scratch_buf, sizeof(m_scratch_buf), fmt, args);
  2391. va_end( args );
  2392. if(size < 0) Error("Too big string passed to sprintf %d", __LINE__);
  2393. _out(m_scratch_buf, size, nl);
  2394. }
  2395. #line 2811 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2396. void FPDF::_out (char const * s, bool nl)
  2397. #line 2812 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2398. {
  2399. _out(s, strlen(s), nl);
  2400. }
  2401. #line 2816 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2402. void FPDF::_out (std::string const & s, bool nl)
  2403. #line 2817 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2404. {
  2405. _out(s.c_str(), s.size(), nl);
  2406. }
  2407. #line 2821 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2408. void FPDF::_putpages ()
  2409. #line 2822 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2410. {
  2411. int nb = m_page;
  2412. if(!m_AliasNbPages.empty())
  2413. {
  2414. // Replace number of pages
  2415. std::string str;
  2416. pdf_sprintf(str, "%d", nb);
  2417. for(int n=0; n<nb; n++)
  2418. {
  2419. std::string &page = m_pages[n];
  2420. for(std::string::size_type loc = page.find(m_AliasNbPages);
  2421. loc != std::string::npos; loc = page.find(m_AliasNbPages, loc))
  2422. {
  2423. page.replace(loc, m_AliasNbPages.size(), str, 0, str.size());
  2424. }
  2425. }
  2426. }
  2427. pdf_float_t wPt, hPt;
  2428. if(m_DefOrientation==e_orientation_portrait)
  2429. {
  2430. wPt = m_DefPageSize.w*m_k;
  2431. hPt = m_DefPageSize.h*m_k;
  2432. }
  2433. else
  2434. {
  2435. wPt = m_DefPageSize.h*m_k;
  2436. hPt = m_DefPageSize.w*m_k;
  2437. }
  2438. std::string filter = (m_compress) ? "/Filter /FlateDecode " : "";
  2439. for(int n=1; n<=nb; n++)
  2440. {
  2441. // Page
  2442. _newobj();
  2443. _outfmt(true, "<<\n/Type /Page");
  2444. _outfmt(true, "/Parent 1 0 R");
  2445. if(m_PageSizes.find(n) != m_PageSizes.end())
  2446. _outfmt(true, "/MediaBox [0 0 %.2f %.2f]",m_PageSizes[n].w,m_PageSizes[n].h);
  2447. _outfmt(true, "/Resources 2 0 R");
  2448. if(m_PageLinks.find(n) != m_PageLinks.end())
  2449. {
  2450. // Links
  2451. std::string annots = "/Annots [";
  2452. #if 0
  2453. link_map_t::iterator iter = m_PageLinks[n].begin();
  2454. link_map_t::iterator iend = m_PageLinks[n].end();
  2455. for(; iter != iend; ++iter)
  2456. {
  2457. st_page_link &pl = *iter->second;
  2458. pdf_snprintf(m_scratch_buf, sizeof(m_scratch_buf), "%.2f %.2f %.2f %.2f",pl[0],pl[1],pl[0]+pl[2],pl[1]-pl[3]);
  2459. rect = m_scratch_buf;
  2460. annots += "<<\n/Type /Annot /Subtype /Link /Rect [" + rect + "] /Border [0 0 0] ";
  2461. if(is_string(pl[4]))
  2462. annots += "/A\n<<\n/S /URI /URI " + _3textstring(pl[4]) + "\n>>\n>>\n";
  2463. else
  2464. {
  2465. l = m_links[pl[4]];
  2466. int lidx = l[0];
  2467. h = m_PageSizes.find([lidx]) != -1 ? m_PageSizes[lidx].h : hPt;
  2468. pdf_sprintf_append(annots, "/Dest [%d 0 R /XYZ 0 %.2f null]\n>>\n",1+2*lidx,h-l[1]*m_k);
  2469. }
  2470. }
  2471. #endif
  2472. _out(annots + "]");
  2473. }
  2474. if(m_PDFVersion > "1.3")
  2475. _outfmt(true, "/Group\n<<\n/Type /Group /S /Transparency /CS /DeviceRGB\n>>");
  2476. _outfmt(true, "/Contents %d 0 R\n>>", m_n+1);
  2477. _out("endobj");
  2478. // Page content
  2479. std::string zbuf, &p =
  2480. #ifdef PDF_USING_ZLIB
  2481. (m_compress) ? gzcompress(zbuf, m_pages[n-1]) :
  2482. #endif
  2483. m_pages[n-1];
  2484. _newobj();
  2485. _out("<<");
  2486. _out(filter, false);
  2487. _outfmt(true, "/Length %d\n>>", p.size());
  2488. _putstream(p);
  2489. _out("endobj");
  2490. }
  2491. // Pages root
  2492. m_offsets[1] = m_buffer.size();
  2493. _out("1 0 obj");
  2494. _out("<<\n/Type /Pages");
  2495. std::string kids = "/Kids [";
  2496. for(int i=0; i<nb; i++) pdf_sprintf_append(kids, "%d 0 R ",(3+2*i));
  2497. _out(kids + "]");
  2498. _outfmt(true, "/Count %d", nb);
  2499. _outfmt(true, "/MediaBox [0 0 %.2f %.2f]", wPt, hPt);
  2500. _out(">>");
  2501. _out("endobj");
  2502. }
  2503. #line 2916 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2504. void FPDF::_putfonts ()
  2505. #line 2917 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2506. {
  2507. #if 0
  2508. int nf = m_n;
  2509. foreach(m_diffs as diff)
  2510. {
  2511. // Encodings
  2512. _newobj();
  2513. _outfmt(true, "<<\n/Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [".diff."]\n>>");
  2514. _outfmt(true, "endobj");
  2515. }
  2516. foreach(m_FontFiles as file=>info)
  2517. {
  2518. // Font file embedding
  2519. _newobj();
  2520. m_FontFiles[file].n = m_n;
  2521. font = file_get_contents(m_fontpath + file,true);
  2522. if(!font) Error("Font file not found: ".file);
  2523. compressed = (substr(file,-2)==".z");
  2524. if(!compressed && isset(info.length2))
  2525. font = substr(font,6,info.length1).substr(font,6+info.length1+6,info.length2);
  2526. _outfmt(true, "<<\n/Length %d", strlen(font));
  2527. if(compressed) _outfmt(true, "/Filter /FlateDecode");
  2528. _outfmt(true, "/Length1 %d", info.length1);
  2529. if(isset(info["length2"]))
  2530. _outfmt(true, "/Length2 %d /Length3 0", info.length2);
  2531. _outfmt(true, ">>");
  2532. _putstream(font);
  2533. _outfmt(true, "endobj");
  2534. }
  2535. #endif
  2536. font_map_t::iterator iter = m_fonts.begin();
  2537. font_map_t::iterator iend = m_fonts.end();
  2538. for(; iter != iend; ++iter)
  2539. {
  2540. // Font objects
  2541. st_pdf_font_base &font = *iter->second;
  2542. font.n = m_n+1;
  2543. e_font_type type = font.font.type;
  2544. std::string name = font.name;
  2545. if(type==e_font_type_core)
  2546. {
  2547. // Core font
  2548. _newobj();
  2549. _out("<<\n/Type /Font");
  2550. _out("/BaseFont /" + name);
  2551. _out("/Subtype /Type1");
  2552. if(name!="Symbol" && name!="ZapfDingbats")
  2553. _out("/Encoding /WinAnsiEncoding");
  2554. _out(">>");
  2555. _out("endobj");
  2556. }
  2557. #if 0
  2558. else if(type==e_font_type_type1 || type==e_font_type_ttf)
  2559. {
  2560. // Additional Type1 or TrueType/OpenType font
  2561. _newobj();
  2562. _out("<<\n/Type /Font");
  2563. _out("/BaseFont /" + name);
  2564. _out("/Subtype /" + type);
  2565. _out("/FirstChar 32 /LastChar 255");
  2566. _outfmt(true, "/Widths %d 0 R", (m_n+1));
  2567. _outfmt(true, "/FontDescriptor %d 0 R", (m_n+2));
  2568. if(isset(font["diffn"]))
  2569. _outfmt(true, "/Encoding %d 0 R", nf+font.diffn);
  2570. else
  2571. _out("/Encoding /WinAnsiEncoding");
  2572. _out(">>");
  2573. _out("endobj");
  2574. // Widths
  2575. _newobj();
  2576. cw = font.cw;
  2577. std::string s = "[";
  2578. s.reserve(1024);
  2579. for(i=32; i<=255; i++)
  2580. pdf_sprintf_append(s, "%d ", cw[chr(i)]);
  2581. _out(s + "]");
  2582. _out("endobj");
  2583. // Descriptor
  2584. _newobj();
  2585. s = "<<\n/Type /FontDescriptor /FontName /" + name;
  2586. foreach(font["desc"] as k=>v)
  2587. s += " /".k." ".v;
  2588. if(!empty(font["file"]))
  2589. s += " /FontFile".(type=="Type1" ? "" : "2")." ".m_FontFiles[font["file"]]["n"]." 0 R";
  2590. _outfmt(true, s.">>");
  2591. _outfmt(true, "endobj");
  2592. }
  2593. else
  2594. {
  2595. // Allow for additional types
  2596. mtd = "_put".strtolower(type);
  2597. if(!method_exists(this,mtd))
  2598. Error("Unsupported font type: ".type);
  2599. mtd(font);
  2600. }
  2601. #endif
  2602. }
  2603. }
  2604. #line 3016 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2605. void FPDF::_putimages ()
  2606. #line 3017 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2607. {
  2608. for(image_map_t::iterator iter = m_images.begin(); iter != m_images.end(); ++iter)
  2609. {
  2610. st_image &image = iter->second;
  2611. _putimage(image);
  2612. image.data.clear();
  2613. image.smask.clear();
  2614. }
  2615. }
  2616. #line 3027 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2617. void FPDF::_putimage (st_image & info)
  2618. #line 3028 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2619. {
  2620. _newobj();
  2621. info.n = m_n;
  2622. _out("<<\n/Type /XObject");
  2623. _out("/Subtype /Image");
  2624. _outfmt(true, "/Width %d", (int)info.w);
  2625. _outfmt(true, "/Height %d", (int)info.h);
  2626. if(info.cs=="Indexed")
  2627. _outfmt(true, "/ColorSpace [/Indexed /DeviceRGB %d %d 0 R]", (info.pal.size())/3-1, (m_n+1));
  2628. else
  2629. {
  2630. _out("/ColorSpace /" + info.cs);
  2631. if(info.cs=="DeviceCMYK")
  2632. _out("/Decode [1 0 1 0 1 0 1 0]");
  2633. }
  2634. _outfmt(true, "/BitsPerComponent %d", info.bpc);
  2635. if(!info.f.empty())
  2636. _out("/Filter /" + info.f);
  2637. if(!info.dp.empty())
  2638. _out("/DecodeParms\n<<\n" + info.dp + "\n>>");
  2639. if(!info.trns.empty())
  2640. {
  2641. std::string trns = "/Mask [";
  2642. for(int i=0, size = info.trns.size(); i<size; i++)
  2643. {
  2644. pdf_sprintf_append(trns, "%d", info.trns[i]);
  2645. trns += " ";
  2646. pdf_sprintf_append(trns, "%d", info.trns[i]);
  2647. trns += " ";
  2648. }
  2649. _out(trns + "]");
  2650. }
  2651. if(!info.smask.empty())
  2652. _outfmt(true, "/SMask %d 0 R", (m_n+1));
  2653. _outfmt(true, "/Length %d\n>>", info.data.size());
  2654. _putstream(info.data);
  2655. _out("endobj");
  2656. // Soft mask
  2657. if(!info.smask.empty())
  2658. {
  2659. std::string dp;
  2660. pdf_sprintf(dp, "/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns %d", (int)info.w);
  2661. st_image smask = info;
  2662. smask.cs = "DeviceGray";
  2663. smask.bpc = 8;
  2664. smask.dp = dp;
  2665. smask.data = info.smask;
  2666. _putimage(smask);
  2667. }
  2668. // Palette
  2669. if(info.cs=="Indexed")
  2670. {
  2671. std::string filter = (m_compress) ? "/Filter /FlateDecode " : "";
  2672. std::string zbuf, &pal =
  2673. #ifdef PDF_USING_ZLIB
  2674. (m_compress) ? gzcompress(zbuf, info.pal) :
  2675. #endif
  2676. info.pal;
  2677. _newobj();
  2678. _outfmt(true, "<<\n%s/Length %d\n>>", filter.c_str(), pal.size());
  2679. _putstream(pal);
  2680. _out("endobj");
  2681. }
  2682. }
  2683. #line 3093 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2684. void FPDF::_putxobjectdict ()
  2685. #line 3094 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2686. {
  2687. for(image_map_t::iterator iter = m_images.begin(); iter != m_images.end(); ++iter)
  2688. _outfmt(true, "/I%d %d 0 R", iter->second.i, iter->second.n);
  2689. }
  2690. #line 3099 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2691. void FPDF::_putextgstates ()
  2692. #line 3100 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2693. {
  2694. for (size_t i = 1, size = m_extgstates.size(); i <= size; ++i)
  2695. {
  2696. _newobj();
  2697. st_alpha_t &gs = m_extgstates[i-1];
  2698. gs.n = m_n;
  2699. _out("<<\n/Type /ExtGState");
  2700. _outfmt(true, "/ca %0.3f", gs.alpha);
  2701. _outfmt(true, "/CA %0.3f", gs.alpha);
  2702. _outfmt(true, "/BM /%s", gs.bm.c_str());
  2703. _out(">>\nendobj");
  2704. }
  2705. }
  2706. #line 3114 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2707. void FPDF::_putjavascript ()
  2708. #line 3115 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2709. {
  2710. _newobj();
  2711. m_n_js=m_n;
  2712. _outfmt(true, "<<\n/Names [(EmbeddedJS) %d 0 R]\n>>\nendobj", m_n+1);
  2713. _newobj();
  2714. _out("<<\n/S /JavaScript\n/JS (", false);
  2715. _out(_escape(m_javascript), false);
  2716. _out(")\n>>\nendobj");
  2717. }
  2718. #line 3125 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2719. void FPDF::_putresourcedict ()
  2720. #line 3126 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2721. {
  2722. _out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]");
  2723. _out("/Font\n<<");
  2724. for(font_map_t::iterator iter = m_fonts.begin(); iter != m_fonts.end(); ++iter)
  2725. _outfmt(true, "/F%d %d 0 R", iter->second->i, iter->second->n);
  2726. _outfmt(true, ">>");
  2727. _outfmt(true, "/XObject\n<<");
  2728. _putxobjectdict();
  2729. _outfmt(true, ">>");
  2730. if(m_extgstates.size())
  2731. {
  2732. _out("/ExtGState\n<<");
  2733. for(size_t i = 1, size = m_extgstates.size(); i <= size; ++i)
  2734. {
  2735. _outfmt(true, "/GS%d %d 0 R", i, m_extgstates[i-1].n);
  2736. }
  2737. _out(">>");
  2738. }
  2739. }
  2740. #line 3146 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2741. void FPDF::_putresources ()
  2742. #line 3147 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2743. {
  2744. _putextgstates();
  2745. _putfonts();
  2746. _putimages();
  2747. // Resource dictionary
  2748. m_offsets[2] = m_buffer.size();
  2749. _outfmt(true, "2 0 obj");
  2750. _outfmt(true, "<<");
  2751. _putresourcedict();
  2752. _out(">>\nendobj");
  2753. if (!m_javascript.empty())
  2754. {
  2755. _putjavascript();
  2756. }
  2757. }
  2758. #line 3163 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2759. void FPDF::_putinfo ()
  2760. #line 3164 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2761. {
  2762. std::string str = _escape(FPDF_VERSION);
  2763. _outfmt(true, "/Producer (CppPDF %s)", str.c_str());
  2764. if(!m_title.empty())
  2765. {
  2766. str = _escape(m_title);
  2767. _out("/Title (" + str + ")");
  2768. }
  2769. if(!m_subject.empty())
  2770. {
  2771. str = _escape(m_subject);
  2772. _out("/Subject (" + str + ")");
  2773. }
  2774. if(!m_author.empty())
  2775. {
  2776. str = _escape(m_author);
  2777. _out("/Author (" + str + ")");
  2778. }
  2779. if(!m_keywords.empty())
  2780. {
  2781. str = _escape(m_keywords);
  2782. _out("/Keywords (" + str + ")");
  2783. }
  2784. if(!m_creator.empty())
  2785. {
  2786. str = _escape(m_creator);
  2787. _out("/Creator (" + str + ")");
  2788. }
  2789. time_t rawtime;
  2790. struct tm * timeinfo;
  2791. time ( &rawtime );
  2792. timeinfo = localtime ( &rawtime );
  2793. strftime (m_scratch_buf,sizeof(m_scratch_buf),"/CreationDate (D:%Y%m%d%H%M%S)", timeinfo);
  2794. _out(m_scratch_buf);
  2795. }
  2796. #line 3200 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2797. void FPDF::_putcatalog ()
  2798. #line 3201 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2799. {
  2800. _outfmt(true, "/Type /Catalog");
  2801. _outfmt(true, "/Pages 1 0 R");
  2802. if(m_CustomZoom)
  2803. _outfmt(true, "/OpenAction [3 0 R /XYZ null null %.2f]", m_CustomZoom/100.0);
  2804. else if(m_ZoomMode==e_zoom_fullpage)
  2805. _outfmt(true, "/OpenAction [3 0 R /Fit]");
  2806. else if(m_ZoomMode==e_zoom_fullwidth)
  2807. _outfmt(true, "/OpenAction [3 0 R /FitH null]");
  2808. else if(m_ZoomMode==e_zoom_real)
  2809. _outfmt(true, "/OpenAction [3 0 R /XYZ null null 1]");
  2810. if(m_LayoutMode==e_layout_single)
  2811. _outfmt(true, "/PageLayout /SinglePage");
  2812. else if(m_LayoutMode==e_layout_continuous)
  2813. _outfmt(true, "/PageLayout /OneColumn");
  2814. else if(m_LayoutMode==e_layout_two)
  2815. _outfmt(true, "/PageLayout /TwoColumnLeft");
  2816. if (!m_javascript.empty())
  2817. {
  2818. _outfmt(true, "/Names\n<<\n/JavaScript %d 0 R\n>>", m_n_js);
  2819. }
  2820. }
  2821. #line 3224 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2822. void FPDF::_putheader ()
  2823. #line 3225 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2824. {
  2825. _out("%PDF-" + m_PDFVersion);
  2826. }
  2827. #line 3229 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2828. void FPDF::_puttrailer ()
  2829. #line 3230 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2830. {
  2831. _outfmt(true, "/Size %d", (m_n+1));
  2832. _outfmt(true, "/Root %d 0 R", m_n);
  2833. _outfmt(true, "/Info %d 0 R", (m_n-1));
  2834. }
  2835. #line 3236 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2836. void FPDF::_enddoc ()
  2837. #line 3237 "/home/mingo/dev/dadbiz++/ourbiz-uk/parts/fpdf.zz"
  2838. {
  2839. if(m_extgstates.size() && (m_PDFVersion < "1.4")) m_PDFVersion = "1.4";
  2840. _putheader();
  2841. _putpages();
  2842. _putresources();
  2843. // Info
  2844. _newobj();
  2845. _out("<<");
  2846. _putinfo();
  2847. _out(">>\nendobj");
  2848. // Catalog
  2849. _newobj();
  2850. _out("<<");
  2851. _putcatalog();
  2852. _out(">>\nendobj");
  2853. //save begining of xref
  2854. int saved_startxref = m_buffer.size();
  2855. // Cross-ref
  2856. _out("xref");
  2857. _outfmt(true, "0 %d", (m_n+1));
  2858. _out("0000000000 65535 f ");
  2859. for(int i=1; i<=m_n; i++)
  2860. {
  2861. _outfmt(true, "%010d 00000 n ",m_offsets[i]);
  2862. }
  2863. // Trailer
  2864. _out("trailer\n<<");
  2865. _puttrailer();
  2866. _out(">>\nstartxref");
  2867. _outfmt(true, "%d", saved_startxref);
  2868. _out("%%EOF", false);
  2869. m_state = 3;
  2870. }
  2871. #undef LZZ_INLINE