1
///////////////////////////////////////////////////////////////////////////////
4
// Author: Ulrich Telle
8
// Copyright: (c) Ulrich Telle
9
// Licence: wxWindows licence + RDS Data Security license
10
///////////////////////////////////////////////////////////////////////////////
12
/// \file pdfxml.cpp Implementation of the wxPdfDocument markup
14
// For compilers that support precompilation, includes <wx.h>.
15
#include <wx/wxprec.h>
26
#include <wx/sstream.h>
28
#include "wx/pdfdocument.h"
29
#include "wx/pdfutility.h"
30
#include "wx/pdfxml.h"
33
GetNodeContent(const wxXmlNode *node)
35
const wxXmlNode *n = node;
36
if (n == NULL) return wxEmptyString;
40
if (n->GetType() == wxXML_TEXT_NODE ||
41
n->GetType() == wxXML_CDATA_SECTION_NODE)
42
return n->GetContent();
49
GetXmlAttribute(const wxXmlNode* node, const wxString& attrName, const wxString& defaultVal)
51
#if wxCHECK_VERSION(2,9,0)
52
return node->GetAttribute(attrName, defaultVal);
54
return node->GetPropVal(attrName, defaultVal);
58
// --- wxPdfCellContext
60
wxPdfCellContext::wxPdfCellContext(double maxWidth, wxPdfAlignment hAlign, wxPdfAlignment vAlign)
62
m_maxWidth = maxWidth;
77
wxPdfCellContext::~wxPdfCellContext()
80
for (j = 0; j < m_contexts.GetCount(); j++)
82
wxPdfCellContext* context = static_cast<wxPdfCellContext*>(m_contexts[j]);
92
wxPdfCellContext::AddLine()
99
wxPdfCellContext::AddLastLineValues(double width, int spaces)
101
m_linewidth.Last() += width;
102
m_spaces.Last() += spaces;
106
wxPdfCellContext::AddCurrentLineWidth(double width)
108
if (m_currentLine < m_linewidth.GetCount())
110
m_linewidth[m_currentLine] += width;
115
wxPdfCellContext::AddCurrentLineSpaces(int spaces)
117
if (m_currentLine < m_spaces.GetCount())
119
m_spaces[m_currentLine] += spaces;
124
wxPdfCellContext::MarkLastLine()
126
if (m_spaces.Last() > 0)
128
m_spaces.Last() *= -1;
133
wxPdfCellContext::IsCurrentLineMarked()
136
if (m_currentLine < m_linewidth.GetCount())
138
marked = (m_spaces[m_currentLine] < 0);
145
wxPdfCellContext::IncrementCurrentLine()
147
if (m_currentLine < m_linewidth.GetCount()-1)
155
wxPdfCellContext::GetLineDelta()
159
m_lineDelta = m_maxWidth - GetCurrentLineWidth();
165
wxPdfCellContext::GetCurrentLineWidth()
167
double linewidth = 0;
168
if (m_currentLine < m_linewidth.GetCount())
170
linewidth = m_linewidth[m_currentLine];
176
wxPdfCellContext::GetLastLineWidth()
178
return m_linewidth.Last();
182
wxPdfCellContext::GetCurrentLineSpaces()
185
if (m_currentLine < m_spaces.GetCount())
187
spaces = m_spaces[m_currentLine];
188
if (spaces < 0) spaces = -spaces;
194
wxPdfCellContext::IncrementCurrentContext()
196
if (m_currentContext < m_contexts.GetCount()-1)
203
wxPdfCellContext::GetCurrentContext()
205
wxPdfCellContext* context = NULL;
206
if (m_currentContext < m_contexts.GetCount())
208
context = static_cast<wxPdfCellContext*>(m_contexts[m_currentContext]);
214
wxPdfCellContext::AppendContext(wxPdfCellContext* context)
216
m_contexts.Add(context);
219
// --- wxPdfTableCell
221
wxPdfTableCell::wxPdfTableCell(wxXmlNode* cell, unsigned int row, unsigned int col, unsigned int rows, unsigned int cols)
231
SetBorder(wxPDF_BORDER_NONE);
233
m_hasCellColour = false;
236
wxPdfTableCell::~wxPdfTableCell()
238
if (m_context != NULL)
246
wxPdfTable::wxPdfTable(wxPdfDocument* document)
248
m_document = document;
261
wxPdfTable::~wxPdfTable()
264
wxPdfCellHashMap::iterator cell;
265
for (cell = m_table.begin(); cell != m_table.end(); cell++)
267
if (cell->second != NULL)
275
wxPdfTable::SetCellDimensions(double maxWidth)
277
unsigned int row, col;
278
double defaultWidth = (m_nCols > 0) ? maxWidth / m_nCols : 0;
279
for (col = 0; col < m_nCols; col++)
281
if (col >= m_colWidths.size() || m_colWidths[col] <= 0)
283
SetColumnWidth(col, defaultWidth);
287
if (m_totalWidth > maxWidth)
289
double factor = maxWidth / m_totalWidth;
290
for (col = 0; col < m_colWidths.size(); col++)
292
m_colWidths[col] /= factor;
297
wxPdfBoolHashMap rowSpans;
298
unsigned int rowSpan;
299
unsigned int maxRowSpan = 1;
300
for (row = 0; row < m_nRows; row++)
303
for (col = 0; col < m_nCols; col++)
305
wxPdfCellHashMap::iterator foundCell = m_table.find((row << 16) | col);
306
if (foundCell != m_table.end())
308
wxPdfTableCell* cell = foundCell->second;
310
double cellWidth = 0;
311
for (span = 0; span < (int) cell->GetColSpan(); span++)
313
cellWidth += m_colWidths[col+span];
315
if (cellWidth > 2*m_pad) cellWidth -= (2*m_pad);
316
cell->SetWidth(cellWidth);
317
wxPdfCellContext* cellContext = new wxPdfCellContext(cellWidth, cell->GetHAlign());
318
cell->SetContext(cellContext);
319
m_document->PrepareXmlCell(cell->GetXmlNode(), *cellContext);
320
double height = cellContext->GetHeight() + 2*m_pad;
321
cell->SetHeight(height);
322
rowSpan = cell->GetRowSpan();
323
rowSpans[rowSpan] = true;
324
if (rowSpan == 1 && height > rowHeight)
330
if (rowSpan > maxRowSpan)
332
maxRowSpan = rowSpan;
337
m_rowHeights[row] = (rowHeight < m_minHeights[row]) ? m_minHeights[row] : rowHeight;
340
for (rowSpan = 2; rowSpan <= maxRowSpan; rowSpan++)
342
wxPdfBoolHashMap::iterator currentRowSpan = rowSpans.find(rowSpan);
343
if (currentRowSpan != rowSpans.end())
345
for (row = 0; row < m_nRows; row++)
348
for (col = 0; col < m_nCols; col++)
350
wxPdfCellHashMap::iterator foundCell = m_table.find((row << 16) | col);
351
if (foundCell != m_table.end())
353
wxPdfTableCell* cell = foundCell->second;
354
if (rowSpan == cell->GetRowSpan())
358
for (span = cell->GetRowSpan()-1; span >= 0; span--)
360
rowHeight += m_rowHeights[row+span];
362
if (cell->GetHeight() > rowHeight)
364
double delta = (cell->GetHeight() - rowHeight) / cell->GetRowSpan();
365
for (span = cell->GetRowSpan()-1; span >= 0; span--)
367
m_rowHeights[row+span] += delta;
377
for (row = m_headRowFirst; row < m_headRowLast; row++)
379
m_headHeight += m_rowHeights[row];
382
for (row = m_bodyRowFirst; row < m_bodyRowLast; row++)
384
m_totalHeight += m_rowHeights[row];
389
wxPdfTable::InsertCell(wxPdfTableCell* cell)
391
unsigned int x = cell->GetCol();
392
unsigned int y = cell->GetRow();
393
unsigned int w = cell->GetColSpan();
394
unsigned int h = cell->GetRowSpan();
395
m_table[(y << 16)|x] = cell;
409
bool writeHeader = m_headRowLast > m_headRowFirst;
410
bool newPage = false;
411
double saveLeftMargin = m_document->GetLeftMargin();
413
unsigned int row, headRow;
414
y = m_document->GetY();
415
double breakMargin = m_document->GetBreakMargin();
416
double pageHeight = m_document->GetPageHeight();
417
double yMax = pageHeight - breakMargin;
418
if (y + m_headHeight + m_rowHeights[m_bodyRowFirst] > yMax)
422
for (row = m_bodyRowFirst; row < m_bodyRowLast; row++)
424
if (!newPage && (y + m_rowHeights[row] > yMax))
431
m_document->AddPage();
432
writeHeader = m_headRowLast > m_headRowFirst;
433
y = m_document->GetY();
438
for (headRow = m_headRowFirst; headRow < m_headRowLast; headRow++)
441
WriteRow(headRow, x, y);
442
y += m_rowHeights[headRow];
447
y += m_rowHeights[row];
452
wxPdfTable::WriteRow(unsigned int row, double x, double y)
454
bool isHeaderRow = (row >= m_headRowFirst && row < m_headRowLast);
456
unsigned int rowspan, colspan;
458
m_document->SetXY(x, y+m_pad);
459
for (col = 0; col < m_nCols; col++)
461
wxPdfCellHashMap::iterator foundCell = m_table.find((row << 16) | col);
462
if (foundCell != m_table.end())
464
wxPdfTableCell* cell = foundCell->second;
466
for (colspan = 0; colspan < cell->GetColSpan(); colspan++)
468
w += m_colWidths[col+colspan];
471
for (rowspan = 0; rowspan < cell->GetRowSpan(); rowspan++)
473
h += m_rowHeights[row+rowspan];
475
if (cell->HasCellColour())
477
wxPdfColour saveFillColour = m_document->GetFillColour();
478
m_document->SetFillColour(cell->GetCellColour());
479
m_document->Rect(x, y, w, h, wxPDF_STYLE_FILL);
480
m_document->SetFillColour(saveFillColour);
482
int border = cell->GetBorder();
483
if ((border & wxPDF_BORDER_FRAME) == wxPDF_BORDER_FRAME)
485
m_document->Rect(x, y, w, h);
489
if (border & wxPDF_BORDER_LEFT) m_document->Line(x, y, x, y+h);
490
if (border & wxPDF_BORDER_TOP) m_document->Line(x, y, x+w, y);
491
if (border & wxPDF_BORDER_BOTTOM) m_document->Line(x, y+h, x+w, y+h);
492
if (border & wxPDF_BORDER_RIGHT) m_document->Line(x+w, y, x+w, y+h);
494
m_document->SetLeftMargin(x+m_pad);
495
double delta = h - cell->GetHeight();
496
switch (cell->GetVAlign())
498
case wxPDF_ALIGN_BOTTOM:
499
m_document->SetXY(x+m_pad, y+m_pad+delta);
501
case wxPDF_ALIGN_MIDDLE:
502
m_document->SetXY(x+m_pad, y+m_pad+0.5*delta);
504
case wxPDF_ALIGN_TOP:
506
m_document->SetXY(x+m_pad, y+m_pad);
509
m_document->WriteXmlCell(cell->GetXmlNode(), *(cell->GetContext()));
512
// For header rows it is necessary to prepare the cells for reprocessing
513
delete cell->GetContext();
514
wxPdfCellContext* cellContext = new wxPdfCellContext(cell->GetWidth(), cell->GetHAlign());
515
cell->SetContext(cellContext);
516
m_document->PrepareXmlCell(cell->GetXmlNode(), *cellContext);
519
x += m_colWidths[col];
524
wxPdfTable::SetColumnWidth(int col, double width)
526
m_colWidths[col] = width;
527
m_totalWidth += width;
530
// ----- wxPdfDocument
533
wxPdfDocument::PrepareXmlTable(wxXmlNode* node, wxPdfCellContext& context)
535
wxPdfTable* table = context.GetTable();
536
double maxWidth = context.GetMaxWidth();
537
wxPdfBoolHashMap cellused;
544
wxXmlNode *child = node->GetChildren();
547
wxString name = (child->GetName()).Lower();
548
if (name == wxT("colgroup"))
550
wxXmlNode *colChild = child->GetChildren();
553
if ((colChild->GetName()).Lower() == wxT("col"))
556
wxString span = GetXmlAttribute(colChild, wxT("span"), wxT("1"));
557
if (span.Length() > 0 && span.ToLong(&colspan))
559
if (colspan < 1) colspan = 1;
566
wxString width = GetXmlAttribute(colChild, wxT("width"), wxT("0"));
567
if (width.Length() > 0)
569
colwidth = wxPdfUtility::String2Double(width);
570
if (colwidth < 0) colwidth = 0;
572
for (col = 0; col < colspan; col++)
574
table->SetColumnWidth(coldef++, colwidth);
575
if (colwidth <= 0) colundef++;
578
colChild = colChild->GetNext();
581
else if (name == wxT("thead") || name == wxT("tbody"))
583
wxString oddColour = GetXmlAttribute(child, wxT("odd"), wxT("")).Lower();
584
wxString evenColour = GetXmlAttribute(child, wxT("even"), wxT("")).Lower();
585
bool isHeader = name == wxT("thead");
588
table->SetHeadRowFirst(row);
592
table->SetBodyRowFirst(row);
594
wxXmlNode *rowChild = child->GetChildren();
598
if ((rowChild->GetName()).Lower() == wxT("tr"))
600
wxString rowColour = GetXmlAttribute(rowChild, wxT("bgcolor"), wxT("")).Lower();
602
if (rowColour.Length() == 0)
604
if (rowCount % 2 == 0)
607
if (evenColour.Length() > 0) rowColour = evenColour;
612
if (oddColour.Length() > 0) rowColour = oddColour;
615
double rowHeight = 0;
616
wxString height = GetXmlAttribute(rowChild, wxT("height"), wxT("0")).Lower();
617
if (height.Length() > 0)
619
rowHeight = wxPdfUtility::String2Double(height);
620
if (rowHeight < 0) rowHeight = 0;
622
table->SetMinRowHeight(row, rowHeight);
623
wxXmlNode *colChild = rowChild->GetChildren();
627
if ((colChild->GetName()).Lower() == wxT("td"))
629
int border = wxPDF_BORDER_NONE;
630
wxString strBorder = GetXmlAttribute(colChild, wxT("border"), wxT("")).Upper();
631
if (strBorder.Length() > 0)
633
if (strBorder.Contains(wxT("L"))) border |= wxPDF_BORDER_LEFT;
634
if (strBorder.Contains(wxT("T"))) border |= wxPDF_BORDER_TOP;
635
if (strBorder.Contains(wxT("B"))) border |= wxPDF_BORDER_BOTTOM;
636
if (strBorder.Contains(wxT("R"))) border |= wxPDF_BORDER_RIGHT;
638
else if (table->HasBorder())
640
border = wxPDF_BORDER_FRAME;
643
wxString align = GetXmlAttribute(colChild, wxT("align"), wxT("left")).Lower();
644
wxPdfAlignment hAlignment = wxPDF_ALIGN_LEFT;
645
if (align == wxT("right")) hAlignment = wxPDF_ALIGN_RIGHT;
646
else if (align == wxT("center")) hAlignment = wxPDF_ALIGN_CENTER;
647
align = GetXmlAttribute(colChild, wxT("valign"), wxT("top")).Lower();
648
wxPdfAlignment vAlignment = wxPDF_ALIGN_TOP;
649
if (align == wxT("bottom")) vAlignment = wxPDF_ALIGN_BOTTOM;
650
else if (align == wxT("middle")) vAlignment = wxPDF_ALIGN_MIDDLE;
651
else if (align == wxT("center")) vAlignment = wxPDF_ALIGN_MIDDLE;
653
wxString bgColour = GetXmlAttribute(colChild, wxT("bgcolor"), wxT("")).Lower();
654
wxString rowspan = GetXmlAttribute(colChild, wxT("rowspan"), wxT("1"));
656
if (rowspan.Length() > 0 && rowspan.ToLong(&rs))
665
wxString colspan = GetXmlAttribute(colChild, wxT("colspan"), wxT("1"));
666
if (colspan.Length() > 0 && colspan.ToLong(&cs))
674
while (cellused.find((row<<16)|col) != cellused.end())
678
for (i = 0; i < cs; i++)
680
for (j = 0; j < rs; j++)
682
cellused[((j+row)<<16)|(i+col)] = true;
685
wxPdfTableCell* cell = new wxPdfTableCell(colChild, row, col, rs, cs);
686
cell->SetHAlign(hAlignment);
687
cell->SetVAlign(vAlignment);
688
cell->SetBorder(border);
689
if (bgColour.Length() > 0)
691
cell->SetCellColour(wxPdfColour(bgColour));
693
else if (rowColour.Length() > 0)
695
cell->SetCellColour(wxPdfColour(rowColour));
697
table->InsertCell(cell);
699
colChild = colChild->GetNext();
705
table->SetHeadRowLast(row);
709
table->SetBodyRowLast(row);
711
rowChild = rowChild->GetNext();
714
child = child->GetNext();
716
table->SetCellDimensions(maxWidth);
717
context.AddHeight(table->GetTotalHeight());
721
wxPdfDocument::WriteXmlTable(wxPdfCellContext& context)
723
double saveLeftMargin = GetLeftMargin();
724
double saveRightMargin = GetRightMargin();
725
wxPdfTable* table = context.GetTable();
726
double maxWidth = context.GetMaxWidth();
727
double tableWidth = table->GetTotalWidth();
729
if (tableWidth < maxWidth)
731
wxPdfAlignment align = context.GetHAlign();
734
case wxPDF_ALIGN_CENTER:
735
delta = 0.5 * (maxWidth - tableWidth);
737
case wxPDF_ALIGN_RIGHT:
738
delta = maxWidth - tableWidth;
740
case wxPDF_ALIGN_LEFT:
746
// Set left and right margin
747
SetLeftMargin(saveLeftMargin+delta);
748
SetRightMargin(GetPageWidth() - saveLeftMargin - tableWidth - delta);
749
SetXY(saveLeftMargin+delta,GetY());
755
SetLeftMargin(saveLeftMargin);
756
SetRightMargin(saveRightMargin);
760
wxPdfDocument::PrepareXmlCell(wxXmlNode* node, wxPdfCellContext& context)
762
wxPdfCellContext* newContext;
763
wxXmlNode *child = node->GetChildren();
766
wxString name = (child->GetName()).Lower();
768
if (name == wxT("b") || name == wxT("i") || name == wxT("u") ||
769
name == wxT("o") || name == wxT("s") ||
770
name == wxT("strong") || name == wxT("em"))
772
// --- Bold, Italic, Underline, Overline, Strikeout
773
// --- Strong (= bold), Emphasize (= italic)
774
wxString addStyle = name.Upper();
775
if (name.Length() > 1)
777
if (name == wxT("strong")) addStyle = wxT("B");
778
else if (name == wxT("em")) addStyle = wxT("I");
780
wxString style = GetFontStyle();
781
if (!style.Contains(addStyle))
783
SelectFont(wxT(""), style + addStyle, 0, false);
784
PrepareXmlCell(child, context);
785
SelectFont(wxT(""), style, 0, false);
789
PrepareXmlCell(child, context);
792
else if (name == wxT("small"))
794
// --- Small font size
795
static double ratio = 2./3.;
796
double currentSize = GetFontSize();
797
SelectFont(wxT(""), wxT(""), currentSize * ratio, false);
798
double delta = (currentSize - GetFontSize()) * 0.5 * ratio / GetScaleFactor();
799
SetXY(GetX(), GetY() + delta);
800
PrepareXmlCell(child, context);
801
SetXY(GetX(), GetY() - delta);
802
SelectFont(wxT(""), wxT(""), currentSize, false);
804
else if (name == wxT("sup"))
807
static double ratio = 2./3.;
808
double currentSize = GetFontSize();
809
SelectFont(wxT(""), wxT(""), currentSize * ratio, false);
810
double delta = (currentSize - GetFontSize()) * ratio / GetScaleFactor();
811
SetXY(GetX(), GetY() - delta);
812
PrepareXmlCell(child, context);
813
SetXY(GetX(), GetY() + delta);
814
SelectFont(wxT(""), wxT(""), currentSize, false);
816
else if (name == wxT("sub"))
819
static double ratio = 2./3.;
820
double currentSize = GetFontSize();
821
SelectFont(wxT(""), wxT(""), currentSize * ratio, false);
822
double delta = (currentSize - GetFontSize()) * ratio / GetScaleFactor();
823
SetXY(GetX(), GetY() + delta);
824
PrepareXmlCell(child, context);
825
SetXY(GetX(), GetY() - delta);
826
SelectFont(wxT(""), wxT(""), currentSize, false);
828
else if (name == wxT("ul"))
830
// --- Unordered list
831
double leftMargin = GetLeftMargin();
832
double indent = GetFontSize() / GetScaleFactor();
833
SetLeftMargin(leftMargin + indent);
834
wxXmlNode *listChild = child->GetChildren();
837
if ((listChild->GetName()).Lower() == wxT("li"))
840
newContext = new wxPdfCellContext(context.GetMaxWidth(), wxPDF_ALIGN_LEFT);
841
//# newContext->AddHeight(GetLineHeight());
842
context.AppendContext(newContext);
843
PrepareXmlCell(listChild, *newContext);
844
context.AddHeight(newContext->GetHeight());
847
listChild = listChild->GetNext();
849
SetLeftMargin(leftMargin);
851
else if (name == wxT("ol"))
854
double leftMargin = GetLeftMargin();
855
double indent = GetStringWidth(wxT(" 00. "));
856
wxString type = GetXmlAttribute(child, wxT("type"), wxT("1"));
857
if (type.Length() > 0)
859
if (type[0] == wxT('a'))
860
indent = GetStringWidth(wxT(" xx. "));
861
else if (type[0] == wxT('A'))
862
indent = GetStringWidth(wxT(" XX. "));
863
else if (type[0] == wxT('i'))
864
indent = GetStringWidth(wxT(" xxx. "));
865
else if (type[0] == wxT('I'))
866
indent = GetStringWidth(wxT(" XXX. "));
867
else if (type[0] == wxT('z') &&
868
type.Length() > 1 && type[1] >= wxT('1') && type[1] <= wxT('4'))
869
indent = 1.1 * GetFontSize() / GetScaleFactor();
871
SetLeftMargin(leftMargin + indent);
872
wxXmlNode *listChild = child->GetChildren();
875
if ((listChild->GetName()).Lower() == wxT("li"))
878
newContext = new wxPdfCellContext(context.GetMaxWidth(), wxPDF_ALIGN_LEFT);
879
//# newContext->AddHeight(GetLineHeight());
880
context.AppendContext(newContext);
881
PrepareXmlCell(listChild, *newContext);
882
context.AddHeight(newContext->GetHeight());
885
listChild = listChild->GetNext();
887
SetLeftMargin(leftMargin);
889
else if (name == wxT("br"))
893
//# context.AddHeight(GetLineHeight());
894
context.MarkLastLine();
897
else if (name == wxT("p"))
900
wxString align = GetXmlAttribute(child, wxT("align"), wxT("left")).Lower();
901
wxPdfAlignment alignment = wxPDF_ALIGN_LEFT;
902
if (align == wxT("right")) alignment = wxPDF_ALIGN_RIGHT;
903
else if (align == wxT("center")) alignment = wxPDF_ALIGN_CENTER;
904
else if (align == wxT("justify")) alignment = wxPDF_ALIGN_JUSTIFY;
907
newContext = new wxPdfCellContext(context.GetMaxWidth(), alignment);
908
context.AppendContext(newContext);
909
PrepareXmlCell(child, *newContext);
910
newContext->MarkLastLine();
911
context.AddHeight(newContext->GetHeight()+GetLineHeight());
915
else if (name == wxT("hr"))
917
// --- Horizontal rule
918
// double hrWidth = GetPageWidth() - GetLeftMargin() - GetRightMargin();
921
// wxString strWidth = child->GetPropVal(wxT("width"), wxT(""));
922
// if (strWidth.Length() > 0 && strWidth.ToLong(&widthAttr))
924
// hrWidth = hrWidth * 0.01 * widthAttr;
926
// double x = GetX();
927
// double y = GetY();
928
// double wLine = GetLineWidth();
929
// SetLineWidth(0.2);
930
// Line(x, y, x + hrWidth, y);
931
// SetLineWidth(wLine);
933
context.AddHeight(GetLineHeight());
936
else if (name == wxT("a"))
939
PrepareXmlCell(child, context);
941
else if (name == wxT("img"))
944
wxString src = GetXmlAttribute(child, wxT("src"), wxT(""));
945
if (src.Length() > 0)
949
// wxString strWidth = child->GetPropVal(wxT("width"), wxT("0"));
950
wxString strHeight = GetXmlAttribute(child, wxT("height"), wxT("0"));
951
// if (!strWidth.ToLong(&width)) width = 0;
952
if (!strHeight.ToLong(&height)) height = 0;
953
double h = ((double) height) / (GetImageScale() * GetScaleFactor());
954
// TODO: handle image
955
// line height, position, margins etc.
956
context.AddHeight(h);
959
else if (name == wxT("span"))
961
PrepareXmlCell(child, context);
963
else if (name == wxT("font"))
966
wxString saveFamily = GetFontFamily();
967
wxString saveStyle = GetFontStyle();
968
double saveSize = GetFontSize();
969
wxString strFace = GetXmlAttribute(child, wxT("face"), wxT(""));
971
wxString strSize = GetXmlAttribute(child, wxT("size"), wxT(""));
972
if (strSize.Length() > 0)
974
size = wxPdfUtility::String2Double(strSize);
976
if (size <= 0) size = saveSize;
977
SelectFont(strFace, saveStyle, size, false);
978
PrepareXmlCell(child, context);
979
SelectFont(saveFamily, saveStyle, saveSize, false);
981
else if (name == wxT("code"))
984
wxString saveFamily = GetFontFamily();
985
wxString saveStyle = GetFontStyle();
986
double saveSize = GetFontSize();
987
wxString strFace = GetXmlAttribute(child, wxT("face"), wxT("courier"));
989
wxString strSize = GetXmlAttribute(child, wxT("size"), wxT("10"));
990
if (strSize.Length() > 0)
992
size = wxPdfUtility::String2Double(strSize);
994
if (size <= 0) size = saveSize;
995
SelectFont(strFace, wxT(""), size, false);
997
context.MarkLastLine();
999
PrepareXmlCell(child, context);
1001
SelectFont(saveFamily, saveStyle, saveSize, false);
1003
else if (name == wxT("h1") || name == wxT("h2") || name == wxT("h3") ||
1004
name == wxT("h4") || name == wxT("h5") || name == wxT("h6"))
1007
wxString align = GetXmlAttribute(child, wxT("align"), wxT("left")).Lower();
1008
wxPdfAlignment alignment = wxPDF_ALIGN_LEFT;
1009
if (align == wxT("right")) alignment = wxPDF_ALIGN_RIGHT;
1010
else if (align == wxT("center")) alignment = wxPDF_ALIGN_CENTER;
1011
else if (align == wxT("justify")) alignment = wxPDF_ALIGN_JUSTIFY;
1013
if (context.GetLastLineWidth() > 0)
1018
context.AddHeight(GetLineHeight());
1019
newContext = new wxPdfCellContext(context.GetMaxWidth(), alignment);
1020
context.AppendContext(newContext);
1022
double headsize = (wxT('4') - name[1]) * 2;
1023
double currentFontSize = GetFontSize();
1024
SelectFont(wxT(""), wxT(""), currentFontSize + headsize, false);
1025
wxString addStyle = wxT("B");
1026
wxString style = GetFontStyle();
1027
if (!style.Contains(addStyle))
1029
SelectFont(wxT(""), style + addStyle, 0, false);
1030
PrepareXmlCell(child, *newContext);
1031
SelectFont(wxT(""), style, 0, false);
1035
PrepareXmlCell(child, *newContext);
1037
context.AddHeight(newContext->GetHeight());
1039
SelectFont(wxT(""), wxT(""), currentFontSize, false);
1042
else if (name == wxT("table"))
1045
wxString border = GetXmlAttribute(child, wxT("border"), wxT("0")).Lower();
1046
bool hasBorder = (border != wxT("0"));
1047
wxString align = GetXmlAttribute(child, wxT("align"), wxT("")).Lower();
1048
wxPdfAlignment hAlignment = context.GetHAlign();
1049
if (align == wxT("right")) hAlignment = wxPDF_ALIGN_RIGHT;
1050
else if (align == wxT("center")) hAlignment = wxPDF_ALIGN_CENTER;
1051
else if (align == wxT("justify")) hAlignment = wxPDF_ALIGN_JUSTIFY;
1052
align = GetXmlAttribute(child, wxT("valign"), wxT("top")).Lower();
1053
wxPdfAlignment vAlignment = wxPDF_ALIGN_TOP;
1054
if (align == wxT("bottom")) vAlignment = wxPDF_ALIGN_BOTTOM;
1055
else if (align == wxT("middle")) vAlignment = wxPDF_ALIGN_MIDDLE;
1056
else if (align == wxT("center")) vAlignment = wxPDF_ALIGN_MIDDLE;
1057
double pad = 1.5 / GetScaleFactor();
1058
wxString padding = GetXmlAttribute(child, wxT("cellpadding"), wxT("")).Lower();
1059
if (padding.Length() > 0)
1061
pad = wxPdfUtility::String2Double(padding);
1062
if (pad < 0) pad = 0;
1065
wxPdfTable* table = new wxPdfTable(this);
1067
table->SetBorder(hasBorder);
1068
newContext = new wxPdfCellContext(context.GetMaxWidth(), hAlignment, vAlignment);
1069
context.AppendContext(newContext);
1070
newContext->SetTable(table);
1071
PrepareXmlTable(child, *newContext);
1072
context.AddHeight(newContext->GetHeight());
1077
if (child->GetType() == wxXML_TEXT_NODE || name == wxT("msg"))
1079
if (context.GetLastLineWidth() == 0)
1081
context.AddHeight(GetLineHeight());
1083
double wmax = context.GetMaxWidth()-context.GetLastLineWidth();
1085
if (name == wxT("msg"))
1087
s = GetNodeContent(child);
1088
if (m_translate) s = wxGetTranslation(s);
1092
s = child->GetContent();
1094
s.Replace(wxT("\r"),wxT("")); // remove carriage returns
1095
int nb = (int) s.Length();
1096
if (nb > 0 && s[nb-1] == wxT('\n'))
1110
// Get next character
1114
// Explicit line break
1116
context.AddLastLineValues(len, ns);
1122
context.MarkLastLine();
1124
context.AddHeight(GetLineHeight());
1125
wmax = context.GetMaxWidth();
1134
double lastlen = len;
1135
len = GetStringWidth(s.SubString(j, i));
1139
// Automatic line break
1143
if (context.GetLastLineWidth() > 0)
1145
if (context.GetLastChar() == wxT(' '))
1147
context.AddLastLineValues(-context.GetLastSpaceWidth(), -1);
1164
context.AddLastLineValues(ls, ns);
1171
context.AddHeight(GetLineHeight());
1172
wmax = context.GetMaxWidth();
1180
context.AddLastLineValues(len, ns);
1181
context.SetLastChar(c);
1182
context.SetLastSpaceWidth(GetStringWidth(wxT(" ")));
1185
child = child->GetNext();
1190
wxPdfDocument::WriteXml(const wxString& xmlString)
1192
if (GetLineHeight() == 0)
1194
SetLineHeight(GetFontSize()*1.25 / GetScaleFactor());
1196
wxString xmlStringWithXmlRoot(wxT("<xml>")+xmlString+wxT("</xml>"));
1197
wxStringInputStream xmlStream(xmlStringWithXmlRoot);
1198
wxXmlDocument xmlDocument;
1199
bool loaded = xmlDocument.Load(xmlStream);
1202
if (xmlDocument.IsOk())
1204
wxXmlNode* root = xmlDocument.GetRoot();
1205
double maxWidth = GetPageWidth() - GetRightMargin() - GetX();
1206
wxPdfCellContext context(maxWidth, wxPDF_ALIGN_LEFT);
1207
double saveX = GetX();
1208
double saveY = GetY();
1209
PrepareXmlCell(root, context);
1210
SetXY(saveX, saveY);
1211
WriteXmlCell(root, context);
1215
wxLogDebug(wxString(wxT("wxPdfDocument::WriteXml: ")) +
1216
wxString(_("Markup invalid.")));
1222
// TODO: Error handling
1223
wxLogDebug(wxString(wxT("wxPdfDocument::WriteXml: ")) +
1224
wxString(_("Unable to load markup string.")));
1229
wxPdfDocument::WriteXml(wxXmlNode* node)
1231
if (GetLineHeight() == 0)
1233
SetLineHeight(GetFontSize()*1.25 / GetScaleFactor());
1235
double maxWidth = GetPageWidth() - GetRightMargin() - GetX();
1236
wxPdfCellContext context(maxWidth, wxPDF_ALIGN_LEFT);
1237
double saveX = GetX();
1238
double saveY = GetY();
1239
PrepareXmlCell(node, context);
1240
SetXY(saveX, saveY);
1241
WriteXmlCell(node, context);
1245
wxPdfDocument::WriteXmlCell(wxXmlNode* node, wxPdfCellContext& context)
1247
wxPdfCellContext* newContext;
1248
wxXmlNode *child = node->GetChildren();
1251
wxString name = (child->GetName()).Lower();
1252
// parse the children
1254
if (name == wxT("b") || name == wxT("i") || name == wxT("u") ||
1255
name == wxT("o") || name == wxT("s") ||
1256
name == wxT("strong") || name == wxT("em"))
1258
// --- Bold, Italic, Underline, Overline, Strikeout
1259
// --- Strong (= bold), Emphasize (= italic)
1260
wxString addStyle = name.Upper();
1261
if (name.Length() > 1)
1263
if (name == wxT("strong")) addStyle = wxT("B");
1264
else if (name == wxT("em")) addStyle = wxT("I");
1266
wxString style = GetFontStyle();
1267
if (!style.Contains(addStyle))
1269
SetFont(wxT(""), style + addStyle);
1270
WriteXmlCell(child, context);
1271
SetFont(wxT(""), style);
1275
WriteXmlCell(child, context);
1278
else if (name == wxT("small"))
1281
static double ratio = 2./3.;
1282
double currentSize = GetFontSize();
1283
SetFontSize(currentSize * ratio);
1284
double delta = (currentSize - GetFontSize()) * 0.5 * ratio / GetScaleFactor();
1285
SetXY(GetX(), GetY() + delta);
1286
WriteXmlCell(child, context);
1287
SetXY(GetX(), GetY() - delta);
1288
SetFontSize(currentSize);
1290
else if (name == wxT("sup"))
1293
static double ratio = 2./3.;
1294
double currentSize = GetFontSize();
1295
SetFontSize(currentSize * ratio);
1296
double delta = (currentSize - GetFontSize()) * ratio / GetScaleFactor();
1297
SetXY(GetX(), GetY() - delta);
1298
WriteXmlCell(child, context);
1299
SetXY(GetX(), GetY() + delta);
1300
SetFontSize(currentSize);
1302
else if (name == wxT("sub"))
1305
static double ratio = 2./3.;
1306
double currentSize = GetFontSize();
1307
SetFontSize(currentSize * ratio);
1308
double delta = (currentSize - GetFontSize()) * ratio / GetScaleFactor();
1309
SetXY(GetX(), GetY() + delta);
1310
WriteXmlCell(child, context);
1311
SetXY(GetX(), GetY() - delta);
1312
SetFontSize(currentSize);
1314
else if (name == wxT("ul"))
1316
// --- Unordered list
1318
static wxChar bulletChar = 0x2022;
1319
static wxChar dashChar = 0x2013;
1321
static wxChar bulletChar = '\x95'; // dec 149
1322
static wxChar dashChar = '\x96'; // dec 150
1324
wxChar itemChar = bulletChar;
1325
bool useZapfDingBats = false;
1327
wxString type = GetXmlAttribute(child, wxT("type"), wxT("bullet"));
1329
if (type.IsNumber() && type.ToLong(&zapfChar))
1331
if (zapfChar >= 0 && zapfChar <= 255)
1333
itemChar = zapfChar;
1334
useZapfDingBats = true;
1337
else if (type.Lower() == wxT("dash"))
1339
itemChar = dashChar;
1341
double leftMargin = GetLeftMargin();
1342
double indent = GetFontSize() / GetScaleFactor();
1343
SetLeftMargin(leftMargin + indent);
1344
wxXmlNode *listChild = child->GetChildren();
1347
if ((listChild->GetName()).Lower() == wxT("li"))
1349
wxString saveFont = GetFontFamily();
1350
wxString saveStyle = GetFontStyle();
1351
double saveSize = GetFontSize();
1352
if (useZapfDingBats)
1354
SetFont(wxT("zapfdingbats"), wxT(""), 0.7*saveSize);
1358
SetFont(wxT("Helvetica"), wxT(""), saveSize);
1360
SetLeftMargin(leftMargin);
1361
SetXY(leftMargin, GetY());
1362
WriteCell(GetLineHeight(), wxString(itemChar));
1363
SetLeftMargin(leftMargin+indent);
1364
SetXY(leftMargin+indent, GetY());
1365
SetFont(saveFont, saveStyle, saveSize);
1367
newContext = context.GetCurrentContext();
1368
context.IncrementCurrentContext();
1369
WriteXmlCell(listChild, *newContext);
1372
listChild = listChild->GetNext();
1374
SetLeftMargin(leftMargin);
1375
SetXY(leftMargin, GetY());
1377
else if (name == wxT("ol"))
1380
bool useZapfDingBats = false;
1385
wxString start = GetXmlAttribute(child, wxT("start"), wxT("1"));
1386
if (start.IsNumber() && start.ToLong(&listStart))
1388
listCount += (listStart - 1);
1390
double indent = GetStringWidth(wxT(" 00. "));
1391
wxString type = GetXmlAttribute(child, wxT("type"), wxT("1"));
1392
if (type.Length() > 0)
1394
if (type[0] == wxT('1'))
1398
else if (type[0] == wxT('a'))
1402
indent = GetStringWidth(wxT(" xx. "));
1404
else if (type[0] == wxT('A'))
1408
indent = GetStringWidth(wxT(" XX. "));
1410
else if (type[0] == wxT('i'))
1413
indent = GetStringWidth(wxT(" xxx. "));
1415
else if (type[0] == wxT('I'))
1418
indent = GetStringWidth(wxT(" XXX. "));
1420
else if (type[0] == wxT('z'))
1422
if (type.Length() > 1 && type[1] >= wxT('1') && type[1] <= wxT('4'))
1424
useZapfDingBats = true;
1425
listType = type[1] - wxT('1');
1427
indent = 1.1 * GetFontSize() / GetScaleFactor();
1431
double leftMargin = GetLeftMargin();
1432
SetLeftMargin(leftMargin + indent);
1434
wxXmlNode *listChild = child->GetChildren();
1437
if ((listChild->GetName()).Lower() == wxT("li"))
1439
wxString saveFont = GetFontFamily();
1440
wxString saveStyle = GetFontStyle();
1441
double saveSize = GetFontSize();
1442
SetLeftMargin(leftMargin);
1443
SetXY(leftMargin, GetY());
1444
if (useZapfDingBats)
1446
SetFont(wxT("zapfdingbats"), wxT(""), 0.85*saveSize);
1447
wxChar itemChar = 172 + 10 * listType + listCount % listCycle;
1448
WriteCell(GetLineHeight(), wxString(itemChar));
1453
SetFont(wxT("Helvetica"), wxT(""), saveSize);
1458
itemChar = wxT('a') + listCount % listCycle;
1459
item = wxString(itemChar) + wxT(". ");
1462
itemChar = wxT('A') + listCount % listCycle;
1463
item = wxString(itemChar) + wxT(". ");
1466
item = wxPdfUtility::Convert2Roman(listCount+1).Lower() + wxT(". ");
1469
item = wxPdfUtility::Convert2Roman(listCount+1) + wxT(". ");
1473
item = wxString::Format(wxT("%d. "), listCount+1);
1476
Cell(indent, GetLineHeight(), item, wxPDF_BORDER_NONE, 0, wxPDF_ALIGN_RIGHT);
1479
SetLeftMargin(leftMargin+indent);
1480
SetXY(leftMargin+indent, GetY());
1481
SetFont(saveFont, saveStyle, saveSize);
1483
newContext = context.GetCurrentContext();
1484
context.IncrementCurrentContext();
1485
WriteXmlCell(listChild, *newContext);
1488
listChild = listChild->GetNext();
1490
SetLeftMargin(leftMargin);
1491
SetXY(leftMargin, GetY());
1493
else if (name == wxT("br"))
1497
context.IncrementCurrentLine();
1499
else if (name == wxT("p"))
1502
if (GetX() > GetLeftMargin())
1506
newContext = context.GetCurrentContext();
1507
context.IncrementCurrentContext();
1508
WriteXmlCell(child, *newContext);
1509
if (GetX() > GetLeftMargin())
1515
else if (name == wxT("hr"))
1517
// --- Horizontal rule
1518
double hrWidth = GetPageWidth() - GetLeftMargin() - GetRightMargin();
1521
wxString strWidth = GetXmlAttribute(child, wxT("width"), wxT(""));
1522
if (strWidth.Length() > 0 && strWidth.ToLong(&widthAttr))
1524
hrWidth = hrWidth * 0.01 * widthAttr;
1528
double wLine = GetLineWidth();
1530
Line(x, y, x + hrWidth, y);
1531
SetLineWidth(wLine);
1534
else if (name == wxT("a"))
1537
wxString href = GetXmlAttribute(child, wxT("href"), wxT(""));
1538
wxString nameAttr = GetXmlAttribute(child, wxT("name"), wxT(""));
1539
if (href.Length() > 0)
1541
if (href[0] == wxT('#'))
1543
nameAttr = href.Right(href.Length()-1);
1544
if (nameAttr.Length() > 0)
1546
if (m_namedLinks->find(nameAttr) == m_namedLinks->end())
1548
(*m_namedLinks)[nameAttr] = AddLink();
1552
context.SetHRef(href);
1553
wxPdfColour saveColour = GetTextColour();
1554
SetTextColour(0, 0, 255);
1555
wxString style = GetFontStyle();
1556
if (!style.Contains(wxT("U")))
1558
SetFont(wxT(""), style + wxT("U"));
1559
WriteXmlCell(child, context);
1560
SetFont(wxT(""), style);
1564
WriteXmlCell(child, context);
1566
SetTextColour(saveColour);
1567
context.SetHRef(wxT(""));
1569
else if (nameAttr.Length() > 0)
1572
if (m_namedLinks->find(nameAttr) == m_namedLinks->end())
1575
(*m_namedLinks)[nameAttr] = link;
1579
link = (*m_namedLinks)[nameAttr];
1581
SetLink(link, -1, -1);
1582
WriteXmlCell(child, context);
1586
WriteXmlCell(child, context);
1589
else if (name == wxT("img"))
1592
wxString src = GetXmlAttribute(child, wxT("src"), wxT(""));
1593
if (src.Length() > 0)
1597
wxString strWidth = GetXmlAttribute(child, wxT("width"), wxT("0"));
1598
wxString strHeight = GetXmlAttribute(child, wxT("height"), wxT("0"));
1599
if (!strWidth.ToLong(&width)) width = 0;
1600
if (!strHeight.ToLong(&height)) height = 0;
1603
double w = ((double) width) / (GetImageScale() * GetScaleFactor());
1604
double h = ((double) height) / (GetImageScale() * GetScaleFactor());
1605
wxString align = GetXmlAttribute(child, wxT("align"), wxT("left")).Lower();
1607
if (align == wxT("right"))
1609
delta = context.GetMaxWidth() - w;
1611
else if (align == wxT("center"))
1613
delta = 0.5 * (context.GetMaxWidth() - w);
1619
// line height, position, margins etc.
1620
if (GetX() > GetLeftMargin())
1624
Image(src, x+delta, y, w, h);
1628
else if (name == wxT("span"))
1630
int saveFillStyle = context.GetFillStyle();
1631
wxPdfColour saveColor = GetFillColour();
1632
wxString strColor = GetXmlAttribute(child, wxT("color"), wxT(""));
1633
if (strColor.Length() > 0)
1635
SetFillColour(wxPdfColour(strColor));
1636
context.SetFillStyle(1);
1638
WriteXmlCell(child, context);
1639
if (strColor.Length() > 0)
1641
context.SetFillStyle(saveFillStyle);
1642
SetFillColour(saveColor);
1645
else if (name == wxT("font"))
1648
wxString saveFamily = GetFontFamily();
1649
wxString saveStyle = GetFontStyle();
1650
double saveSize = GetFontSize();
1651
wxPdfColour saveColour = GetTextColour();
1652
wxString strFace = GetXmlAttribute(child, wxT("face"), wxT(""));
1653
wxString strSize = GetXmlAttribute(child, wxT("size"), wxT(""));
1654
wxString strColour = GetXmlAttribute(child, wxT("color"), wxT(""));
1656
if (strSize.Length() > 0)
1658
size = wxPdfUtility::String2Double(strSize);
1660
if (size <= 0) size = saveSize;
1661
SetFont(strFace, saveStyle, size);
1662
if (strColour.Length() > 0)
1664
SetTextColour(wxPdfColour(strColour));
1666
WriteXmlCell(child, context);
1667
if (strColour.Length() > 0)
1669
SetTextColour(saveColour);
1671
SetFont(saveFamily, saveStyle, saveSize);
1673
else if (name == wxT("code"))
1676
wxString saveFamily = GetFontFamily();
1677
wxString saveStyle = GetFontStyle();
1678
double saveSize = GetFontSize();
1679
wxPdfColour saveColour = GetTextColour();
1680
wxString strFace = GetXmlAttribute(child, wxT("face"), wxT("courier"));
1681
wxString strSize = GetXmlAttribute(child, wxT("size"), wxT("10"));
1682
wxString strColour = GetXmlAttribute(child, wxT("color"), wxT(""));
1684
if (strSize.Length() > 0)
1686
size = wxPdfUtility::String2Double(strSize);
1688
if (size <= 0) size = saveSize;
1689
SetFont(strFace, wxT(""), size);
1690
if (strColour.Length() > 0)
1692
SetTextColour(wxPdfColour(strColour));
1695
context.IncrementCurrentLine();
1696
WriteXmlCell(child, context);
1698
if (strColour.Length() > 0)
1700
SetTextColour(saveColour);
1702
SetFont(saveFamily, saveStyle, saveSize);
1704
else if (name == wxT("h1") || name == wxT("h2") || name == wxT("h3") ||
1705
name == wxT("h4") || name == wxT("h5") || name == wxT("h6"))
1708
newContext = context.GetCurrentContext();
1709
context.IncrementCurrentContext();
1711
double headsize = (wxT('4') - name[1]) * 2;
1712
double currentFontSize = GetFontSize();
1713
if (GetX() > GetLeftMargin())
1718
wxString addStyle = wxT("B");
1719
wxString style = GetFontStyle();
1720
if (!style.Contains(addStyle))
1722
SetFont(wxT(""), style + addStyle, currentFontSize + headsize);
1723
WriteXmlCell(child, *newContext);
1724
SetFont(wxT(""), style, currentFontSize);
1728
SetFontSize(currentFontSize + headsize);
1729
WriteXmlCell(child, *newContext);
1730
SetFontSize(currentFontSize);
1734
else if (name == wxT("table"))
1737
newContext = context.GetCurrentContext();
1738
context.IncrementCurrentContext();
1739
WriteXmlTable(*newContext);
1744
if (child->GetType() == wxXML_TEXT_NODE || name == wxT("msg"))
1746
wxPdfLink link = wxPdfLink(-1);
1747
wxString href = context.GetHRef();
1748
if (href.Length() > 0)
1750
if (href[0] == wxT('#'))
1752
wxString nameAttr = href.Right(href.Length()-1);
1753
if (nameAttr.Length() > 0)
1755
if (m_namedLinks->find(nameAttr) != m_namedLinks->end())
1757
link = wxPdfLink((*m_namedLinks)[nameAttr]);
1763
link = wxPdfLink(href);
1767
double h = GetLineHeight();
1768
double wmax = context.GetCurrentLineWidth() + wxPDF_EPSILON;
1769
DoXmlAlign(context);
1772
if (name == wxT("msg"))
1774
s = GetNodeContent(child);
1775
if (m_translate) s = wxGetTranslation(s);
1779
s = child->GetContent();
1781
s.Replace(wxT("\r"),wxT("")); // remove carriage returns
1782
int nb = (int) s.Length();
1783
if (nb > 0 && s[nb-1] == wxT('\n'))
1797
// Get next character
1801
// Explicit line break
1807
WriteCell(h,s.SubString(j,i-1), wxPDF_BORDER_NONE, context.GetFillStyle(), link);
1814
context.IncrementCurrentLine();
1816
DoXmlAlign(context);
1817
wmax = context.GetCurrentLineWidth();
1825
len = GetStringWidth(s.SubString(j, i));
1829
// Automatic line break
1832
// Case 1: current line length exactly matches the maximum with
1833
// Case 2: current line contains no spaces and line length plus epsilon exactly matches the maximum width
1834
// (line break in the middle of a word if the word is too long to fit on the line)
1835
if ( wmax == context.GetCurrentLineWidth() ||
1836
((wmax == context.GetCurrentLineWidth() + wxPDF_EPSILON) && context.GetCurrentLineSpaces() == 0))
1842
WriteCell(h,s.SubString(j,i-1), wxPDF_BORDER_NONE, context.GetFillStyle(), link);
1851
WriteCell(h,s.SubString(j,sep-1), wxPDF_BORDER_NONE, context.GetFillStyle(), link);
1859
context.IncrementCurrentLine();
1861
DoXmlAlign(context);
1862
wmax = context.GetCurrentLineWidth();
1870
WriteCell(h,s.SubString(j,i-1), wxPDF_BORDER_NONE, context.GetFillStyle(), link);
1871
context.AddCurrentLineWidth(-len);
1872
if (context.GetHAlign() == wxPDF_ALIGN_JUSTIFY && m_ws > 0)
1874
double delta = ns * m_ws;
1875
SetXY(GetX()+delta, GetY());
1879
child = child->GetNext();
1884
wxPdfDocument::DoXmlAlign(wxPdfCellContext& context)
1886
if (!context.GetAligned())
1888
if (m_ws > 0 && context.GetHAlign() != wxPDF_ALIGN_JUSTIFY)
1893
switch (context.GetHAlign())
1895
case wxPDF_ALIGN_JUSTIFY:
1897
m_ws = (!context.IsCurrentLineMarked() && context.GetCurrentLineSpaces() > 0) ? (context.GetMaxWidth() - context.GetCurrentLineWidth())/context.GetCurrentLineSpaces() : 0;
1898
OutAscii(wxPdfUtility::Double2String(m_ws*m_k,3)+wxString(wxT(" Tw")));
1901
case wxPDF_ALIGN_CENTER:
1903
double delta = 0.5 * (context.GetMaxWidth() - context.GetCurrentLineWidth());
1904
SetXY(GetX()+delta,GetY());
1907
case wxPDF_ALIGN_RIGHT:
1909
double delta = context.GetMaxWidth() - context.GetCurrentLineWidth();
1910
SetXY(GetX()+delta,GetY());
1913
case wxPDF_ALIGN_LEFT:
1918
context.SetAligned();