Rich2ReportObject.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. using FastReport.Table;
  2. using FastReport.Utils;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. namespace FastReport.RichTextParser
  9. {
  10. class RichText2ReportObject : IDisposable
  11. {
  12. static int DpiX = 96;
  13. Font default_font = new Font(FontFamily.GenericSerif, 12, FontStyle.Regular);
  14. RunFormat current_format;
  15. bool usePadding = false; // Control page margins
  16. private static int Twips2Pixels(int twips)
  17. {
  18. return (int)(((double)twips) * (1.0 / 1440.0) * DpiX);
  19. }
  20. public void Dispose()
  21. {
  22. }
  23. private string GetRawText(Paragraph paragraph)
  24. {
  25. StringBuilder sb = new StringBuilder();
  26. foreach (Run run in paragraph.runs)
  27. sb.Append(run.text);
  28. return sb.ToString();
  29. }
  30. private void GetHTMLText(FastReport.RichObject rich, ref TextObject clone, RichDocument rtf, int position, Paragraph paragraph)
  31. {
  32. int run_num = 0;
  33. bool span_condition = false;
  34. StringBuilder sb = new StringBuilder();
  35. RunFormat format;
  36. string colorname = String.Empty;
  37. string fontname = String.Empty;
  38. string fontsize = String.Empty;
  39. string backcolor = String.Empty;
  40. string URL = String.Empty;
  41. Font current_font = clone.Font;
  42. int len;
  43. foreach (Run run in paragraph.runs)
  44. {
  45. if(run.text.StartsWith("HYPERLINK "))
  46. {
  47. URL = run.text.Substring(9);
  48. continue;
  49. }
  50. len = run.text != "\r" ? run.text.Length : 1;
  51. if (rich.ActualTextStart != 0 && position + len <= rich.ActualTextStart)
  52. {
  53. position += len;
  54. continue;
  55. }
  56. format = run.format;
  57. if (run_num == 0)
  58. {
  59. current_format = run.format;
  60. clone.Font = GetFontFromRichStyle(rtf, current_format);
  61. current_font = clone.Font;
  62. clone.TextColor = current_format.color;
  63. if (format.underline)
  64. {
  65. sb.Append("<u>");
  66. current_format.underline = true;
  67. }
  68. if (format.bold)
  69. {
  70. sb.Append("<b>");
  71. current_format.bold = true;
  72. }
  73. if (format.italic)
  74. {
  75. sb.Append("<i>");
  76. current_format.italic = true;
  77. }
  78. if(format.strike)
  79. {
  80. sb.Append("<strike>");
  81. current_format.strike = true;
  82. }
  83. if (current_format.BColor != null)
  84. {
  85. if (current_format.BColor != Color.White && current_format.BColor != Color.Empty)
  86. backcolor = string.Format("background-color:#{0:X2}{1:X2}{2:X2}", format.BColor.R, format.BColor.G, format.BColor.B);
  87. }
  88. if (backcolor.Length > 0)
  89. {
  90. sb.Append("<span style=\"");
  91. sb.Append(backcolor);
  92. sb.Append("\">");
  93. span_condition = true;
  94. }
  95. }
  96. else
  97. {
  98. if (current_format.underline != format.underline && !format.underline)
  99. {
  100. sb.Append("</u>");
  101. current_format.underline = format.underline;
  102. }
  103. if (current_format.italic != format.italic && !format.italic)
  104. {
  105. sb.Append("</i>");
  106. current_format.italic = format.italic;
  107. }
  108. if (current_format.bold != format.bold && !format.bold)
  109. {
  110. sb.Append("</b>");
  111. current_format.bold = format.bold;
  112. }
  113. if(current_format.strike != format.strike && ! format.strike)
  114. {
  115. sb.Append("</strike>");
  116. current_format.strike = format.strike;
  117. }
  118. if (current_format.strike != format.strike && format.strike)
  119. {
  120. sb.Append("<strike>");
  121. current_format.strike = format.strike;
  122. }
  123. if (current_format.bold != format.bold && format.bold)
  124. {
  125. sb.Append("<b>");
  126. current_format.bold = format.bold;
  127. }
  128. if (current_format.italic != format.italic && format.italic)
  129. {
  130. sb.Append("<i>");
  131. current_format.italic = format.italic;
  132. }
  133. if (current_format.underline != format.underline && format.underline)
  134. {
  135. sb.Append("<u>");
  136. current_format.underline = format.underline;
  137. }
  138. if (current_format.script_type != format.script_type)
  139. {
  140. if (format.script_type == RunFormat.ScriptType.Subscript)
  141. sb.Append("<sub>");
  142. else if (format.script_type == RunFormat.ScriptType.Superscript)
  143. sb.Append("<sup>");
  144. else if (current_format.script_type == RunFormat.ScriptType.Subscript)
  145. sb.Append("</sub>");
  146. else if (current_format.script_type == RunFormat.ScriptType.Superscript)
  147. sb.Append("</sup>");
  148. current_format.script_type = format.script_type;
  149. }
  150. if (current_format.color != format.color)
  151. {
  152. colorname = string.Format("color:#{0:X2}{1:X2}{2:X2};", format.color.R, format.color.G, format.color.B);
  153. current_format.color = format.color;
  154. }
  155. if (current_format.BColor != format.BColor && format.BColor != Color.Empty)
  156. {
  157. backcolor = string.Format("background-color:#{0:X2}{1:X2}{2:X2}", format.BColor.R, format.BColor.G, format.BColor.B);
  158. #if IGNORE_SPAN
  159. current_format.BColor = format.BColor;
  160. #endif
  161. }
  162. if (current_format.font_size != format.font_size)
  163. {
  164. int fs = run.format.font_size / 2;
  165. fontsize = string.Format("font-size:{0}pt;", fs);
  166. //#ifIGNORE_SPAN
  167. current_format.font_size = format.font_size;
  168. //#endif
  169. }
  170. Font fnt = GetFontFromRichStyle(rtf, format);
  171. if (!current_font.FontFamily.Equals(fnt.FontFamily))
  172. {
  173. fontname = string.Format("font-family:{0};", fnt.FontFamily.Name);
  174. #if IGNORE_SPAN
  175. current_font = fnt;
  176. #endif
  177. }
  178. else
  179. fontname = string.Empty;
  180. if (colorname.Length > 0 || fontsize.Length > 0 || fontname.Length > 0 || backcolor.Length > 0)
  181. {
  182. sb.Append("<span style=\"");
  183. if (colorname.Length > 0)
  184. sb.Append(colorname);
  185. if (fontsize.Length > 0)
  186. sb.Append(fontsize);
  187. if (fontname.Length > 0)
  188. sb.Append(fontname);
  189. if (backcolor.Length > 0)
  190. sb.Append(backcolor);
  191. sb.Append("\">");
  192. span_condition = true;
  193. }
  194. }
  195. if (run.text != "\r")
  196. sb.Append(run.text);
  197. else if( run_num != 0 && run_num + 1 < paragraph.runs.Count)
  198. sb.Append("<br>");
  199. position += len;
  200. if (rich.ActualTextLength != 0 && position >= rich.ActualTextStart + rich.ActualTextLength)
  201. break;
  202. if (span_condition)
  203. {
  204. sb.Append("</span>");
  205. span_condition = false;
  206. }
  207. URL = String.Empty;
  208. run_num++;
  209. }
  210. clone.Text = sb.ToString();
  211. }
  212. private FastReport.BorderLine TranslateBorderLine(BorderLine rtf_border_line)
  213. {
  214. FastReport.BorderLine border_line = new FastReport.BorderLine();
  215. switch (rtf_border_line.style)
  216. {
  217. case BorderLine.Style.Thin:
  218. border_line.Style = LineStyle.Solid;
  219. break;
  220. case BorderLine.Style.Thick:
  221. border_line.Style = LineStyle.Solid;
  222. break;
  223. case BorderLine.Style.Double:
  224. border_line.Style = LineStyle.Double;
  225. break;
  226. case BorderLine.Style.Dotted:
  227. border_line.Style = LineStyle.Dot;
  228. break;
  229. default:
  230. border_line.Style = LineStyle.Solid;
  231. break;
  232. }
  233. border_line.Color = rtf_border_line.color;
  234. border_line.Width = Twips2Pixels((int)rtf_border_line.width);
  235. return border_line;
  236. }
  237. private FastReport.Border TranslateBorders(Column rtf_column)
  238. {
  239. FastReport.Border border = new Border();
  240. border.Lines = BorderLines.None;
  241. if (rtf_column.border_top.width > 0)
  242. {
  243. border.TopLine = TranslateBorderLine(rtf_column.border_top);
  244. border.Lines |= BorderLines.Top;
  245. }
  246. if (rtf_column.border_right.width > 0)
  247. {
  248. border.RightLine = TranslateBorderLine(rtf_column.border_right);
  249. border.Lines |= BorderLines.Right;
  250. }
  251. if (rtf_column.border_left.width > 0)
  252. {
  253. border.LeftLine = TranslateBorderLine(rtf_column.border_left);
  254. border.Lines |= BorderLines.Left;
  255. }
  256. if (rtf_column.border_bottom.width > 0)
  257. {
  258. border.BottomLine = TranslateBorderLine(rtf_column.border_bottom);
  259. border.Lines |= BorderLines.Bottom;
  260. }
  261. return border;
  262. }
  263. private Font GetFontFromRichStyle(RichDocument rtf, RunFormat format)
  264. {
  265. int font_idx = (int)format.font_idx;
  266. if (font_idx < rtf.font_list.Count)
  267. {
  268. RFont rf = rtf.font_list[font_idx];
  269. string Name = rf.FontName;
  270. #if false // Broke PDF export
  271. FontStyle style = format.bold ? FontStyle.Bold : FontStyle.Regular;
  272. #else
  273. FontStyle style = FontStyle.Regular;
  274. #endif
  275. return new Font(rf.FontName, format.font_size / 2, style);
  276. }
  277. else
  278. return default_font;
  279. }
  280. internal TextObject Paragraph2ReportObjects(FastReport.RichObject rich, RichDocument rtf, int position, Paragraph paragraph)
  281. {
  282. TextObject clone = new TextObject();
  283. clone.TextRenderType = TextRenderType.HtmlParagraph;
  284. clone.CanShrink = rich.CanShrink;
  285. clone.CanGrow = rich.CanGrow;
  286. clone.CanBreak = rich.CanBreak;
  287. clone.Left = 0; // Will set in another place
  288. clone.GrowToBottom = false; // Can't be set here;
  289. clone.ClientSize = rich.ClientSize;
  290. clone.TextColor = Color.Black;
  291. clone.FirstTabOffset = 48;
  292. clone.TabWidth = 48;
  293. clone.Bookmark = rich.Bookmark;
  294. clone.Hyperlink = rich.Hyperlink;
  295. clone.FillColor = rich.FillColor;
  296. if (paragraph.runs.Count > 0)
  297. {
  298. if(paragraph.format.tab_positions != null)
  299. {
  300. int count = paragraph.format.tab_positions.Count;
  301. if (count > 0)
  302. clone.FirstTabOffset = Twips2Pixels(paragraph.format.tab_positions[0]);
  303. if(count > 1)
  304. clone.TabWidth = Twips2Pixels(paragraph.format.tab_positions[1]) - clone.FirstTabOffset;
  305. if (count > 2)
  306. for(int i = 1; i < paragraph.format.tab_positions.Count; i++)
  307. clone.TabPositions.Add(Twips2Pixels(paragraph.format.tab_positions[i]) - Twips2Pixels(paragraph.format.tab_positions[i -1]));
  308. }
  309. GetHTMLText(rich, ref clone, rtf, position, paragraph);
  310. }
  311. else
  312. clone.Font = default_font;
  313. switch (paragraph.format.align)
  314. {
  315. case ParagraphFormat.HorizontalAlign.Right:
  316. clone.HorzAlign = HorzAlign.Right;
  317. break;
  318. case ParagraphFormat.HorizontalAlign.Centered:
  319. clone.HorzAlign = HorzAlign.Center;
  320. break;
  321. case ParagraphFormat.HorizontalAlign.Justified:
  322. clone.HorzAlign = HorzAlign.Justify;
  323. break;
  324. default:
  325. clone.HorzAlign = HorzAlign.Left;
  326. break;
  327. }
  328. switch (paragraph.format.Valign)
  329. {
  330. case ParagraphFormat.VerticalAlign.Top:
  331. clone.VertAlign = VertAlign.Top;
  332. break;
  333. case ParagraphFormat.VerticalAlign.Center:
  334. clone.VertAlign = VertAlign.Center;
  335. break;
  336. case ParagraphFormat.VerticalAlign.Bottom:
  337. clone.VertAlign = VertAlign.Bottom;
  338. break;
  339. default:
  340. clone.VertAlign = VertAlign.Top;
  341. break;
  342. }
  343. clone.Border.Lines = BorderLines.None;
  344. int lineheight = paragraph.format.line_spacing;
  345. if (lineheight == 0)
  346. clone.LineHeight = (float)Math.Ceiling(clone.Font.Height * DrawUtils.ScreenDpiFX);
  347. else
  348. {
  349. switch (paragraph.format.lnspcmult)
  350. {
  351. case ParagraphFormat.LnSpcMult.Exactly:
  352. lineheight = Twips2Pixels(lineheight);
  353. break;
  354. case ParagraphFormat.LnSpcMult.Multiply:
  355. lineheight = (int)(lineheight / 240f);
  356. break;
  357. }
  358. lineheight = lineheight < 0 ? -lineheight : lineheight >= clone.Font.Height ? lineheight : clone.Font.Height;
  359. clone.ParagraphFormat.LineSpacingType = LineSpacingType.Exactly;
  360. clone.ParagraphFormat.LineSpacing = (lineheight)/* * DrawUtils.ScreenDpiFX */;
  361. clone.LineHeight = lineheight;
  362. }
  363. clone.Padding = new Padding(rich.Padding.Left, 0, rich.Padding.Right, 0);
  364. clone.SetReport(rich.Report);
  365. return clone;
  366. }
  367. internal TableObject Table2ReportObjects(FastReport.RichObject rich, RichDocument rtf, Table rtf_table)
  368. {
  369. TableObject table = new TableObject();
  370. int idx = 0;
  371. uint prev_width = 0;
  372. IList<TranslationPropeties> row_properties = new List<TranslationPropeties>();
  373. foreach (Column rtf_column in rtf_table.columns)
  374. {
  375. TableColumn column = new TableColumn();
  376. column.Width = Twips2Pixels((int)(rtf_column.Width - prev_width));
  377. prev_width = rtf_column.Width;
  378. column.SetIndex(idx);
  379. TranslationPropeties prop = new TranslationPropeties(
  380. TranslateBorders(rtf_column),
  381. rtf_column.back_color);
  382. row_properties.Add(prop);
  383. table.Columns.Add(column);
  384. idx++;
  385. }
  386. foreach (TableRow rtf_row in rtf_table.rows)
  387. {
  388. int height = rtf_row.height;
  389. if (height < 0)
  390. height = -height;
  391. FastReport.Table.TableRow row = new FastReport.Table.TableRow();
  392. int cell_idx = 0;
  393. float x_pos = 0;
  394. foreach (RichObjectSequence sequence in rtf_row.cells)
  395. {
  396. float top = 0;
  397. TableColumn rtf_column = table.Columns[cell_idx];
  398. TableCell cell = new TableCell();
  399. TranslationPropeties prop = row_properties[cell_idx];
  400. cell.Border = prop.border;
  401. cell.FillColor = prop.background_color;
  402. foreach (RichObject obj in sequence.objects)
  403. {
  404. switch (obj.type)
  405. {
  406. case RichObject.Type.Paragraph:
  407. TextObject text_paragraph = Paragraph2ReportObjects(rich, rtf, 0, obj.pargraph); // TODO: Fix "pos" argument
  408. text_paragraph.Width = rtf_column.Width;
  409. Padding p = text_paragraph.Padding;
  410. p.Top = Twips2Pixels((int)obj.pargraph.format.space_before);
  411. p.Bottom = Twips2Pixels((int)obj.pargraph.format.space_after);
  412. p.Left = Twips2Pixels((int)obj.pargraph.format.left_indent);
  413. p.Right = Twips2Pixels((int)obj.pargraph.format.right_indent);
  414. if (p.Left == 0)
  415. p.Left = 3;
  416. text_paragraph.Padding = p;
  417. if (obj.pargraph.runs.Count > 0)
  418. text_paragraph.Height = text_paragraph.CalcHeight() + 3.0f;
  419. else
  420. text_paragraph.Height = height;
  421. text_paragraph.Top = top;
  422. top += text_paragraph.Height;
  423. text_paragraph.Parent = cell;
  424. break;
  425. case RichObject.Type.Picture:
  426. PictureObject picture = Picture2ReportObject(rtf, obj.picture);
  427. picture.Top = top;
  428. top += picture.Height;
  429. picture.Parent = cell;
  430. break;
  431. case RichObject.Type.Table:
  432. TableObject subtable = Table2ReportObjects(rich, rtf, obj.table);
  433. subtable.Top = top;
  434. top += subtable.Height;
  435. table.Parent = cell;
  436. break;
  437. }
  438. cell.Left = x_pos;
  439. cell.Height = top; // height;
  440. }
  441. row.Height = (row.Height > cell.Height) ? row.Height : cell.Height;
  442. row.AddChild(cell);
  443. x_pos += rtf_column.Width;
  444. cell_idx++;
  445. }
  446. table.Rows.Add(row);
  447. table.Height += row.Height;
  448. }
  449. return table;
  450. }
  451. internal PictureObject Picture2ReportObject(RichDocument rtf, Picture rtf_picture)
  452. {
  453. PictureObject picture = new PictureObject();
  454. picture.Image = rtf_picture.image;
  455. if (rtf_picture.desired_width != 0)
  456. {
  457. if (rtf_picture.scalex == 0)
  458. picture.Width = Twips2Pixels(rtf_picture.desired_width);
  459. else
  460. picture.Width = Twips2Pixels(rtf_picture.desired_width * rtf_picture.scalex / 100);
  461. }
  462. else
  463. picture.Width = Twips2Pixels(rtf_picture.width);
  464. if (rtf_picture.desired_height != 0)
  465. {
  466. if (rtf_picture.scaley != 0)
  467. picture.Height = Twips2Pixels(rtf_picture.desired_height);
  468. else
  469. picture.Height = Twips2Pixels(rtf_picture.desired_height * rtf_picture.scaley / 100);
  470. }
  471. else
  472. picture.Height = Twips2Pixels(rtf_picture.height);
  473. return picture;
  474. }
  475. internal List<ComponentBase> Page2ReportObjects(FastReport.RichObject rich, RichDocument rtf, Page page, int start_text_index, out float page_height)
  476. {
  477. int object_counter = 0;
  478. page_height = 0;
  479. int empty_paragraph_height = 0;
  480. float object_vertical_position = rich.Padding.Top; // Twips2Pixels(page.margin_top); //
  481. List<ComponentBase> clone_list = new List<ComponentBase>();
  482. foreach (RichObject obj in page.sequence.objects)
  483. {
  484. TextObject left_label = null;
  485. if (rich.ActualTextStart != 0 && start_text_index + obj.size <= rich.ActualTextStart)
  486. {
  487. start_text_index += (int) obj.size;
  488. continue;
  489. }
  490. bool backindent = false;
  491. switch (obj.type)
  492. {
  493. case RichObject.Type.Paragraph:
  494. if (obj.pargraph.runs.Count == 0)
  495. {
  496. start_text_index++; // TODO: Check position increment size
  497. ParagraphFormat format = obj.pargraph.format;
  498. int lnspc;
  499. int line_height = 17; // Not calculated yet
  500. if (format.lnspcmult == ParagraphFormat.LnSpcMult.Multiply)
  501. lnspc = (int)(format.line_spacing / 240f);
  502. else
  503. lnspc = Twips2Pixels(format.line_spacing);
  504. empty_paragraph_height = lnspc < 0 ? -lnspc : lnspc >= line_height ? lnspc : line_height;
  505. empty_paragraph_height += Twips2Pixels(format.space_before + format.space_after);
  506. object_vertical_position += empty_paragraph_height;
  507. TextObject empty_paragraph = Paragraph2ReportObjects(rich, rtf, start_text_index, obj.pargraph);
  508. empty_paragraph.Top = object_vertical_position;
  509. empty_paragraph.Height = empty_paragraph_height;
  510. ++object_counter;
  511. clone_list.Add(empty_paragraph);
  512. continue;
  513. }
  514. empty_paragraph_height = 0;
  515. TextObject list_label = null; ;
  516. if (obj.pargraph.format.list_id != null && obj.pargraph.format.list_id.Count != 0)
  517. {
  518. ++object_counter;
  519. list_label = new TextObject();
  520. Run run = obj.pargraph.format.list_id[0];
  521. if (run.text[0] == 183)
  522. list_label.Text = "●";
  523. else
  524. list_label.Text = run.text;
  525. list_label.Top = object_vertical_position;
  526. list_label.HorzAlign = HorzAlign.Right;
  527. list_label.VertAlign = VertAlign.Bottom;
  528. list_label.Width = Twips2Pixels(obj.pargraph.format.left_indent);
  529. list_label.Height = (float)Math.Ceiling(list_label.Font.Height * DrawUtils.ScreenDpiFX); // * 1.2f;
  530. clone_list.Add(list_label);
  531. }
  532. TextObject text_paragraph = Paragraph2ReportObjects(rich, rtf, start_text_index, obj.pargraph);
  533. if (list_label != null)
  534. {
  535. text_paragraph.Left = Twips2Pixels(obj.pargraph.format.left_indent);
  536. list_label.Font = text_paragraph.Font;
  537. list_label.VertAlign = text_paragraph.VertAlign;
  538. list_label.LineHeight = text_paragraph.LineHeight;
  539. text_paragraph.Width = rich.Width - text_paragraph.Left;
  540. }
  541. else
  542. {
  543. int ftb = text_paragraph.Text.IndexOf('\t');
  544. backindent = ftb > 0
  545. && obj.pargraph.format.first_line_indent < 0 &&
  546. -obj.pargraph.format.first_line_indent <= obj.pargraph.format.left_indent ;
  547. text_paragraph.Width = rich.Width;
  548. if (backindent)
  549. {
  550. string left_text = text_paragraph.Text.Substring(0, ftb);
  551. ++object_counter;
  552. left_label = new TextObject();
  553. left_label.Text = left_text;
  554. left_label.Top = object_vertical_position;
  555. left_label.HorzAlign = HorzAlign.Left;
  556. left_label.VertAlign = text_paragraph.VertAlign;
  557. if(obj.pargraph.format.left_indent != 0)
  558. {
  559. left_label.Width = Twips2Pixels(obj.pargraph.format.left_indent);
  560. }
  561. else
  562. {
  563. left_label.Width = Twips2Pixels(obj.pargraph.format.tab_positions[0]);
  564. }
  565. left_label.Height = (float)Math.Ceiling(left_label.Font.Height * DrawUtils.ScreenDpiFX); // * 1.2f;
  566. left_label.TextRenderType = TextRenderType.HtmlParagraph;
  567. clone_list.Add(left_label);
  568. int charcount = text_paragraph.Text.Length - ftb - 1;
  569. if(charcount > 0)
  570. {
  571. text_paragraph.Text = text_paragraph.Text.Substring(ftb + 1, charcount);
  572. }
  573. }
  574. else
  575. {
  576. text_paragraph.ParagraphFormat.FirstLineIndent = Twips2Pixels(obj.pargraph.format.first_line_indent);
  577. }
  578. }
  579. ++object_counter;
  580. Padding p = text_paragraph.Padding;
  581. p.Top = Twips2Pixels((int)obj.pargraph.format.space_before);
  582. p.Bottom = Twips2Pixels((int)obj.pargraph.format.space_after);
  583. p.Right = Twips2Pixels((int)obj.pargraph.format.right_indent);
  584. if(backindent)
  585. {
  586. p.Left = 0;
  587. text_paragraph.Left += left_label.Right + 0.01f;
  588. text_paragraph.Width -= left_label.Right + 0.01F;
  589. }
  590. else if (text_paragraph.HorzAlign != HorzAlign.Center)
  591. {
  592. p.Left += list_label != null ? 0 : Twips2Pixels((int)obj.pargraph.format.left_indent);
  593. }
  594. else
  595. {
  596. p.Left = Twips2Pixels((int)obj.pargraph.format.left_indent);
  597. }
  598. text_paragraph.Padding = p;
  599. text_paragraph.Top = object_vertical_position;
  600. text_paragraph.PreserveLastLineSpace = true;
  601. text_paragraph.Height = text_paragraph.CalcHeight() + p.Vertical;
  602. if (backindent)
  603. {
  604. left_label.Height = text_paragraph.Height;
  605. left_label.Padding = p;
  606. }
  607. object_vertical_position += text_paragraph.Height;
  608. clone_list.Add(text_paragraph);
  609. break;
  610. case RichObject.Type.Picture:
  611. {
  612. PictureObject pict = Picture2ReportObject(rtf, obj.picture);
  613. if (obj.picture.horizontalAlign == ParagraphFormat.HorizontalAlign.Centered)
  614. pict.Left = (rich.Width / 2) - (pict.Width / 2);
  615. else if (obj.picture.horizontalAlign == ParagraphFormat.HorizontalAlign.Right)
  616. pict.Left = rich.Right - pict.Width;
  617. else
  618. pict.Left = rich.Left;
  619. pict.Top = object_vertical_position;
  620. object_vertical_position += pict.Height;
  621. clone_list.Add(pict);
  622. }
  623. break;
  624. case RichObject.Type.Table:
  625. {
  626. TableObject tbl = Table2ReportObjects(rich, rtf, obj.table);
  627. tbl.Top = object_vertical_position;
  628. object_vertical_position += tbl.Height;
  629. clone_list.Add(tbl);
  630. }
  631. break;
  632. }
  633. start_text_index += (int)obj.size;
  634. if (rich.ActualTextLength != 0 && start_text_index >= rich.ActualTextStart + rich.ActualTextLength)
  635. break;
  636. }
  637. int idx = 1;
  638. foreach (ComponentBase obj in clone_list)
  639. {
  640. obj.SetName(rich.Name + "_" + idx.ToString());
  641. idx++;
  642. obj.SetReport(rich.Report);
  643. page_height += obj.Height;
  644. }
  645. return clone_list;
  646. }
  647. private float AssingClones(FastReport.RichObject rich, List<ComponentBase> clone_list)
  648. {
  649. float bottom = rich.Bottom;
  650. foreach (ComponentBase clone in clone_list)
  651. {
  652. clone.SetReport(rich.Report);
  653. bottom = clone.Bottom;
  654. }
  655. return bottom + (usePadding ? rich.Padding.Top + rich.Padding.Bottom : 0);
  656. }
  657. internal List<ComponentBase> RichObject2ReportObjects(FastReport.RichObject rich, ref RichDocument rtf, out float total_height)
  658. {
  659. List<ComponentBase> clone_list = new List<ComponentBase>();
  660. int position = 0;
  661. float vertical_shift = 0;
  662. total_height = 0;
  663. if (rtf.pages != null)
  664. foreach (Page page in rtf.pages)
  665. {
  666. if (position + page.size < rich.ActualTextStart)
  667. {
  668. position += (int)page.size;
  669. continue;
  670. }
  671. float page_height;
  672. List<ComponentBase> virtual_object_list = Page2ReportObjects(rich, rtf, page, position, out page_height);
  673. foreach(ComponentBase obj in virtual_object_list)
  674. {
  675. if (obj is TextObject)
  676. {
  677. TextObject text_object = obj as TextObject;
  678. text_object.Top += vertical_shift;
  679. if (total_height < text_object.Bottom)
  680. total_height = text_object.Bottom;
  681. clone_list.Add(obj);
  682. }
  683. else if(obj is PictureObject)
  684. {
  685. PictureObject pic = obj as PictureObject;
  686. pic.Top += vertical_shift;
  687. total_height += pic.Height;
  688. clone_list.Add(obj);
  689. }
  690. else if(obj is TableObject)
  691. {
  692. TableObject tbl = obj as TableObject;
  693. tbl.Top += vertical_shift;
  694. tbl.Left = 0; // Fix me
  695. total_height += tbl.Height;
  696. clone_list.Add(obj);
  697. }
  698. else
  699. {
  700. throw new Exception("Rich2ReportObject.cs: object type not supported");
  701. }
  702. }
  703. position += (int)page.size;
  704. vertical_shift = total_height;
  705. if (rich.ActualTextLength != 0 && position >= rich.ActualTextStart + rich.ActualTextLength)
  706. break;
  707. }
  708. total_height = AssingClones(rich, clone_list);
  709. return clone_list;
  710. }
  711. }
  712. #if READONLY_STRUCTS
  713. internal readonly struct TranslationPropeties
  714. #else
  715. internal struct TranslationPropeties
  716. #endif
  717. {
  718. internal readonly Border border;
  719. internal readonly Color background_color;
  720. public TranslationPropeties(Border border, Color background_color)
  721. {
  722. this.border = border;
  723. this.background_color = background_color;
  724. }
  725. }
  726. }