PDFExport.cs 120 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101
  1. using System.Collections.Generic;
  2. using System.Drawing;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Text;
  7. using FastReport.Export.TTF;
  8. using FastReport.Table;
  9. using FastReport.Utils;
  10. using System;
  11. using System.Windows.Forms;
  12. using System.Drawing.Drawing2D;
  13. namespace FastReport.Export.Pdf
  14. {
  15. /// <summary>
  16. /// PDF export (Adobe Acrobat)
  17. /// </summary>
  18. public partial class PDFExport : ExportBase
  19. {
  20. #region Private Constants
  21. const float PDF_DIVIDER = 0.75f;
  22. const float PDF_PAGE_DIVIDER = 2.8346400000000003f; // mm to point
  23. const int PDF_PRINTOPT = 3;
  24. #endregion
  25. /// <summary>
  26. /// Embedded File
  27. /// </summary>
  28. public class EmbeddedFile
  29. {
  30. private string name;
  31. private string description;
  32. private DateTime modDate;
  33. private EmbeddedRelation relation;
  34. private string mime;
  35. private Stream fileStream;
  36. private long xref;
  37. private ZUGFeRD_ConformanceLevel zUGFeRD_ConformanceLevel;
  38. /// <summary>
  39. /// Name of embedded file.
  40. /// </summary>
  41. public string Name
  42. {
  43. get { return name; }
  44. set { name = value; }
  45. }
  46. /// <summary>
  47. /// Description of embedded file.
  48. /// </summary>
  49. public string Description
  50. {
  51. get { return description; }
  52. set { description = value; }
  53. }
  54. /// <summary>
  55. /// Modify Date of embedded file.
  56. /// </summary>
  57. public DateTime ModDate
  58. {
  59. get { return modDate; }
  60. set { modDate = value; }
  61. }
  62. /// <summary>
  63. /// Relationship between the embedded document and the PDF part.
  64. /// </summary>
  65. public EmbeddedRelation Relation
  66. {
  67. get { return relation; }
  68. set { relation = value; }
  69. }
  70. /// <summary>
  71. /// Valid MIME type.
  72. /// </summary>
  73. public string MIME
  74. {
  75. get { return mime; }
  76. set { mime = value; }
  77. }
  78. /// <summary>
  79. /// Stream of embedded file.
  80. /// </summary>
  81. public Stream FileStream
  82. {
  83. get { return fileStream; }
  84. set { fileStream = value; }
  85. }
  86. /// <summary>
  87. /// File reference.
  88. /// </summary>
  89. public long Xref
  90. {
  91. get { return xref; }
  92. set { xref = value; }
  93. }
  94. /// <summary>
  95. /// ZUGFeRD Conformance Level.
  96. /// </summary>
  97. public ZUGFeRD_ConformanceLevel ZUGFeRDConformanceLevel
  98. {
  99. get { return zUGFeRD_ConformanceLevel; }
  100. set { zUGFeRD_ConformanceLevel = value; }
  101. }
  102. /// Initializes a new instance of the <see cref="EmbeddedFile"/> class.
  103. public EmbeddedFile()
  104. {
  105. modDate = SystemFake.DateTime.Now;
  106. relation = EmbeddedRelation.Alternative;
  107. zUGFeRD_ConformanceLevel = ZUGFeRD_ConformanceLevel.BASIC;
  108. mime = "text/xml";
  109. fileStream = null;
  110. }
  111. }
  112. #region Public Enums
  113. /// <summary>
  114. /// Default preview size.
  115. /// </summary>
  116. public enum MagnificationFactor
  117. {
  118. /// <summary>
  119. /// Actual size
  120. /// </summary>
  121. ActualSize = 0,
  122. /// <summary>
  123. /// Fit Page
  124. /// </summary>
  125. FitPage = 1,
  126. /// <summary>
  127. /// Fit Width
  128. /// </summary>
  129. FitWidth = 2,
  130. /// <summary>
  131. /// Default
  132. /// </summary>
  133. Default = 3,
  134. /// <summary>
  135. /// 10%
  136. /// </summary>
  137. Percent_10 = 4,
  138. /// <summary>
  139. /// 25%
  140. /// </summary>
  141. Percent_25 = 5,
  142. /// <summary>
  143. /// 50%
  144. /// </summary>
  145. Percent_50 = 6,
  146. /// <summary>
  147. /// 75%
  148. /// </summary>
  149. Percent_75 = 7,
  150. /// <summary>
  151. /// 100%
  152. /// </summary>
  153. Percent_100 = 8,
  154. /// <summary>
  155. /// 125%
  156. /// </summary>
  157. Percent_125 = 9,
  158. /// <summary>
  159. /// 150%
  160. /// </summary>
  161. Percent_150 = 10,
  162. /// <summary>
  163. /// 200%
  164. /// </summary>
  165. Percent_200 = 11,
  166. /// <summary>
  167. /// 400%
  168. /// </summary>
  169. Percent_400 = 12,
  170. /// <summary>
  171. /// 800%
  172. /// </summary>
  173. Percent_800 = 13,
  174. }
  175. /// <summary>
  176. /// Standard of PDF format.
  177. /// </summary>
  178. public enum PdfStandard
  179. {
  180. /// <summary>
  181. /// PDF 1.5
  182. /// </summary>
  183. None = 0,
  184. /// <summary>
  185. /// PDF/A-1a
  186. /// </summary>
  187. PdfA_1a = 1,
  188. /// <summary>
  189. /// PDF/A-2a
  190. /// </summary>
  191. PdfA_2a = 2,
  192. /// <summary>
  193. /// PDF/A-2b
  194. /// </summary>
  195. PdfA_2b = 3,
  196. /// <summary>
  197. /// PDF/A-2u
  198. /// </summary>
  199. PdfA_2u = 4,
  200. /// <summary>
  201. /// PDF/A-3a
  202. /// </summary>
  203. PdfA_3a = 5,
  204. /// <summary>
  205. /// PDF/A-3b
  206. /// </summary>
  207. PdfA_3b = 6,
  208. /// <summary>
  209. /// Pdf/X-3
  210. /// </summary>
  211. PdfX_3 = 7,
  212. /// <summary>
  213. /// Pdf/X-4
  214. /// </summary>
  215. PdfX_4 = 8
  216. }
  217. /// <summary>
  218. /// Color Space.
  219. /// </summary>
  220. public enum PdfColorSpace
  221. {
  222. /// <summary>
  223. /// RGB color space
  224. /// </summary>
  225. RGB = 0,
  226. /// <summary>
  227. /// CMYK color space
  228. /// </summary>
  229. CMYK = 1,
  230. }
  231. /// <summary>
  232. /// Types of pdf export.
  233. /// </summary>
  234. public enum ExportType
  235. {
  236. /// <summary>
  237. /// Simple export
  238. /// </summary>
  239. Export,
  240. /// <summary>
  241. /// Web print mode
  242. /// </summary>
  243. WebPrint
  244. }
  245. /// <summary>
  246. /// Relationship between the embedded document and the PDF part.
  247. /// </summary>
  248. public enum EmbeddedRelation
  249. {
  250. /// <summary>
  251. /// The embedded file contains data which is used for the visual representation.
  252. /// </summary>
  253. Data,
  254. /// <summary>
  255. /// The embedded file contains the source data for the visual representation derived therefrom in the PDF part.
  256. /// </summary>
  257. Source,
  258. /// <summary>
  259. /// This data relationship should be used if the embedded data are an alternative representation of the PDF contents.
  260. /// </summary>
  261. Alternative,
  262. /// <summary>
  263. /// This data relationship is used if the embedded file serves neither as the source nor as the alternative representation, but the file contains additional information.
  264. /// </summary>
  265. Supplement,
  266. /// <summary>
  267. /// If none of the data relationships above apply or there is an unknown data relationship, this data relationship is used.
  268. /// </summary>
  269. Unspecified
  270. }
  271. /// <summary>
  272. /// ZUGFeRD Conformance Level.
  273. /// </summary>
  274. public enum ZUGFeRD_ConformanceLevel
  275. {
  276. /// <summary>
  277. /// Basic level.
  278. /// </summary>
  279. BASIC,
  280. /// <summary>
  281. /// Comfort level.
  282. /// </summary>
  283. COMFORT,
  284. /// <summary>
  285. /// Extended level.
  286. /// </summary>
  287. EXTENDED
  288. }
  289. #endregion
  290. #region Private Fields
  291. // Options
  292. private PdfStandard pdfCompliance = PdfStandard.None;
  293. private bool embeddingFonts = true;
  294. private bool background = true;
  295. private bool textInCurves = false;
  296. private PdfColorSpace colorSpace = PdfColorSpace.RGB;
  297. private bool imagesOriginalResolution = false;
  298. private bool printOptimized = true;
  299. private bool jpegCompression = false;
  300. private int jpegQuality = 95;
  301. private bool interactiveForms = false;
  302. private string interactiveFormsFontSetPattern = string.Empty;
  303. // end
  304. // Document Information
  305. private string title = "";
  306. private string author = "";
  307. private string subject = "";
  308. private string keywords = "";
  309. private string creator = "FastReport";
  310. private string producer = "FastReport.NET";
  311. // end
  312. // Security
  313. private string ownerPassword = "";
  314. private string userPassword = "";
  315. private bool allowPrint = true;
  316. private bool allowModify = true;
  317. private bool allowCopy = true;
  318. private bool allowAnnotate = true;
  319. // end
  320. // Viewer
  321. private bool showPrintDialog = false;
  322. private bool hideToolbar = false;
  323. private bool hideMenubar = false;
  324. private bool hideWindowUI = false;
  325. private bool fitWindow = false;
  326. private bool centerWindow = true;
  327. private bool printScaling = false;
  328. private bool outline = true;
  329. private MagnificationFactor defaultZoom = MagnificationFactor.ActualSize;
  330. // end
  331. // Other options
  332. private bool displayDocTitle = true;
  333. private bool encrypted = false;
  334. private bool compressed = true;
  335. private bool transparentImages = true;
  336. private int richTextQuality = 95;
  337. private int defaultPage = 1;
  338. private float dpiFX = 96f / DrawUtils.ScreenDpi;
  339. private byte[] colorProfile = null;
  340. private List<EmbeddedFile> embeddedFiles;
  341. private bool useFileStream;
  342. // end
  343. // Internal fields
  344. private string fileID;
  345. private long rootNumber;
  346. private long pagesNumber;
  347. private long outlineNumber;
  348. private long infoNumber;
  349. private long startXRef;
  350. private long actionDict;
  351. private long printDict;
  352. private List<long> xRef;
  353. private List<long> pagesRef;
  354. private List<string> trasparentStroke;
  355. private List<string> trasparentFill;
  356. private List<float> pagesHeights;
  357. private List<float> pagesTopMargins;
  358. private float marginLeft;
  359. private float marginWoBottom;
  360. private Stream pdf;
  361. private float paperWidth;
  362. private float paperHeight;
  363. private long metaFileId;
  364. private long structId;
  365. private long colorProfileId;
  366. private long attachmentsNamesId;
  367. private long attachmentsListId;
  368. private IGraphics graphics;
  369. private StringBuilder contentBuilder;
  370. private long contentsPos;
  371. private ExportType exportMode;
  372. private string zUGFeRDDescription;
  373. private List<long> acroFormsRefs;
  374. //private List<long> FAcroFormsAnnotsRefs;
  375. private List<int> acroFormsFonts;
  376. private string tempFileName;
  377. // end
  378. // for signature purposes
  379. private bool isDigitalSignEnable;
  380. private bool isDigitalSignatureInvisible;
  381. private DateTime digitalSignCreationDate;
  382. private SignatureDictIndicies signatureDictIndicies;
  383. private long[] digitalSignByteRange;
  384. private System.Security.Cryptography.X509Certificates.X509Certificate2 digitalSignCertificate;
  385. private string digitalSignLocation;
  386. private string digitalSignReason;
  387. private string digitalSignContactInfo;
  388. private bool haveToSaveDigitalSignCertificate;
  389. private string digitalSignCertificatePath;
  390. private string digitalSignCertificatePassword;
  391. //end
  392. #endregion
  393. #region Public Properties
  394. #region Options
  395. /// <summary>
  396. /// Gets or sets PDF Compliance standard.
  397. /// After set, do not change other settings, it may lead to fail compliance test.
  398. /// </summary>
  399. public PdfStandard PdfCompliance
  400. {
  401. get
  402. {
  403. return pdfCompliance;
  404. }
  405. set
  406. {
  407. pdfCompliance = value;
  408. switch (pdfCompliance)
  409. {
  410. case PdfStandard.None:
  411. break;
  412. case PdfStandard.PdfA_1a:
  413. case PdfStandard.PdfA_2a:
  414. case PdfStandard.PdfA_2b:
  415. case PdfStandard.PdfA_2u:
  416. case PdfStandard.PdfA_3a:
  417. case PdfStandard.PdfA_3b:
  418. EmbeddingFonts = true;
  419. TextInCurves = false;
  420. OwnerPassword = "";
  421. UserPassword = "";
  422. encrypted = false;
  423. break;
  424. case PdfStandard.PdfX_3:
  425. case PdfStandard.PdfX_4:
  426. OwnerPassword = "";
  427. UserPassword = "";
  428. encrypted = false;
  429. break;
  430. }
  431. }
  432. }
  433. /// <summary>
  434. /// Enable or disable of embedding the TrueType fonts.
  435. /// </summary>
  436. public bool EmbeddingFonts
  437. {
  438. get { return embeddingFonts; }
  439. set
  440. {
  441. embeddingFonts = value;
  442. if (embeddingFonts)
  443. textInCurves = false;
  444. }
  445. }
  446. /// <summary>
  447. /// Enable or disable of exporting the background.
  448. /// </summary>
  449. public bool Background
  450. {
  451. get { return background; }
  452. set { background = value; }
  453. }
  454. /// <summary>
  455. /// Enable or disable export text in curves
  456. /// </summary>
  457. public bool TextInCurves
  458. {
  459. get { return textInCurves; }
  460. set
  461. {
  462. textInCurves = value;
  463. if (textInCurves)
  464. embeddingFonts = false;
  465. }
  466. }
  467. /// <summary>
  468. /// Gets or sets PDF color space
  469. /// </summary>
  470. public PdfColorSpace ColorSpace
  471. {
  472. get { return colorSpace; }
  473. set { colorSpace = value; }
  474. }
  475. /// <summary>
  476. /// Enables or disables saving images in their original resolution
  477. /// </summary>
  478. public bool ImagesOriginalResolution
  479. {
  480. get { return imagesOriginalResolution; }
  481. set { imagesOriginalResolution = value; }
  482. }
  483. /// <summary>
  484. /// Enables or disables optimization of images for printing
  485. /// </summary>
  486. public bool PrintOptimized
  487. {
  488. get { return printOptimized; }
  489. set { printOptimized = value; }
  490. }
  491. /// <summary>
  492. /// Enable or disable image jpeg compression
  493. /// </summary>
  494. public bool JpegCompression
  495. {
  496. get { return jpegCompression; }
  497. set { jpegCompression = value; }
  498. }
  499. /// <summary>
  500. /// Sets the quality of images in the PDF
  501. /// </summary>
  502. public int JpegQuality
  503. {
  504. get { return jpegQuality; }
  505. set
  506. {
  507. jpegQuality = value;
  508. RichTextQuality = value;
  509. }
  510. }
  511. #endregion
  512. #region Document Information
  513. /// <summary>
  514. /// Title of the document.
  515. /// </summary>
  516. public string Title
  517. {
  518. get { return title; }
  519. set { title = value; }
  520. }
  521. /// <summary>
  522. /// Author of the document.
  523. /// </summary>
  524. public string Author
  525. {
  526. get { return author; }
  527. set { author = value; }
  528. }
  529. /// <summary>
  530. /// Subject of the document.
  531. /// </summary>
  532. public string Subject
  533. {
  534. get { return subject; }
  535. set { subject = value; }
  536. }
  537. /// <summary>
  538. /// Keywords of the document.
  539. /// </summary>
  540. public string Keywords
  541. {
  542. get { return keywords; }
  543. set { keywords = value; }
  544. }
  545. /// <summary>
  546. /// Creator of the document.
  547. /// </summary>
  548. public string Creator
  549. {
  550. get { return creator; }
  551. set { creator = value; }
  552. }
  553. /// <summary>
  554. /// Producer of the document.
  555. /// </summary>
  556. public string Producer
  557. {
  558. get { return producer; }
  559. set { producer = value; }
  560. }
  561. #endregion
  562. #region Security
  563. /// <summary>
  564. /// Sets the owner password.
  565. /// </summary>
  566. public string OwnerPassword
  567. {
  568. get { return ownerPassword; }
  569. set { ownerPassword = value; }
  570. }
  571. /// <summary>
  572. /// Sets the user password.
  573. /// </summary>
  574. public string UserPassword
  575. {
  576. get { return userPassword; }
  577. set { userPassword = value; }
  578. }
  579. /// <summary>
  580. /// Enable or disable printing in protected document.
  581. /// </summary>
  582. public bool AllowPrint
  583. {
  584. get { return allowPrint; }
  585. set { allowPrint = value; }
  586. }
  587. /// <summary>
  588. /// Enable or disable modifying in protected document.
  589. /// </summary>
  590. public bool AllowModify
  591. {
  592. get { return allowModify; }
  593. set { allowModify = value; }
  594. }
  595. /// <summary>
  596. /// Enable or disable copying in protected document.
  597. /// </summary>
  598. public bool AllowCopy
  599. {
  600. get { return allowCopy; }
  601. set { allowCopy = value; }
  602. }
  603. /// <summary>
  604. /// Enable or disable annotating in protected document.
  605. /// </summary>
  606. public bool AllowAnnotate
  607. {
  608. get { return allowAnnotate; }
  609. set { allowAnnotate = value; }
  610. }
  611. #endregion
  612. #region Viewer
  613. /// <summary>
  614. /// Enable or disable the print dialog window after opening
  615. /// </summary>
  616. public bool ShowPrintDialog
  617. {
  618. get { return showPrintDialog; }
  619. set { showPrintDialog = value; }
  620. }
  621. /// <summary>
  622. /// Enable or disable hide the toolbar.
  623. /// </summary>
  624. public bool HideToolbar
  625. {
  626. get { return hideToolbar; }
  627. set { hideToolbar = value; }
  628. }
  629. /// <summary>
  630. /// Enable or disable hide the menu's bar.
  631. /// </summary>
  632. public bool HideMenubar
  633. {
  634. get { return hideMenubar; }
  635. set { hideMenubar = value; }
  636. }
  637. /// <summary>
  638. /// Enable or disable hide the Windows UI.
  639. /// </summary>
  640. public bool HideWindowUI
  641. {
  642. get { return hideWindowUI; }
  643. set { hideWindowUI = value; }
  644. }
  645. /// <summary>
  646. /// Enable or disable of fitting the window
  647. /// </summary>
  648. public bool FitWindow
  649. {
  650. get { return fitWindow; }
  651. set { fitWindow = value; }
  652. }
  653. /// <summary>
  654. /// Enable or disable of centering the window.
  655. /// </summary>
  656. public bool CenterWindow
  657. {
  658. get { return centerWindow; }
  659. set { centerWindow = value; }
  660. }
  661. /// <summary>
  662. /// Enable or disable of scaling the page for shrink to printable area.
  663. /// </summary>
  664. public bool PrintScaling
  665. {
  666. get { return printScaling; }
  667. set { printScaling = value; }
  668. }
  669. /// <summary>
  670. /// Enable or disable of document's Outline.
  671. /// </summary>
  672. public bool Outline
  673. {
  674. get { return outline; }
  675. set { outline = value; }
  676. }
  677. /// <summary>
  678. /// Set default zoom on open document
  679. /// </summary>
  680. public MagnificationFactor DefaultZoom
  681. {
  682. get { return defaultZoom; }
  683. set { defaultZoom = value; }
  684. }
  685. #endregion
  686. #region Other
  687. /// <summary>
  688. /// Sets the quality of RichText objects in the PDF
  689. /// </summary>
  690. public int RichTextQuality
  691. {
  692. get { return richTextQuality; }
  693. set { richTextQuality = value; }
  694. }
  695. /// <summary>
  696. /// Enable or disable the compression in PDF document.
  697. /// </summary>
  698. public bool Compressed
  699. {
  700. get { return compressed; }
  701. set { compressed = value; }
  702. }
  703. /// <summary>
  704. /// Enable or disable of images transparency.
  705. /// </summary>
  706. public bool TransparentImages
  707. {
  708. get { return transparentImages; }
  709. set { transparentImages = value; }
  710. }
  711. /// <summary>
  712. /// Enable or disable of displaying document's title.
  713. /// </summary>
  714. public bool DisplayDocTitle
  715. {
  716. get { return displayDocTitle; }
  717. set { displayDocTitle = value; }
  718. }
  719. /// <summary>
  720. /// Set default page on open document
  721. /// </summary>
  722. public int DefaultPage
  723. {
  724. get { return defaultPage; }
  725. set { defaultPage = value; }
  726. }
  727. /// <summary>
  728. /// Color Profile (ICC file).
  729. /// If "null" then default profile will be used
  730. /// </summary>
  731. public byte[] ColorProfile
  732. {
  733. get { return colorProfile; }
  734. set { colorProfile = value; }
  735. }
  736. /// <summary>
  737. /// Gets or sets pdf export mode
  738. /// </summary>
  739. public ExportType ExportMode
  740. {
  741. get { return exportMode; }
  742. set { exportMode = value; }
  743. }
  744. /// <summary>
  745. /// Gets pdf AcroForms compatibility, if set then EmbeddingFonts = false and PdfCompliance = PdfStandard.None
  746. /// </summary>
  747. public bool InteractiveForms
  748. {
  749. get
  750. {
  751. return interactiveForms && PdfCompliance == PdfStandard.None;
  752. }
  753. set
  754. {
  755. if (value)
  756. PdfCompliance = PdfStandard.None;
  757. interactiveForms = value;
  758. }
  759. }
  760. /// <summary>
  761. /// Set pattern for selection of embedding glyphs for Interactive Forms
  762. /// </summary>
  763. public string InteractiveFormsFontSetPattern
  764. {
  765. get
  766. {
  767. return interactiveFormsFontSetPattern;
  768. }
  769. set
  770. {
  771. interactiveFormsFontSetPattern = value;
  772. }
  773. }
  774. /// <summary>
  775. /// Enable or disable using FileStream instead of MemoryStream when exporting.
  776. /// Its useful when exporting huge reports on machines with small amount of RAM.
  777. /// </summary>
  778. public bool UseFileStream
  779. {
  780. get { return useFileStream; }
  781. set { useFileStream = value; }
  782. }
  783. #endregion
  784. #region DigitalSign
  785. /// <summary>
  786. /// Enable or disable digital sign for pdf document
  787. /// </summary>
  788. /// <remarks>
  789. /// Be sure to specify a valid certificate for signing using the DigitalSignCertificate property.
  790. /// Or using the DigitalSignCertificatePath and DigitalSignCertificatePassword properties.
  791. /// </remarks>
  792. public bool IsDigitalSignEnable
  793. {
  794. get { return isDigitalSignEnable; }
  795. set { isDigitalSignEnable = value; }
  796. }
  797. /// <summary>
  798. /// Should save and serialize password for digital sign certificate.
  799. /// Do not save password unless absolutely necessary!!!
  800. /// </summary>
  801. public bool SaveDigitalSignCertificatePassword
  802. {
  803. get { return haveToSaveDigitalSignCertificate; }
  804. set { haveToSaveDigitalSignCertificate = value; }
  805. }
  806. /// <summary>
  807. /// Manualy sets digital sign certificate for exported documents.
  808. /// </summary>
  809. /// <remarks>
  810. /// This property is in priority, i.e. if a certificate is specified,
  811. /// the DigitalSignCertificatePath and DigitalSignCertificatePassword properties will not be used.
  812. /// </remarks>
  813. public System.Security.Cryptography.X509Certificates.X509Certificate2 DigitalSignCertificate
  814. {
  815. set { digitalSignCertificate = value; }
  816. }
  817. /// <summary>
  818. /// The path for load digital sign certificate.
  819. /// </summary>
  820. public string DigitalSignCertificatePath
  821. {
  822. get { return digitalSignCertificatePath; }
  823. set { digitalSignCertificatePath = value; }
  824. }
  825. /// <summary>
  826. /// Sets digital sign certificate password.
  827. /// </summary>
  828. public string DigitalSignCertificatePassword
  829. {
  830. get { return Crypter.DecryptString(digitalSignCertificatePassword); }
  831. set
  832. {
  833. if (Crypter.IsStringEncrypted(value))
  834. digitalSignCertificatePassword = value;
  835. else
  836. digitalSignCertificatePassword = Crypter.EncryptString(value);
  837. }
  838. }
  839. /// <summary>
  840. /// Gets or sets the cpu host name or physical location of the signing
  841. /// </summary>
  842. public string DigitalSignLocation
  843. {
  844. get { return digitalSignLocation; }
  845. set { digitalSignLocation = value; }
  846. }
  847. /// <summary>
  848. /// The reason for the signing, such as (I agree ...)
  849. /// </summary>
  850. public string DigitalSignReason
  851. {
  852. get { return digitalSignReason; }
  853. set { digitalSignReason = value; }
  854. }
  855. /// <summary>
  856. /// The information to enable the recipient to contact the signer to verify the signature
  857. /// </summary>
  858. public string DigitalSignContactInfo
  859. {
  860. get { return digitalSignContactInfo; }
  861. set { digitalSignContactInfo = value; }
  862. }
  863. #endregion
  864. #endregion
  865. #region Private Methods
  866. private string getPdfVersion()
  867. {
  868. switch (PdfCompliance)
  869. {
  870. case PdfStandard.PdfA_2a:
  871. case PdfStandard.PdfA_2b:
  872. case PdfStandard.PdfA_2u:
  873. case PdfStandard.PdfA_3a:
  874. case PdfStandard.PdfA_3b:
  875. return "1.7";
  876. case PdfStandard.PdfA_1a:
  877. case PdfStandard.PdfX_3: // PDF/X-3:2003
  878. return "1.4";
  879. case PdfStandard.PdfX_4:
  880. return "1.6";
  881. case PdfStandard.None:
  882. default:
  883. return "1.5";
  884. }
  885. }
  886. private bool isPdfX()
  887. {
  888. switch (PdfCompliance)
  889. {
  890. case PdfStandard.PdfX_3:
  891. case PdfStandard.PdfX_4:
  892. return true;
  893. default:
  894. return false;
  895. }
  896. }
  897. private bool isPdfA()
  898. {
  899. switch (PdfCompliance)
  900. {
  901. case PdfStandard.PdfA_1a:
  902. case PdfStandard.PdfA_2a:
  903. case PdfStandard.PdfA_2b:
  904. case PdfStandard.PdfA_2u:
  905. case PdfStandard.PdfA_3a:
  906. case PdfStandard.PdfA_3b:
  907. return true;
  908. default:
  909. return false;
  910. }
  911. }
  912. private void AddPDFHeader()
  913. {
  914. WriteLn(pdf, "%PDF-" + getPdfVersion());
  915. byte[] signature = { 0x25, 0xE2, 0xE3, 0xCF, 0xD3, 0x0D, 0x0A };
  916. pdf.Write(signature, 0, signature.Length);
  917. // reserve object for pages
  918. UpdateXRef();
  919. }
  920. //private void AddPage(ReportPage page)
  921. //{
  922. // pageFonts = new List<ExportTTFFont>();
  923. // trasparentStroke = new List<string>();
  924. // trasparentFill = new List<string>();
  925. // picResList = new List<long>();
  926. // paperWidth = ExportUtils.GetPageWidth(page) * Units.Millimeters;
  927. // paperHeight = ExportUtils.GetPageHeight(page) * Units.Millimeters;
  928. // marginWoBottom = (ExportUtils.GetPageHeight(page) - page.TopMargin) * PDF_PAGE_DIVIDER;
  929. // marginLeft = page.LeftMargin * PDF_PAGE_DIVIDER;
  930. // pagesHeights.Add(marginWoBottom);
  931. // pagesTopMargins.Add(page.TopMargin * PDF_PAGE_DIVIDER);
  932. // long FContentsPos = 0;
  933. // StringBuilder contentBuilder = new StringBuilder(65535);
  934. // // page fill
  935. // if (background)
  936. // using (TextObject pageFill = new TextObject())
  937. // {
  938. // pageFill.Fill = page.Fill;
  939. // pageFill.Left = -marginLeft / PDF_DIVIDER;
  940. // pageFill.Top = -page.TopMargin * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  941. // pageFill.Width = ExportUtils.GetPageWidth(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  942. // pageFill.Height = ExportUtils.GetPageHeight(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  943. // AddTextObject(pageFill, false, contentBuilder);
  944. // }
  945. // // bitmap watermark on bottom
  946. // if (page.Watermark.Enabled && !page.Watermark.ShowImageOnTop)
  947. // AddBitmapWatermark(page, contentBuilder);
  948. // // text watermark on bottom
  949. // if (page.Watermark.Enabled && !page.Watermark.ShowTextOnTop)
  950. // AddTextWatermark(page, contentBuilder);
  951. // // page borders
  952. // if (page.Border.Lines != BorderLines.None)
  953. // {
  954. // using (TextObject pageBorder = new TextObject())
  955. // {
  956. // pageBorder.Border = page.Border;
  957. // pageBorder.Left = 0;
  958. // pageBorder.Top = 0;
  959. // pageBorder.Width = (ExportUtils.GetPageWidth(page) - page.LeftMargin - page.RightMargin) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  960. // pageBorder.Height = (ExportUtils.GetPageHeight(page) - page.TopMargin - page.BottomMargin) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  961. // AddTextObject(pageBorder, true, contentBuilder);
  962. // }
  963. // }
  964. // foreach (Base c in page.AllObjects)
  965. // {
  966. // ExportObj(c);
  967. // }
  968. // // bitmap watermark on top
  969. // if (page.Watermark.Enabled && page.Watermark.ShowImageOnTop)
  970. // AddBitmapWatermark(page, contentBuilder);
  971. // // text watermark on top
  972. // if (page.Watermark.Enabled && page.Watermark.ShowTextOnTop)
  973. // AddTextWatermark(page, contentBuilder);
  974. // // write page
  975. // FContentsPos = UpdateXRef();
  976. // WriteLn(pdf, ObjNumber(FContentsPos));
  977. // using (MemoryStream tempContentStream = new MemoryStream())
  978. // {
  979. // Write(tempContentStream, contentBuilder.ToString());
  980. // tempContentStream.Position = 0;
  981. // WritePDFStream(pdf, tempContentStream, FContentsPos, compressed, encrypted, true, true);
  982. // }
  983. // if (!textInCurves)
  984. // if (pageFonts.Count > 0)
  985. // for (int i = 0; i < pageFonts.Count; i++)
  986. // if (!pageFonts[i].Saved)
  987. // {
  988. // pageFonts[i].Reference = UpdateXRef();
  989. // pageFonts[i].Saved = true;
  990. // }
  991. // long PageNumber = UpdateXRef();
  992. // pagesRef.Add(PageNumber);
  993. // WriteLn(pdf, ObjNumber(PageNumber));
  994. // StringBuilder sb = new StringBuilder(512);
  995. // sb.AppendLine("<<").AppendLine("/Type /Page");
  996. // sb.Append("/MediaBox [0 0 ").Append(FloatToString(ExportUtils.GetPageWidth(page) * PDF_PAGE_DIVIDER)).Append(" ");
  997. // sb.Append(FloatToString(ExportUtils.GetPageHeight(page) * PDF_PAGE_DIVIDER)).AppendLine(" ]");
  998. // //margins
  999. // if (isPdfX())
  1000. // sb.Append("/TrimBox [")
  1001. // .Append(FloatToString(page.LeftMargin * PDF_PAGE_DIVIDER)).Append(" ")
  1002. // .Append(FloatToString(page.TopMargin * PDF_PAGE_DIVIDER)).Append(" ")
  1003. // .Append(FloatToString(page.RightMargin * PDF_PAGE_DIVIDER)).Append(" ")
  1004. // .Append(FloatToString(page.BottomMargin * PDF_PAGE_DIVIDER)).Append("]");
  1005. // sb.AppendLine("/Parent 1 0 R");
  1006. // if (!isPdfX())
  1007. // {
  1008. // if (ColorSpace == PdfColorSpace.RGB)
  1009. // sb.AppendLine("/Group << /Type /Group /S /Transparency /CS /DeviceRGB >>");
  1010. // else if (ColorSpace == PdfColorSpace.CMYK)
  1011. // sb.AppendLine("/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >>");
  1012. // }
  1013. // sb.AppendLine("/Resources << ");
  1014. // if (pageFonts.Count > 0)
  1015. // {
  1016. // sb.Append("/Font << ");
  1017. // foreach (ExportTTFFont font in pageFonts)
  1018. // sb.Append(font.Name).Append(" ").Append(ObjNumberRef(font.Reference)).Append(" ");
  1019. // sb.AppendLine(" >>");
  1020. // }
  1021. // if (isPdfX())
  1022. // {
  1023. // sb.AppendLine("/ExtGState <<");
  1024. // for (int i = 0; i < trasparentStroke.Count; i++)
  1025. // sb.Append("/GS").Append(i.ToString()).Append("S << /Type /ExtGState /ca ").Append(1).AppendLine(" >>");
  1026. // for (int i = 0; i < trasparentFill.Count; i++)
  1027. // sb.Append("/GS").Append(i.ToString()).Append("F << /Type /ExtGState /CA ").Append(1).AppendLine(" >>");
  1028. // sb.AppendLine(">>");
  1029. // }
  1030. // else
  1031. // {
  1032. // sb.AppendLine("/ExtGState <<");
  1033. // for (int i = 0; i < trasparentStroke.Count; i++)
  1034. // sb.Append("/GS").Append(i.ToString()).Append("S << /Type /ExtGState /ca ").Append(trasparentStroke[i]).AppendLine(" >>");
  1035. // for (int i = 0; i < trasparentFill.Count; i++)
  1036. // sb.Append("/GS").Append(i.ToString()).Append("F << /Type /ExtGState /CA ").Append(trasparentFill[i]).AppendLine(" >>");
  1037. // sb.AppendLine(">>");
  1038. // }
  1039. // if (picResList.Count > 0)
  1040. // {
  1041. // sb.Append("/XObject << ");
  1042. // foreach (long resIndex in picResList)
  1043. // sb.Append("/Im").Append(resIndex.ToString()).Append(" ").Append(ObjNumberRef(resIndex)).Append(" ");
  1044. // sb.AppendLine(" >>");
  1045. // }
  1046. // sb.AppendLine("/ProcSet [/PDF /Text /ImageC ]");
  1047. // sb.AppendLine(">>");
  1048. // sb.Append("/Contents ").AppendLine(ObjNumberRef(FContentsPos));
  1049. // if (pageAnnots.Length > 0)
  1050. // {
  1051. // sb.AppendLine(GetPageAnnots());
  1052. // pageAnnots.Length = 0;
  1053. // }
  1054. // sb.AppendLine(">>");
  1055. // sb.AppendLine("endobj");
  1056. // Write(pdf, sb.ToString());
  1057. //}
  1058. private void AddBitmapWatermark(ReportPage page, StringBuilder sb)
  1059. {
  1060. if (page.Watermark.Image != null)
  1061. {
  1062. using (PictureObject pictureWatermark = new PictureObject())
  1063. {
  1064. pictureWatermark.Left = -marginLeft / PDF_DIVIDER;
  1065. pictureWatermark.Top = -page.TopMargin * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  1066. pictureWatermark.Width = ExportUtils.GetPageWidth(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  1067. pictureWatermark.Height = ExportUtils.GetPageHeight(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  1068. PictureWatermarkSizeMode(pictureWatermark, page.Watermark.ImageSize);
  1069. pictureWatermark.Image = new Bitmap(page.Watermark.Image);
  1070. float transparency = page.Watermark.ImageTransparency;
  1071. page.Watermark.ImageTransparency = 0;
  1072. using (Graphics g = Graphics.FromImage(page.Watermark.Image))
  1073. {
  1074. g.Clear(Color.Transparent);
  1075. page.Watermark.DrawImage(new FRPaintEventArgs(g, 1, 1, Report.GraphicCache),
  1076. new RectangleF(0, 0, pictureWatermark.Width, pictureWatermark.Height), Report, true);
  1077. }
  1078. pictureWatermark.Transparency = page.Watermark.ImageTransparency = transparency;
  1079. pictureWatermark.Fill = new SolidFill(Color.Transparent);
  1080. pictureWatermark.FillColor = Color.Transparent;
  1081. AddPictureObject(pictureWatermark, false, jpegQuality, sb);
  1082. }
  1083. }
  1084. }
  1085. private void PictureWatermarkSizeMode(PictureObject pictureBoxSize, WatermarkImageSize imageSize)
  1086. {
  1087. switch (imageSize)
  1088. {
  1089. case WatermarkImageSize.Normal:
  1090. pictureBoxSize.SizeMode = PictureBoxSizeMode.Normal;
  1091. break;
  1092. case WatermarkImageSize.Center:
  1093. pictureBoxSize.SizeMode = PictureBoxSizeMode.CenterImage;
  1094. break;
  1095. case WatermarkImageSize.Stretch:
  1096. pictureBoxSize.SizeMode = PictureBoxSizeMode.StretchImage;
  1097. break;
  1098. case WatermarkImageSize.Zoom:
  1099. pictureBoxSize.SizeMode = PictureBoxSizeMode.Zoom;
  1100. break;
  1101. case WatermarkImageSize.Tile:
  1102. pictureBoxSize.Tile = imageSize == WatermarkImageSize.Tile;
  1103. break;
  1104. default:
  1105. pictureBoxSize.SizeMode = PictureBoxSizeMode.AutoSize;
  1106. break;
  1107. }
  1108. }
  1109. private void AddTextWatermark(ReportPage page, StringBuilder sb)
  1110. {
  1111. if (!String.IsNullOrEmpty(page.Watermark.Text))
  1112. using (TextObject textWatermark = new TextObject())
  1113. {
  1114. textWatermark.HorzAlign = HorzAlign.Center;
  1115. textWatermark.VertAlign = VertAlign.Center;
  1116. textWatermark.Left = -marginLeft / PDF_DIVIDER;
  1117. textWatermark.Top = -page.TopMargin * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  1118. textWatermark.Width = ExportUtils.GetPageWidth(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  1119. textWatermark.Height = ExportUtils.GetPageHeight(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  1120. textWatermark.Text = page.Watermark.Text;
  1121. textWatermark.TextFill = page.Watermark.TextFill;
  1122. if (page.Watermark.TextRotation == WatermarkTextRotation.Vertical)
  1123. textWatermark.Angle = 270;
  1124. else if (page.Watermark.TextRotation == WatermarkTextRotation.ForwardDiagonal)
  1125. textWatermark.Angle = 360 - (int)(Math.Atan(textWatermark.Height / textWatermark.Width) * (180 / Math.PI));
  1126. else if (page.Watermark.TextRotation == WatermarkTextRotation.BackwardDiagonal)
  1127. textWatermark.Angle = (int)(Math.Atan(textWatermark.Height / textWatermark.Width) * (180 / Math.PI));
  1128. textWatermark.Font = page.Watermark.Font;
  1129. if (page.Watermark.TextFill is SolidFill)
  1130. textWatermark.TextColor = (page.Watermark.TextFill as SolidFill).Color;
  1131. textWatermark.Fill = new SolidFill(Color.Transparent);
  1132. textWatermark.FillColor = Color.Transparent;
  1133. AddTextObject(textWatermark, false, sb);
  1134. }
  1135. }
  1136. private void AddTable(TableBase table, bool drawCells, StringBuilder sb_in)
  1137. {
  1138. float y = 0;
  1139. StringBuilder sb = new StringBuilder(1024);
  1140. for (int i = 0; i < table.RowCount; i++)
  1141. {
  1142. float x = 0;
  1143. for (int j = 0; j < table.ColumnCount; j++)
  1144. {
  1145. if (!table.IsInsideSpan(table[j, i]))
  1146. {
  1147. table[j, i].Left = x;
  1148. table[j, i].Top = y;
  1149. if (drawCells)
  1150. {
  1151. Border oldBorder = table[j, i].Border.Clone();
  1152. table[j, i].Border.Lines = BorderLines.None;
  1153. if (table[j, i] is TextObject)
  1154. AddTextObject(table[j, i] as TextObject, false, sb_in);
  1155. else
  1156. AddPictureObject(table[j, i] as ReportComponentBase, false, jpegQuality, sb_in);
  1157. table[j, i].Border = null;
  1158. table[j, i].Border = oldBorder;
  1159. }
  1160. else
  1161. DrawPDFBorder(table[j, i].Border, table[j, i].AbsLeft, table[j, i].AbsTop, table[j, i].Width, table[j, i].Height, sb);
  1162. }
  1163. x += (table.Columns[j]).Width;
  1164. }
  1165. y += (table.Rows[i]).Height;
  1166. }
  1167. sb_in.Append(sb);
  1168. }
  1169. private void AddShape(ShapeObject shapeObject, StringBuilder sb)
  1170. {
  1171. // Shapes with a custom dash pattern are exported as images.
  1172. // There is a difference between shapes with a custom dash pattern and shapes with standard Border styles in the display in pdf -
  1173. // shapes with standard Border styles in pdf are larger than in the preview.
  1174. if (shapeObject.Shape != ShapeKind.RoundRectangle && shapeObject.Fill is SolidFill && shapeObject.DashPattern.Count == 0)
  1175. {
  1176. if (shapeObject.Shape == ShapeKind.Rectangle)
  1177. {
  1178. DrawPDFFillRect(
  1179. GetLeft(shapeObject.AbsLeft), GetTop(shapeObject.AbsTop),
  1180. shapeObject.Width * PDF_DIVIDER, shapeObject.Height * PDF_DIVIDER,
  1181. shapeObject.Fill, sb);
  1182. DrawPDFRect(
  1183. GetLeft(shapeObject.AbsLeft),
  1184. GetTop(shapeObject.AbsTop),
  1185. GetLeft(shapeObject.AbsLeft + shapeObject.Width),
  1186. GetTop(shapeObject.AbsTop + shapeObject.Height),
  1187. shapeObject.Border.Color, shapeObject.Border.Width * PDF_DIVIDER,
  1188. shapeObject.Border.Style, sb);
  1189. }
  1190. else if (shapeObject.Shape == ShapeKind.Triangle)
  1191. DrawPDFTriangle(GetLeft(shapeObject.AbsLeft), GetTop(shapeObject.AbsTop),
  1192. shapeObject.Width * PDF_DIVIDER, shapeObject.Height * PDF_DIVIDER,
  1193. shapeObject.FillColor, shapeObject.Border.Color, shapeObject.Border.Width * PDF_DIVIDER,
  1194. shapeObject.Border.Style, sb);
  1195. else if (shapeObject.Shape == ShapeKind.Diamond)
  1196. DrawPDFDiamond(GetLeft(shapeObject.AbsLeft), GetTop(shapeObject.AbsTop),
  1197. shapeObject.Width * PDF_DIVIDER, shapeObject.Height * PDF_DIVIDER,
  1198. shapeObject.FillColor, shapeObject.Border.Color, shapeObject.Border.Width * PDF_DIVIDER,
  1199. shapeObject.Border.Style, sb);
  1200. else if (shapeObject.Shape == ShapeKind.Ellipse)
  1201. DrawPDFEllipse(GetLeft(shapeObject.AbsLeft), GetTop(shapeObject.AbsTop),
  1202. shapeObject.Width * PDF_DIVIDER, shapeObject.Height * PDF_DIVIDER,
  1203. shapeObject.FillColor, shapeObject.Border.Color, shapeObject.Border.Width * PDF_DIVIDER,
  1204. shapeObject.Border.Style, sb);
  1205. if (!isPdfX())
  1206. AddAnnot(shapeObject);
  1207. }
  1208. else
  1209. AddPictureObject(shapeObject, true, jpegQuality, sb);
  1210. }
  1211. //private void AddPolyLine(PolyLineObject obj, StringBuilder sb)
  1212. //{
  1213. // int len = obj.PointsArray.Length;
  1214. // if (len == 0 || len == 1)
  1215. // {
  1216. // float localX = GetLeft(obj.AbsLeft);
  1217. // float localY = GetTop(obj.AbsTop);
  1218. // DrawPDFLine(
  1219. // localX, localY + 6 * PDF_DIVIDER,
  1220. // localX, localY - 6 * PDF_DIVIDER,
  1221. // obj.Border.Color, obj.Border.Width * PDF_DIVIDER, obj.Border.Style, null, null, sb);
  1222. // DrawPDFLine(
  1223. // localX - 6 * PDF_DIVIDER, localY,
  1224. // localX + 6 * PDF_DIVIDER, localY,
  1225. // obj.Border.Color, obj.Border.Width * PDF_DIVIDER, obj.Border.Style, null, null, sb);
  1226. // }
  1227. // else if (len == 2)
  1228. // {
  1229. // DrawPDFLine(
  1230. // GetLeft(obj.AbsLeft) + (obj.PointsArray[0].X + obj.CenterX) * PDF_DIVIDER,
  1231. // GetTop(obj.AbsTop) - (obj.PointsArray[0].Y + obj.CenterY) * PDF_DIVIDER,
  1232. // GetLeft(obj.AbsLeft) + (obj.PointsArray[1].X + obj.CenterX) * PDF_DIVIDER,
  1233. // GetTop(obj.AbsTop) - (obj.PointsArray[1].Y + obj.CenterY) * PDF_DIVIDER, obj.Border.Color, obj.Border.Width * PDF_DIVIDER, obj.Border.Style, null, null, sb);
  1234. // }
  1235. // else
  1236. // {
  1237. // if (obj is PolygonObject)
  1238. // {
  1239. // if (obj.Fill is SolidFill)
  1240. // DrawPDFPolygon(GetLeft(obj.AbsLeft),
  1241. // GetTop(obj.AbsTop), GetLeft(obj.AbsLeft + obj.Width), GetTop(obj.AbsTop + obj.Height),
  1242. // obj.CenterX, obj.CenterY, obj.PointsArray, obj.FillColor,
  1243. // obj.Border.Color, obj.Border.Width * PDF_DIVIDER, obj.Border.Style, sb);
  1244. // //else if (obj.Fill is LinearGradientFill || obj.Fill is PathGradientFill)
  1245. // // FillPDFGraphicsPath(GetLeft(obj.AbsLeft),
  1246. // // GetTop(obj.AbsTop), obj.Width * PDF_DIVIDER, obj.Height * PDF_DIVIDER,
  1247. // // obj.GetPath(null, 0,0,0,0, PDF_DIVIDER, PDF_DIVIDER),
  1248. // // obj.Fill.CreateBrush(new RectangleF(0, 0, obj.Width, obj.Height)), sb);
  1249. // else
  1250. // AddPictureObject(obj, true, jpegQuality, sb);
  1251. // }
  1252. // else
  1253. // DrawPDFPolyLine(GetLeft(obj.AbsLeft),
  1254. // GetTop(obj.AbsTop), GetLeft(obj.AbsLeft + obj.Width), GetTop(obj.AbsTop + obj.Height),
  1255. // obj.CenterX, obj.CenterY, obj.PointsArray, false,
  1256. // obj.Border.Color, obj.Border.Width * PDF_DIVIDER, obj.Border.Style, sb);
  1257. // }
  1258. //}
  1259. private void AddLine(LineObject l, StringBuilder sb)
  1260. {
  1261. if (l.DashPattern.Count == 1)
  1262. l.Border.Style = LineStyle.Solid;
  1263. DrawPDFLine(GetLeft(l.AbsLeft),
  1264. GetTop(l.AbsTop), GetLeft(l.AbsLeft + l.Width), GetTop(l.AbsTop + l.Height),
  1265. l.Border.Color, l.Border.Width * PDF_DIVIDER,
  1266. l.DashPattern.Count > 1 ? LineStyle.Custom : l.Border.Style,
  1267. l.StartCap, l.EndCap, sb,
  1268. l.DashPattern);
  1269. }
  1270. private void AddBandObject(BandBase band, StringBuilder sb)
  1271. {
  1272. if (band.Border.Lines == BorderLines.None && band.Fill.IsTransparent)
  1273. return;
  1274. using (TextObject newObj = new TextObject())
  1275. {
  1276. newObj.Left = band.AbsLeft;
  1277. newObj.Top = band.AbsTop;
  1278. newObj.Width = band.Width;
  1279. newObj.Height = band.Height;
  1280. newObj.Fill = band.Fill;
  1281. newObj.Border = band.Border;
  1282. AddTextObject(newObj, true, sb);
  1283. }
  1284. }
  1285. private void AddTextObject(TextObject obj, bool drawBorder, StringBuilder sb_in)
  1286. {
  1287. if (!isPdfX())
  1288. AddAnnot(obj);
  1289. StringBuilder sb = new StringBuilder(256);
  1290. StringBuilder image_sb = null;
  1291. sb.AppendLine("q");
  1292. sb.Append(FloatToString(GetLeft(obj.AbsLeft))).Append(" ");
  1293. sb.Append(FloatToString(GetTop(obj.AbsTop + obj.Height))).Append(" ");
  1294. sb.Append(FloatToString((obj.Width) * PDF_DIVIDER)).Append(" ");
  1295. sb.Append(FloatToString((obj.Height) * PDF_DIVIDER)).AppendLine(" re");
  1296. if (obj.Clip)
  1297. sb.AppendLine("W");
  1298. sb.AppendLine("n");
  1299. // draw background
  1300. if (obj.Fill is SolidFill || (obj.Fill is GlassFill && !(obj.Fill as GlassFill).Hatch) || IsFillableGradientGrid(obj.Fill))
  1301. {
  1302. DrawPDFFillRect(GetLeft(obj.AbsLeft), GetTop(obj.AbsTop),
  1303. obj.Width * PDF_DIVIDER, obj.Height * PDF_DIVIDER, obj.Fill, sb);
  1304. }
  1305. else if (obj.Width > 0 && obj.Height > 0)
  1306. {
  1307. using (PictureObject backgroundPicture = new PictureObject())
  1308. {
  1309. backgroundPicture.Left = obj.AbsLeft;
  1310. backgroundPicture.Top = obj.AbsTop;
  1311. backgroundPicture.Width = obj.Width;
  1312. backgroundPicture.Height = obj.Height;
  1313. backgroundPicture.Image = new Bitmap((int)backgroundPicture.Width, (int)backgroundPicture.Height);
  1314. using (Graphics g = Graphics.FromImage(backgroundPicture.Image))
  1315. {
  1316. g.Clear(Color.Transparent);
  1317. g.TranslateTransform(-obj.AbsLeft, -obj.AbsTop);
  1318. BorderLines oldLines = obj.Border.Lines;
  1319. obj.Border.Lines = BorderLines.None;
  1320. string oldText = obj.Text;
  1321. obj.Text = String.Empty;
  1322. obj.Draw(new FRPaintEventArgs(g, 1, 1, Report.GraphicCache));
  1323. obj.Text = oldText;
  1324. obj.Border.Lines = oldLines;
  1325. }
  1326. AddPictureObject(backgroundPicture, false, jpegQuality, sb_in);
  1327. }
  1328. }
  1329. switch (obj.TextRenderType)
  1330. {
  1331. case TextRenderType.HtmlParagraph:
  1332. {
  1333. RectangleF textRect = new RectangleF(
  1334. obj.AbsLeft + obj.Padding.Left,
  1335. obj.AbsTop + obj.Padding.Top,
  1336. obj.Width - obj.Padding.Horizontal,
  1337. obj.Height - obj.Padding.Vertical);
  1338. AddTextObjectHtmlInternal(obj, textRect, sb);
  1339. }
  1340. break;
  1341. default:
  1342. if (obj.Underlines)
  1343. AppendUnderlines(sb, obj);
  1344. if (obj.Editable && InteractiveForms)
  1345. {
  1346. long xref = AddTextDefaultValueForEditable(obj);
  1347. AddTextField(obj, xref);
  1348. }
  1349. else if (!String.IsNullOrEmpty(obj.Text))
  1350. {
  1351. RectangleF textRect = new RectangleF(
  1352. obj.AbsLeft + obj.Padding.Left,
  1353. obj.AbsTop + obj.Padding.Top,
  1354. obj.Width - obj.Padding.Horizontal,
  1355. obj.Height - obj.Padding.Vertical);
  1356. bool transformNeeded = obj.Angle != 0 || obj.FontWidthRatio != 1;
  1357. // transform, rotate and scale pdf coordinates if needed
  1358. if (transformNeeded)
  1359. {
  1360. textRect.X = -textRect.Width / 2;
  1361. textRect.Y = -textRect.Height / 2;
  1362. float angle = (float)((360 - obj.Angle) * Math.PI / 180);
  1363. float sin = (float)Math.Sin(angle);
  1364. float cos = (float)Math.Cos(angle);
  1365. float x = GetLeft(obj.AbsLeft + obj.Width / 2);
  1366. float y = GetTop(obj.AbsTop + obj.Height / 2);
  1367. // offset the origin to the middle of bounding rectangle, then rotate
  1368. sb.Append(FloatToString(cos)).Append(" ").
  1369. Append(FloatToString(sin)).Append(" ").
  1370. Append(FloatToString(-sin)).Append(" ").
  1371. Append(FloatToString(cos)).Append(" ").
  1372. Append(FloatToString(x)).Append(" ").
  1373. Append(FloatToString(y)).AppendLine(" cm");
  1374. // apply additional matrix to scale x coordinate
  1375. if (obj.FontWidthRatio != 1)
  1376. sb.Append(FloatToString(obj.FontWidthRatio)).AppendLine(" 0 0 1 0 0 cm");
  1377. }
  1378. image_sb = AddTextObjectInternal(obj, textRect, transformNeeded, sb, false);
  1379. }
  1380. break;
  1381. }
  1382. sb.AppendLine("Q");
  1383. if (drawBorder)
  1384. DrawPDFBorder(obj.Border, obj.AbsLeft, obj.AbsTop, obj.Width, obj.Height, sb);
  1385. sb_in.Append(sb);
  1386. if (image_sb != null)
  1387. sb_in.Append(image_sb);
  1388. }
  1389. private void AddTextObjectHtmlInternal(TextObject obj, RectangleF textRect, StringBuilder sb)
  1390. {
  1391. StringFormat format = obj.GetStringFormat(Report.GraphicCache /*cache*/, 0);
  1392. Color color = Color.Black;
  1393. if (obj.TextFill is SolidFill) color = (obj.TextFill as SolidFill).Color;
  1394. using (HtmlTextRenderer renderer = new HtmlTextRenderer(obj.Text, graphics, obj.Font.FontFamily, obj.Font.Size, obj.Font.Style, color,
  1395. obj.TextOutline.Color, textRect, obj.Underlines,
  1396. format, obj.HorzAlign, obj.VertAlign, obj.ParagraphFormat.MultipleScale(dpiFX), obj.ForceJustify,
  1397. dpiFX, dpiFX, obj.InlineImageCache, false, obj.TabPositions.Count > 0))
  1398. {
  1399. foreach (HtmlTextRenderer.RectangleFColor rect in renderer.Backgrounds)
  1400. DrawPDFFillRect(GetLeft(rect.Left), GetTop(rect.Top),
  1401. rect.Width * PDF_DIVIDER, rect.Height * PDF_DIVIDER, new SolidFill(rect.Color), sb);
  1402. List<PictureObject> pictures = new List<PictureObject>();
  1403. if (obj.RightToLeft)
  1404. {
  1405. foreach (HtmlTextRenderer.Paragraph paragraph in renderer.Paragraphs)
  1406. foreach (HtmlTextRenderer.Line line in paragraph.Lines)
  1407. foreach (HtmlTextRenderer.Word word in line.Words)
  1408. if (word.Type == HtmlTextRenderer.WordType.Normal)
  1409. foreach (HtmlTextRenderer.Run run in word.Runs)
  1410. {
  1411. if (run is HtmlTextRenderer.RunText)
  1412. {
  1413. HtmlTextRenderer.RunText runText = run as HtmlTextRenderer.RunText;
  1414. using (Font fnt = runText.Style.GetFont())
  1415. {
  1416. AppendText(sb, fnt, run.Left - run.Width + fnt.Size * 0.2f, run.Top, 0, run.Width, runText.Text,
  1417. obj.RightToLeft, false, obj.TextOutline, run.Style.Color, false, 0);
  1418. }
  1419. }
  1420. else if (run is HtmlTextRenderer.RunImage)
  1421. {
  1422. HtmlTextRenderer.RunImage runImage = run as HtmlTextRenderer.RunImage;
  1423. PictureObject picture = new PictureObject();
  1424. picture.Left = (runImage.Left - runImage.Width) / renderer.Scale;
  1425. picture.Top = runImage.Top / renderer.Scale;
  1426. picture.Width = runImage.Width / renderer.Scale;
  1427. picture.Height = runImage.Height / renderer.Scale;
  1428. picture.SizeMode = PictureBoxSizeMode.StretchImage;
  1429. picture.Image = runImage.Image;
  1430. picture.SetReport(obj.Report);
  1431. pictures.Add(picture);
  1432. }
  1433. }
  1434. }
  1435. else
  1436. {
  1437. foreach (HtmlTextRenderer.Paragraph paragraph in renderer.Paragraphs)
  1438. foreach (HtmlTextRenderer.Line line in paragraph.Lines)
  1439. foreach (HtmlTextRenderer.Word word in line.Words)
  1440. if (word.Type == HtmlTextRenderer.WordType.Normal)
  1441. foreach (HtmlTextRenderer.Run run in word.Runs)
  1442. {
  1443. if (run is HtmlTextRenderer.RunText)
  1444. {
  1445. HtmlTextRenderer.RunText runText = run as HtmlTextRenderer.RunText;
  1446. using (Font fnt = runText.Style.GetFont())
  1447. {
  1448. AppendText(sb, fnt, run.Left, run.Top, 0, run.Width, runText.Text,
  1449. obj.RightToLeft, false, obj.TextOutline, run.Style.Color, false, 0);
  1450. }
  1451. }
  1452. else if (run is HtmlTextRenderer.RunImage)
  1453. {
  1454. HtmlTextRenderer.RunImage runImage = run as HtmlTextRenderer.RunImage;
  1455. PictureObject picture = new PictureObject();
  1456. picture.Left = runImage.Left / renderer.Scale;
  1457. picture.Top = runImage.Top / renderer.Scale;
  1458. picture.Width = runImage.Width / renderer.Scale;
  1459. picture.Height = runImage.Height / renderer.Scale;
  1460. picture.SizeMode = PictureBoxSizeMode.StretchImage;
  1461. picture.Image = runImage.Image;
  1462. picture.SetReport(obj.Report);
  1463. pictures.Add(picture);
  1464. }
  1465. }
  1466. }
  1467. foreach (PictureObject pobj in pictures)
  1468. {
  1469. try
  1470. {
  1471. AddPictureObject(pobj, false, jpegQuality, sb);
  1472. }
  1473. finally
  1474. {
  1475. pobj.Dispose();
  1476. }
  1477. }
  1478. foreach (HtmlTextRenderer.LineFColor line in renderer.Underlines)
  1479. DrawPDFLine(GetLeft(line.Left), GetTop(line.Top), GetLeft(line.Right), GetTop(line.Top),
  1480. line.Color, line.Width * PDF_DIVIDER, LineStyle.Solid, null, null, sb);
  1481. foreach (HtmlTextRenderer.LineFColor line in renderer.Stikeouts)
  1482. DrawPDFLine(GetLeft(line.Left), GetTop(line.Top), GetLeft(line.Right), GetTop(line.Top),
  1483. line.Color, line.Width * PDF_DIVIDER, LineStyle.Solid, null, null, sb);
  1484. }
  1485. }
  1486. private StringBuilder AddTextObjectInternal(TextObject obj, RectangleF textRect, bool transformNeeded, StringBuilder sb, bool bbox)
  1487. {
  1488. StringBuilder image_sb = null;
  1489. StringFormat format = obj.GetStringFormat(Report.GraphicCache /*cache*/, 0);
  1490. Brush textBrush = Report.GraphicCache.GetBrush(obj.TextColor);
  1491. Font f = Report.GraphicCache.GetFont(obj.Font.FontFamily, obj.Font.Size * dpiFX, obj.Font.Style);
  1492. float w = Config.IsRunningOnMono ? 0 : f.GetHeight(graphics.Graphics) * 0.1f;// to match .net char X offset.
  1493. #if SKIA
  1494. w = f.Height * 0.1f;
  1495. if (obj.HorzAlign == HorzAlign.Right)
  1496. w *= 2;
  1497. #else
  1498. // invert offset in case of rtl
  1499. if (obj.RightToLeft)
  1500. w = -w;
  1501. #endif
  1502. // we don't need this offset if text is centered
  1503. if (obj.HorzAlign == HorzAlign.Center)
  1504. w = 0;
  1505. if (obj.TextRenderType == TextRenderType.Inline)
  1506. w = 0;
  1507. // break the text to paragraphs, lines, words and runs
  1508. AdvancedTextRenderer renderer = new AdvancedTextRenderer(obj.Text, graphics, f, textBrush, null,
  1509. textRect, format, obj.HorzAlign, obj.VertAlign, obj.LineHeight, obj.Angle, obj.FontWidthRatio,
  1510. obj.ForceJustify, obj.Wysiwyg, obj.HasHtmlTags, true, dpiFX, dpiFX,
  1511. obj.InlineImageCache);
  1512. if (obj.HasHtmlTags)
  1513. {
  1514. image_sb = new StringBuilder();
  1515. foreach (PictureObject pobj in obj.GetPictureFromHtmlText(renderer))
  1516. {
  1517. pobj.SetReport(obj.Report);
  1518. AddPictureObject(pobj, false, jpegQuality, image_sb);
  1519. }
  1520. }
  1521. // render
  1522. foreach (AdvancedTextRenderer.Paragraph paragraph in renderer.Paragraphs)
  1523. foreach (AdvancedTextRenderer.Line line in paragraph.Lines)
  1524. {
  1525. float lineOffset = 0;
  1526. float lineHeight = line.CalcHeight();
  1527. float objHeight = (obj.Angle == 0 || obj.Angle == 180) ?
  1528. obj.Height - obj.Padding.Vertical :
  1529. obj.Width - obj.Padding.Horizontal;
  1530. if (lineHeight > objHeight)
  1531. {
  1532. if (obj.VertAlign == VertAlign.Center)
  1533. lineOffset = -lineHeight / 2;
  1534. else if (obj.VertAlign == VertAlign.Bottom)
  1535. lineOffset = -lineHeight;
  1536. }
  1537. float lineThickness = lineHeight * 0.05f;
  1538. foreach (RectangleF rect in line.Underlines)
  1539. DrawPDFLine(rect.Left, rect.Top + GetBaseline(f) + 2 + lineThickness, rect.Width, lineThickness, w,
  1540. obj.TextColor, transformNeeded, sb);
  1541. foreach (RectangleF rect in line.Strikeouts)
  1542. DrawPDFLine(rect.Left, rect.Top + lineHeight / 2, rect.Width, lineThickness * 0.7f, w,
  1543. obj.TextColor, transformNeeded, sb);
  1544. foreach (AdvancedTextRenderer.Word word in line.Words)
  1545. if (renderer.HtmlTags)
  1546. foreach (AdvancedTextRenderer.Run run in word.Runs)
  1547. using (Font fnt = run.GetFont())
  1548. {
  1549. AppendText(sb, fnt, run.Left, run.Top, w, run.Width, run.Text,
  1550. obj.RightToLeft, transformNeeded, obj.TextOutline, run.Style.Color, bbox, obj.Height - obj.Padding.Vertical);
  1551. }
  1552. else
  1553. AppendText(sb, f, word.Left, word.Top + lineOffset, w, word.Width, word.Text,
  1554. obj.RightToLeft, transformNeeded, obj.TextOutline, obj.TextColor, bbox, obj.Height - obj.Padding.Vertical);
  1555. }
  1556. return image_sb;
  1557. }
  1558. private void AppendUnderlines(StringBuilder Result, TextObject obj)
  1559. {
  1560. float lineHeight = obj.LineHeight == 0 ? obj.Font.GetHeight() : obj.LineHeight;
  1561. lineHeight *= dpiFX * PDF_DIVIDER;
  1562. float curY = GetTop(obj.AbsTop) - lineHeight;
  1563. float bottom = GetTop(obj.AbsBottom);
  1564. float left = GetLeft(obj.AbsLeft);
  1565. float right = GetLeft(obj.AbsRight);
  1566. float width = obj.Border.Width * PDF_DIVIDER;
  1567. while (curY > bottom)
  1568. {
  1569. DrawPDFLine(left, curY, right, curY, obj.Border.Color, width, LineStyle.Solid, null, null, Result);
  1570. curY -= lineHeight;
  1571. }
  1572. }
  1573. private void DrawText(StringBuilder Result, float x, float y, string s, ExportTTFFont font, Color fontColor)
  1574. {
  1575. bool SimulateItalic = font.NeedSimulateItalic && font.SourceFont.Italic;
  1576. bool SimulateBold = font.NeedSimulateBold && font.SourceFont.Bold;
  1577. Result.AppendLine("BT");
  1578. Result.Append(FloatToString(x)).Append(" ").Append(FloatToString(y)).AppendLine(" Td");
  1579. if (SimulateItalic)
  1580. Result.Append("1 0 0.3333 1 ").Append(FloatToString(x)).Append(' ').Append(FloatToString(y)).AppendLine(" Tm");
  1581. if (SimulateBold)
  1582. {
  1583. GetPDFStrokeColor(fontColor, Result);
  1584. Result.Append("2 Tr ").Append(FloatToString(font.SourceFontBoldMultiplier)).Append(" w ");
  1585. }
  1586. else
  1587. Result.AppendLine("0 Tr");
  1588. Result.Append("[<").Append(s).AppendLine(">] TJ");
  1589. if (SimulateBold)
  1590. Result.AppendLine("0 Tr");
  1591. Result.AppendLine("ET");
  1592. }
  1593. private void DrawTextOutline(StringBuilder Result, float x, float y, string s, TextOutline objTextOutline)
  1594. {
  1595. Result.AppendLine();
  1596. GetPDFStrokeColor(objTextOutline.Color, Result);
  1597. Result.AppendLine("BT");
  1598. Result.Append(FloatToString(x)).Append(" ").Append(FloatToString(y)).AppendLine(" Td");
  1599. Result.AppendLine("1 Tr");
  1600. Result.Append(FloatToString(objTextOutline.Width * PDF_DIVIDER)).AppendLine(" w");
  1601. Result.Append("[<").Append(s).AppendLine(">] TJ");
  1602. Result.AppendLine("ET");
  1603. }
  1604. private string GetGlyphString(ExportTTFFont.RunInfo run, float width)
  1605. {
  1606. #if WITHOUT_UNISCRIBE && !SKIA
  1607. // in linux + libgdiplus, kerning is used to display and measure text. Width of text reported by Graphics.MeasureString differs from sum of glyph widths in pdf.
  1608. // case: right-aligned text such as
  1609. // 11111111111111111111111111111111
  1610. // 1
  1611. // may produce pdf output like this:
  1612. // 11111111111111111111111111111111
  1613. // 1
  1614. // or this:
  1615. // 11111111111111111111111111111111
  1616. // 1
  1617. // depending on font used.
  1618. // Solution: we have got desired width and actual pdf width. Calculate delta and use it (along with kerning) for inter-character spacing
  1619. float pdfWidth = 0;
  1620. int lastNotWhiteSpaceIndex = Array.FindLastIndex(run.GlyphToUnicode, c => !string.IsNullOrWhiteSpace(c));
  1621. for (int i = 0; i <= lastNotWhiteSpaceIndex; i++)
  1622. {
  1623. pdfWidth += run.Widths[i] + run.Kernings[i];
  1624. }
  1625. float delta = width == 0 ? 0 : (pdfWidth - width * dpiFX * 750 / run.Font.Size) / run.Glyphs.Length;
  1626. #else
  1627. // windows gdi+ does not use kerning. Also, MeasureString returns the correct width so no adjustment is needed.
  1628. // Skia also measures correctly.
  1629. float delta = 0;
  1630. #endif
  1631. // convert glyph indices to a string
  1632. StringBuilder sb = new StringBuilder(run.Glyphs.Length * 4);
  1633. for (int i = 0; i < run.Glyphs.Length; i++)
  1634. {
  1635. sb.Append(run.Glyphs[i].ToString("X4"));
  1636. int offs = (int)Math.Round(-run.Kernings[i] + delta); // dpiFX is not needed here.
  1637. if (offs != 0)
  1638. sb.Append(">" + offs.ToString() + "<");
  1639. }
  1640. return sb.ToString();
  1641. }
  1642. private void DrawTextRun(ExportTTFFont.RunInfo run, StringBuilder result, float x, float y, float width, ExportTTFFont pdffont,
  1643. TextOutline objTextOutline, Color fontColor)
  1644. {
  1645. string s = GetGlyphString(run, width);
  1646. if (objTextOutline == null || !objTextOutline.Enabled)
  1647. {
  1648. DrawText(result, x, y, s, pdffont, fontColor);
  1649. }
  1650. else
  1651. {
  1652. if (objTextOutline.DrawBehind)
  1653. {
  1654. DrawTextOutline(result, x, y, s, objTextOutline);
  1655. DrawText(result, x, y, s, pdffont, fontColor);
  1656. }
  1657. else
  1658. {
  1659. DrawText(result, x, y, s, pdffont, fontColor);
  1660. DrawTextOutline(result, x, y, s, objTextOutline);
  1661. }
  1662. }
  1663. }
  1664. private void DrawGlyphRun(ExportTTFFont.RunInfo run, StringBuilder result, float x, float y, ExportTTFFont pdffont,
  1665. TextOutline objTextOutline, Color fontColor)
  1666. {
  1667. ExportTTFFont.GlyphTTF[] txt = pdffont.GetGlyphPath(run);
  1668. Action DrawText = () =>
  1669. {
  1670. float shift = 0;
  1671. foreach (ExportTTFFont.GlyphTTF ch in txt)
  1672. {
  1673. DrawPDFPolygonChar(ch.Path, x + shift * PDF_DIVIDER, y, fontColor, result);
  1674. shift += ch.Width;
  1675. }
  1676. };
  1677. Action DrawOutline = () =>
  1678. {
  1679. float shift = 0;
  1680. foreach (ExportTTFFont.GlyphTTF ch in txt)
  1681. {
  1682. DrawPDFPolygonCharOutline(ch.Path, x + shift * PDF_DIVIDER, y, objTextOutline.Color, objTextOutline.Width, result);
  1683. shift += ch.Width;
  1684. }
  1685. };
  1686. if (objTextOutline == null || !objTextOutline.Enabled)
  1687. {
  1688. DrawText();
  1689. }
  1690. else
  1691. {
  1692. if (objTextOutline.DrawBehind)
  1693. {
  1694. DrawOutline();
  1695. DrawText();
  1696. }
  1697. else
  1698. {
  1699. DrawText();
  1700. DrawOutline();
  1701. }
  1702. }
  1703. }
  1704. private void AppendText(StringBuilder result, Font font, float x, float y, float offsX, float width, string text, bool rtl, bool transformNeeded,
  1705. TextOutline objTextOutline, Color fontColor, bool bbox, float bbox_height)
  1706. {
  1707. // set up initial font
  1708. int fontNumber = GetObjFontNumber(font);
  1709. ExportTTFFont pdffont = pageFonts[fontNumber];
  1710. Font currentFont = null;
  1711. // this may return several runs if text is bidi or font fallback is needed
  1712. ExportTTFFont.RunInfo[] runs = pdffont.GetFontRuns(text, rtl, font);
  1713. // width correction (for libgdiplus) must be switched off if we got several runs
  1714. if (runs.Length > 1)
  1715. width = 0;
  1716. foreach (var run in runs)
  1717. {
  1718. // each run may have its own font.
  1719. if (run.Font != currentFont)
  1720. {
  1721. currentFont = run.Font;
  1722. fontNumber = GetObjFontNumber(currentFont);
  1723. AppendFont(result, fontNumber, currentFont.Size / dpiFX, fontColor);
  1724. pdffont = pageFonts[fontNumber];
  1725. }
  1726. pdffont.AddUsedGlyphs(run);
  1727. float textX = x + run.OffsetX;
  1728. // run with vertical offset has single glyph, use its 0 index
  1729. float textY = y + run.VerticalOffsets[0];
  1730. if (!bbox)
  1731. {
  1732. textX = (transformNeeded ? textX * PDF_DIVIDER : GetLeft(textX)) + offsX;
  1733. textY = transformNeeded ? -textY * PDF_DIVIDER : GetTop(textY);
  1734. textY -= GetBaseline(currentFont) * PDF_DIVIDER;
  1735. }
  1736. else
  1737. {
  1738. textX = textX * PDF_DIVIDER + offsX;
  1739. textY = (bbox_height - textY - GetBaseline(currentFont)) * PDF_DIVIDER;
  1740. }
  1741. if (textInCurves)
  1742. DrawGlyphRun(run, result, textX, textY, pdffont, objTextOutline, fontColor);
  1743. else
  1744. DrawTextRun(run, result, textX, textY, width, pdffont, objTextOutline, fontColor);
  1745. }
  1746. }
  1747. private string GetZoomString(int page, float zoom)
  1748. {
  1749. return ExportUtils.StringFormat(" /XYZ 0 {0} {1}", Math.Round(pagesHeights[page - 1] + pagesTopMargins[page - 1]).ToString(), FloatToString(zoom));
  1750. }
  1751. private void SetMagnificationFactor(int PageNumber, MagnificationFactor factor)
  1752. {
  1753. if (factor == MagnificationFactor.Default)
  1754. return;
  1755. if (pagesRef.Count <= 0)
  1756. return;
  1757. string Magnificator = "";
  1758. actionDict = UpdateXRef();
  1759. WriteLn(pdf, ObjNumber(actionDict));
  1760. WriteLn(pdf, "<<");
  1761. WriteLn(pdf, "/S /GoTo");
  1762. switch (factor)
  1763. {
  1764. case MagnificationFactor.ActualSize:
  1765. Magnificator = GetZoomString(PageNumber, 1f);
  1766. break;
  1767. case MagnificationFactor.FitPage:
  1768. Magnificator = " /Fit";
  1769. break;
  1770. case MagnificationFactor.FitWidth:
  1771. Magnificator = " /FitH 0";
  1772. break;
  1773. case MagnificationFactor.Percent_10:
  1774. Magnificator = GetZoomString(PageNumber, 0.1f);
  1775. break;
  1776. case MagnificationFactor.Percent_25:
  1777. Magnificator = GetZoomString(PageNumber, 0.25f);
  1778. break;
  1779. case MagnificationFactor.Percent_50:
  1780. Magnificator = GetZoomString(PageNumber, 0.5f);
  1781. break;
  1782. case MagnificationFactor.Percent_75:
  1783. Magnificator = GetZoomString(PageNumber, 0.75f);
  1784. break;
  1785. case MagnificationFactor.Percent_100:
  1786. Magnificator = GetZoomString(PageNumber, 1f);
  1787. break;
  1788. case MagnificationFactor.Percent_125:
  1789. Magnificator = GetZoomString(PageNumber, 1.25f);
  1790. break;
  1791. case MagnificationFactor.Percent_150:
  1792. Magnificator = GetZoomString(PageNumber, 1.5f);
  1793. break;
  1794. case MagnificationFactor.Percent_200:
  1795. Magnificator = GetZoomString(PageNumber, 2f);
  1796. break;
  1797. case MagnificationFactor.Percent_400:
  1798. Magnificator = GetZoomString(PageNumber, 4f);
  1799. break;
  1800. case MagnificationFactor.Percent_800:
  1801. Magnificator = GetZoomString(PageNumber, 8f);
  1802. break;
  1803. }
  1804. string targetPage = ObjNumberRef(pagesRef[PageNumber - 1]);
  1805. WriteLn(pdf, ExportUtils.StringFormat("/D [{0}{1}]", targetPage, Magnificator));
  1806. WriteLn(pdf, ">>");
  1807. WriteLn(pdf, "endobj");
  1808. }
  1809. private void AddPDFFooter()
  1810. {
  1811. if (!textInCurves)
  1812. {
  1813. foreach (ExportTTFFont font in fonts)
  1814. {
  1815. WriteFont(font);
  1816. }
  1817. }
  1818. pagesNumber = 1;
  1819. xRef[0] = pdf.Position;
  1820. WriteLn(pdf, ObjNumber(pagesNumber));
  1821. WriteLn(pdf, "<<");
  1822. WriteLn(pdf, "/Type /Pages");
  1823. Write(pdf, "/Kids [");
  1824. foreach (long page in pagesRef)
  1825. Write(pdf, ObjNumberRef(page) + " ");
  1826. WriteLn(pdf, "]");
  1827. WriteLn(pdf, "/Count " + pagesRef.Count.ToString());
  1828. WriteLn(pdf, ">>");
  1829. WriteLn(pdf, "endobj");
  1830. if (outline)
  1831. {
  1832. FastReport.Preview.Outline outlineTree = Report.PreparedPages.Outline;
  1833. outlineNumber = UpdateXRef();
  1834. this.outlineTree = new PDFOutlineNode();
  1835. this.outlineTree.number = outlineNumber;
  1836. BuildOutline(this.outlineTree, outlineTree.Xml);
  1837. WriteOutline(this.outlineTree);
  1838. }
  1839. if (!isPdfX() && defaultZoom != MagnificationFactor.Default && defaultPage < Report.PreparedPages.Count)
  1840. SetMagnificationFactor(defaultPage, defaultZoom);
  1841. if (!isPdfX())
  1842. WriteAnnots();
  1843. if (isPdfX())
  1844. {
  1845. AddMetaDataPdfX();
  1846. if (ColorSpace == PdfColorSpace.RGB)
  1847. AddColorProfile("PDFX", "pdfxprofile");
  1848. else if (ColorSpace == PdfColorSpace.CMYK)
  1849. AddColorProfile("PDFX", "pdfcmykprofile");
  1850. }
  1851. if (isPdfA())
  1852. {
  1853. AddAttachments();
  1854. AddStructure();
  1855. AddMetaDataPdfA();
  1856. if (ColorSpace == PdfColorSpace.RGB)
  1857. AddColorProfile("PDFA1", "pdfaprofile");
  1858. else if (ColorSpace == PdfColorSpace.CMYK)
  1859. AddColorProfile("PDFA1", "pdfcmykprofile");
  1860. }
  1861. infoNumber = UpdateXRef();
  1862. StringBuilder sb = new StringBuilder(1024);
  1863. sb.AppendLine(ObjNumber(infoNumber));
  1864. sb.Append("<<");
  1865. sb.Append("/Title ");
  1866. if (isPdfX() && String.IsNullOrEmpty(title))
  1867. title = "FastReport.Net";
  1868. PrepareString(title, encKey, encrypted, infoNumber, sb);
  1869. sb.Append("/Author ");
  1870. PrepareString(author, encKey, encrypted, infoNumber, sb);
  1871. sb.Append("/Subject ");
  1872. PrepareString(subject, encKey, encrypted, infoNumber, sb);
  1873. sb.Append("/Keywords ");
  1874. PrepareString(keywords, encKey, encrypted, infoNumber, sb);
  1875. sb.Append("/Creator ");
  1876. PrepareString(creator, encKey, encrypted, infoNumber, sb);
  1877. sb.Append("/Producer ");
  1878. PrepareString(producer, encKey, encrypted, infoNumber, sb);
  1879. string s = "D:" + digitalSignCreationDate.ToString("yyyyMMddHHmmssZ");
  1880. if (encrypted)
  1881. {
  1882. sb.Append("/CreationDate ");
  1883. PrepareString(s, encKey, encrypted, infoNumber, sb);
  1884. sb.Append("/ModDate ");
  1885. PrepareString(s, encKey, encrypted, infoNumber, sb);
  1886. }
  1887. else
  1888. {
  1889. sb.AppendLine("/CreationDate (" + s + ")");
  1890. sb.AppendLine("/ModDate (" + s + ")");
  1891. }
  1892. if (PdfCompliance == PdfStandard.PdfX_3)
  1893. {
  1894. sb.AppendLine("/GTS_PDFXVersion(PDF/X-3:2003)");
  1895. sb.AppendLine("/Trapped /False");
  1896. }
  1897. else if (PdfCompliance == PdfStandard.PdfX_4)
  1898. {
  1899. sb.AppendLine("/GTS_PDFXVersion(PDF/X-4)");
  1900. sb.AppendLine("/Trapped /False");
  1901. }
  1902. sb.AppendLine(">>");
  1903. sb.AppendLine("endobj");
  1904. Write(pdf, sb.ToString());
  1905. //acroform
  1906. long acroform = AddAcroForm();
  1907. //end_acroform
  1908. rootNumber = UpdateXRef();
  1909. WriteLn(pdf, ObjNumber(rootNumber));
  1910. WriteLn(pdf, "<<");
  1911. WriteLn(pdf, "/Type /Catalog");
  1912. WriteLn(pdf, "/Version /" + getPdfVersion());
  1913. WriteLn(pdf, "/MarkInfo << /Marked true >>");
  1914. if (acroform > 0)
  1915. WriteLn(pdf, "/AcroForm " + ObjNumberRef(acroform).ToString());
  1916. WriteLn(pdf, "/Pages " + ObjNumberRef(pagesNumber));
  1917. if (!isPdfX())
  1918. {
  1919. if (defaultZoom != MagnificationFactor.Default)
  1920. WriteLn(pdf, "/OpenAction " + ObjNumberRef(actionDict));
  1921. }
  1922. if (showPrintDialog)
  1923. {
  1924. WriteLn(pdf, "/Names <</JavaScript " + ObjNumberRef(printDict) + ">>");
  1925. }
  1926. Write(pdf, "/PageMode ");
  1927. if (outline)
  1928. {
  1929. WriteLn(pdf, "/UseOutlines");
  1930. WriteLn(pdf, "/Outlines " + ObjNumberRef(outlineNumber));
  1931. }
  1932. else
  1933. {
  1934. WriteLn(pdf, "/UseNone");
  1935. }
  1936. if (isPdfA())
  1937. {
  1938. WriteLn(pdf, "/Metadata " + ObjNumberRef(metaFileId));
  1939. if (embeddedFiles.Count > 0)
  1940. {
  1941. Write(pdf, "/AF " + ObjNumberRef(attachmentsListId));
  1942. WriteLn(pdf, " /Names << /EmbeddedFiles " + ObjNumberRef(attachmentsNamesId) + " >>");
  1943. }
  1944. WriteLn(pdf, "/OutputIntents [ " + ObjNumberRef(colorProfileId) + " ]");
  1945. WriteLn(pdf, "/StructTreeRoot " + ObjNumberRef(structId));
  1946. }
  1947. if (isPdfX())
  1948. {
  1949. WriteLn(pdf, "/Metadata " + ObjNumberRef(metaFileId));
  1950. WriteLn(pdf, "/OutputIntents [ " + ObjNumberRef(colorProfileId) + " ]");
  1951. }
  1952. WriteLn(pdf, "/ViewerPreferences <<");
  1953. if (displayDocTitle && !String.IsNullOrEmpty(title))
  1954. WriteLn(pdf, "/DisplayDocTitle true");
  1955. if (hideToolbar)
  1956. WriteLn(pdf, "/HideToolbar true");
  1957. if (hideMenubar)
  1958. WriteLn(pdf, "/HideMenubar true");
  1959. if (hideWindowUI)
  1960. WriteLn(pdf, "/HideWindowUI true");
  1961. if (fitWindow)
  1962. WriteLn(pdf, "/FitWindow true");
  1963. if (centerWindow)
  1964. WriteLn(pdf, "/CenterWindow true");
  1965. if (!printScaling)
  1966. WriteLn(pdf, "/PrintScaling false"); // /None
  1967. WriteLn(pdf, ">>");
  1968. WriteLn(pdf, ">>");
  1969. WriteLn(pdf, "endobj");
  1970. startXRef = pdf.Position;
  1971. WriteLn(pdf, "xref");
  1972. WriteLn(pdf, "0 " + (xRef.Count + 1).ToString());
  1973. WriteLn(pdf, "0000000000 65535 f");
  1974. foreach (long xref in xRef)
  1975. WriteLn(pdf, PrepXRefPos(xref) + " 00000 n");
  1976. WriteLn(pdf, "trailer");
  1977. WriteLn(pdf, "<<");
  1978. WriteLn(pdf, "/Size " + (xRef.Count + 1).ToString());
  1979. WriteLn(pdf, "/Root " + ObjNumberRef(rootNumber));
  1980. WriteLn(pdf, "/Info " + ObjNumberRef(infoNumber));
  1981. WriteLn(pdf, "/ID [<" + fileID + "><" + fileID + ">]");
  1982. if (encrypted)
  1983. {
  1984. WriteLn(pdf, GetEncryptionDescriptor());
  1985. }
  1986. WriteLn(pdf, ">>");
  1987. WriteLn(pdf, "startxref");
  1988. WriteLn(pdf, startXRef.ToString());
  1989. WriteLn(pdf, "%%EOF");
  1990. if (isDigitalSignEnable && digitalSignCertificate != null && signatureDictIndicies.byteRangeIndex != 0)
  1991. {
  1992. digitalSignByteRange = new long[4] { 0, signatureDictIndicies.contentsIndex - 1, signatureDictIndicies.contentsIndex + 16384 + 1, pdf.Length - signatureDictIndicies.contentsIndex - 16384 - 1 };
  1993. string byteRangeStr = string.Format("{0} {1} {2} {3} ]", digitalSignByteRange[0], digitalSignByteRange[1], digitalSignByteRange[2], digitalSignByteRange[3]);
  1994. if (byteRangeStr.Length > 81)
  1995. throw new OverflowException("ByteRange was bigger than 80 bytes");
  1996. pdf.Flush();
  1997. pdf.Seek(signatureDictIndicies.byteRangeIndex, SeekOrigin.Begin);
  1998. byte[] arr = Encoding.ASCII.GetBytes(byteRangeStr);
  1999. pdf.Write(arr, 0, byteRangeStr.Length);
  2000. AddSignature(digitalSignCertificate);
  2001. }
  2002. }
  2003. private void AddEmbeddedFileItem(EmbeddedFile file)
  2004. {
  2005. long fileRef = UpdateXRef();
  2006. WriteLn(pdf, ObjNumber(fileRef));
  2007. Write(pdf, "<< /Params << /ModDate (D:" + file.ModDate.ToString("yyyyMMddHHmmss") + ")");
  2008. Write(pdf, " /Size " + file.FileStream.Length.ToString());
  2009. WriteLn(pdf, " >>");
  2010. WriteLn(pdf, "/Subtype /" + file.MIME.Replace("/", "#2f"));
  2011. WriteLn(pdf, "/Type /EmbeddedFile");
  2012. WritePDFStream(pdf, file.FileStream, fileRef, compressed, encrypted, false, true, true);
  2013. long fileRel = UpdateXRef();
  2014. file.Xref = fileRel;
  2015. WriteLn(pdf, ObjNumber(fileRel));
  2016. WriteLn(pdf, "<< /AFRelationship /" + file.Relation.ToString());
  2017. StringBuilder desc = new StringBuilder();
  2018. PrepareString(file.Description, encKey, encrypted, fileRel, desc);
  2019. WriteLn(pdf, "/Desc " + desc.ToString());
  2020. Write(pdf, "/EF <<");
  2021. Write(pdf, " /F " + ObjNumberRef(fileRef));
  2022. Write(pdf, " /UF " + ObjNumberRef(fileRef));
  2023. WriteLn(pdf, " >>");
  2024. WriteLn(pdf, "/F (" + file.Name + ")");
  2025. WriteLn(pdf, "/Type /Filespec");
  2026. StringBuilder uf = new StringBuilder();
  2027. StrToUTF16(file.Name, uf);
  2028. WriteLn(pdf, "/UF <" + uf.ToString() + ">");
  2029. WriteLn(pdf, ">>");
  2030. WriteLn(pdf, "endobj");
  2031. }
  2032. private void AddAttachments()
  2033. {
  2034. if (embeddedFiles.Count > 0)
  2035. {
  2036. foreach (EmbeddedFile file in embeddedFiles)
  2037. AddEmbeddedFileItem(file);
  2038. attachmentsNamesId = UpdateXRef();
  2039. WriteLn(pdf, ObjNumber(attachmentsNamesId));
  2040. Write(pdf, "<< /Names [");
  2041. foreach (EmbeddedFile file in embeddedFiles)
  2042. {
  2043. Write(pdf, " (" + file.Name + ") ");
  2044. Write(pdf, ObjNumberRef(file.Xref));
  2045. }
  2046. WriteLn(pdf, " ] >>");
  2047. WriteLn(pdf, "endobj");
  2048. attachmentsListId = UpdateXRef();
  2049. WriteLn(pdf, ObjNumber(attachmentsListId));
  2050. Write(pdf, "[ ");
  2051. foreach (EmbeddedFile file in embeddedFiles)
  2052. Write(pdf, ObjNumberRef(file.Xref) + " ");
  2053. WriteLn(pdf, "]");
  2054. WriteLn(pdf, "endobj");
  2055. }
  2056. }
  2057. private void AddStructure()
  2058. {
  2059. long roleMaps = UpdateXRef();
  2060. WriteLn(pdf, ObjNumber(roleMaps));
  2061. WriteLn(pdf, "<<\n/Footnote /Note\n/Endnote /Note\n/Textbox /Sect\n/Header /Sect\n/Footer /Sect\n/InlineShape /Sect\n/Annotation /Sect\n/Artifact /Sect\n/Workbook /Document\n/Worksheet /Part\n/Macrosheet /Part\n/Chartsheet /Part\n/Dialogsheet /Part\n/Slide /Part\n/Chart /Sect\n/Diagram /Figure\n>>\nendobj");
  2062. structId = UpdateXRef();
  2063. WriteLn(pdf, ObjNumber(structId));
  2064. WriteLn(pdf, "<<\n/Type /StructTreeRoot");
  2065. WriteLn(pdf, "/RoleMap " + ObjNumberRef(roleMaps));
  2066. // /ParentTree /K /ParentTreeNextKey
  2067. WriteLn(pdf, ">>\nendobj");
  2068. }
  2069. private void AddColorProfile(string GTS, string ICC)
  2070. {
  2071. string profileName = "default";
  2072. // color profile stream
  2073. long FColorProfileStreamId = UpdateXRef();
  2074. WriteLn(pdf, ObjNumber(FColorProfileStreamId));
  2075. WriteLn(pdf, "<<");
  2076. WriteLn(pdf, "/N 3");
  2077. if (ColorProfile != null)
  2078. {
  2079. string pname = ParseICCFile(ColorProfile);
  2080. if (pname != null)
  2081. {
  2082. profileName = pname.Trim('\0');
  2083. using (MemoryStream profileStream = new MemoryStream(ColorProfile))
  2084. {
  2085. WritePDFStream(pdf, profileStream, FColorProfileStreamId, compressed, encrypted, false, true);
  2086. }
  2087. }
  2088. }
  2089. if (profileName == "default")
  2090. {
  2091. Assembly a = Assembly.GetExecutingAssembly();
  2092. using (Stream stream = a.GetManifestResourceStream("FastReport.Resources.Pdf." + ICC + ".icc"))
  2093. {
  2094. byte[] buf = new byte[stream.Length];
  2095. stream.Read(buf, 0, (int)stream.Length);
  2096. string pname = ParseICCFile(buf);
  2097. if (pname != null) profileName = pname.Trim('\0');
  2098. using (MemoryStream profileStream = new MemoryStream(buf))
  2099. {
  2100. WritePDFStream(pdf, profileStream, FColorProfileStreamId, compressed, encrypted, false, true);
  2101. }
  2102. }
  2103. }
  2104. // color profile intent
  2105. colorProfileId = UpdateXRef();
  2106. WriteLn(pdf, ObjNumber(colorProfileId));
  2107. WriteLn(pdf, "<<");
  2108. WriteLn(pdf, "/Type /OutputIntent");
  2109. WriteLn(pdf, "/S /GTS_" + GTS);
  2110. WriteLn(pdf, ExportUtils.StringFormat("/OutputCondition ({0})", profileName));
  2111. WriteLn(pdf, ExportUtils.StringFormat("/OutputConditionIdentifier ({0})", profileName));
  2112. WriteLn(pdf, ExportUtils.StringFormat("/Info ({0})", profileName));
  2113. WriteLn(pdf, "/DestOutputProfile " + ObjNumberRef(FColorProfileStreamId));
  2114. WriteLn(pdf, ">>");
  2115. WriteLn(pdf, "endobj");
  2116. }
  2117. private string ParseICCFile(byte[] file)
  2118. {
  2119. using (MemoryStream profileStream = new MemoryStream(file))
  2120. {
  2121. profileStream.Position = 128;
  2122. byte[] temp = new byte[4];
  2123. profileStream.Read(temp, 0, temp.Length);
  2124. int count = temp[3];//limit to 255 tag count, for error avoid
  2125. uint offset = 0;//if 0 then error
  2126. uint size = 0;//size of desc
  2127. byte[] desc = new byte[4] { 0x64, 0x65, 0x73, 0x63 };
  2128. for (int i = 0; i < count; i++)
  2129. {
  2130. //try to find desc tag
  2131. profileStream.Read(temp, 0, temp.Length);//read signature
  2132. bool flag_eq = true;
  2133. for (int j = 0; j < temp.Length; j++)
  2134. if (temp[j] != desc[j])
  2135. flag_eq = false;
  2136. profileStream.Read(temp, 0, temp.Length);//read offset
  2137. if (flag_eq)
  2138. {
  2139. offset = (uint)(temp[0] << 24) + (uint)(temp[1] << 16) + (uint)(temp[2] << 8) + (uint)(temp[3]);
  2140. }
  2141. profileStream.Read(temp, 0, temp.Length);//read lenght
  2142. if (flag_eq)
  2143. {
  2144. size = (uint)(temp[0] << 24) + (uint)(temp[1] << 16) + (uint)(temp[2] << 8) + (uint)(temp[3]);
  2145. break;
  2146. }
  2147. }
  2148. if (offset == 0)
  2149. return null;
  2150. profileStream.Position = offset;
  2151. profileStream.Read(temp, 0, temp.Length);//read signature
  2152. for (int j = 0; j < temp.Length; j++)
  2153. if (temp[j] != desc[j])
  2154. return null;//test 2 for desc error
  2155. profileStream.Read(temp, 0, temp.Length);//read 0
  2156. profileStream.Read(temp, 0, temp.Length);//read lenght
  2157. uint len = (uint)(temp[3]);
  2158. byte[] result = new byte[len];
  2159. profileStream.Read(result, 0, result.Length);
  2160. return Encoding.ASCII.GetString(result);
  2161. }
  2162. }
  2163. private void AddMetaDataPdfA()
  2164. {
  2165. PDFMetaData pmd = new PDFMetaData();
  2166. pmd.Creator = Creator;
  2167. pmd.Description = Subject;
  2168. pmd.Keywords = Keywords;
  2169. pmd.Title = Title;
  2170. pmd.Producer = Producer;
  2171. pmd.CreateDate = digitalSignCreationDate.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz");
  2172. pmd.DocumentID = fileID;
  2173. pmd.InstanceID = fileID;
  2174. pmd.ZUGFeRD = zUGFeRDDescription;
  2175. switch (PdfCompliance)
  2176. {
  2177. default:
  2178. pmd.Part = "2";
  2179. pmd.Conformance = "A";
  2180. break;
  2181. case PdfStandard.PdfA_1a:
  2182. pmd.Part = "1";
  2183. pmd.Conformance = "A";
  2184. break;
  2185. case PdfStandard.PdfA_2b:
  2186. pmd.Part = "2";
  2187. pmd.Conformance = "B";
  2188. break;
  2189. case PdfStandard.PdfA_2u:
  2190. pmd.Part = "2";
  2191. pmd.Conformance = "U";
  2192. break;
  2193. case PdfStandard.PdfA_3a:
  2194. pmd.Part = "3";
  2195. pmd.Conformance = "A";
  2196. break;
  2197. case PdfStandard.PdfA_3b:
  2198. pmd.Part = "3";
  2199. pmd.Conformance = "B";
  2200. break;
  2201. }
  2202. if (PdfCompliance == PdfStandard.PdfA_1a)
  2203. {
  2204. Author = Creator;
  2205. }
  2206. metaFileId = UpdateXRef();
  2207. WriteLn(pdf, ObjNumber(metaFileId));
  2208. WriteLn(pdf, "<< /Type /Metadata /Subtype /XML ");
  2209. using (MemoryStream metaStream = new MemoryStream())
  2210. {
  2211. ExportUtils.WriteLn(metaStream, pmd.MetaDataString);
  2212. metaStream.Position = 0;
  2213. WritePDFStream(pdf, metaStream, metaFileId, false, encrypted, false, true);
  2214. }
  2215. }
  2216. private void AddMetaDataPdfX()
  2217. {
  2218. string metadata = null;
  2219. if (PdfCompliance == PdfStandard.PdfX_3)
  2220. metadata = "MetaDataX3";
  2221. else if (PdfCompliance == PdfStandard.PdfX_4)
  2222. metadata = "MetaDataX4";
  2223. else
  2224. throw new Exception("Error while adding metadata to PDF. Unknown PDF/X version: " + PdfCompliance.ToString());
  2225. // to pass adobe acrobat compliance test
  2226. if (PdfCompliance == PdfStandard.PdfX_4)
  2227. {
  2228. Author = Creator;
  2229. }
  2230. PDFMetaData pmd = new PDFMetaData(metadata);
  2231. pmd.Creator = Creator;
  2232. pmd.Description = Subject;
  2233. pmd.Keywords = Keywords;
  2234. pmd.Title = Title;
  2235. pmd.Producer = Producer;
  2236. pmd.CreateDate = SystemFake.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
  2237. pmd.DocumentID = fileID;
  2238. pmd.InstanceID = fileID;
  2239. // to pass adobe acrobat compliance test
  2240. if (PdfCompliance == PdfStandard.PdfX_4)
  2241. {
  2242. if (pmd.Title == null || pmd.Title.Trim() == "")
  2243. pmd.Title = "FastReport.Net";
  2244. }
  2245. metaFileId = UpdateXRef();
  2246. WriteLn(pdf, ObjNumber(metaFileId));
  2247. WriteLn(pdf, "<< /Type /Metadata /Subtype /XML ");
  2248. using (MemoryStream metaStream = new MemoryStream())
  2249. {
  2250. ExportUtils.WriteLn(metaStream, pmd.MetaDataString);
  2251. metaStream.Position = 0;
  2252. WritePDFStream(pdf, metaStream, metaFileId, false, encrypted, false, true);
  2253. }
  2254. }
  2255. #endregion
  2256. #region Protected Methods
  2257. /// <inheritdoc/>
  2258. protected override string GetFileFilter()
  2259. {
  2260. return new MyRes("FileFilters").Get("PdfFile");
  2261. }
  2262. /// <inheritdoc/>
  2263. protected override void Start()
  2264. {
  2265. base.Start();
  2266. graphics = Report.MeasureGraphics;
  2267. xRef = new List<long>();
  2268. pagesRef = new List<long>();
  2269. pagesTopMargins = new List<float>();
  2270. pagesHeights = new List<float>();
  2271. fonts = new List<ExportTTFFont>();
  2272. hashList = new Dictionary<string, long>();
  2273. pageAnnots = new StringBuilder();
  2274. annots = new List<PDFExportAnnotation>();
  2275. acroFormsRefs = new List<long>();
  2276. acroFormsFonts = new List<int>();
  2277. gradientHashSet = new Dictionary<HashableByteArray, long>();
  2278. digitalSignCreationDate = SystemFake.DateTime.UtcNow;
  2279. fileID = ExportUtils.GetID().Replace("-", "");
  2280. if (!String.IsNullOrEmpty(ownerPassword) || !String.IsNullOrEmpty(userPassword))
  2281. {
  2282. encrypted = true;
  2283. embeddingFonts = true;
  2284. PrepareKeys();
  2285. }
  2286. if (isDigitalSignEnable)
  2287. {
  2288. if (digitalSignCertificate == null && !String.IsNullOrEmpty(digitalSignCertificatePath))
  2289. {
  2290. if (String.IsNullOrEmpty(digitalSignCertificatePassword))
  2291. digitalSignCertificate = new System.Security.Cryptography.X509Certificates
  2292. .X509Certificate2(digitalSignCertificatePath);
  2293. else
  2294. digitalSignCertificate = new System.Security.Cryptography.X509Certificates
  2295. .X509Certificate2(digitalSignCertificatePath, DigitalSignCertificatePassword);
  2296. isDigitalSignatureInvisible = true;
  2297. }
  2298. if (digitalSignCertificate != null && !digitalSignCertificate.HasPrivateKey)
  2299. {
  2300. throw new InvalidOperationException("Certificate for signing is not valid, use another certificate or disable digital signature.");
  2301. }
  2302. else
  2303. {
  2304. isDigitalSignatureInvisible = true;
  2305. }
  2306. if (digitalSignCertificate == null)
  2307. {
  2308. //isDigitalSignEnable = false;
  2309. isDigitalSignatureInvisible = true;
  2310. }
  2311. }
  2312. if (useFileStream)
  2313. {
  2314. tempFileName = FileName + ".tmp";
  2315. pdf = new FileStream(tempFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
  2316. }
  2317. else
  2318. pdf = new MemoryStream();
  2319. if (Report.PreparedPages.Outline.Xml.Count == 0)
  2320. outline = false;
  2321. AddPDFHeader();
  2322. if (showPrintDialog)
  2323. {
  2324. long FPrintDictJS = UpdateXRef();
  2325. WriteLn(pdf, ObjNumber(FPrintDictJS));
  2326. WriteLn(pdf, @"<</S/JavaScript/JS(this.print\({bUI:true,bSilent:false,bShrinkToFit:true}\);)>>");
  2327. WriteLn(pdf, "endobj");
  2328. printDict = UpdateXRef();
  2329. WriteLn(pdf, ObjNumber(printDict));
  2330. WriteLn(pdf, "<</Names[(0000000000000000) " + ObjNumberRef(FPrintDictJS) + "] >>");
  2331. WriteLn(pdf, "endobj");
  2332. }
  2333. }
  2334. /*/// <inheritdoc/>
  2335. protected override void ExportPage(int pageNo)
  2336. {
  2337. using (ReportPage page = GetPage(pageNo))
  2338. {
  2339. AddPage(page);
  2340. ObjectCollection allObjects = page.AllObjects;
  2341. for (int i = 0; i < allObjects.Count; i++)
  2342. {
  2343. ReportComponentBase c = allObjects[i] as ReportComponentBase;
  2344. if (c != null)
  2345. {
  2346. c.Dispose();
  2347. c = null;
  2348. }
  2349. }
  2350. }
  2351. if (pageNo % 50 == 0)
  2352. Application.DoEvents();
  2353. }*/
  2354. /// <summary>
  2355. /// Begin exporting of page
  2356. /// </summary>
  2357. /// <param name="page"></param>
  2358. protected override void ExportPageBegin(ReportPage page)
  2359. {
  2360. if (ExportMode == ExportType.Export)
  2361. base.ExportPageBegin(page);
  2362. //reset shadings
  2363. pageShadings = new List<long>();
  2364. pageAlphaShading = new List<long>();
  2365. //end reset shadings
  2366. pageFonts = new List<ExportTTFFont>();
  2367. trasparentStroke = new List<string>();
  2368. trasparentFill = new List<string>();
  2369. picResList = new List<long>();
  2370. //FAcroFormsAnnotsRefs = new List<long>();
  2371. paperWidth = ExportUtils.GetPageWidth(page) * Units.Millimeters;
  2372. paperHeight = ExportUtils.GetPageHeight(page) * Units.Millimeters;
  2373. marginWoBottom = (ExportUtils.GetPageHeight(page) - page.TopMargin) * PDF_PAGE_DIVIDER;
  2374. marginLeft = page.LeftMargin * PDF_PAGE_DIVIDER;
  2375. pagesHeights.Add(marginWoBottom);
  2376. pagesTopMargins.Add(page.TopMargin * PDF_PAGE_DIVIDER);
  2377. contentsPos = 0;
  2378. contentBuilder = new StringBuilder(65535);
  2379. // page fill
  2380. if (background)
  2381. using (TextObject pageFill = new TextObject())
  2382. {
  2383. pageFill.Fill = page.Fill;
  2384. pageFill.Left = -marginLeft / PDF_DIVIDER;
  2385. pageFill.Top = -page.TopMargin * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  2386. pageFill.Width = ExportUtils.GetPageWidth(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  2387. pageFill.Height = ExportUtils.GetPageHeight(page) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  2388. AddTextObject(pageFill, false, contentBuilder);
  2389. }
  2390. // bitmap watermark on bottom
  2391. if (page.Watermark.Enabled && !page.Watermark.ShowImageOnTop)
  2392. AddBitmapWatermark(page, contentBuilder);
  2393. // text watermark on bottom
  2394. if (page.Watermark.Enabled && !page.Watermark.ShowTextOnTop)
  2395. AddTextWatermark(page, contentBuilder);
  2396. // page borders
  2397. if (page.Border.Lines != BorderLines.None)
  2398. {
  2399. using (TextObject pageBorder = new TextObject())
  2400. {
  2401. pageBorder.Border = page.Border;
  2402. pageBorder.Left = 0;
  2403. pageBorder.Top = 0;
  2404. pageBorder.Width = (ExportUtils.GetPageWidth(page) - page.LeftMargin - page.RightMargin) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  2405. pageBorder.Height = (ExportUtils.GetPageHeight(page) - page.TopMargin - page.BottomMargin) * PDF_PAGE_DIVIDER / PDF_DIVIDER;
  2406. AddTextObject(pageBorder, true, contentBuilder);
  2407. }
  2408. }
  2409. }
  2410. /// <summary>
  2411. /// End exporting
  2412. /// </summary>
  2413. /// <param name="page"></param>
  2414. protected override void ExportPageEnd(ReportPage page)
  2415. {
  2416. base.ExportPageEnd(page);
  2417. // bitmap watermark on top
  2418. if (page.Watermark.Enabled && page.Watermark.ShowImageOnTop)
  2419. AddBitmapWatermark(page, contentBuilder);
  2420. // text watermark on top
  2421. if (page.Watermark.Enabled && page.Watermark.ShowTextOnTop)
  2422. AddTextWatermark(page, contentBuilder);
  2423. // write page
  2424. contentsPos = UpdateXRef();
  2425. WriteLn(pdf, ObjNumber(contentsPos));
  2426. using (MemoryStream tempContentStream = new MemoryStream())
  2427. {
  2428. Write(tempContentStream, contentBuilder.ToString());
  2429. tempContentStream.Position = 0;
  2430. WritePDFStream(pdf, tempContentStream, contentsPos, compressed, encrypted, true, true);
  2431. }
  2432. if (!textInCurves)
  2433. {
  2434. if (pageFonts.Count > 0)
  2435. for (int i = 0; i < pageFonts.Count; i++)
  2436. if (!pageFonts[i].Saved)
  2437. {
  2438. pageFonts[i].Reference = UpdateXRef();
  2439. pageFonts[i].Saved = true;
  2440. }
  2441. for (int i = 0; i < acroFormsFonts.Count; i++)
  2442. {
  2443. if (!fonts[acroFormsFonts[i]].Saved)
  2444. {
  2445. fonts[acroFormsFonts[i]].Reference = UpdateXRef();
  2446. fonts[acroFormsFonts[i]].Saved = true;
  2447. }
  2448. }
  2449. }
  2450. long PageNumber = UpdateXRef();
  2451. if (isDigitalSignEnable && pagesRef.Count == Report.PreparedPages.Count - 1 && isDigitalSignatureInvisible)
  2452. {
  2453. signatureDictIndicies = AddSignatureDict(null);
  2454. UpdateXRef(PageNumber);
  2455. }
  2456. pagesRef.Add(PageNumber);
  2457. WriteLn(pdf, ObjNumber(PageNumber));
  2458. StringBuilder sb = new StringBuilder(512);
  2459. sb.AppendLine("<<").AppendLine("/Type /Page");
  2460. sb.Append("/MediaBox [0 0 ").Append(FloatToString(ExportUtils.GetPageWidth(page) * PDF_PAGE_DIVIDER)).Append(" ");
  2461. sb.Append(FloatToString(ExportUtils.GetPageHeight(page) * PDF_PAGE_DIVIDER)).AppendLine(" ]");
  2462. //margins
  2463. if (isPdfX())
  2464. sb.Append("/TrimBox [")
  2465. .Append(FloatToString(page.LeftMargin * PDF_PAGE_DIVIDER)).Append(" ")
  2466. .Append(FloatToString(page.TopMargin * PDF_PAGE_DIVIDER)).Append(" ")
  2467. .Append(FloatToString(page.RightMargin * PDF_PAGE_DIVIDER)).Append(" ")
  2468. .Append(FloatToString(page.BottomMargin * PDF_PAGE_DIVIDER)).Append("]");
  2469. sb.AppendLine("/Parent 1 0 R");
  2470. if (!isPdfX() && (PdfCompliance != PdfStandard.PdfA_1a))
  2471. {
  2472. if (ColorSpace == PdfColorSpace.RGB)
  2473. sb.AppendLine("/Group << /Type /Group /S /Transparency /CS /DeviceRGB >>");
  2474. else if (ColorSpace == PdfColorSpace.CMYK)
  2475. sb.AppendLine("/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >>");
  2476. }
  2477. sb.AppendLine("/Resources << ");
  2478. if (pageFonts.Count > 0)
  2479. {
  2480. sb.Append("/Font << ");
  2481. foreach (ExportTTFFont font in pageFonts)
  2482. sb.Append(font.Name).Append(" ").Append(ObjNumberRef(font.Reference)).Append(" ");
  2483. sb.AppendLine(" >>");
  2484. }
  2485. if (pageShadings != null && pageShadings.Count > 0)
  2486. {
  2487. sb.Append("/Shading <<");
  2488. for (int i = 0; i < pageShadings.Count; i++)
  2489. sb.Append(" /sh").Append(i + 1).Append(" ").Append(ObjNumberRef(pageShadings[i]));
  2490. //sb.Append(FPageShadings);
  2491. sb.Append(" >>");
  2492. }
  2493. sb.AppendLine("/ExtGState <<");
  2494. for (int i = 0; i < trasparentStroke.Count; i++)
  2495. sb.Append("/GS").Append(i.ToString()).Append("S << /Type /ExtGState /ca ").Append(trasparentStroke[i]).AppendLine(" >>");
  2496. for (int i = 0; i < trasparentFill.Count; i++)
  2497. sb.Append("/GS").Append(i.ToString()).Append("F << /Type /ExtGState /CA ").Append(trasparentFill[i]).AppendLine(" >>");
  2498. for (int i = 0; i < pageAlphaShading.Count; i++)
  2499. {
  2500. if (isPdfX())
  2501. {
  2502. // /s6 << /ca 1 /Type /ExtGState /AIS false /SMask << /Type /Mask /G << >> /S /Luminosity >> /CA 1 >>
  2503. sb.Append("/s").Append(i + 1).AppendLine(" << /ca 1 /Type /ExtGState /CA 1 >>");
  2504. }
  2505. else
  2506. {
  2507. // /s6 << /ca 1 /Type /ExtGState /AIS false /SMask << /Type /Mask /G << >> /S /Luminosity >> /CA 1 >>
  2508. sb.Append("/s").Append(i + 1).Append(" << /ca 1 /Type /ExtGState /AIS false /SMask << /Type /Mask /G ")
  2509. .Append(ObjNumberRef(pageAlphaShading[i])).AppendLine(" /S /Luminosity >> /CA 1 >>");
  2510. }
  2511. }
  2512. sb.AppendLine(">>");
  2513. if (picResList.Count > 0)
  2514. {
  2515. sb.Append("/XObject << ");
  2516. foreach (long resIndex in picResList)
  2517. sb.Append("/Im").Append(resIndex.ToString()).Append(" ").Append(ObjNumberRef(resIndex)).Append(" ");
  2518. sb.AppendLine(" >>");
  2519. }
  2520. sb.AppendLine("/ProcSet [/PDF /Text /ImageC ]");
  2521. sb.AppendLine(">>");
  2522. sb.Append("/Contents ").AppendLine(ObjNumberRef(contentsPos));
  2523. if (pageAnnots.Length > 0)
  2524. {
  2525. sb.AppendLine(GetPageAnnots());
  2526. pageAnnots.Length = 0;
  2527. }
  2528. sb.AppendLine(">>");
  2529. sb.AppendLine("endobj");
  2530. Write(pdf, sb.ToString());
  2531. }
  2532. /// <summary>
  2533. /// Export of Band
  2534. /// </summary>
  2535. /// <param name="band"></param>
  2536. protected override void ExportBand(BandBase band)
  2537. {
  2538. if (ExportMode == ExportType.Export)
  2539. base.ExportBand(band);
  2540. ExportObj(band);
  2541. foreach (Base c in band.ForEachAllConvectedObjects(this))
  2542. {
  2543. ExportObj(c);
  2544. }
  2545. }
  2546. private void ExportObj(Base c)
  2547. {
  2548. if (c is ReportComponentBase && (c as ReportComponentBase).Exportable)
  2549. {
  2550. ReportComponentBase obj = c as ReportComponentBase;
  2551. if (obj is CellularTextObject)
  2552. obj = (obj as CellularTextObject).GetTable();
  2553. if (obj is TableCell)
  2554. return;
  2555. #if DOTNET_4
  2556. else if (PDFExportV4(obj)) { }
  2557. #endif
  2558. else
  2559. if (obj is TableBase)
  2560. {
  2561. //using (TableBase table = obj as TableBase)
  2562. {
  2563. if ((obj as TableBase).ColumnCount > 0 && (obj as TableBase).RowCount > 0)
  2564. {
  2565. StringBuilder tableBorder = new StringBuilder(64);
  2566. using (TextObject tableback = new TextObject())
  2567. {
  2568. tableback.Border = (obj as TableBase).Border;
  2569. tableback.Fill = (obj as TableBase).Fill;
  2570. tableback.FillColor = (obj as TableBase).FillColor;
  2571. tableback.Left = (obj as TableBase).AbsLeft;
  2572. tableback.Top = (obj as TableBase).AbsTop;
  2573. float tableWidth = 0;
  2574. float tableHeight = 0;
  2575. for (int i = 0; i < (obj as TableBase).ColumnCount; i++)
  2576. tableWidth += (obj as TableBase).Columns[i].Width;// table[i, 0].Width;
  2577. for (int i = 0; i < (obj as TableBase).RowCount; i++)
  2578. tableHeight += (obj as TableBase).Rows[i].Height;
  2579. tableback.Width = tableWidth;// (tableWidth < table.Width) ? tableWidth : table.Width;
  2580. tableback.Height = tableHeight;
  2581. AddTextObject(tableback, false, contentBuilder);
  2582. DrawPDFBorder(tableback.Border, tableback.AbsLeft, tableback.AbsTop, tableback.Width, tableback.Height, tableBorder);
  2583. }
  2584. // draw cells
  2585. AddTable((obj as TableBase), true, contentBuilder);
  2586. // draw cells border
  2587. AddTable((obj as TableBase), false, contentBuilder);
  2588. // draw table border
  2589. contentBuilder.Append(tableBorder);
  2590. }
  2591. }
  2592. }
  2593. else if (obj is TextObject)
  2594. AddTextObject(obj as TextObject, true, contentBuilder);
  2595. else if (obj is BandBase)
  2596. AddBandObject(obj as BandBase, contentBuilder);
  2597. else if (obj is LineObject)
  2598. AddLine(obj as LineObject, contentBuilder);
  2599. else if (obj is ShapeObject)
  2600. AddShape(obj as ShapeObject, contentBuilder);
  2601. else if (obj is RichObject)
  2602. AddPictureObject(obj, true, richTextQuality, contentBuilder);
  2603. else if (obj is PolyLineObject)
  2604. AddPDFPolylineVector(obj as PolyLineObject, contentBuilder);
  2605. //AddPolyLine(obj as PolyLineObject, contentBuilder);
  2606. else if (obj is CheckBoxObject && (obj as CheckBoxObject).Editable && InteractiveForms)
  2607. AddCheckBoxField(obj as CheckBoxObject);
  2608. else if (!(obj is HtmlObject))
  2609. AddPictureObject(obj, true, jpegQuality, contentBuilder);
  2610. if (obj is DigitalSignatureObject && isDigitalSignEnable)
  2611. {
  2612. AddSignatureDict(obj);
  2613. if (digitalSignCertificate == null)
  2614. {
  2615. isDigitalSignatureInvisible = false;
  2616. }
  2617. }
  2618. }
  2619. }
  2620. /// <inheritdoc/>
  2621. protected override void Finish()
  2622. {
  2623. AddPDFFooter();
  2624. for (int i = fonts.Count - 1; i >= 0; i--)
  2625. fonts[i].Dispose();
  2626. if (useFileStream)
  2627. {
  2628. pdf.Close();
  2629. if (File.Exists(FileName))
  2630. {
  2631. Stream.Close();
  2632. File.Delete(FileName);
  2633. File.Move(tempFileName, FileName);
  2634. }
  2635. else
  2636. File.Delete(tempFileName);
  2637. }
  2638. else
  2639. ((MemoryStream)pdf).WriteTo(Stream);
  2640. }
  2641. #endregion
  2642. #region Public Methods
  2643. /// <inheritdoc/>
  2644. public override void Serialize(FRWriter writer)
  2645. {
  2646. base.Serialize(writer);
  2647. // Options
  2648. writer.WriteValue("PdfCompliance", PdfCompliance);
  2649. writer.WriteBool("EmbeddingFonts", EmbeddingFonts);
  2650. writer.WriteBool("Background", Background);
  2651. writer.WriteBool("TextInCurves", TextInCurves);
  2652. writer.WriteValue("ColorSpace", ColorSpace);
  2653. writer.WriteBool("ImagesOriginalResolution", ImagesOriginalResolution);
  2654. writer.WriteBool("PrintOptimized", PrintOptimized);
  2655. writer.WriteBool("JpegCompression", JpegCompression);
  2656. writer.WriteInt("JpegQuality", JpegQuality);
  2657. writer.WriteBool("InteractiveForms", InteractiveForms);
  2658. // end
  2659. // Document Information
  2660. writer.WriteStr("Title", Title);
  2661. writer.WriteStr("Author", Author);
  2662. writer.WriteStr("Subject", Subject);
  2663. writer.WriteStr("Keywords", Keywords);
  2664. writer.WriteStr("Creator", Creator);
  2665. writer.WriteStr("Producer", Producer);
  2666. // end
  2667. // Security
  2668. writer.WriteBool("AllowPrint", AllowPrint);
  2669. writer.WriteBool("AllowModify", AllowModify);
  2670. writer.WriteBool("AllowCopy", AllowCopy);
  2671. writer.WriteBool("AllowAnnotate", AllowAnnotate);
  2672. // end
  2673. // Viewer
  2674. writer.WriteBool("AutoPrint", ShowPrintDialog);
  2675. writer.WriteBool("HideToolbar", HideToolbar);
  2676. writer.WriteBool("HideMenubar", HideMenubar);
  2677. writer.WriteBool("HideWindowUI", HideWindowUI);
  2678. writer.WriteBool("FitWindow", FitWindow);
  2679. writer.WriteBool("CenterWindow", CenterWindow);
  2680. writer.WriteBool("PrintScaling", PrintScaling);
  2681. writer.WriteBool("Outline", Outline);
  2682. writer.WriteValue("DefaultZoom", DefaultZoom);
  2683. // end
  2684. // Curves
  2685. writer.WriteValue("GradientInterpolationPoints", GradientInterpolationPoints);
  2686. writer.WriteValue("GradientQuality", GradientQuality);
  2687. writer.WriteValue("CurvesInterpolation", CurvesInterpolation);
  2688. writer.WriteValue("CurvesInterpolationText", CurvesInterpolationText);
  2689. writer.WriteBool("SvgAsPicture", SvgAsPicture);
  2690. writer.WriteBool("SaveDigitalSignCertificatePassword", SaveDigitalSignCertificatePassword);
  2691. writer.WriteBool("IsDigitalSignEnable", IsDigitalSignEnable);
  2692. writer.WriteValue("DigitalSignCertificatePath", DigitalSignCertificatePath);
  2693. writer.WriteValue("DigitalSignLocation", DigitalSignLocation);
  2694. writer.WriteValue("DigitalSignContactInfo", DigitalSignContactInfo);
  2695. writer.WriteValue("DigitalSignReason", DigitalSignReason);
  2696. if (SaveDigitalSignCertificatePassword)
  2697. {
  2698. writer.WriteValue("DigitalSignCertificatePassword", digitalSignCertificatePassword);
  2699. }
  2700. else
  2701. {
  2702. writer.WriteValue("DigitalSignCertificatePassword", null);
  2703. }
  2704. // end
  2705. }
  2706. /// <summary>
  2707. /// Add an embedded XML file (only for PDF/A-3 standard).
  2708. /// </summary>
  2709. /// <param name="name">File name</param>
  2710. /// <param name="description">Description</param>
  2711. /// <param name="modDate">Modification date</param>
  2712. /// <param name="fileStream">File stream</param>
  2713. public void AddEmbeddedXML(string name, string description, DateTime modDate, Stream fileStream)
  2714. {
  2715. AddEmbeddedXML(name, description, modDate, fileStream, ZUGFeRD_ConformanceLevel.BASIC);
  2716. }
  2717. /// <summary>
  2718. /// Add an embedded XML file (only for PDF/A-3 standard).
  2719. /// </summary>
  2720. /// <param name="name">File name</param>
  2721. /// <param name="description">Description</param>
  2722. /// <param name="modDate">Modification date</param>
  2723. /// <param name="fileStream">File stream</param>
  2724. /// <param name="ZUGFeRDLevel">ZUGFeRD Conformance Level</param>
  2725. public void AddEmbeddedXML(string name, string description, DateTime modDate, Stream fileStream, ZUGFeRD_ConformanceLevel ZUGFeRDLevel)
  2726. {
  2727. zUGFeRDDescription = ExportUtils.StringFormat("<rdf:Description xmlns:zf=\"urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#\" rdf:about=\"\" zf:ConformanceLevel=\"{0}\" zf:DocumentFileName=\"{1}\" zf:DocumentType=\"INVOICE\" zf:Version=\"1.0\"/>", ZUGFeRDLevel.ToString(), name);
  2728. AddEmbeddedFile(name, description, modDate, EmbeddedRelation.Alternative, "text/xml", fileStream);
  2729. }
  2730. /// <summary>
  2731. /// Add an embedded file (only for PDF/A-3 standard).
  2732. /// </summary>
  2733. /// <param name="name">File name</param>
  2734. /// <param name="description">Description</param>
  2735. /// <param name="modDate">Modification date</param>
  2736. /// <param name="relation">Relation type</param>
  2737. /// <param name="mime">MIME type</param>
  2738. /// <param name="fileStream">File stream</param>
  2739. public void AddEmbeddedFile(string name, string description, DateTime modDate, EmbeddedRelation relation, string mime, Stream fileStream)
  2740. {
  2741. EmbeddedFile file = new EmbeddedFile();
  2742. file.Name = name;
  2743. file.Description = description;
  2744. file.ModDate = modDate;
  2745. file.Relation = relation;
  2746. file.MIME = mime;
  2747. file.FileStream = fileStream;
  2748. embeddedFiles.Add(file);
  2749. }
  2750. #endregion
  2751. #region Constructors
  2752. /// <summary>
  2753. /// Initializes a new instance of the <see cref="PDFExport"/> class.
  2754. /// </summary>
  2755. public PDFExport()
  2756. {
  2757. embeddedFiles = new List<EmbeddedFile>();
  2758. exportMode = ExportType.Export;
  2759. embeddingFonts = true;
  2760. useFileStream = false;
  2761. }
  2762. #endregion
  2763. }
  2764. }