1
///////////////////////////////////////////////////////////////////////////////
2
// Name: pdfdocument.cpp
3
// Purpose: Implementation of wxPdfDocument (public methods)
4
// Author: Ulrich Telle
7
// Copyright: (c) Ulrich Telle
8
// Licence: wxWindows licence
9
///////////////////////////////////////////////////////////////////////////////
11
/// \file pdfdocument.cpp Implementation of the wxPdfDocument class
13
// For compilers that support precompilation, includes <wx/wx.h>.
14
#include <wx/wxprec.h>
26
#include <wx/wfstream.h>
28
#include "wx/pdfbookmark.h"
29
#include "wx/pdfdocument.h"
30
#include "wx/pdffont.h"
31
#include "wx/pdffontdetails.h"
32
#include "wx/pdffontmanager.h"
33
#include "wx/pdfform.h"
34
#include "wx/pdfgradient.h"
35
#include "wx/pdfgraphics.h"
36
#include "wx/pdflayer.h"
37
#include "wx/pdfparser.h"
38
#include "wx/pdfpattern.h"
39
#include "wx/pdfspotcolour.h"
40
#include "wx/pdftemplate.h"
41
#include "wx/pdffontparser.h"
42
#include "wx/pdfutility.h"
44
#if WXPDFDOC_INHERIT_WXOBJECT
45
IMPLEMENT_DYNAMIC_CLASS(wxPdfDocument, wxObject)
48
// ----------------------------------------------------------------------------
49
// wxPdfDocument: class representing a PDF document
50
// ----------------------------------------------------------------------------
52
wxPdfDocument::wxPdfDocument(int orientation, const wxString& unit, wxPaperSize format)
53
#if WXPDFDOC_INHERIT_WXOBJECT
57
m_yAxisOriginTop = true;
61
m_defPageSize = CalculatePageSize(format);
62
Initialize(orientation);
65
wxPdfDocument::wxPdfDocument(int orientation, double pageWidth, double pageHeight, const wxString& unit)
66
#if WXPDFDOC_INHERIT_WXOBJECT
70
m_yAxisOriginTop = true;
72
m_defPageSize = CalculatePageSize(pageWidth, pageHeight);
73
Initialize(orientation);
77
wxPdfDocument::SetScaleFactor(const wxString& unit)
80
if (unit == wxT("pt"))
84
else if (unit == wxT("in"))
88
else if (unit == wxT("cm"))
92
else // if (unit == "mm") or unknown
99
wxPdfDocument::CalculatePageSize(wxPaperSize format)
101
bool deletePaperDatabase = false;
102
wxPrintPaperDatabase* printPaperDatabase = wxThePrintPaperDatabase;
103
if (printPaperDatabase == NULL)
105
printPaperDatabase = new wxPrintPaperDatabase;
106
printPaperDatabase->CreateDatabase();
107
deletePaperDatabase = true;
109
wxPrintPaperType* paperType = printPaperDatabase->FindPaperType(format);
110
if (paperType == NULL)
112
paperType = printPaperDatabase->FindPaperType(wxPAPER_A4);
114
wxSize paperSize = paperType->GetSize();
115
if (deletePaperDatabase)
117
delete printPaperDatabase;
123
wxPdfDocument::CalculatePageSize(double pageWidth, double pageHeight)
125
int width = (int) (pageWidth * (m_k * 254. / 72.));
126
int height = (int) (pageHeight * (m_k * 254. / 72.));
127
return wxSize(width,height);
131
wxPdfDocument::Initialize(int orientation)
134
m_currentFont = NULL;
135
m_buffer = new wxMemoryOutputStream();
139
m_offsets = new wxPdfOffsetHashMap();
141
m_pages = new wxPdfPageHashMap();
142
m_pageSizes = new wxPdfPageSizeMap();
143
m_orientationChanges = new wxPdfBoolHashMap();
146
m_fonts = new wxPdfFontHashMap();
147
m_images = new wxPdfImageHashMap();
148
m_pageLinks = new wxPdfPageLinksMap();
149
m_links = new wxPdfLinkHashMap();
150
m_namedLinks = new wxPdfNamedLinksMap();
151
m_diffs = new wxPdfStringHashMap();
152
m_winansi = new wxPdfBoolHashMap();
153
m_extGStates = new wxPdfExtGStateMap();
154
m_extGSLookup = new wxPdfExtGSLookupMap();
155
m_currentExtGState = 0;
156
m_gradients = new wxPdfGradientMap();
157
m_annotations = new wxPdfAnnotationsMap();
158
m_formAnnotations = new wxPdfFormAnnotsMap();
159
m_formFields = new wxPdfFormFieldsMap();
160
m_radioGroups = new wxPdfRadioGroupMap();
161
m_templates = new wxPdfTemplatesMap();
162
m_parsers = new wxPdfParserMap();
163
m_spotColours = new wxPdfSpotColourMap();
164
m_patterns = new wxPdfPatternMap();
165
m_ocgs = new wxPdfOcgMap();
166
m_rgLayers = new wxPdfLayerRGMap();
167
m_lockedLayers = NULL;
168
m_attachments = new wxPdfAttachmentMap();
171
m_maxOutlineLevel = 0;
175
m_fontFamily = wxEmptyString;
176
m_fontStyle = wxPDF_FONTSTYLE_REGULAR;
178
m_decoration = wxPDF_FONTSTYLE_REGULAR;
179
m_fontSubsetting = true;
181
m_drawColour = wxPdfColour();
182
m_fillColour = wxPdfColour();
183
m_textColour = wxPdfColour();
184
m_colourFlag = false;
186
m_textRenderMode = wxPDF_TEXT_RENDER_FILL;
188
// Initialize image scale factor
192
m_curPageSize = m_defPageSize;
193
m_fwPt = m_defPageSize.GetWidth() / 254. * 72.;
194
m_fhPt = m_defPageSize.GetHeight() / 254. * 72.;
199
if (orientation == wxLANDSCAPE)
201
m_defOrientation = wxLANDSCAPE;
205
else // orientation == wxPORTRAIT or unknown
207
m_defOrientation = wxPORTRAIT;
212
m_curOrientation = m_defOrientation;
216
m_fillRule = wxWINDING_RULE;
219
// Page margins (1 cm)
220
double margin = 28.35 / m_k;
221
SetMargins(margin, margin);
223
// Interior cell margin (1 mm)
224
m_cMargin = margin / 10;
226
// Line width (0.2 mm)
227
m_lineWidth = .567 / m_k;
229
// Automatic page break
230
SetAutoPageBreak(true, 2*margin);
232
// Full width display mode
233
SetDisplayMode(wxPDF_ZOOM_FULLWIDTH);
236
// Default viewer preferences
242
// Enable compression
243
SetCompression(true);
245
// Set default PDF version number
246
m_PDFVersion = wxT("1.3");
247
m_importVersion = m_PDFVersion;
252
m_javascript = wxEmptyString;
254
m_inTemplate = false;
256
m_templatePrefix = wxT("/TPL");
258
m_currentParser = NULL;
259
m_currentSource = wxEmptyString;
266
wxPdfDocument::~wxPdfDocument()
268
wxPdfFontHashMap::iterator font = m_fonts->begin();
269
for (font = m_fonts->begin(); font != m_fonts->end(); font++)
271
if (font->second != NULL)
278
wxPdfImageHashMap::iterator image = m_images->begin();
279
for (image = m_images->begin(); image != m_images->end(); image++)
281
if (image->second != NULL)
283
delete image->second;
288
wxPdfPageHashMap::iterator page = m_pages->begin();
289
for (page = m_pages->begin(); page != m_pages->end(); page++)
291
if (page->second != NULL)
298
wxPdfPageLinksMap::iterator pageLinks = m_pageLinks->begin();
299
for (pageLinks = m_pageLinks->begin(); pageLinks != m_pageLinks->end(); pageLinks++)
301
if (pageLinks->second != NULL)
303
delete pageLinks->second;
308
wxPdfLinkHashMap::iterator link = m_links->begin();
309
for (link = m_links->begin(); link != m_links->end(); link++)
311
if (link->second != NULL)
321
for (j = 0; j < m_outlines.GetCount(); j++)
323
wxPdfBookmark* bookmark = (wxPdfBookmark*) m_outlines[j];
327
wxPdfStringHashMap::iterator diff = m_diffs->begin();
328
for (diff = m_diffs->begin(); diff != m_diffs->end(); diff++)
330
if (diff->second != NULL)
339
wxPdfExtGStateMap::iterator extGState = m_extGStates->begin();
340
for (extGState = m_extGStates->begin(); extGState != m_extGStates->end(); extGState++)
342
if (extGState->second != NULL)
344
delete extGState->second;
349
delete m_extGSLookup;
351
wxPdfGradientMap::iterator gradient = m_gradients->begin();
352
for (gradient = m_gradients->begin(); gradient != m_gradients->end(); gradient++)
354
if (gradient->second != NULL)
356
delete gradient->second;
361
wxPdfAnnotationsMap::iterator annotation = m_annotations->begin();
362
for (annotation = m_annotations->begin(); annotation != m_annotations->end(); annotation++)
364
if (annotation->second != NULL)
366
delete annotation->second;
369
delete m_annotations;
371
wxPdfFormAnnotsMap::iterator formAnnotation = m_formAnnotations->begin();
372
for (formAnnotation = m_formAnnotations->begin(); formAnnotation != m_formAnnotations->end(); formAnnotation++)
374
if (formAnnotation->second != NULL)
376
delete formAnnotation->second;
379
delete m_formAnnotations;
381
wxPdfFormFieldsMap::iterator formField = m_formFields->begin();
382
for (formField = m_formFields->begin(); formField != m_formFields->end(); formField++)
384
if (formField->second != NULL)
386
delete formField->second;
391
wxPdfRadioGroupMap::iterator radioGroup = m_radioGroups->begin();
392
for (radioGroup = m_radioGroups->begin(); radioGroup != m_radioGroups->end(); radioGroup++)
394
if (radioGroup->second != NULL)
396
delete radioGroup->second;
399
delete m_radioGroups;
401
wxPdfTemplatesMap::iterator templateIter = m_templates->begin();
402
for (templateIter = m_templates->begin(); templateIter != m_templates->end(); templateIter++)
404
if (templateIter->second != NULL)
406
delete templateIter->second;
411
wxPdfParserMap::iterator parser = m_parsers->begin();
412
for (parser = m_parsers->begin(); parser != m_parsers->end(); parser++)
414
if (parser->second != NULL)
416
delete parser->second;
421
wxPdfSpotColourMap::iterator spotColour = m_spotColours->begin();
422
for (spotColour = m_spotColours->begin(); spotColour != m_spotColours->end(); spotColour++)
424
if (spotColour->second != NULL)
426
delete spotColour->second;
429
delete m_spotColours;
431
wxPdfPatternMap::iterator pattern = m_patterns->begin();
432
for (pattern = m_patterns->begin(); pattern != m_patterns->end(); pattern++)
434
if (pattern->second != NULL)
436
delete pattern->second;
441
wxPdfOcgMap::iterator ocg = m_ocgs->begin();
442
for (ocg = m_ocgs->begin(); ocg != m_ocgs->end(); ++ocg)
444
if (ocg->second != NULL)
451
wxPdfLayerRGMap::iterator rg;
452
for (rg = m_rgLayers->begin(); rg != m_rgLayers->end(); ++rg)
454
if (rg->second != NULL)
461
if (m_lockedLayers != NULL)
463
delete m_lockedLayers;
466
wxPdfAttachmentMap::iterator attach;
467
for (attach = m_attachments->begin(); attach != m_attachments->end(); ++attach)
469
if (attach->second != NULL)
471
delete attach->second;
474
delete m_attachments;
476
delete m_orientationChanges;
481
if (m_encryptor != NULL)
486
if (m_buffer != NULL)
492
// --- Public methods
495
wxPdfDocument::SetProtection(int permissions,
496
const wxString& userPassword,
497
const wxString& ownerPassword,
498
wxPdfEncryptionMethod encryptionMethod,
501
if (m_encryptor == NULL)
503
int revision = (keyLength > 0) ? 3 : 2;
504
switch (encryptionMethod)
506
case wxPDF_ENCRYPTION_AESV2:
508
if (m_PDFVersion < wxT("1.6"))
510
m_PDFVersion = wxT("1.6");
513
case wxPDF_ENCRYPTION_RC4V2:
516
case wxPDF_ENCRYPTION_RC4V1:
521
m_encryptor = new wxPdfEncrypt(revision, keyLength);
523
int allowedFlags = wxPDF_PERMISSION_PRINT | wxPDF_PERMISSION_MODIFY |
524
wxPDF_PERMISSION_COPY | wxPDF_PERMISSION_ANNOT;
525
int protection = 192;
526
protection += (permissions & allowedFlags);
527
wxString ownerPswd = ownerPassword;
528
if (ownerPswd.Length() == 0)
530
ownerPswd = wxPdfUtility::GetUniqueId(wxT("wxPdfDoc"));
532
m_encryptor->GenerateEncryptionKey(userPassword, ownerPswd, protection);
537
wxPdfDocument::SetImageScale(double scale)
543
wxPdfDocument::GetImageScale()
549
wxPdfDocument::GetPageWidth()
555
wxPdfDocument::GetPageHeight()
561
wxPdfDocument::GetBreakMargin()
567
wxPdfDocument::GetScaleFactor()
573
wxPdfDocument::AliasNbPages(const wxString& alias)
575
// Define an alias for total number of pages
576
m_aliasNbPages = alias;
580
wxPdfDocument::Open()
587
wxPdfDocument::AddPage(int orientation)
589
AddPage(orientation, m_defPageSize);
593
wxPdfDocument::AddPage(int orientation, wxPaperSize format)
595
wxSize pageSize = CalculatePageSize(format);
596
AddPage(orientation, pageSize);
600
wxPdfDocument::AddPage(int orientation, double pageWidth, double pageHeight)
602
if (pageWidth > 0 && pageHeight > 0)
604
wxSize pageSize = CalculatePageSize(pageWidth, pageHeight);
605
AddPage(orientation, pageSize);
609
wxLogError(wxString(wxT("wxPdfDocument::AddPage: ")) +
610
wxString::Format(_("Invalid page size (%.1f,%.1f)."), pageWidth, pageHeight));
615
wxPdfDocument::AddPage(int orientation, wxSize pageSize)
619
wxLogError(wxString(wxT("wxPdfDocument::AddPage: ")) +
620
wxString::Format(_("Adding pages in templates is impossible. Current template ID is %d."), m_templateId));
629
wxPdfFontDetails* currentFont = m_currentFont;
630
wxString family = m_fontFamily;
631
int style = m_fontStyle;
632
if (m_decoration & wxPDF_FONTSTYLE_UNDERLINE)
634
style |= wxPDF_FONTSTYLE_UNDERLINE;
636
if (m_decoration & wxPDF_FONTSTYLE_OVERLINE)
638
style |= wxPDF_FONTSTYLE_OVERLINE;
640
if (m_decoration & wxPDF_FONTSTYLE_STRIKEOUT)
642
style |= wxPDF_FONTSTYLE_STRIKEOUT;
644
double size = m_fontSizePt;
645
double lw = m_lineWidth;
646
wxPdfColour dc = m_drawColour;
647
wxPdfColour fc = m_fillColour;
648
wxPdfColour tc = m_textColour;
649
bool cf = m_colourFlag;
662
BeginPage(orientation, pageSize);
664
// Set line cap style to square
669
OutAscii(wxPdfUtility::Double2String(lw*m_k,2)+wxString(wxT(" w")));
672
if (currentFont != NULL)
674
m_currentFont = currentFont;
682
if (dc != wxPdfColour(0))
684
OutAscii(dc.GetColour(true));
687
if (fc != wxPdfColour(0))
689
OutAscii(fc.GetColour(false));
697
// Restore line width
698
if (m_lineWidth != lw)
701
OutAscii(wxPdfUtility::Double2String(lw*m_k,2)+wxString(wxT(" w")));
705
if(family.Length() > 0)
707
SetFont(family, style, size);
709
if (currentFont != NULL)
711
SetFont(currentFont->GetUserFont(), style, size);
715
if (m_drawColour != dc)
718
OutAscii(dc.GetColour(true));
720
if (m_fillColour != fc)
723
OutAscii(fc.GetColour(false));
730
wxPdfDocument::SetLineWidth(double width)
736
OutAscii(wxPdfUtility::Double2String(width*m_k,2)+ wxString(wxT(" w")));
741
wxPdfDocument::GetLineWidth()
747
wxPdfDocument::AddFont(const wxString& family, const wxString& style, const wxString& file)
749
bool ok = !family.IsEmpty();
752
wxPdfFont regFont = wxPdfFontManager::GetFontManager()->GetFont(family, style);
753
if (!regFont.IsValid())
755
wxString fileName = file;
756
if (fileName.IsEmpty())
758
fileName = family.Lower() + style.Lower() + wxString(wxT(".xml"));
759
fileName.Replace(wxT(" "),wxT(""));
761
regFont = wxPdfFontManager::GetFontManager()->RegisterFont(fileName, family);
762
ok = regFont.IsValid();
771
wxPdfDocument::AddFontCJK(const wxString& family)
773
bool ok = !family.IsEmpty();
776
wxPdfFont regFont = wxPdfFontManager::GetFontManager()->GetFont(family);
777
if (!regFont.IsValid())
779
ok = wxPdfFontManager::GetFontManager()->RegisterFontCJK(family);
785
#endif // wxUSE_UNICODE
788
wxPdfDocument::SetFont(const wxString& family, const wxString& style, double size)
790
return SelectFont(family, style, size);
794
wxPdfDocument::SetFont(const wxString& family, int style, double size)
796
return SelectFont(family, style, size);
800
wxPdfDocument::SetFont(const wxPdfFont& font, int style, double size)
802
return SelectFont(font, style, size);
806
wxPdfDocument::SetFont(const wxFont& font)
808
return SelectFont(font);
812
wxPdfDocument::SetFontSize(double size)
814
if (m_currentFont == NULL)
816
wxLogError(wxString(wxT("wxPdfDocument::SetFontSize: ")) +
817
wxString(_("No font selected.")));
820
// Set font size in points
821
if (m_fontSizePt == size)
826
m_fontSize = size / m_k;
829
OutAscii(wxString::Format(wxT("BT /F%d "),m_currentFont->GetIndex()) +
830
wxPdfUtility::Double2String(m_fontSizePt,2) + wxString(wxT(" Tf ET")));
835
wxPdfDocument::GetCurrentFont() const
837
if (m_currentFont == NULL)
839
wxLogError(wxString(wxT("wxPdfDocument::GetCurrentFont: ")) +
840
wxString(_("No font selected.")));
843
return m_currentFont->GetUserFont();
846
const wxPdfFontDescription&
847
wxPdfDocument::GetFontDescription() const
849
if (m_currentFont == NULL)
851
wxLogError(wxString(wxT("wxPdfDocument::SetFontSize: ")) +
852
wxString(_("No font selected.")));
853
static wxPdfFontDescription dummy;
856
return m_currentFont->GetDescription();
860
wxPdfDocument::GetFontFamily()
866
wxPdfDocument::GetFontStyle() const
868
wxString style = wxEmptyString;
869
int styles = GetFontStyles();
870
if (styles & wxPDF_FONTSTYLE_BOLD)
872
style += wxString(wxT("B"));
874
if (styles & wxPDF_FONTSTYLE_ITALIC)
876
style += wxString(wxT("I"));
878
if (styles & wxPDF_FONTSTYLE_UNDERLINE)
880
style += wxString(wxT("U"));
882
if (styles & wxPDF_FONTSTYLE_OVERLINE)
884
style += wxString(wxT("O"));
886
if (styles & wxPDF_FONTSTYLE_STRIKEOUT)
888
style += wxString(wxT("S"));
894
wxPdfDocument::GetFontStyles() const
896
return m_fontStyle | m_decoration;
900
wxPdfDocument::GetFontSize() const
906
wxPdfDocument::GetStringWidth(const wxString& s)
908
wxString voText = ApplyVisualOrdering(s);
909
return DoGetStringWidth(voText);
913
wxPdfDocument::DoGetStringWidth(const wxString& s)
916
if (m_currentFont != 0)
918
w = m_currentFont->GetStringWidth(s, m_kerning) * m_fontSize;
924
wxPdfDocument::Text(double x, double y, const wxString& txt)
927
wxString voText = ApplyVisualOrdering(txt);
932
OutAscii(m_textColour.GetColour(false), false);
935
if (m_yAxisOriginTop)
937
OutAscii(wxString(wxT("BT 1 0 0 -1 ")) +
938
wxPdfUtility::Double2String(x*m_k,2) + wxString(wxT(" ")) +
939
wxPdfUtility::Double2String(y*m_k,2) + wxString(wxT(" Tm ")), false);
943
OutAscii(wxString(wxT("BT ")) +
944
wxPdfUtility::Double2String(x*m_k,2) + wxString(wxT(" ")) +
945
wxPdfUtility::Double2String(y*m_k,2) + wxString(wxT(" Td ")), false);
947
OutAscii(wxString::Format(wxT("%d Tr "), m_textRenderMode), false);
951
if ((m_decoration & wxPDF_FONTSTYLE_DECORATION_MASK) && voText.Length() > 0)
954
OutAscii(DoDecoration(x, y, voText), false);
965
wxPdfDocument::RotatedText(double x, double y, const wxString& txt, double angle)
967
// Text rotated around its origin
982
wxPdfDocument::AcceptPageBreak()
984
// Accept automatic page break or not
985
return m_autoPageBreak;
989
wxPdfDocument::Cell(double w, double h, const wxString& txt, int border, int ln, int align, int fill, const wxPdfLink& link)
991
wxString voText = ApplyVisualOrdering(txt);
992
DoCell(w, h, voText, border, ln, align, fill, link);
996
wxPdfDocument::DoCell(double w, double h, const wxString& txt, int border, int ln, int align, int fill, const wxPdfLink& link)
1001
bool doPageBreak = (m_yAxisOriginTop) ? (m_y+h > m_pageBreakTrigger) : (m_y-h < m_pageBreakTrigger);
1002
if (doPageBreak && !m_inFooter && AcceptPageBreak())
1004
// Automatic page break
1012
AddPage(m_curOrientation);
1017
OutAscii(wxPdfUtility::Double2String(ws*k,3)+wxString(wxT(" Tw")));
1022
w = m_w - m_rMargin - m_x;
1024
wxString s = wxEmptyString;
1025
if (fill == 1 || border == wxPDF_BORDER_FRAME)
1027
s = wxPdfUtility::Double2String(m_x*k,2) + wxString(wxT(" ")) +
1028
wxPdfUtility::Double2String(m_y*k,2) + wxString(wxT(" ")) +
1029
wxPdfUtility::Double2String(w*k,2) + wxString(wxT(" ")) +
1030
wxPdfUtility::Double2String(h*k,2);
1033
if (border == wxPDF_BORDER_FRAME)
1035
s += wxString(wxT(" re B "));
1039
s += wxString(wxT(" re f "));
1044
s += wxString(wxT(" re S "));
1047
if (border != wxPDF_BORDER_NONE && border != wxPDF_BORDER_FRAME)
1051
if (border & wxPDF_BORDER_LEFT)
1053
s += wxPdfUtility::Double2String(x*k,2) + wxString(wxT(" ")) +
1054
wxPdfUtility::Double2String(y*k,2) + wxString(wxT(" m ")) +
1055
wxPdfUtility::Double2String(x*k,2) + wxString(wxT(" ")) +
1056
wxPdfUtility::Double2String((y+h)*k,2) + wxString(wxT(" l S "));
1058
if (border & wxPDF_BORDER_TOP)
1060
s += wxPdfUtility::Double2String(x*k,2) + wxString(wxT(" ")) +
1061
wxPdfUtility::Double2String(y*k,2) + wxString(wxT(" m ")) +
1062
wxPdfUtility::Double2String((x+w)*k,2) + wxString(wxT(" ")) +
1063
wxPdfUtility::Double2String(y*k,2) + wxString(wxT(" l S "));
1065
if (border & wxPDF_BORDER_RIGHT)
1067
s += wxPdfUtility::Double2String((x+w)*k,2) + wxString(wxT(" ")) +
1068
wxPdfUtility::Double2String(y*k,2) + wxString(wxT(" m ")) +
1069
wxPdfUtility::Double2String((x+w)*k,2) + wxString(wxT(" ")) +
1070
wxPdfUtility::Double2String((y+h)*k,2) + wxString(wxT(" l S "));
1072
if (border & wxPDF_BORDER_BOTTOM)
1074
s += wxPdfUtility::Double2String(x*k,2) + wxString(wxT(" ")) +
1075
wxPdfUtility::Double2String((y+h)*k,2) + wxString(wxT(" m ")) +
1076
wxPdfUtility::Double2String((x+w)*k,2) + wxString(wxT(" ")) +
1077
wxPdfUtility::Double2String((y+h)*k,2) + wxString(wxT(" l S "));
1082
bool newline = txt.Length() == 0;
1083
OutAscii(s, newline);
1087
if (txt.Length() > 0)
1089
double width = DoGetStringWidth(txt);
1091
if (align == wxPDF_ALIGN_RIGHT)
1093
dx = w - m_cMargin - width;
1095
else if (align == wxPDF_ALIGN_CENTER)
1097
dx = (w - width) / 2;
1105
s += wxString(wxT("q ")) + m_textColour.GetColour(false) + wxString(wxT(" "));
1107
if (m_yAxisOriginTop)
1109
s += wxString(wxT("BT 1 0 0 -1 ")) +
1110
wxPdfUtility::Double2String((m_x+dx)*k,2) + wxString(wxT(" ")) +
1111
wxPdfUtility::Double2String((m_y+.5*h+.3*m_fontSize)*k,2) + wxString(wxT(" Tm "));
1115
s += wxString(wxT("BT ")) +
1116
wxPdfUtility::Double2String((m_x+dx)*k,2) + wxString(wxT(" ")) +
1117
wxPdfUtility::Double2String((m_y+.5*h+.3*m_fontSize)*k,2) + wxString(wxT(" Td "));
1120
OutAscii(wxString::Format(wxT("%d Tr "), m_textRenderMode), false);
1124
if (m_decoration & wxPDF_FONTSTYLE_DECORATION_MASK)
1126
s += wxString(wxT(" ")) + DoDecoration(m_x+dx,m_y+.5*h+.3*m_fontSize,txt);
1130
s += wxString(wxT(" Q"));
1134
Link(m_x+dx,m_y+.5*h-.5*m_fontSize,width,m_fontSize,link);
1142
if (m_yAxisOriginTop)
1162
wxPdfDocument::MultiCell(double w, double h, const wxString& txt, int border, int align, int fill, int maxline)
1164
// Output text with automatic or explicit line breaks
1167
w = m_w - m_rMargin - m_x;
1170
double wmax = (w - 2 * m_cMargin);
1171
wxString s = ApplyVisualOrdering(txt);
1172
s.Replace(wxT("\r"),wxT("")); // remove carriage returns
1173
int nb = (int) s.Length();
1174
if (nb > 0 && s[nb-1] == wxT('\n'))
1179
int b = wxPDF_BORDER_NONE;
1180
int b2 = wxPDF_BORDER_NONE;
1181
if (border != wxPDF_BORDER_NONE)
1183
if (border == wxPDF_BORDER_FRAME)
1185
b = wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT | wxPDF_BORDER_TOP;
1186
b2 = wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT;
1190
b2 = wxPDF_BORDER_NONE;
1191
if (border & wxPDF_BORDER_LEFT)
1193
b2 = b2 | wxPDF_BORDER_LEFT;
1195
if (border & wxPDF_BORDER_RIGHT)
1197
b2 = b2 | wxPDF_BORDER_RIGHT;
1199
b = (border & wxPDF_BORDER_TOP) ? b2 | wxPDF_BORDER_TOP : b2;
1212
// Get next character
1216
// Explicit line break
1222
DoCell(w,h,s.SubString(j,i-1),b,2,align,fill);
1229
if (border != wxPDF_BORDER_NONE && nl == 2)
1233
if (maxline > 0 && nl > maxline)
1245
len = DoGetStringWidth(s.SubString(j, i));
1249
// Automatic line break
1261
DoCell(w,h,s.SubString(j,i-1),b,2,align,fill);
1265
if (align == wxPDF_ALIGN_JUSTIFY)
1267
m_ws = (ns > 1) ? (wmax - ls)/(ns-1) : 0;
1268
OutAscii(wxPdfUtility::Double2String(m_ws*m_k,3)+wxString(wxT(" Tw")));
1270
DoCell(w,h,s.SubString(j,sep-1),b,2,align,fill);
1278
if (border != wxPDF_BORDER_NONE && nl == 2)
1282
if (maxline > 0 && nl > maxline)
1298
if ((border != wxPDF_BORDER_NONE) && (border & wxPDF_BORDER_BOTTOM))
1300
b = b | wxPDF_BORDER_BOTTOM;
1302
DoCell(w,h,s.SubString(j,i-1),b,2,align,fill);
1308
wxPdfDocument::LineCount(double w, const wxString& txt)
1310
// Output text with automatic or explicit line breaks
1313
w = m_w - m_rMargin - m_x;
1316
double wmax = (w - 2 * m_cMargin);
1318
s.Replace(wxT("\r"),wxT("")); // remove carriage returns
1319
int nb = (int) s.Length();
1320
if (nb > 0 && s[nb-1] == wxT('\n'))
1333
// Get next character
1337
// Explicit line break
1349
len = DoGetStringWidth(s.SubString(j, i));
1353
// Automatic line break
1379
wxPdfDocument::TextBox(double w, double h, const wxString& txt,
1380
int halign, int valign, int border, int fill)
1385
double hrow = m_fontSize;
1386
int textrows = LineCount(w, txt);
1387
int maxrows = (int) floor(h / hrow);
1388
int rows = (textrows < maxrows) ? textrows : maxrows;
1391
if (valign == wxPDF_ALIGN_MIDDLE)
1393
dy = (h - rows * hrow) / 2;
1395
else if (valign == wxPDF_ALIGN_BOTTOM)
1397
dy = h - rows * hrow;
1402
int trail = MultiCell(w, hrow, txt, 0, halign, fill, rows);
1404
if (border == wxPDF_BORDER_FRAME)
1410
if (border & wxPDF_BORDER_LEFT) Line(xi,yi,xi,yi+h);
1411
if (border & wxPDF_BORDER_RIGHT) Line(xi+w,yi,xi+w,yi+h);
1412
if (border & wxPDF_BORDER_TOP) Line(xi,yi,xi+w,yi);
1413
if (border & wxPDF_BORDER_BOTTOM) Line(xi,yi+h,xi+w,yi+h);
1420
wxPdfDocument::Write(double h, const wxString& txt, const wxPdfLink& link)
1422
WriteCell(h, txt, wxPDF_BORDER_NONE, 0, link);
1426
wxPdfDocument::WriteCell(double h, const wxString& txt, int border, int fill, const wxPdfLink& link)
1428
// Output text in flowing mode
1429
wxString s = ApplyVisualOrdering(txt);
1431
s.Replace(wxT("\r"),wxT("")); // remove carriage returns
1432
int nb = (int) s.Length();
1434
// handle single space character
1435
if ((nb == 1) && s[0] == wxT(' '))
1437
m_x += DoGetStringWidth(s);
1441
double saveCellMargin = GetCellMargin();
1444
double w = m_w - m_rMargin - m_x;
1445
double wmax = (w - 2 * m_cMargin) + wxPDF_EPSILON;
1455
// Get next character
1459
// Explicit line break
1460
DoCell(w, h, s.SubString(j,i-1), border, 2, wxPDF_ALIGN_LEFT, fill, link);
1468
w = m_w - m_rMargin - m_x;
1469
wmax = (w - 2 * m_cMargin);
1478
len = DoGetStringWidth(s.SubString(j, i));
1481
// Automatic line break
1484
if (m_x > m_lMargin)
1486
// Move to next line
1488
if (m_yAxisOriginTop)
1496
w = m_w - m_rMargin - m_x;
1497
wmax = (w - 2 * m_cMargin);
1506
DoCell(w, h,s.SubString(j, i-1), border, 2, wxPDF_ALIGN_LEFT, fill, link);
1510
DoCell(w, h, s.SubString(j, sep-1), border, 2, wxPDF_ALIGN_LEFT, fill, link);
1519
w = m_w - m_rMargin - m_x;
1520
wmax = (w - 2 * m_cMargin);
1532
DoCell(len, h, s.SubString(j,i-1), border, 0, wxPDF_ALIGN_LEFT, fill, link);
1535
// Following statement was in PHP code, but seems to be in error.
1536
// m_x += GetStringWidth(s.SubString(j, i-1));
1537
SetCellMargin(saveCellMargin);
1541
wxPdfDocument::WriteGlyphArray(wxPdfArrayDouble& x, wxPdfArrayDouble& y, wxPdfArrayUint32& glyphs)
1543
bool ok = m_currentFont != NULL;
1547
// Check whether the current font is valid for this method
1548
wxString fontType = m_currentFont->GetType();
1549
if (fontType.IsSameAs(wxT("TrueTypeUnicode")) || fontType.IsSameAs(wxT("OpenTypeUnicode")))
1551
// if the arrays have different sizes use only the smallest size
1552
size_t nx = x.GetCount();
1553
size_t ny = y.GetCount();
1554
size_t ng = glyphs.GetCount();
1555
size_t n = (nx > ny) ? ((ny > ng) ? ng : ny) : ((nx > ng) ? ng : nx);
1558
for (j = 0; j < n; ++j)
1562
if (m_yAxisOriginTop)
1564
Out("BT 1 0 0 -1 ", false);
1570
OutAscii(wxPdfUtility::Double2String(xp*m_k,2), false);
1572
OutAscii(wxPdfUtility::Double2String(yp*m_k,2), false);
1573
if (m_yAxisOriginTop)
1581
ShowGlyph(glyphs[j]);
1588
wxLogError(wxString(wxT("wxPdfDocument::WriteGlyphArray: ")) +
1589
wxString::Format(_("Font type '%s' not supported."), fontType.c_str()));
1594
wxLogError(wxString(wxT("wxPdfDocument::WriteGlyphArray: ")) +
1595
wxString(_("No font selected.")));
1600
wxUnusedVar(glyphs);
1601
wxLogError(wxString(wxT("wxPdfDocument::WriteGlyphArray: ")) +
1602
wxString(_("Supported in Unicode build only.")));
1603
#endif // wxUSE_UNICODE
1608
wxPdfDocument::Image(const wxString& file, double x, double y, double w, double h,
1609
const wxString& type, const wxPdfLink& link, int maskImage)
1611
wxPdfImage* currentImage = NULL;
1612
// Put an image on the page
1613
wxPdfImageHashMap::iterator image = (*m_images).find(file);
1614
if (image == (*m_images).end())
1616
// First use of image, get info
1617
int i = (int) (*m_images).size() + 1;
1618
currentImage = new wxPdfImage(this, i, file, type);
1619
if (!currentImage->Parse())
1621
bool isValid = false;
1622
delete currentImage;
1624
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == NULL)
1626
wxImage::AddHandler(new wxPNGHandler());
1629
tempImage.LoadFile(file);
1632
isValid = Image(file, tempImage, x, y, w, h, link, maskImage);
1638
currentImage->SetMaskImage(maskImage);
1640
(*m_images)[file] = currentImage;
1644
currentImage = image->second;
1645
if (maskImage > 0 && currentImage->GetMaskImage() != maskImage)
1647
currentImage->SetMaskImage(maskImage);
1650
OutImage(currentImage, x, y, w, h, link);
1655
wxPdfDocument::Image(const wxString& name, const wxImage& img, double x, double y, double w, double h,
1656
const wxPdfLink& link, int maskImage, bool jpegFormat, int jpegQuality)
1658
bool isValid = false;
1661
wxImage tempImage = img.Copy();
1662
wxPdfImage* currentImage = NULL;
1663
// Put an image on the page
1664
wxPdfImageHashMap::iterator image = (*m_images).find(name);
1665
if (image == (*m_images).end())
1667
if (tempImage.HasAlpha())
1671
maskImage = ImageMask(name+wxString(wxT(".mask")), tempImage);
1673
if(!tempImage.ConvertAlphaToMask(0))
1678
else if (tempImage.HasMask() && maskImage <= 0)
1681
wxImage mask = tempImage.ConvertToMono(tempImage.GetMaskRed(), tempImage.GetMaskGreen(), tempImage.GetMaskBlue());
1683
mask = mask.ConvertToMono(0, 0, 0);
1684
maskImage = ImageMask(name+wxString(wxT(".mask")), mask);
1686
// First use of image, get info
1687
tempImage.SetMask(false);
1690
tempImage.SetOption(wxIMAGE_OPTION_QUALITY, jpegQuality);
1692
int i = (int) (*m_images).size() + 1;
1693
currentImage = new wxPdfImage(this, i, name, tempImage, jpegFormat);
1694
if (!currentImage->Parse())
1696
delete currentImage;
1701
currentImage->SetMaskImage(maskImage);
1703
(*m_images)[name] = currentImage;
1707
currentImage = image->second;
1708
if (maskImage > 0 && currentImage->GetMaskImage() != maskImage)
1710
currentImage->SetMaskImage(maskImage);
1713
OutImage(currentImage, x, y, w, h, link);
1720
wxPdfDocument::Image(const wxString& name, wxInputStream& stream,
1721
const wxString& mimeType,
1722
double x, double y, double w, double h,
1723
const wxPdfLink& link, int maskImage)
1725
bool isValid = false;
1726
wxPdfImage* currentImage = NULL;
1727
// Put an image on the page
1728
wxPdfImageHashMap::iterator image = (*m_images).find(name);
1729
if (image == (*m_images).end())
1731
// First use of image, get info
1732
int i = (int) (*m_images).size() + 1;
1733
currentImage = new wxPdfImage(this, i, name, stream, mimeType);
1734
if (!currentImage->Parse())
1736
delete currentImage;
1737
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == NULL)
1739
wxImage::AddHandler(new wxPNGHandler());
1742
tempImage.LoadFile(stream, mimeType);
1745
isValid = Image(name, tempImage, x, y, w, h, link, maskImage);
1752
currentImage->SetMaskImage(maskImage);
1754
(*m_images)[name] = currentImage;
1758
currentImage = image->second;
1759
if (maskImage > 0 && currentImage->GetMaskImage() != maskImage)
1761
currentImage->SetMaskImage(maskImage);
1764
OutImage(currentImage, x, y, w, h, link);
1770
wxPdfDocument::ImageMask(const wxString& file, const wxString& type)
1773
wxPdfImage* currentImage = NULL;
1774
// Put an image on the page
1775
wxPdfImageHashMap::iterator image = (*m_images).find(file);
1776
if (image == (*m_images).end())
1778
// First use of image, get info
1779
n = (int) (*m_images).size() + 1;
1780
currentImage = new wxPdfImage(this, n, file, type);
1781
if (!currentImage->Parse())
1783
delete currentImage;
1786
// Check whether this is a gray scale image (must be)
1787
if (currentImage->GetColourSpace() != wxT("DeviceGray"))
1789
delete currentImage;
1792
(*m_images)[file] = currentImage;
1796
currentImage = image->second;
1797
n = currentImage->GetIndex();
1799
if (m_PDFVersion < wxT("1.4"))
1801
m_PDFVersion = wxT("1.4");
1807
wxPdfDocument::ImageMask(const wxString& name, const wxImage& img)
1812
wxPdfImage* currentImage = NULL;
1813
// Put an image on the page
1814
wxPdfImageHashMap::iterator image = (*m_images).find(name);
1815
if (image == (*m_images).end())
1821
int w = img.GetWidth();
1822
int h = img.GetHeight();
1823
tempImage = wxImage(w, h);
1824
unsigned char alpha;
1825
for (x = 0; x < w; x++)
1827
for (y = 0; y < h; y++)
1829
alpha = img.GetAlpha(x, y);
1830
tempImage.SetRGB(x, y, alpha, alpha, alpha);
1833
tempImage.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_GREY_RED);
1837
tempImage = img.ConvertToGreyscale();
1838
tempImage.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_GREY_RED);
1840
tempImage.SetMask(false);
1841
// First use of image, get info
1842
n = (int) (*m_images).size() + 1;
1843
currentImage = new wxPdfImage(this, n, name, tempImage);
1844
if (!currentImage->Parse())
1846
delete currentImage;
1849
(*m_images)[name] = currentImage;
1853
currentImage = image->second;
1854
n = currentImage->GetIndex();
1856
if (m_PDFVersion < wxT("1.4"))
1858
m_PDFVersion = wxT("1.4");
1865
wxPdfDocument::ImageMask(const wxString& name, wxInputStream& stream, const wxString& mimeType)
1868
wxPdfImage* currentImage = NULL;
1869
// Put an image on the page
1870
wxPdfImageHashMap::iterator image = (*m_images).find(name);
1871
if (image == (*m_images).end())
1873
// First use of image, get info
1874
n = (int) (*m_images).size() + 1;
1875
currentImage = new wxPdfImage(this, n, name, stream, mimeType);
1876
if (!currentImage->Parse())
1878
delete currentImage;
1881
// Check whether this is a gray scale image (must be)
1882
if (currentImage->GetColourSpace() != wxT("DeviceGray"))
1884
delete currentImage;
1887
(*m_images)[name] = currentImage;
1891
currentImage = image->second;
1892
n = currentImage->GetIndex();
1894
if (m_PDFVersion < wxT("1.4"))
1896
m_PDFVersion = wxT("1.4");
1902
wxPdfDocument::RotatedImage(const wxString& file, double x, double y, double w, double h,
1903
double angle, const wxString& type, const wxPdfLink& link, int maskImage)
1905
// Image rotated around its upper-left corner
1907
Rotate(angle, x, y);
1908
Image(file, x, y, w, h, type, link, maskImage);
1913
wxPdfDocument::Ln(double h)
1915
// Line feed; default value is last cell height
1919
if (m_yAxisOriginTop)
1930
if (m_yAxisOriginTop)
1942
wxPdfDocument::SaveAsFile(const wxString& name)
1944
wxString fileName = name;
1945
// Normalize parameters
1946
if(fileName.Length() == 0)
1948
fileName = wxT("doc.pdf");
1951
wxFileOutputStream outfile(fileName);
1953
// Finish document if necessary
1956
if (m_buffer != NULL)
1960
m_buffer = &outfile;
1966
// Save to local file
1967
wxMemoryInputStream tmp(*((wxMemoryOutputStream*) m_buffer));
1973
const wxMemoryOutputStream&
1974
wxPdfDocument::CloseAndGetBuffer()
1981
return *((wxMemoryOutputStream*) m_buffer);
1985
wxPdfDocument::SetViewerPreferences(int preferences)
1987
m_viewerPrefs = (preferences > 0) ? preferences : 0;
1988
if (((m_viewerPrefs & wxPDF_VIEWER_DISPLAYDOCTITLE) != 0) && (m_PDFVersion < wxT("1.4")))
1990
m_PDFVersion = wxT("1.4");
1995
wxPdfDocument::SetTitle(const wxString& title)
1997
// Title of document
2002
wxPdfDocument::SetSubject(const wxString& subject)
2004
// Subject of document
2005
m_subject = subject;
2009
wxPdfDocument::SetAuthor(const wxString& author)
2011
// Author of document
2016
wxPdfDocument::SetKeywords(const wxString& keywords)
2018
// Keywords of document
2019
m_keywords = keywords;
2023
wxPdfDocument::SetCreator(const wxString& creator)
2025
// Creator of document
2026
m_creator = creator;
2030
wxPdfDocument::SetMargins(double left, double top, double right)
2032
// Set left, top and right margins
2043
wxPdfDocument::SetLeftMargin(double margin)
2047
if (m_page > 0 && m_x < margin)
2054
wxPdfDocument::GetLeftMargin()
2060
wxPdfDocument::SetTopMargin(double margin)
2067
wxPdfDocument::GetTopMargin()
2073
wxPdfDocument::SetRightMargin(double margin)
2080
wxPdfDocument::GetRightMargin()
2086
wxPdfDocument::SetCellMargin(double margin)
2093
wxPdfDocument::GetCellMargin()
2099
wxPdfDocument::SetLineHeight(double height)
2105
wxPdfDocument::GetLineHeight()
2111
wxPdfDocument::SetAutoPageBreak(bool autoPageBreak, double margin)
2113
// Set auto page break mode and triggering margin
2114
m_autoPageBreak = autoPageBreak;
2116
m_pageBreakTrigger = (m_yAxisOriginTop) ? m_h - margin : margin;
2120
wxPdfDocument::SetDisplayMode(wxPdfZoom zoom, wxPdfLayout layout, double zoomFactor)
2122
// Set display mode in viewer
2125
case wxPDF_ZOOM_FULLPAGE:
2126
case wxPDF_ZOOM_FULLWIDTH:
2127
case wxPDF_ZOOM_REAL:
2128
case wxPDF_ZOOM_DEFAULT:
2131
case wxPDF_ZOOM_FACTOR:
2133
m_zoomFactor = (zoomFactor > 0) ? zoomFactor : 100.;
2136
m_zoomMode = wxPDF_ZOOM_FULLWIDTH;
2142
case wxPDF_LAYOUT_SINGLE:
2143
case wxPDF_LAYOUT_TWO:
2144
case wxPDF_LAYOUT_DEFAULT:
2145
case wxPDF_LAYOUT_CONTINUOUS:
2146
m_layoutMode = layout;
2149
m_layoutMode = wxPDF_LAYOUT_CONTINUOUS;
2155
wxPdfDocument::Close()
2157
// Terminate document
2180
wxPdfDocument::Header()
2182
// To be implemented in your own inherited class
2186
wxPdfDocument::Footer()
2188
// To be implemented in your own inherited class
2192
wxPdfDocument::IsInFooter()
2198
wxPdfDocument::PageNo()
2200
// Get current page number
2205
wxPdfDocument::GetX()
2212
wxPdfDocument::SetX(double x)
2226
wxPdfDocument::GetY()
2233
wxPdfDocument::SetY(double y)
2235
// Set y position and reset x
2248
wxPdfDocument::SetXY(double x, double y)
2250
// Set x and y positions
2256
wxPdfDocument::SetKerning(bool kerning)
2258
m_kerning = kerning;
2262
wxPdfDocument::SetCompression(bool compress)
2264
m_compress = compress;
2268
wxPdfDocument::AppendJavascript(const wxString& javascript)
2270
m_javascript += javascript;
2274
wxPdfDocument::AttachFile(const wxString& fileName, const wxString& attachName, const wxString& description)
2276
wxFileName attachFile(fileName);
2277
bool ok = attachFile.FileExists();
2280
wxArrayString* attachment = new wxArrayString();
2281
attachment->Add(fileName);
2282
if (!attachName.IsEmpty())
2284
attachment->Add(attachName);
2288
attachment->Add(attachFile.GetFullName());
2290
attachment->Add(description);
2292
int index = (int) (m_attachments->size() + 1);
2293
(*m_attachments)[index] = attachment;
2297
wxLogDebug(wxT("*** Attachment file '%s' does not exist."), fileName.c_str());
2305
wxPdfDocument::AddSpotColour(const wxString& name, double cyan, double magenta, double yellow, double black)
2307
wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
2308
if (spotColour == (*m_spotColours).end())
2310
int i = (int) (*m_spotColours).size() + 1;
2311
(*m_spotColours)[name] = new wxPdfSpotColour(i, cyan, magenta, yellow, black);
2316
wxPdfDocument::AddPattern(const wxString& patternName, const wxImage& image, double width, double height)
2318
bool isValid = true;
2319
wxPdfPatternMap::iterator patternIter = m_patterns->find(patternName);
2320
if (patternIter == m_patterns->end())
2322
if (image.IsOk() && width > 0 && height > 0)
2324
wxString imageName = wxString(wxT("pattern:")) + patternName;
2325
wxPdfImage* currentImage = NULL;
2326
wxPdfImageHashMap::iterator imageIter = (*m_images).find(imageName);
2327
if (imageIter == (*m_images).end())
2329
// Prepare new image
2331
wxImage tempImage = image.Copy();
2332
if (tempImage.HasAlpha())
2334
maskImage = ImageMask(imageName+wxString(wxT(".mask")), tempImage);
2335
tempImage.ConvertAlphaToMask(0);
2337
tempImage.SetMask(false);
2338
int i = (*m_images).size() + 1;
2339
currentImage = new wxPdfImage(this, i, imageName, tempImage);
2340
currentImage->Parse();
2343
currentImage->SetMaskImage(maskImage);
2345
(*m_images)[imageName] = currentImage;
2349
// Use existing image
2350
currentImage = imageIter->second;
2353
// Register new pattern
2354
wxPdfPattern* pattern;
2355
int i = (int) m_patterns->size() + 1;
2356
pattern = new wxPdfPattern(i, width, height);
2357
pattern->SetImage(currentImage);
2358
(*m_patterns)[patternName] = pattern;
2365
wxLogError(wxString(wxT("wxPdfDocument::AddPattern: ")) +
2366
wxString(_("Invalid image.")));
2370
wxLogError(wxString(wxT("wxPdfDocument::AddPattern: ")) +
2371
wxString::Format(_("Invalid width (%.1f) and/or height (%.1f)."), width, height));
2379
wxPdfDocument::SetDrawColour(const wxColour& colour)
2381
wxPdfColour tempColour(colour);
2382
m_drawColour = tempColour;
2385
OutAscii(m_drawColour.GetColour(true));
2390
wxPdfDocument::SetDrawColour(const unsigned char grayscale)
2392
wxPdfColour tempColour(grayscale);
2393
m_drawColour = tempColour;
2396
OutAscii(m_drawColour.GetColour(true));
2401
wxPdfDocument::SetDrawColour(const unsigned char red, const unsigned char green, const unsigned char blue)
2403
SetDrawColour(wxColour(red, green, blue));
2407
wxPdfDocument::SetDrawColour(double cyan, double magenta, double yellow, double black)
2409
SetDrawColour(wxPdfColour(cyan, magenta, yellow, black));
2413
wxPdfDocument::SetDrawColour(const wxPdfColour& colour)
2415
m_drawColour = colour;
2418
OutAscii(m_drawColour.GetColour(true));
2423
wxPdfDocument::SetDrawColour(const wxString& name, double tint)
2425
wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
2426
if (spotColour != (*m_spotColours).end())
2428
wxPdfColour tempColour(*(spotColour->second), tint);
2429
m_drawColour = tempColour;
2432
OutAscii(m_drawColour.GetColour(true));
2437
wxLogError(wxString(wxT("wxPdfDocument::SetDrawColour: ")) +
2438
wxString::Format(_("Undefined spot colour: '%s'."), name.c_str()));
2443
wxPdfDocument::SetDrawPattern(const wxString& name)
2445
wxPdfPatternMap::iterator pattern = m_patterns->find(name);
2446
if (pattern != m_patterns->end())
2448
wxPdfColour tempColour(*(pattern->second));
2449
m_drawColour = tempColour;
2452
OutAscii(m_drawColour.GetColour(true));
2457
wxLogError(wxString(wxT("wxPdfDocument::SetDrawPattern: ")) +
2458
wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
2463
wxPdfDocument::GetDrawColour()
2465
return wxPdfColour(m_drawColour);
2469
wxPdfDocument::SetFillColour(const wxColour& colour)
2471
wxPdfColour tempColour(colour);
2472
m_fillColour = tempColour;
2473
m_colourFlag = (m_fillColour != m_textColour);
2476
OutAscii(m_fillColour.GetColour(false));
2481
wxPdfDocument::SetFillColour(const unsigned char grayscale)
2483
wxPdfColour tempColour(grayscale);
2484
m_fillColour = tempColour;
2485
m_colourFlag = (m_fillColour != m_textColour);
2488
OutAscii(m_fillColour.GetColour(false));
2493
wxPdfDocument::SetFillColour(const wxPdfColour& colour)
2495
m_fillColour = colour;
2496
m_colourFlag = (m_fillColour != m_textColour);
2499
OutAscii(m_fillColour.GetColour(false));
2504
wxPdfDocument::SetFillColour(const unsigned char red, const unsigned char green, const unsigned char blue)
2506
SetFillColour(wxColour(red, green, blue));
2510
wxPdfDocument::SetFillColour(double cyan, double magenta, double yellow, double black)
2512
SetFillColour(wxPdfColour(cyan, magenta, yellow, black));
2516
wxPdfDocument::SetFillColour(const wxString& name, double tint)
2518
wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
2519
if (spotColour != (*m_spotColours).end())
2521
wxPdfColour tempColour(*(spotColour->second), tint);
2522
m_fillColour = tempColour;
2523
m_colourFlag = (m_fillColour != m_textColour);
2526
OutAscii(m_fillColour.GetColour(false));
2531
wxLogError(wxString(wxT("wxPdfDocument::SetFillColour: ")) +
2532
wxString::Format(_("Undefined spot colour: '%s'."), name.c_str()));
2537
wxPdfDocument::SetFillPattern(const wxString& name)
2539
wxPdfPatternMap::iterator pattern = m_patterns->find(name);
2540
if (pattern != m_patterns->end())
2542
wxPdfColour tempColour(*(pattern->second));
2543
m_fillColour = tempColour;
2544
m_colourFlag = (m_fillColour != m_textColour);
2547
OutAscii(m_fillColour.GetColour(false));
2552
wxLogError(wxString(wxT("wxPdfDocument::SetFillPattern: ")) +
2553
wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
2558
wxPdfDocument::GetPatternColour(const wxString& name)
2560
wxPdfColour colour(0);
2561
wxPdfPatternMap::iterator pattern = m_patterns->find(name);
2562
if (pattern != m_patterns->end())
2564
wxPdfColour tempColour(*(pattern->second));
2565
colour = tempColour;
2569
wxLogError(wxString(wxT("wxPdfDocument::GetPatternColour: ")) +
2570
wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
2576
wxPdfDocument::GetFillColour()
2578
return wxPdfColour(m_fillColour);
2582
wxPdfDocument::SetTextColour(const wxColour& colour)
2584
wxPdfColour tempColour(colour);
2585
m_textColour = tempColour;
2586
m_colourFlag = (m_fillColour != m_textColour);
2590
wxPdfDocument::SetTextColour(const unsigned char grayscale)
2592
wxPdfColour tempColour(grayscale);
2593
m_textColour = tempColour;
2594
m_colourFlag = (m_fillColour != m_textColour);
2598
wxPdfDocument::SetTextColour(const wxPdfColour& colour)
2600
m_textColour = colour;
2601
m_colourFlag = (m_fillColour != m_textColour);
2605
wxPdfDocument::SetTextColour(const unsigned char red, const unsigned char green, const unsigned char blue)
2607
SetTextColour(wxColour(red, green, blue));
2611
wxPdfDocument::SetTextColour(double cyan, double magenta, double yellow, double black)
2613
SetTextColour(wxPdfColour(cyan, magenta, yellow, black));
2617
wxPdfDocument::SetTextColour(const wxString& name, double tint)
2619
wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
2620
if (spotColour != (*m_spotColours).end())
2622
wxPdfColour tempColour(*(spotColour->second), tint);
2623
m_textColour = tempColour;
2624
m_colourFlag = (m_fillColour != m_textColour);
2628
wxLogError(wxString(wxT("wxPdfDocument::SetTextColour: ")) +
2629
wxString::Format(_("Undefined spot colour: '%s'."), name.c_str()));
2634
wxPdfDocument::SetTextPattern(const wxString& name)
2636
wxPdfPatternMap::iterator pattern = m_patterns->find(name);
2637
if (pattern != m_patterns->end())
2639
wxPdfColour tempColour(*(pattern->second));
2640
m_textColour = tempColour;
2641
m_colourFlag = (m_fillColour != m_textColour);
2645
wxLogError(wxString(wxT("wxPdfDocument::SetFillPattern: ")) +
2646
wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
2651
wxPdfDocument::GetTextColour()
2653
return wxPdfColour(m_textColour);
2657
wxPdfDocument::SetTextRenderMode(wxPdfTextRenderMode mode)
2659
m_textRenderMode = mode;
2663
wxPdfDocument::GetTextRenderMode() const
2665
return m_textRenderMode;