~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/plugins/contrib/source_exporter/wxPdfDocument/src/pdfdocument.cpp

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        pdfdocument.cpp
 
3
// Purpose:     Implementation of wxPdfDocument (public methods)
 
4
// Author:      Ulrich Telle
 
5
// Modified by:
 
6
// Created:     2005-08-04
 
7
// Copyright:   (c) Ulrich Telle
 
8
// Licence:     wxWindows licence
 
9
///////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
/// \file pdfdocument.cpp Implementation of the wxPdfDocument class
 
12
 
 
13
// For compilers that support precompilation, includes <wx/wx.h>.
 
14
#include <wx/wxprec.h>
 
15
 
 
16
#ifdef __BORLANDC__
 
17
#pragma hdrstop
 
18
#endif
 
19
 
 
20
#ifndef WX_PRECOMP
 
21
#include <wx/wx.h>
 
22
#endif
 
23
 
 
24
#include <wx/image.h>
 
25
#include <wx/paper.h>
 
26
#include <wx/wfstream.h>
 
27
 
 
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"
 
43
 
 
44
#if WXPDFDOC_INHERIT_WXOBJECT
 
45
IMPLEMENT_DYNAMIC_CLASS(wxPdfDocument, wxObject)
 
46
#endif
 
47
 
 
48
// ----------------------------------------------------------------------------
 
49
// wxPdfDocument: class representing a PDF document
 
50
// ----------------------------------------------------------------------------
 
51
 
 
52
wxPdfDocument::wxPdfDocument(int orientation, const wxString& unit, wxPaperSize format)
 
53
#if WXPDFDOC_INHERIT_WXOBJECT
 
54
  : wxObject()
 
55
#endif
 
56
{
 
57
  m_yAxisOriginTop = true;
 
58
  SetScaleFactor(unit);
 
59
 
 
60
  // Page format
 
61
  m_defPageSize = CalculatePageSize(format);
 
62
  Initialize(orientation);
 
63
}
 
64
 
 
65
wxPdfDocument::wxPdfDocument(int orientation, double pageWidth, double pageHeight, const wxString& unit)
 
66
#if WXPDFDOC_INHERIT_WXOBJECT
 
67
  : wxObject()
 
68
#endif
 
69
{
 
70
  m_yAxisOriginTop = true;
 
71
  SetScaleFactor(unit);
 
72
  m_defPageSize = CalculatePageSize(pageWidth, pageHeight);
 
73
  Initialize(orientation);
 
74
}
 
75
 
 
76
void
 
77
wxPdfDocument::SetScaleFactor(const wxString& unit)
 
78
{
 
79
  // Scale factor
 
80
  if (unit == wxT("pt"))
 
81
  {
 
82
    m_k = 1.;
 
83
  }
 
84
  else if (unit == wxT("in"))
 
85
  {
 
86
    m_k = 72.;
 
87
  }
 
88
  else if (unit == wxT("cm"))
 
89
  {
 
90
    m_k = 72. / 2.54;
 
91
  }
 
92
  else // if (unit == "mm") or unknown
 
93
  {
 
94
    m_k = 72. / 25.4;
 
95
  }
 
96
}
 
97
 
 
98
wxSize
 
99
wxPdfDocument::CalculatePageSize(wxPaperSize format)
 
100
{
 
101
  bool deletePaperDatabase = false;
 
102
  wxPrintPaperDatabase* printPaperDatabase = wxThePrintPaperDatabase;
 
103
  if (printPaperDatabase == NULL)
 
104
  {
 
105
    printPaperDatabase = new wxPrintPaperDatabase;
 
106
    printPaperDatabase->CreateDatabase();
 
107
    deletePaperDatabase = true;
 
108
  }
 
109
  wxPrintPaperType* paperType = printPaperDatabase->FindPaperType(format);
 
110
  if (paperType == NULL)
 
111
  {
 
112
    paperType = printPaperDatabase->FindPaperType(wxPAPER_A4);
 
113
  }
 
114
  wxSize paperSize = paperType->GetSize();
 
115
  if (deletePaperDatabase)
 
116
  {
 
117
    delete printPaperDatabase;
 
118
  }
 
119
  return paperSize;
 
120
}
 
121
 
 
122
wxSize
 
123
wxPdfDocument::CalculatePageSize(double pageWidth, double pageHeight)
 
124
{
 
125
  int width  = (int) (pageWidth  * (m_k * 254. / 72.));
 
126
  int height = (int) (pageHeight * (m_k * 254. / 72.));
 
127
  return wxSize(width,height);
 
128
}
 
129
 
 
130
void
 
131
wxPdfDocument::Initialize(int orientation)
 
132
{
 
133
  // Allocate arrays
 
134
  m_currentFont = NULL;
 
135
  m_buffer = new wxMemoryOutputStream();
 
136
 
 
137
  m_page       = 0;
 
138
  m_n          = 2;
 
139
  m_offsets = new wxPdfOffsetHashMap();
 
140
 
 
141
  m_pages = new wxPdfPageHashMap();
 
142
  m_pageSizes = new wxPdfPageSizeMap();
 
143
  m_orientationChanges = new wxPdfBoolHashMap();
 
144
 
 
145
  m_state            = 0;
 
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();
 
169
 
 
170
  m_outlineRoot      = -1;
 
171
  m_maxOutlineLevel  = 0;
 
172
 
 
173
  m_inFooter   = false;
 
174
  m_lasth      = 0;
 
175
  m_fontFamily = wxEmptyString;
 
176
  m_fontStyle  = wxPDF_FONTSTYLE_REGULAR;
 
177
  m_fontSizePt = 12;
 
178
  m_decoration = wxPDF_FONTSTYLE_REGULAR;
 
179
  m_fontSubsetting = true;
 
180
 
 
181
  m_drawColour  = wxPdfColour();
 
182
  m_fillColour  = wxPdfColour();
 
183
  m_textColour  = wxPdfColour();
 
184
  m_colourFlag  = false;
 
185
  m_ws          = 0;
 
186
  m_textRenderMode = wxPDF_TEXT_RENDER_FILL;
 
187
 
 
188
  // Initialize image scale factor
 
189
  m_imgscale = 1.;
 
190
 
 
191
  // Page format
 
192
  m_curPageSize = m_defPageSize;
 
193
  m_fwPt = m_defPageSize.GetWidth() / 254. * 72.;
 
194
  m_fhPt = m_defPageSize.GetHeight() / 254. * 72.;
 
195
  m_fw = m_fwPt / m_k;
 
196
  m_fh = m_fhPt / m_k;
 
197
 
 
198
  // Page orientation
 
199
  if (orientation == wxLANDSCAPE)
 
200
  {
 
201
    m_defOrientation = wxLANDSCAPE;
 
202
    m_wPt = m_fhPt;
 
203
    m_hPt = m_fwPt;
 
204
  }
 
205
  else // orientation == wxPORTRAIT or unknown
 
206
  {
 
207
    m_defOrientation = wxPORTRAIT;
 
208
    m_wPt = m_fwPt;
 
209
    m_hPt = m_fhPt;
 
210
  }
 
211
  
 
212
  m_curOrientation = m_defOrientation;
 
213
  m_w = m_wPt / m_k;
 
214
  m_h = m_hPt / m_k;
 
215
  m_angle = 0;
 
216
  m_fillRule = wxWINDING_RULE;
 
217
  m_inTransform = 0;
 
218
 
 
219
  // Page margins (1 cm)
 
220
  double margin = 28.35 / m_k;
 
221
  SetMargins(margin, margin);
 
222
  
 
223
  // Interior cell margin (1 mm)
 
224
  m_cMargin = margin / 10;
 
225
  
 
226
  // Line width (0.2 mm)
 
227
  m_lineWidth = .567 / m_k;
 
228
  
 
229
  // Automatic page break
 
230
  SetAutoPageBreak(true, 2*margin);
 
231
  
 
232
  // Full width display mode
 
233
  SetDisplayMode(wxPDF_ZOOM_FULLWIDTH);
 
234
  m_zoomFactor = 100.;
 
235
 
 
236
  // Default viewer preferences
 
237
  m_viewerPrefs = 0;
 
238
 
 
239
  // Disable kerning
 
240
  SetKerning(false);
 
241
 
 
242
  // Enable compression
 
243
  SetCompression(true);
 
244
 
 
245
  // Set default PDF version number
 
246
  m_PDFVersion = wxT("1.3");
 
247
  m_importVersion = m_PDFVersion;
 
248
 
 
249
  m_encrypted = false;
 
250
  m_encryptor = NULL;
 
251
 
 
252
  m_javascript = wxEmptyString;
 
253
 
 
254
  m_inTemplate = false;
 
255
  m_templateId = 0;
 
256
  m_templatePrefix = wxT("/TPL");
 
257
 
 
258
  m_currentParser = NULL;
 
259
  m_currentSource = wxEmptyString;
 
260
 
 
261
  m_translate = false;
 
262
 
 
263
  m_zapfdingbats = 0;
 
264
}
 
265
 
 
266
wxPdfDocument::~wxPdfDocument()
 
267
{
 
268
  wxPdfFontHashMap::iterator font = m_fonts->begin();
 
269
  for (font = m_fonts->begin(); font != m_fonts->end(); font++)
 
270
  {
 
271
    if (font->second != NULL)
 
272
    {
 
273
      delete font->second;
 
274
    }
 
275
  }
 
276
  delete m_fonts;
 
277
 
 
278
  wxPdfImageHashMap::iterator image = m_images->begin();
 
279
  for (image = m_images->begin(); image != m_images->end(); image++)
 
280
  {
 
281
    if (image->second != NULL)
 
282
    {
 
283
      delete image->second;
 
284
    }
 
285
  }
 
286
  delete m_images;
 
287
 
 
288
  wxPdfPageHashMap::iterator page = m_pages->begin();
 
289
  for (page = m_pages->begin(); page != m_pages->end(); page++)
 
290
  {
 
291
    if (page->second != NULL)
 
292
    {
 
293
      delete page->second;
 
294
    }
 
295
  }
 
296
  delete m_pages;
 
297
 
 
298
  wxPdfPageLinksMap::iterator pageLinks = m_pageLinks->begin();
 
299
  for (pageLinks = m_pageLinks->begin(); pageLinks != m_pageLinks->end(); pageLinks++)
 
300
  {
 
301
    if (pageLinks->second != NULL)
 
302
    {
 
303
      delete pageLinks->second;
 
304
    }
 
305
  }
 
306
  delete m_pageLinks;
 
307
 
 
308
  wxPdfLinkHashMap::iterator link = m_links->begin();
 
309
  for (link = m_links->begin(); link != m_links->end(); link++)
 
310
  {
 
311
    if (link->second != NULL)
 
312
    {
 
313
      delete link->second;
 
314
    }
 
315
  }
 
316
  delete m_links;
 
317
 
 
318
  delete m_namedLinks;
 
319
 
 
320
  size_t j;
 
321
  for (j = 0; j < m_outlines.GetCount(); j++)
 
322
  {
 
323
    wxPdfBookmark* bookmark = (wxPdfBookmark*) m_outlines[j];
 
324
    delete bookmark;
 
325
  }
 
326
 
 
327
  wxPdfStringHashMap::iterator diff = m_diffs->begin();
 
328
  for (diff = m_diffs->begin(); diff != m_diffs->end(); diff++)
 
329
  {
 
330
    if (diff->second != NULL)
 
331
    {
 
332
      delete diff->second;
 
333
    }
 
334
  }
 
335
  delete m_diffs;
 
336
 
 
337
  delete m_winansi;
 
338
 
 
339
  wxPdfExtGStateMap::iterator extGState = m_extGStates->begin();
 
340
  for (extGState = m_extGStates->begin(); extGState != m_extGStates->end(); extGState++)
 
341
  {
 
342
    if (extGState->second != NULL)
 
343
    {
 
344
      delete extGState->second;
 
345
    }
 
346
  }
 
347
  delete m_extGStates;
 
348
 
 
349
  delete m_extGSLookup;
 
350
 
 
351
  wxPdfGradientMap::iterator gradient = m_gradients->begin();
 
352
  for (gradient = m_gradients->begin(); gradient != m_gradients->end(); gradient++)
 
353
  {
 
354
    if (gradient->second != NULL)
 
355
    {
 
356
      delete gradient->second;
 
357
    }
 
358
  }
 
359
  delete m_gradients;
 
360
 
 
361
  wxPdfAnnotationsMap::iterator annotation = m_annotations->begin();
 
362
  for (annotation = m_annotations->begin(); annotation != m_annotations->end(); annotation++)
 
363
  {
 
364
    if (annotation->second != NULL)
 
365
    {
 
366
      delete annotation->second;
 
367
    }
 
368
  }
 
369
  delete m_annotations;
 
370
 
 
371
  wxPdfFormAnnotsMap::iterator formAnnotation = m_formAnnotations->begin();
 
372
  for (formAnnotation = m_formAnnotations->begin(); formAnnotation != m_formAnnotations->end(); formAnnotation++)
 
373
  {
 
374
    if (formAnnotation->second != NULL)
 
375
    {
 
376
      delete formAnnotation->second;
 
377
    }
 
378
  }
 
379
  delete m_formAnnotations;
 
380
 
 
381
  wxPdfFormFieldsMap::iterator formField = m_formFields->begin();
 
382
  for (formField = m_formFields->begin(); formField != m_formFields->end(); formField++)
 
383
  {
 
384
    if (formField->second != NULL)
 
385
    {
 
386
      delete formField->second;
 
387
    }
 
388
  }
 
389
  delete m_formFields;
 
390
 
 
391
  wxPdfRadioGroupMap::iterator radioGroup = m_radioGroups->begin();
 
392
  for (radioGroup = m_radioGroups->begin(); radioGroup != m_radioGroups->end(); radioGroup++)
 
393
  {
 
394
    if (radioGroup->second != NULL)
 
395
    {
 
396
      delete radioGroup->second;
 
397
    }
 
398
  }
 
399
  delete m_radioGroups;
 
400
 
 
401
  wxPdfTemplatesMap::iterator templateIter = m_templates->begin();
 
402
  for (templateIter = m_templates->begin(); templateIter != m_templates->end(); templateIter++)
 
403
  {
 
404
    if (templateIter->second != NULL)
 
405
    {
 
406
      delete templateIter->second;
 
407
    }
 
408
  }
 
409
  delete m_templates;
 
410
 
 
411
  wxPdfParserMap::iterator parser = m_parsers->begin();
 
412
  for (parser = m_parsers->begin(); parser != m_parsers->end(); parser++)
 
413
  {
 
414
    if (parser->second != NULL)
 
415
    {
 
416
      delete parser->second;
 
417
    }
 
418
  }
 
419
  delete m_parsers;
 
420
 
 
421
  wxPdfSpotColourMap::iterator spotColour = m_spotColours->begin();
 
422
  for (spotColour = m_spotColours->begin(); spotColour != m_spotColours->end(); spotColour++)
 
423
  {
 
424
    if (spotColour->second != NULL)
 
425
    {
 
426
      delete spotColour->second;
 
427
    }
 
428
  }
 
429
  delete m_spotColours;
 
430
 
 
431
  wxPdfPatternMap::iterator pattern = m_patterns->begin();
 
432
  for (pattern = m_patterns->begin(); pattern != m_patterns->end(); pattern++)
 
433
  {
 
434
    if (pattern->second != NULL)
 
435
    {
 
436
      delete pattern->second;
 
437
    }
 
438
  }
 
439
  delete m_patterns;
 
440
 
 
441
  wxPdfOcgMap::iterator ocg = m_ocgs->begin();
 
442
  for (ocg = m_ocgs->begin(); ocg != m_ocgs->end(); ++ocg)
 
443
  {
 
444
    if (ocg->second != NULL)
 
445
    {
 
446
      delete ocg->second;
 
447
    }
 
448
  }
 
449
  delete m_ocgs;
 
450
 
 
451
  wxPdfLayerRGMap::iterator rg;
 
452
  for (rg = m_rgLayers->begin(); rg != m_rgLayers->end(); ++rg)
 
453
  {
 
454
    if (rg->second != NULL)
 
455
    {
 
456
      delete rg->second;
 
457
    }
 
458
  }
 
459
  delete m_rgLayers;
 
460
 
 
461
  if (m_lockedLayers != NULL)
 
462
  {
 
463
    delete m_lockedLayers;
 
464
  }
 
465
 
 
466
  wxPdfAttachmentMap::iterator attach;
 
467
  for (attach = m_attachments->begin(); attach != m_attachments->end(); ++attach)
 
468
  {
 
469
    if (attach->second != NULL)
 
470
    {
 
471
      delete attach->second;
 
472
    }
 
473
  }
 
474
  delete m_attachments;
 
475
 
 
476
  delete m_orientationChanges;
 
477
  delete m_pageSizes;
 
478
 
 
479
  delete m_offsets;
 
480
 
 
481
  if (m_encryptor != NULL)
 
482
  {
 
483
    delete m_encryptor;
 
484
  }
 
485
 
 
486
  if (m_buffer != NULL)
 
487
  {
 
488
    delete m_buffer;
 
489
  }
 
490
}
 
491
 
 
492
// --- Public methods
 
493
 
 
494
void
 
495
wxPdfDocument::SetProtection(int permissions,
 
496
                             const wxString& userPassword,
 
497
                             const wxString& ownerPassword,
 
498
                             wxPdfEncryptionMethod encryptionMethod,
 
499
                             int keyLength)
 
500
{
 
501
  if (m_encryptor == NULL)
 
502
  {
 
503
    int revision = (keyLength > 0) ? 3 : 2;
 
504
    switch (encryptionMethod)
 
505
    {
 
506
      case wxPDF_ENCRYPTION_AESV2:
 
507
        revision = 4;
 
508
        if (m_PDFVersion < wxT("1.6"))
 
509
        {
 
510
          m_PDFVersion = wxT("1.6");
 
511
        }
 
512
        break;
 
513
      case wxPDF_ENCRYPTION_RC4V2:
 
514
        revision = 3;
 
515
        break;
 
516
      case wxPDF_ENCRYPTION_RC4V1:
 
517
      default:
 
518
        revision = 2;
 
519
        break;
 
520
    }
 
521
    m_encryptor = new wxPdfEncrypt(revision, keyLength);
 
522
    m_encrypted = true;
 
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)
 
529
    {
 
530
      ownerPswd = wxPdfUtility::GetUniqueId(wxT("wxPdfDoc"));
 
531
    }
 
532
    m_encryptor->GenerateEncryptionKey(userPassword, ownerPswd, protection);
 
533
  }
 
534
}
 
535
 
 
536
void
 
537
wxPdfDocument::SetImageScale(double scale)
 
538
{
 
539
  m_imgscale = scale;
 
540
}
 
541
 
 
542
double
 
543
wxPdfDocument::GetImageScale()
 
544
{
 
545
  return m_imgscale;
 
546
}
 
547
 
 
548
double
 
549
wxPdfDocument::GetPageWidth()
 
550
{
 
551
  return m_w;
 
552
}
 
553
 
 
554
double
 
555
wxPdfDocument::GetPageHeight()
 
556
{
 
557
  return m_h;
 
558
}
 
559
 
 
560
double
 
561
wxPdfDocument::GetBreakMargin()
 
562
{
 
563
  return m_bMargin;
 
564
}
 
565
 
 
566
double
 
567
wxPdfDocument::GetScaleFactor()
 
568
{
 
569
  return m_k;
 
570
}
 
571
 
 
572
void
 
573
wxPdfDocument::AliasNbPages(const wxString& alias)
 
574
{
 
575
  // Define an alias for total number of pages
 
576
  m_aliasNbPages = alias;
 
577
}
 
578
 
 
579
void
 
580
wxPdfDocument::Open()
 
581
{
 
582
  // Begin document
 
583
  m_state = 1;
 
584
}
 
585
 
 
586
void
 
587
wxPdfDocument::AddPage(int orientation)
 
588
{
 
589
  AddPage(orientation, m_defPageSize);
 
590
}
 
591
 
 
592
void
 
593
wxPdfDocument::AddPage(int orientation, wxPaperSize format)
 
594
{
 
595
  wxSize pageSize = CalculatePageSize(format);
 
596
  AddPage(orientation, pageSize);
 
597
}
 
598
 
 
599
void
 
600
wxPdfDocument::AddPage(int orientation, double pageWidth, double pageHeight)
 
601
{
 
602
  if (pageWidth > 0 && pageHeight > 0)
 
603
  {
 
604
    wxSize pageSize = CalculatePageSize(pageWidth, pageHeight);
 
605
    AddPage(orientation, pageSize);
 
606
  }
 
607
  else
 
608
  {
 
609
    wxLogError(wxString(wxT("wxPdfDocument::AddPage: ")) +
 
610
               wxString::Format(_("Invalid page size (%.1f,%.1f)."), pageWidth, pageHeight));
 
611
  }
 
612
}
 
613
 
 
614
void
 
615
wxPdfDocument::AddPage(int orientation, wxSize pageSize)
 
616
{
 
617
  if (m_inTemplate)
 
618
  {
 
619
    wxLogError(wxString(wxT("wxPdfDocument::AddPage: ")) +
 
620
               wxString::Format(_("Adding pages in templates is impossible. Current template ID is %d."), m_templateId));
 
621
    return;
 
622
  }
 
623
 
 
624
  // Start a new page
 
625
  if (m_state == 0)
 
626
  {
 
627
    Open();
 
628
  }
 
629
  wxPdfFontDetails* currentFont = m_currentFont;
 
630
  wxString family = m_fontFamily;
 
631
  int style = m_fontStyle;
 
632
  if (m_decoration & wxPDF_FONTSTYLE_UNDERLINE)
 
633
  {
 
634
    style |= wxPDF_FONTSTYLE_UNDERLINE;
 
635
  }
 
636
  if (m_decoration & wxPDF_FONTSTYLE_OVERLINE)
 
637
  {
 
638
    style |= wxPDF_FONTSTYLE_OVERLINE;
 
639
  }
 
640
  if (m_decoration & wxPDF_FONTSTYLE_STRIKEOUT)
 
641
  {
 
642
    style |= wxPDF_FONTSTYLE_STRIKEOUT;
 
643
  }
 
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;
 
650
 
 
651
  if (m_page > 0)
 
652
  {
 
653
    // Page footer
 
654
    m_inFooter = true;
 
655
    Footer();
 
656
    m_inFooter = false;
 
657
    // Close page
 
658
    EndPage();
 
659
  }
 
660
 
 
661
  // Start new page
 
662
  BeginPage(orientation, pageSize);
 
663
  
 
664
  // Set line cap style to square
 
665
  Out("2 J");
 
666
  
 
667
  // Set line width
 
668
  m_lineWidth = lw;
 
669
  OutAscii(wxPdfUtility::Double2String(lw*m_k,2)+wxString(wxT(" w")));
 
670
 
 
671
  // Set font
 
672
  if (currentFont != NULL)
 
673
  {
 
674
    m_currentFont = currentFont;
 
675
    m_fontStyle = style;
 
676
    m_fontSizePt = size;
 
677
    ForceCurrentFont();
 
678
  }
 
679
  
 
680
  // Set colours
 
681
  m_drawColour = dc;
 
682
  if (dc != wxPdfColour(0))
 
683
  {
 
684
    OutAscii(dc.GetColour(true));
 
685
  }
 
686
  m_fillColour = fc;
 
687
  if (fc != wxPdfColour(0))
 
688
  {
 
689
    OutAscii(fc.GetColour(false));
 
690
  }
 
691
  m_textColour = tc;
 
692
  m_colourFlag = cf;
 
693
 
 
694
  // Page header
 
695
  Header();
 
696
 
 
697
  // Restore line width
 
698
  if (m_lineWidth != lw)
 
699
  {
 
700
    m_lineWidth = lw;
 
701
    OutAscii(wxPdfUtility::Double2String(lw*m_k,2)+wxString(wxT(" w")));
 
702
  }
 
703
 
 
704
  // Restore font
 
705
  if(family.Length() > 0)
 
706
  {
 
707
    SetFont(family, style, size);
 
708
  }
 
709
  if (currentFont != NULL)
 
710
  {
 
711
    SetFont(currentFont->GetUserFont(), style, size);
 
712
  }
 
713
  
 
714
  // Restore colours
 
715
  if (m_drawColour != dc)
 
716
  {
 
717
    m_drawColour = dc;
 
718
    OutAscii(dc.GetColour(true));
 
719
  }
 
720
  if (m_fillColour != fc)
 
721
  {
 
722
    m_fillColour = fc;
 
723
    OutAscii(fc.GetColour(false));
 
724
  }
 
725
  m_textColour = tc;
 
726
  m_colourFlag = cf;
 
727
}
 
728
 
 
729
void
 
730
wxPdfDocument::SetLineWidth(double width)
 
731
{
 
732
  // Set line width
 
733
  m_lineWidth = width;
 
734
  if (m_page > 0)
 
735
  {
 
736
    OutAscii(wxPdfUtility::Double2String(width*m_k,2)+ wxString(wxT(" w")));
 
737
  }
 
738
}
 
739
 
 
740
double
 
741
wxPdfDocument::GetLineWidth()
 
742
{
 
743
  return m_lineWidth;
 
744
}
 
745
 
 
746
bool
 
747
wxPdfDocument::AddFont(const wxString& family, const wxString& style, const wxString& file)
 
748
{
 
749
  bool ok = !family.IsEmpty();
 
750
  if (ok)
 
751
  {
 
752
    wxPdfFont regFont = wxPdfFontManager::GetFontManager()->GetFont(family, style);
 
753
    if (!regFont.IsValid())
 
754
    {
 
755
      wxString fileName = file;
 
756
      if (fileName.IsEmpty())
 
757
      {
 
758
        fileName = family.Lower() + style.Lower() + wxString(wxT(".xml"));
 
759
        fileName.Replace(wxT(" "),wxT(""));
 
760
      }
 
761
      regFont = wxPdfFontManager::GetFontManager()->RegisterFont(fileName, family);
 
762
      ok = regFont.IsValid();
 
763
    }
 
764
  }
 
765
  return ok;
 
766
}
 
767
 
 
768
#if wxUSE_UNICODE
 
769
 
 
770
bool
 
771
wxPdfDocument::AddFontCJK(const wxString& family)
 
772
{
 
773
  bool ok = !family.IsEmpty();
 
774
  if (ok)
 
775
  {
 
776
    wxPdfFont regFont = wxPdfFontManager::GetFontManager()->GetFont(family);
 
777
    if (!regFont.IsValid())
 
778
    {
 
779
      ok = wxPdfFontManager::GetFontManager()->RegisterFontCJK(family);
 
780
    }
 
781
  }
 
782
  return ok;
 
783
}
 
784
 
 
785
#endif // wxUSE_UNICODE
 
786
 
 
787
bool
 
788
wxPdfDocument::SetFont(const wxString& family, const wxString& style, double size)
 
789
{
 
790
  return SelectFont(family, style, size);
 
791
}
 
792
 
 
793
bool
 
794
wxPdfDocument::SetFont(const wxString& family, int style, double size)
 
795
{
 
796
  return SelectFont(family, style, size);
 
797
}
 
798
 
 
799
bool
 
800
wxPdfDocument::SetFont(const wxPdfFont& font, int style, double size)
 
801
{
 
802
  return SelectFont(font, style, size);
 
803
}
 
804
 
 
805
bool
 
806
wxPdfDocument::SetFont(const wxFont& font)
 
807
{
 
808
  return SelectFont(font);
 
809
}
 
810
 
 
811
void
 
812
wxPdfDocument::SetFontSize(double size)
 
813
{
 
814
  if (m_currentFont == NULL)
 
815
  {
 
816
    wxLogError(wxString(wxT("wxPdfDocument::SetFontSize: ")) +
 
817
               wxString(_("No font selected.")));
 
818
    return;
 
819
  }
 
820
  // Set font size in points
 
821
  if (m_fontSizePt == size)
 
822
  {
 
823
    return;
 
824
  }
 
825
  m_fontSizePt = size;
 
826
  m_fontSize = size / m_k;
 
827
  if ( m_page > 0)
 
828
  {
 
829
    OutAscii(wxString::Format(wxT("BT /F%d "),m_currentFont->GetIndex()) +
 
830
             wxPdfUtility::Double2String(m_fontSizePt,2) + wxString(wxT(" Tf ET")));
 
831
  }
 
832
}
 
833
 
 
834
wxPdfFont
 
835
wxPdfDocument::GetCurrentFont() const
 
836
{
 
837
  if (m_currentFont == NULL)
 
838
  {
 
839
    wxLogError(wxString(wxT("wxPdfDocument::GetCurrentFont: ")) +
 
840
               wxString(_("No font selected.")));
 
841
    return wxPdfFont();
 
842
  }
 
843
  return m_currentFont->GetUserFont();
 
844
}
 
845
 
 
846
const wxPdfFontDescription&
 
847
wxPdfDocument::GetFontDescription() const
 
848
{
 
849
  if (m_currentFont == NULL)
 
850
  {
 
851
    wxLogError(wxString(wxT("wxPdfDocument::SetFontSize: ")) +
 
852
               wxString(_("No font selected.")));
 
853
    static wxPdfFontDescription dummy;
 
854
    return dummy;
 
855
  }
 
856
  return m_currentFont->GetDescription();
 
857
}
 
858
 
 
859
const wxString
 
860
wxPdfDocument::GetFontFamily()
 
861
{
 
862
  return m_fontFamily;
 
863
}
 
864
 
 
865
const wxString
 
866
wxPdfDocument::GetFontStyle() const
 
867
{
 
868
  wxString style = wxEmptyString;
 
869
  int styles = GetFontStyles();
 
870
  if (styles & wxPDF_FONTSTYLE_BOLD)
 
871
  {
 
872
    style += wxString(wxT("B"));
 
873
  }
 
874
  if (styles & wxPDF_FONTSTYLE_ITALIC)
 
875
  {
 
876
    style += wxString(wxT("I"));
 
877
  }
 
878
  if (styles & wxPDF_FONTSTYLE_UNDERLINE)
 
879
  {
 
880
    style += wxString(wxT("U"));
 
881
  }
 
882
  if (styles & wxPDF_FONTSTYLE_OVERLINE)
 
883
  {
 
884
    style += wxString(wxT("O"));
 
885
  }
 
886
  if (styles & wxPDF_FONTSTYLE_STRIKEOUT)
 
887
  {
 
888
    style += wxString(wxT("S"));
 
889
  }
 
890
  return style;
 
891
}
 
892
 
 
893
int
 
894
wxPdfDocument::GetFontStyles() const
 
895
{
 
896
  return m_fontStyle | m_decoration;
 
897
}
 
898
 
 
899
double
 
900
wxPdfDocument::GetFontSize() const
 
901
{
 
902
  return m_fontSizePt;
 
903
}
 
904
 
 
905
double
 
906
wxPdfDocument::GetStringWidth(const wxString& s)
 
907
{
 
908
  wxString voText = ApplyVisualOrdering(s);
 
909
  return DoGetStringWidth(voText);
 
910
}
 
911
 
 
912
double
 
913
wxPdfDocument::DoGetStringWidth(const wxString& s)
 
914
{
 
915
  double w = 0;
 
916
  if (m_currentFont != 0)
 
917
  {
 
918
    w = m_currentFont->GetStringWidth(s, m_kerning) * m_fontSize;
 
919
  }
 
920
  return w;
 
921
}
 
922
 
 
923
void
 
924
wxPdfDocument::Text(double x, double y, const wxString& txt)
 
925
{
 
926
  // Output a string
 
927
  wxString voText = ApplyVisualOrdering(txt);
 
928
 
 
929
  if (m_colourFlag)
 
930
  {
 
931
    Out("q ", false);
 
932
    OutAscii(m_textColour.GetColour(false), false);
 
933
    Out(" ", false);
 
934
  }
 
935
  if (m_yAxisOriginTop)
 
936
  {
 
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);
 
940
  }
 
941
  else
 
942
  {
 
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);
 
946
  }
 
947
  OutAscii(wxString::Format(wxT("%d Tr "), m_textRenderMode), false);
 
948
  ShowText(voText);
 
949
  Out("ET", false);
 
950
 
 
951
  if ((m_decoration & wxPDF_FONTSTYLE_DECORATION_MASK) && voText.Length() > 0)
 
952
  {
 
953
    Out(" ", false);
 
954
    OutAscii(DoDecoration(x, y, voText), false);
 
955
  }
 
956
 
 
957
  if (m_colourFlag)
 
958
  {
 
959
    Out(" Q", false);
 
960
  }
 
961
  Out("\n", false);
 
962
}
 
963
 
 
964
void
 
965
wxPdfDocument::RotatedText(double x, double y, const wxString& txt, double angle)
 
966
{
 
967
  // Text rotated around its origin
 
968
  if (angle == 0)
 
969
  {
 
970
    Text(x, y, txt);
 
971
  }
 
972
  else
 
973
  {
 
974
    StartTransform();
 
975
    Rotate(angle, x, y);
 
976
    Text(x, y, txt);
 
977
    StopTransform();
 
978
  }
 
979
}
 
980
 
 
981
bool
 
982
wxPdfDocument::AcceptPageBreak()
 
983
{
 
984
  // Accept automatic page break or not
 
985
  return m_autoPageBreak;
 
986
}
 
987
 
 
988
void
 
989
wxPdfDocument::Cell(double w, double h, const wxString& txt, int border, int ln, int align, int fill, const wxPdfLink& link)
 
990
{
 
991
  wxString voText = ApplyVisualOrdering(txt);
 
992
  DoCell(w, h, voText, border, ln, align, fill, link);
 
993
}
 
994
 
 
995
void
 
996
wxPdfDocument::DoCell(double w, double h, const wxString& txt, int border, int ln, int align, int fill, const wxPdfLink& link)
 
997
{
 
998
  // Output a cell
 
999
  double x, y;
 
1000
  double k = m_k;
 
1001
  bool doPageBreak = (m_yAxisOriginTop) ? (m_y+h > m_pageBreakTrigger) : (m_y-h < m_pageBreakTrigger);
 
1002
  if (doPageBreak && !m_inFooter && AcceptPageBreak())
 
1003
  {
 
1004
    // Automatic page break
 
1005
    x = m_x;
 
1006
    double ws = m_ws;
 
1007
    if (ws > 0)
 
1008
    {
 
1009
      m_ws = 0;
 
1010
      Out("0 Tw");
 
1011
    }
 
1012
    AddPage(m_curOrientation);
 
1013
    m_x = x;
 
1014
    if (ws > 0)
 
1015
    {
 
1016
      m_ws = ws;
 
1017
      OutAscii(wxPdfUtility::Double2String(ws*k,3)+wxString(wxT(" Tw")));
 
1018
    }
 
1019
  }
 
1020
  if ( w == 0)
 
1021
  {
 
1022
    w = m_w - m_rMargin - m_x;
 
1023
  }
 
1024
  wxString s = wxEmptyString;
 
1025
  if (fill == 1 || border == wxPDF_BORDER_FRAME)
 
1026
  {
 
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);
 
1031
    if (fill == 1)
 
1032
    {
 
1033
      if (border == wxPDF_BORDER_FRAME)
 
1034
      {
 
1035
        s += wxString(wxT(" re B "));
 
1036
      }
 
1037
      else
 
1038
      {
 
1039
        s += wxString(wxT(" re f "));
 
1040
      }
 
1041
    }
 
1042
    else
 
1043
    {
 
1044
      s += wxString(wxT(" re S "));
 
1045
    }
 
1046
  }
 
1047
  if (border != wxPDF_BORDER_NONE && border != wxPDF_BORDER_FRAME)
 
1048
  {
 
1049
    x = m_x;
 
1050
    y = m_y;
 
1051
    if (border & wxPDF_BORDER_LEFT)
 
1052
    {
 
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 "));
 
1057
    }
 
1058
    if (border & wxPDF_BORDER_TOP)
 
1059
    {
 
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 "));
 
1064
    }
 
1065
    if (border & wxPDF_BORDER_RIGHT)
 
1066
    {
 
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 "));
 
1071
    }
 
1072
    if (border & wxPDF_BORDER_BOTTOM)
 
1073
    {
 
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 "));
 
1078
    }
 
1079
  }
 
1080
  if (s.Length() > 0)
 
1081
  {
 
1082
    bool newline = txt.Length() == 0;
 
1083
    OutAscii(s, newline);
 
1084
    s = wxT("");
 
1085
  }
 
1086
  
 
1087
  if (txt.Length() > 0)
 
1088
  {
 
1089
    double width = DoGetStringWidth(txt);
 
1090
    double dx;
 
1091
    if (align == wxPDF_ALIGN_RIGHT)
 
1092
    {
 
1093
      dx = w - m_cMargin - width;
 
1094
    }
 
1095
    else if (align == wxPDF_ALIGN_CENTER)
 
1096
    {
 
1097
      dx = (w - width) / 2;
 
1098
    }
 
1099
    else
 
1100
    {
 
1101
      dx = m_cMargin;
 
1102
    }
 
1103
    if (m_colourFlag)
 
1104
    {
 
1105
      s += wxString(wxT("q ")) + m_textColour.GetColour(false) + wxString(wxT(" "));
 
1106
    }
 
1107
    if (m_yAxisOriginTop)
 
1108
    {
 
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 "));
 
1112
    }
 
1113
    else
 
1114
    {
 
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 "));
 
1118
    }
 
1119
    OutAscii(s,false);
 
1120
    OutAscii(wxString::Format(wxT("%d Tr "), m_textRenderMode), false);
 
1121
    ShowText(txt);
 
1122
    s = wxT(" ET");
 
1123
 
 
1124
    if (m_decoration & wxPDF_FONTSTYLE_DECORATION_MASK)
 
1125
    {
 
1126
      s += wxString(wxT(" ")) + DoDecoration(m_x+dx,m_y+.5*h+.3*m_fontSize,txt);
 
1127
    }
 
1128
    if (m_colourFlag)
 
1129
    {
 
1130
      s += wxString(wxT(" Q"));
 
1131
    }
 
1132
    if (link.IsValid())
 
1133
    {
 
1134
      Link(m_x+dx,m_y+.5*h-.5*m_fontSize,width,m_fontSize,link);
 
1135
    }
 
1136
    OutAscii(s);
 
1137
  }
 
1138
  m_lasth = h;
 
1139
  if (ln > 0)
 
1140
  {
 
1141
    // Go to next line
 
1142
    if (m_yAxisOriginTop)
 
1143
    {
 
1144
      m_y += h;
 
1145
    }
 
1146
    else
 
1147
    {
 
1148
      m_y -= h;
 
1149
    }
 
1150
    if ( ln == 1)
 
1151
    {
 
1152
      m_x = m_lMargin;
 
1153
    }
 
1154
  }
 
1155
  else
 
1156
  {
 
1157
    m_x += w;
 
1158
  }
 
1159
}
 
1160
 
 
1161
int
 
1162
wxPdfDocument::MultiCell(double w, double h, const wxString& txt, int border, int align, int fill, int maxline)
 
1163
{
 
1164
  // Output text with automatic or explicit line breaks
 
1165
  if (w == 0)
 
1166
  {
 
1167
    w = m_w - m_rMargin - m_x;
 
1168
  }
 
1169
 
 
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'))
 
1175
  {
 
1176
    nb--;
 
1177
  }
 
1178
 
 
1179
  int b = wxPDF_BORDER_NONE;
 
1180
  int b2 = wxPDF_BORDER_NONE;
 
1181
  if (border != wxPDF_BORDER_NONE)
 
1182
  {
 
1183
    if (border == wxPDF_BORDER_FRAME)
 
1184
    {
 
1185
      b = wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT | wxPDF_BORDER_TOP;
 
1186
      b2 = wxPDF_BORDER_LEFT | wxPDF_BORDER_RIGHT;
 
1187
    }
 
1188
    else
 
1189
    {
 
1190
      b2 = wxPDF_BORDER_NONE;
 
1191
      if (border & wxPDF_BORDER_LEFT)
 
1192
      {
 
1193
        b2 = b2 | wxPDF_BORDER_LEFT;
 
1194
      }
 
1195
      if (border & wxPDF_BORDER_RIGHT)
 
1196
      {
 
1197
        b2 = b2 | wxPDF_BORDER_RIGHT;
 
1198
      }
 
1199
      b = (border & wxPDF_BORDER_TOP) ? b2 | wxPDF_BORDER_TOP : b2;
 
1200
    }
 
1201
  }
 
1202
  int sep = -1;
 
1203
  int i = 0;
 
1204
  int j = 0;
 
1205
  double len = 0;
 
1206
  double ls = 0;
 
1207
  int ns = 0;
 
1208
  int nl = 1;
 
1209
  wxChar c;
 
1210
  while (i < nb)
 
1211
  {
 
1212
    // Get next character
 
1213
    c = s[i];
 
1214
    if (c == wxT('\n'))
 
1215
    {
 
1216
      // Explicit line break
 
1217
      if (m_ws > 0)
 
1218
      {
 
1219
        m_ws = 0;
 
1220
        Out("0 Tw");
 
1221
      }
 
1222
      DoCell(w,h,s.SubString(j,i-1),b,2,align,fill);
 
1223
      i++;
 
1224
      sep = -1;
 
1225
      j = i;
 
1226
      len = 0;
 
1227
      ns = 0;
 
1228
      nl++;
 
1229
      if (border != wxPDF_BORDER_NONE && nl == 2)
 
1230
      {
 
1231
        b = b2;
 
1232
      }
 
1233
      if (maxline > 0 && nl > maxline)
 
1234
      {
 
1235
        return j;
 
1236
      }
 
1237
      continue;
 
1238
    }
 
1239
    if (c == wxT(' '))
 
1240
    {
 
1241
      sep = i;
 
1242
      ls = len;
 
1243
      ns++;
 
1244
    }
 
1245
    len = DoGetStringWidth(s.SubString(j, i));
 
1246
 
 
1247
    if (len > wmax)
 
1248
    {
 
1249
      // Automatic line break
 
1250
      if (sep == -1)
 
1251
      {
 
1252
        if (i == j)
 
1253
        {
 
1254
          i++;
 
1255
        }
 
1256
        if (m_ws > 0)
 
1257
        {
 
1258
          m_ws=0;
 
1259
          Out("0 Tw");
 
1260
        }
 
1261
        DoCell(w,h,s.SubString(j,i-1),b,2,align,fill);
 
1262
      }
 
1263
      else
 
1264
      {
 
1265
        if (align == wxPDF_ALIGN_JUSTIFY)
 
1266
        {
 
1267
          m_ws = (ns > 1) ? (wmax - ls)/(ns-1) : 0;
 
1268
          OutAscii(wxPdfUtility::Double2String(m_ws*m_k,3)+wxString(wxT(" Tw")));
 
1269
        }
 
1270
        DoCell(w,h,s.SubString(j,sep-1),b,2,align,fill);
 
1271
        i = sep + 1;
 
1272
      }
 
1273
      sep = -1;
 
1274
      j = i;
 
1275
      len = 0;
 
1276
      ns = 0;
 
1277
      nl++;
 
1278
      if (border != wxPDF_BORDER_NONE && nl == 2)
 
1279
      {
 
1280
        b = b2;
 
1281
      }
 
1282
      if (maxline > 0 && nl > maxline)
 
1283
      {
 
1284
        return j;
 
1285
      }
 
1286
    }
 
1287
    else
 
1288
    {
 
1289
      i++;
 
1290
    }
 
1291
  }
 
1292
  // Last chunk
 
1293
  if (m_ws > 0)
 
1294
  {
 
1295
    m_ws = 0;
 
1296
    Out("0 Tw");
 
1297
  }
 
1298
  if ((border != wxPDF_BORDER_NONE) && (border & wxPDF_BORDER_BOTTOM))
 
1299
  {
 
1300
    b = b | wxPDF_BORDER_BOTTOM;
 
1301
  }
 
1302
  DoCell(w,h,s.SubString(j,i-1),b,2,align,fill);
 
1303
  m_x = m_lMargin;
 
1304
  return i;
 
1305
}
 
1306
 
 
1307
int
 
1308
wxPdfDocument::LineCount(double w, const wxString& txt)
 
1309
{
 
1310
  // Output text with automatic or explicit line breaks
 
1311
  if (w == 0)
 
1312
  {
 
1313
    w = m_w - m_rMargin - m_x;
 
1314
  }
 
1315
 
 
1316
  double wmax = (w - 2 * m_cMargin);
 
1317
  wxString s = txt;
 
1318
  s.Replace(wxT("\r"),wxT("")); // remove carriage returns
 
1319
  int nb = (int) s.Length();
 
1320
  if (nb > 0 && s[nb-1] == wxT('\n'))
 
1321
  {
 
1322
    nb--;
 
1323
  }
 
1324
 
 
1325
  int sep = -1;
 
1326
  int i = 0;
 
1327
  int j = 0;
 
1328
  double len = 0;
 
1329
  int nl = 1;
 
1330
  wxChar c;
 
1331
  while (i < nb)
 
1332
  {
 
1333
    // Get next character
 
1334
    c = s[i];
 
1335
    if (c == wxT('\n'))
 
1336
    {
 
1337
      // Explicit line break
 
1338
      i++;
 
1339
      sep = -1;
 
1340
      j = i;
 
1341
      len = 0;
 
1342
      nl++;
 
1343
      continue;
 
1344
    }
 
1345
    if (c == wxT(' '))
 
1346
    {
 
1347
      sep = i;
 
1348
    }
 
1349
    len = DoGetStringWidth(s.SubString(j, i));
 
1350
 
 
1351
    if (len > wmax)
 
1352
    {
 
1353
      // Automatic line break
 
1354
      if (sep == -1)
 
1355
      {
 
1356
        if (i == j)
 
1357
        {
 
1358
          i++;
 
1359
        }
 
1360
      }
 
1361
      else
 
1362
      {
 
1363
        i = sep + 1;
 
1364
      }
 
1365
      sep = -1;
 
1366
      j = i;
 
1367
      len = 0;
 
1368
      nl++;
 
1369
    }
 
1370
    else
 
1371
    {
 
1372
      i++;
 
1373
    }
 
1374
  }
 
1375
  return nl;
 
1376
}
 
1377
 
 
1378
int
 
1379
wxPdfDocument::TextBox(double w, double h, const wxString& txt,
 
1380
                       int halign, int valign, int border, int fill)
 
1381
{
 
1382
  double xi = m_x;
 
1383
  double yi = m_y;
 
1384
  
 
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;
 
1389
 
 
1390
  double dy = 0;
 
1391
  if (valign == wxPDF_ALIGN_MIDDLE)
 
1392
  {
 
1393
    dy = (h - rows * hrow) / 2;
 
1394
  }
 
1395
  else if (valign == wxPDF_ALIGN_BOTTOM)
 
1396
  {
 
1397
    dy = h - rows * hrow;
 
1398
  }
 
1399
 
 
1400
  SetY(yi+dy);
 
1401
  SetX(xi);
 
1402
  int trail = MultiCell(w, hrow, txt, 0, halign, fill, rows);
 
1403
 
 
1404
  if (border == wxPDF_BORDER_FRAME)
 
1405
  {
 
1406
    Rect(xi, yi, w, h);
 
1407
  }
 
1408
  else
 
1409
  {
 
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);
 
1414
  }
 
1415
 
 
1416
  return trail;
 
1417
}
 
1418
 
 
1419
void
 
1420
wxPdfDocument::Write(double h, const wxString& txt, const wxPdfLink& link)
 
1421
{
 
1422
  WriteCell(h, txt, wxPDF_BORDER_NONE, 0, link);
 
1423
}
 
1424
 
 
1425
void
 
1426
wxPdfDocument::WriteCell(double h, const wxString& txt, int border, int fill, const wxPdfLink& link)
 
1427
{
 
1428
  // Output text in flowing mode
 
1429
  wxString s = ApplyVisualOrdering(txt);
 
1430
 
 
1431
  s.Replace(wxT("\r"),wxT("")); // remove carriage returns
 
1432
  int nb = (int) s.Length();
 
1433
 
 
1434
  // handle single space character
 
1435
  if ((nb == 1) && s[0] == wxT(' '))
 
1436
  {
 
1437
    m_x += DoGetStringWidth(s);
 
1438
    return;
 
1439
  }
 
1440
 
 
1441
  double saveCellMargin = GetCellMargin();
 
1442
  SetCellMargin(0);
 
1443
 
 
1444
  double w = m_w - m_rMargin - m_x;
 
1445
  double wmax = (w - 2 * m_cMargin) + wxPDF_EPSILON;
 
1446
 
 
1447
  int sep = -1;
 
1448
  int i = 0;
 
1449
  int j = 0;
 
1450
  double len=0;
 
1451
  int nl = 1;
 
1452
  wxChar c;
 
1453
  while (i < nb)
 
1454
  {
 
1455
    // Get next character
 
1456
    c = s[i];
 
1457
    if (c == wxT('\n'))
 
1458
    {
 
1459
      // Explicit line break
 
1460
      DoCell(w, h, s.SubString(j,i-1), border, 2, wxPDF_ALIGN_LEFT, fill, link);
 
1461
      i++;
 
1462
      sep = -1;
 
1463
      j = i;
 
1464
      len = 0;
 
1465
      if (nl == 1)
 
1466
      {
 
1467
        m_x = m_lMargin;
 
1468
        w = m_w - m_rMargin - m_x;
 
1469
        wmax = (w - 2 * m_cMargin);
 
1470
      }
 
1471
      nl++;
 
1472
      continue;
 
1473
    }
 
1474
    if (c == wxT(' '))
 
1475
    {
 
1476
      sep = i;
 
1477
    }
 
1478
    len = DoGetStringWidth(s.SubString(j, i));
 
1479
    if (len > wmax)
 
1480
    {
 
1481
      // Automatic line break
 
1482
      if (sep == -1)
 
1483
      {
 
1484
        if (m_x > m_lMargin)
 
1485
        {
 
1486
          // Move to next line
 
1487
          m_x = m_lMargin;
 
1488
          if (m_yAxisOriginTop)
 
1489
          {
 
1490
            m_y += h;
 
1491
          }
 
1492
          else
 
1493
          {
 
1494
            m_y -= h;
 
1495
          }
 
1496
          w = m_w - m_rMargin - m_x;
 
1497
          wmax = (w - 2 * m_cMargin);
 
1498
          i++;
 
1499
          nl++;
 
1500
          continue;
 
1501
        }
 
1502
        if (i == j)
 
1503
        {
 
1504
          i++;
 
1505
        }
 
1506
        DoCell(w, h,s.SubString(j, i-1), border, 2, wxPDF_ALIGN_LEFT, fill, link);
 
1507
      }
 
1508
      else
 
1509
      {
 
1510
        DoCell(w, h, s.SubString(j, sep-1), border, 2, wxPDF_ALIGN_LEFT, fill, link);
 
1511
        i = sep + 1;
 
1512
      }
 
1513
      sep = -1;
 
1514
      j = i;
 
1515
      len = 0;
 
1516
      if (nl == 1)
 
1517
      {
 
1518
        m_x = m_lMargin;
 
1519
        w = m_w - m_rMargin - m_x;
 
1520
        wmax = (w - 2 * m_cMargin);
 
1521
      }
 
1522
      nl++;
 
1523
    }
 
1524
    else
 
1525
    {
 
1526
      i++;
 
1527
    }
 
1528
  }
 
1529
  // Last chunk
 
1530
  if (i != j)
 
1531
  {
 
1532
    DoCell(len, h, s.SubString(j,i-1), border, 0, wxPDF_ALIGN_LEFT, fill, link);
 
1533
  }
 
1534
 
 
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);
 
1538
}
 
1539
 
 
1540
bool
 
1541
wxPdfDocument::WriteGlyphArray(wxPdfArrayDouble& x, wxPdfArrayDouble& y, wxPdfArrayUint32& glyphs)
 
1542
{
 
1543
  bool ok = m_currentFont != NULL;
 
1544
#if wxUSE_UNICODE
 
1545
  if (ok)
 
1546
  {
 
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")))
 
1550
    {
 
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);
 
1556
      double xp, yp;
 
1557
      size_t j;
 
1558
      for (j = 0; j < n; ++j)
 
1559
      {
 
1560
        xp = m_x + x[j];
 
1561
        yp = m_y + y[j];
 
1562
        if (m_yAxisOriginTop)
 
1563
        {
 
1564
          Out("BT 1 0 0 -1 ", false);
 
1565
        }
 
1566
        else
 
1567
        {
 
1568
          Out("BT ", false);
 
1569
        }
 
1570
        OutAscii(wxPdfUtility::Double2String(xp*m_k,2), false);
 
1571
        Out(" ", false);
 
1572
        OutAscii(wxPdfUtility::Double2String(yp*m_k,2), false);
 
1573
        if (m_yAxisOriginTop)
 
1574
        {
 
1575
          Out(" Tm ", false);
 
1576
        }
 
1577
        else
 
1578
        {
 
1579
          Out(" Td ", false);
 
1580
        }
 
1581
        ShowGlyph(glyphs[j]);
 
1582
        Out(" ET");
 
1583
      }
 
1584
    }
 
1585
    else
 
1586
    {
 
1587
      ok = false;
 
1588
      wxLogError(wxString(wxT("wxPdfDocument::WriteGlyphArray: ")) +
 
1589
                 wxString::Format(_("Font type '%s' not supported."), fontType.c_str()));
 
1590
    }
 
1591
  }
 
1592
  else
 
1593
  {
 
1594
    wxLogError(wxString(wxT("wxPdfDocument::WriteGlyphArray: ")) +
 
1595
               wxString(_("No font selected.")));
 
1596
  }
 
1597
#else
 
1598
  wxUnusedVar(x);
 
1599
  wxUnusedVar(y);
 
1600
  wxUnusedVar(glyphs);
 
1601
  wxLogError(wxString(wxT("wxPdfDocument::WriteGlyphArray: ")) +
 
1602
             wxString(_("Supported in Unicode build only.")));
 
1603
#endif // wxUSE_UNICODE
 
1604
  return ok;
 
1605
}
 
1606
 
 
1607
bool
 
1608
wxPdfDocument::Image(const wxString& file, double x, double y, double w, double h,
 
1609
                     const wxString& type, const wxPdfLink& link, int maskImage)
 
1610
{
 
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())
 
1615
  {
 
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())
 
1620
    {
 
1621
      bool isValid = false;
 
1622
      delete currentImage;
 
1623
 
 
1624
      if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == NULL)
 
1625
      {
 
1626
        wxImage::AddHandler(new wxPNGHandler());
 
1627
      }
 
1628
      wxImage tempImage;
 
1629
      tempImage.LoadFile(file);
 
1630
      if (tempImage.Ok())
 
1631
      {
 
1632
        isValid = Image(file, tempImage, x, y, w, h, link, maskImage);
 
1633
      }
 
1634
      return isValid;
 
1635
    }
 
1636
    if (maskImage > 0)
 
1637
    {
 
1638
      currentImage->SetMaskImage(maskImage);
 
1639
    }
 
1640
    (*m_images)[file] = currentImage;
 
1641
  }
 
1642
  else
 
1643
  {
 
1644
    currentImage = image->second;
 
1645
    if (maskImage > 0 && currentImage->GetMaskImage() != maskImage)
 
1646
    {
 
1647
      currentImage->SetMaskImage(maskImage);
 
1648
    }
 
1649
  }
 
1650
  OutImage(currentImage, x, y, w, h, link);
 
1651
  return true;
 
1652
}
 
1653
 
 
1654
bool
 
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)
 
1657
{
 
1658
  bool isValid = false;
 
1659
  if (img.Ok())
 
1660
  {
 
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())
 
1666
    {
 
1667
      if (tempImage.HasAlpha())
 
1668
      {
 
1669
        if (maskImage <= 0)
 
1670
        {
 
1671
          maskImage = ImageMask(name+wxString(wxT(".mask")), tempImage);
 
1672
        }
 
1673
        if(!tempImage.ConvertAlphaToMask(0))
 
1674
        {
 
1675
          return false;
 
1676
        }
 
1677
      }
 
1678
      else if (tempImage.HasMask() && maskImage <= 0)
 
1679
      {
 
1680
        // Extract the mask
 
1681
        wxImage mask = tempImage.ConvertToMono(tempImage.GetMaskRed(), tempImage.GetMaskGreen(), tempImage.GetMaskBlue());
 
1682
        // Invert the mask
 
1683
        mask = mask.ConvertToMono(0, 0, 0);
 
1684
        maskImage = ImageMask(name+wxString(wxT(".mask")), mask);
 
1685
      }
 
1686
      // First use of image, get info
 
1687
      tempImage.SetMask(false);
 
1688
      if (jpegFormat)
 
1689
      {
 
1690
        tempImage.SetOption(wxIMAGE_OPTION_QUALITY, jpegQuality);
 
1691
      }
 
1692
      int i = (int) (*m_images).size() + 1;
 
1693
      currentImage = new wxPdfImage(this, i, name, tempImage, jpegFormat);
 
1694
      if (!currentImage->Parse())
 
1695
      {
 
1696
        delete currentImage;
 
1697
        return false;
 
1698
      }
 
1699
      if (maskImage > 0)
 
1700
      {
 
1701
        currentImage->SetMaskImage(maskImage);
 
1702
      }
 
1703
      (*m_images)[name] = currentImage;
 
1704
    }
 
1705
    else
 
1706
    {
 
1707
      currentImage = image->second;
 
1708
      if (maskImage > 0 && currentImage->GetMaskImage() != maskImage)
 
1709
      {
 
1710
        currentImage->SetMaskImage(maskImage);
 
1711
      }
 
1712
    }
 
1713
    OutImage(currentImage, x, y, w, h, link);
 
1714
    isValid = true;
 
1715
  }
 
1716
  return isValid;
 
1717
}
 
1718
 
 
1719
bool
 
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)
 
1724
{
 
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())
 
1730
  {
 
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())
 
1735
    {
 
1736
      delete currentImage;
 
1737
      if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == NULL)
 
1738
      {
 
1739
        wxImage::AddHandler(new wxPNGHandler());
 
1740
      }
 
1741
      wxImage tempImage;
 
1742
      tempImage.LoadFile(stream, mimeType);
 
1743
      if (tempImage.Ok())
 
1744
      {
 
1745
        isValid = Image(name, tempImage, x, y, w, h, link, maskImage);
 
1746
      }
 
1747
      return isValid;
 
1748
 
 
1749
    }
 
1750
    if (maskImage > 0)
 
1751
    {
 
1752
      currentImage->SetMaskImage(maskImage);
 
1753
    }
 
1754
    (*m_images)[name] = currentImage;
 
1755
  }
 
1756
  else
 
1757
  {
 
1758
    currentImage = image->second;
 
1759
    if (maskImage > 0 && currentImage->GetMaskImage() != maskImage)
 
1760
    {
 
1761
      currentImage->SetMaskImage(maskImage);
 
1762
    }
 
1763
  }
 
1764
  OutImage(currentImage, x, y, w, h, link);
 
1765
  isValid = true;
 
1766
  return isValid;
 
1767
}
 
1768
 
 
1769
int
 
1770
wxPdfDocument::ImageMask(const wxString& file, const wxString& type)
 
1771
{
 
1772
  int n = 0;
 
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())
 
1777
  {
 
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())
 
1782
    {
 
1783
      delete currentImage;
 
1784
      return 0;
 
1785
    }
 
1786
    // Check whether this is a gray scale image (must be)
 
1787
    if (currentImage->GetColourSpace() != wxT("DeviceGray"))
 
1788
    {
 
1789
      delete currentImage;
 
1790
      return 0;
 
1791
    }
 
1792
    (*m_images)[file] = currentImage;
 
1793
  }
 
1794
  else
 
1795
  {
 
1796
    currentImage = image->second;
 
1797
    n = currentImage->GetIndex();
 
1798
  }
 
1799
  if (m_PDFVersion < wxT("1.4"))
 
1800
  {
 
1801
    m_PDFVersion = wxT("1.4");
 
1802
  }
 
1803
  return n;
 
1804
}
 
1805
 
 
1806
int
 
1807
wxPdfDocument::ImageMask(const wxString& name, const wxImage& img)
 
1808
{
 
1809
  int n = 0;
 
1810
  if (img.Ok())
 
1811
  {
 
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())
 
1816
    {
 
1817
      wxImage tempImage;
 
1818
      if (img.HasAlpha())
 
1819
      {
 
1820
        int x, y;
 
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++)
 
1826
        {
 
1827
          for (y = 0; y < h; y++)
 
1828
          {
 
1829
            alpha = img.GetAlpha(x, y);
 
1830
            tempImage.SetRGB(x, y, alpha, alpha, alpha);
 
1831
          }
 
1832
        }
 
1833
        tempImage.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_GREY_RED);
 
1834
      }
 
1835
      else
 
1836
      {
 
1837
        tempImage = img.ConvertToGreyscale();
 
1838
        tempImage.SetOption(wxIMAGE_OPTION_PNG_FORMAT, wxPNG_TYPE_GREY_RED);
 
1839
      }
 
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())
 
1845
      {
 
1846
        delete currentImage;
 
1847
        return 0;
 
1848
      }
 
1849
      (*m_images)[name] = currentImage;
 
1850
    }
 
1851
    else
 
1852
    {
 
1853
      currentImage = image->second;
 
1854
      n = currentImage->GetIndex();
 
1855
    }
 
1856
    if (m_PDFVersion < wxT("1.4"))
 
1857
    {
 
1858
      m_PDFVersion = wxT("1.4");
 
1859
    }
 
1860
  }
 
1861
  return n;
 
1862
}
 
1863
 
 
1864
int
 
1865
wxPdfDocument::ImageMask(const wxString& name, wxInputStream& stream, const wxString& mimeType)
 
1866
{
 
1867
  int n = 0;
 
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())
 
1872
  {
 
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())
 
1877
    {
 
1878
      delete currentImage;
 
1879
      return 0;
 
1880
    }
 
1881
    // Check whether this is a gray scale image (must be)
 
1882
    if (currentImage->GetColourSpace() != wxT("DeviceGray"))
 
1883
    {
 
1884
      delete currentImage;
 
1885
      return 0;
 
1886
    }
 
1887
    (*m_images)[name] = currentImage;
 
1888
  }
 
1889
  else
 
1890
  {
 
1891
    currentImage = image->second;
 
1892
    n = currentImage->GetIndex();
 
1893
  }
 
1894
  if (m_PDFVersion < wxT("1.4"))
 
1895
  {
 
1896
    m_PDFVersion = wxT("1.4");
 
1897
  }
 
1898
  return n;
 
1899
}
 
1900
 
 
1901
void
 
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)
 
1904
{
 
1905
  // Image rotated around its upper-left corner
 
1906
  StartTransform();
 
1907
  Rotate(angle, x, y);
 
1908
  Image(file, x, y, w, h, type, link, maskImage);
 
1909
  StopTransform();
 
1910
}
 
1911
 
 
1912
void
 
1913
wxPdfDocument::Ln(double h)
 
1914
{
 
1915
  // Line feed; default value is last cell height
 
1916
  m_x = m_lMargin;
 
1917
  if (h < 0)
 
1918
  {
 
1919
    if (m_yAxisOriginTop)
 
1920
    {
 
1921
      m_y += m_lasth;
 
1922
    }
 
1923
    else
 
1924
    {
 
1925
      m_y -= m_lasth;
 
1926
    }
 
1927
  }
 
1928
  else
 
1929
  {
 
1930
    if (m_yAxisOriginTop)
 
1931
    {
 
1932
      m_y += h;
 
1933
    }
 
1934
    else
 
1935
    {
 
1936
      m_y -= h;
 
1937
    }
 
1938
  }
 
1939
}
 
1940
 
 
1941
void
 
1942
wxPdfDocument::SaveAsFile(const wxString& name)
 
1943
{
 
1944
  wxString fileName = name;
 
1945
  // Normalize parameters
 
1946
  if(fileName.Length() == 0)
 
1947
  {
 
1948
    fileName = wxT("doc.pdf");
 
1949
  }
 
1950
 
 
1951
  wxFileOutputStream outfile(fileName);
 
1952
 
 
1953
  // Finish document if necessary
 
1954
  if (m_state < 3)
 
1955
  {
 
1956
    if (m_buffer != NULL)
 
1957
    {
 
1958
      delete m_buffer;
 
1959
    }
 
1960
    m_buffer = &outfile;
 
1961
    Close();
 
1962
    m_buffer = NULL;
 
1963
  }
 
1964
  else
 
1965
  {
 
1966
    // Save to local file
 
1967
    wxMemoryInputStream tmp(*((wxMemoryOutputStream*) m_buffer));
 
1968
    outfile.Write(tmp);
 
1969
  }
 
1970
  outfile.Close();
 
1971
}
 
1972
 
 
1973
const wxMemoryOutputStream&
 
1974
wxPdfDocument::CloseAndGetBuffer()
 
1975
{
 
1976
  if (m_state < 3)
 
1977
  {
 
1978
    Close();
 
1979
  }
 
1980
  
 
1981
  return *((wxMemoryOutputStream*) m_buffer);
 
1982
}
 
1983
 
 
1984
void
 
1985
wxPdfDocument::SetViewerPreferences(int preferences)
 
1986
{
 
1987
  m_viewerPrefs = (preferences > 0) ? preferences : 0;
 
1988
  if (((m_viewerPrefs & wxPDF_VIEWER_DISPLAYDOCTITLE) != 0) && (m_PDFVersion < wxT("1.4")))
 
1989
  {
 
1990
    m_PDFVersion = wxT("1.4");
 
1991
  }
 
1992
}
 
1993
 
 
1994
void
 
1995
wxPdfDocument::SetTitle(const wxString& title)
 
1996
{
 
1997
  // Title of document
 
1998
  m_title = title;
 
1999
}
 
2000
 
 
2001
void
 
2002
wxPdfDocument::SetSubject(const wxString& subject)
 
2003
{
 
2004
  // Subject of document
 
2005
  m_subject = subject;
 
2006
}
 
2007
 
 
2008
void
 
2009
wxPdfDocument::SetAuthor(const wxString& author)
 
2010
{
 
2011
  // Author of document
 
2012
  m_author = author;
 
2013
}
 
2014
 
 
2015
void
 
2016
wxPdfDocument::SetKeywords(const wxString& keywords)
 
2017
{
 
2018
  // Keywords of document
 
2019
  m_keywords = keywords;
 
2020
}
 
2021
 
 
2022
void
 
2023
wxPdfDocument::SetCreator(const wxString& creator)
 
2024
{
 
2025
  // Creator of document
 
2026
  m_creator = creator;
 
2027
}
 
2028
 
 
2029
void
 
2030
wxPdfDocument::SetMargins(double left, double top, double right)
 
2031
{
 
2032
  // Set left, top and right margins
 
2033
  m_lMargin = left;
 
2034
  m_tMargin = top;
 
2035
  if (right == -1)
 
2036
  {
 
2037
    right = left;
 
2038
  }
 
2039
  m_rMargin = right;
 
2040
}
 
2041
 
 
2042
void
 
2043
wxPdfDocument::SetLeftMargin(double margin)
 
2044
{
 
2045
  // Set left margin
 
2046
  m_lMargin = margin;
 
2047
  if (m_page > 0 && m_x < margin)
 
2048
  {
 
2049
    m_x = margin;
 
2050
  }
 
2051
}
 
2052
 
 
2053
double
 
2054
wxPdfDocument::GetLeftMargin()
 
2055
{
 
2056
  return m_lMargin;
 
2057
}
 
2058
 
 
2059
void
 
2060
wxPdfDocument::SetTopMargin(double margin)
 
2061
{
 
2062
  // Set top margin
 
2063
  m_tMargin = margin;
 
2064
}
 
2065
 
 
2066
double
 
2067
wxPdfDocument::GetTopMargin()
 
2068
{
 
2069
  return m_tMargin;
 
2070
}
 
2071
 
 
2072
void
 
2073
wxPdfDocument::SetRightMargin(double margin)
 
2074
{
 
2075
  // Set right margin
 
2076
  m_rMargin = margin;
 
2077
}
 
2078
 
 
2079
double
 
2080
wxPdfDocument::GetRightMargin()
 
2081
{
 
2082
  return m_rMargin;
 
2083
}
 
2084
 
 
2085
void
 
2086
wxPdfDocument::SetCellMargin(double margin)
 
2087
{
 
2088
  // Set cell margin
 
2089
  m_cMargin = margin;
 
2090
}
 
2091
 
 
2092
double
 
2093
wxPdfDocument::GetCellMargin()
 
2094
{
 
2095
  return m_cMargin;
 
2096
}
 
2097
 
 
2098
void
 
2099
wxPdfDocument::SetLineHeight(double height)
 
2100
{
 
2101
  m_lasth = height;
 
2102
}
 
2103
 
 
2104
double
 
2105
wxPdfDocument::GetLineHeight()
 
2106
{
 
2107
  return m_lasth;
 
2108
}
 
2109
 
 
2110
void
 
2111
wxPdfDocument::SetAutoPageBreak(bool autoPageBreak, double margin)
 
2112
{
 
2113
  // Set auto page break mode and triggering margin
 
2114
  m_autoPageBreak = autoPageBreak;
 
2115
  m_bMargin = margin;
 
2116
  m_pageBreakTrigger = (m_yAxisOriginTop) ? m_h - margin : margin;
 
2117
}
 
2118
 
 
2119
void
 
2120
wxPdfDocument::SetDisplayMode(wxPdfZoom zoom, wxPdfLayout layout, double zoomFactor)
 
2121
{
 
2122
  // Set display mode in viewer
 
2123
  switch (zoom)
 
2124
  {
 
2125
    case wxPDF_ZOOM_FULLPAGE:
 
2126
    case wxPDF_ZOOM_FULLWIDTH:
 
2127
    case wxPDF_ZOOM_REAL:
 
2128
    case wxPDF_ZOOM_DEFAULT:
 
2129
      m_zoomMode = zoom;
 
2130
      break;
 
2131
    case wxPDF_ZOOM_FACTOR:
 
2132
      m_zoomMode = zoom;
 
2133
      m_zoomFactor = (zoomFactor > 0) ? zoomFactor : 100.;
 
2134
      break;
 
2135
    default:
 
2136
      m_zoomMode = wxPDF_ZOOM_FULLWIDTH;
 
2137
      break;
 
2138
  }
 
2139
 
 
2140
  switch (layout)
 
2141
  {
 
2142
    case wxPDF_LAYOUT_SINGLE:
 
2143
    case wxPDF_LAYOUT_TWO:
 
2144
    case wxPDF_LAYOUT_DEFAULT:
 
2145
    case wxPDF_LAYOUT_CONTINUOUS:
 
2146
      m_layoutMode = layout;
 
2147
      break;
 
2148
    default:
 
2149
      m_layoutMode = wxPDF_LAYOUT_CONTINUOUS;
 
2150
      break;
 
2151
  }
 
2152
}
 
2153
 
 
2154
void
 
2155
wxPdfDocument::Close()
 
2156
{
 
2157
  // Terminate document
 
2158
  if (m_state == 3)
 
2159
  {
 
2160
    return;
 
2161
  }
 
2162
  if (m_page == 0)
 
2163
  {
 
2164
    AddPage();
 
2165
  }
 
2166
  
 
2167
  // Page footer
 
2168
  m_inFooter = true;
 
2169
  Footer();
 
2170
  m_inFooter = false;
 
2171
 
 
2172
  // Close page
 
2173
  EndPage();
 
2174
 
 
2175
  // Close document
 
2176
  EndDoc();
 
2177
}
 
2178
 
 
2179
void
 
2180
wxPdfDocument::Header()
 
2181
{
 
2182
  // To be implemented in your own inherited class
 
2183
}
 
2184
 
 
2185
void
 
2186
wxPdfDocument::Footer()
 
2187
{
 
2188
  // To be implemented in your own inherited class
 
2189
}
 
2190
 
 
2191
bool
 
2192
wxPdfDocument::IsInFooter()
 
2193
{
 
2194
  return m_inFooter;
 
2195
}
 
2196
 
 
2197
int
 
2198
wxPdfDocument::PageNo()
 
2199
{
 
2200
  // Get current page number
 
2201
  return m_page;
 
2202
}
 
2203
 
 
2204
double
 
2205
wxPdfDocument::GetX()
 
2206
{
 
2207
  // Get x position
 
2208
  return m_x;
 
2209
}
 
2210
 
 
2211
void
 
2212
wxPdfDocument::SetX(double x)
 
2213
{
 
2214
  // Set x position
 
2215
  if ( x >= 0.0)
 
2216
  {
 
2217
    m_x = x;
 
2218
  }
 
2219
  else
 
2220
  {
 
2221
    m_x = m_w + x;
 
2222
  }
 
2223
}
 
2224
 
 
2225
double
 
2226
wxPdfDocument::GetY()
 
2227
{
 
2228
  // Get y position
 
2229
  return m_y;
 
2230
}
 
2231
 
 
2232
void
 
2233
wxPdfDocument::SetY(double y)
 
2234
{
 
2235
  // Set y position and reset x
 
2236
  m_x = m_lMargin;
 
2237
  if ( y >= 0)
 
2238
  {
 
2239
    m_y = y;
 
2240
  }
 
2241
  else
 
2242
  {
 
2243
    m_y = m_h + y;
 
2244
  }
 
2245
}
 
2246
 
 
2247
void
 
2248
wxPdfDocument::SetXY(double x, double y)
 
2249
{
 
2250
  // Set x and y positions
 
2251
  SetY(y);
 
2252
  SetX(x);
 
2253
}
 
2254
 
 
2255
void
 
2256
wxPdfDocument::SetKerning(bool kerning)
 
2257
{
 
2258
  m_kerning = kerning;
 
2259
}
 
2260
 
 
2261
void
 
2262
wxPdfDocument::SetCompression(bool compress)
 
2263
{
 
2264
  m_compress = compress;
 
2265
}
 
2266
 
 
2267
void
 
2268
wxPdfDocument::AppendJavascript(const wxString& javascript)
 
2269
{
 
2270
  m_javascript += javascript;
 
2271
}
 
2272
 
 
2273
bool
 
2274
wxPdfDocument::AttachFile(const wxString& fileName, const wxString& attachName, const wxString& description)
 
2275
{
 
2276
  wxFileName attachFile(fileName);
 
2277
  bool ok = attachFile.FileExists();
 
2278
  if (ok)
 
2279
  {
 
2280
    wxArrayString* attachment = new wxArrayString();
 
2281
    attachment->Add(fileName);
 
2282
    if (!attachName.IsEmpty())
 
2283
    {
 
2284
      attachment->Add(attachName);
 
2285
    }
 
2286
    else
 
2287
    {
 
2288
      attachment->Add(attachFile.GetFullName());
 
2289
    }
 
2290
    attachment->Add(description);
 
2291
 
 
2292
    int index = (int) (m_attachments->size() + 1);
 
2293
    (*m_attachments)[index] = attachment;
 
2294
  }
 
2295
  else
 
2296
  {
 
2297
    wxLogDebug(wxT("*** Attachment file '%s' does not exist."), fileName.c_str());
 
2298
  }
 
2299
  return ok;
 
2300
}
 
2301
 
 
2302
// ---
 
2303
 
 
2304
void
 
2305
wxPdfDocument::AddSpotColour(const wxString& name, double cyan, double magenta, double yellow, double black)
 
2306
{
 
2307
  wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
 
2308
  if (spotColour == (*m_spotColours).end())
 
2309
  {
 
2310
    int i = (int) (*m_spotColours).size() + 1;
 
2311
    (*m_spotColours)[name] = new wxPdfSpotColour(i, cyan, magenta, yellow, black);
 
2312
  }
 
2313
}
 
2314
 
 
2315
bool
 
2316
wxPdfDocument::AddPattern(const wxString& patternName, const wxImage& image, double width, double height)
 
2317
{
 
2318
  bool isValid = true;
 
2319
  wxPdfPatternMap::iterator patternIter = m_patterns->find(patternName);
 
2320
  if (patternIter == m_patterns->end())
 
2321
  {
 
2322
    if (image.IsOk() && width > 0 && height > 0)
 
2323
    {
 
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())
 
2328
      {
 
2329
        // Prepare new image
 
2330
        int maskImage = 0;
 
2331
        wxImage tempImage = image.Copy();
 
2332
        if (tempImage.HasAlpha())
 
2333
        {
 
2334
          maskImage = ImageMask(imageName+wxString(wxT(".mask")), tempImage);
 
2335
          tempImage.ConvertAlphaToMask(0);
 
2336
        }
 
2337
        tempImage.SetMask(false);
 
2338
        int i = (*m_images).size() + 1;
 
2339
        currentImage = new wxPdfImage(this, i, imageName, tempImage);
 
2340
        currentImage->Parse();
 
2341
        if (maskImage > 0)
 
2342
        {
 
2343
          currentImage->SetMaskImage(maskImage);
 
2344
        }
 
2345
        (*m_images)[imageName] = currentImage;
 
2346
      }
 
2347
      else
 
2348
      {
 
2349
        // Use existing image
 
2350
        currentImage = imageIter->second;
 
2351
      }
 
2352
 
 
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;
 
2359
    }
 
2360
    else
 
2361
    {
 
2362
      isValid = false;
 
2363
      if (!image.IsOk())
 
2364
      {
 
2365
        wxLogError(wxString(wxT("wxPdfDocument::AddPattern: ")) +
 
2366
                   wxString(_("Invalid image.")));
 
2367
      }
 
2368
      else
 
2369
      {
 
2370
        wxLogError(wxString(wxT("wxPdfDocument::AddPattern: ")) +
 
2371
                   wxString::Format(_("Invalid width (%.1f) and/or height (%.1f)."), width, height));
 
2372
      }
 
2373
    }
 
2374
  }
 
2375
  return isValid;
 
2376
}
 
2377
 
 
2378
void
 
2379
wxPdfDocument::SetDrawColour(const wxColour& colour)
 
2380
{
 
2381
  wxPdfColour tempColour(colour);
 
2382
  m_drawColour = tempColour;
 
2383
  if (m_page > 0)
 
2384
  {
 
2385
    OutAscii(m_drawColour.GetColour(true));
 
2386
  }
 
2387
}
 
2388
 
 
2389
void
 
2390
wxPdfDocument::SetDrawColour(const unsigned char grayscale)
 
2391
{
 
2392
  wxPdfColour tempColour(grayscale);
 
2393
  m_drawColour = tempColour;
 
2394
  if (m_page > 0)
 
2395
  {
 
2396
    OutAscii(m_drawColour.GetColour(true));
 
2397
  }
 
2398
}
 
2399
 
 
2400
void
 
2401
wxPdfDocument::SetDrawColour(const unsigned char red, const unsigned char green, const unsigned char blue)
 
2402
{
 
2403
  SetDrawColour(wxColour(red, green, blue));
 
2404
}
 
2405
 
 
2406
void
 
2407
wxPdfDocument::SetDrawColour(double cyan, double magenta, double yellow, double black)
 
2408
{
 
2409
  SetDrawColour(wxPdfColour(cyan, magenta, yellow, black));
 
2410
}
 
2411
 
 
2412
void
 
2413
wxPdfDocument::SetDrawColour(const wxPdfColour& colour)
 
2414
{
 
2415
  m_drawColour = colour;
 
2416
  if (m_page > 0)
 
2417
  {
 
2418
    OutAscii(m_drawColour.GetColour(true));
 
2419
  }
 
2420
}
 
2421
 
 
2422
void
 
2423
wxPdfDocument::SetDrawColour(const wxString& name, double tint)
 
2424
{
 
2425
  wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
 
2426
  if (spotColour != (*m_spotColours).end())
 
2427
  {
 
2428
    wxPdfColour tempColour(*(spotColour->second), tint);
 
2429
    m_drawColour = tempColour;
 
2430
    if (m_page > 0)
 
2431
    {
 
2432
      OutAscii(m_drawColour.GetColour(true));
 
2433
    }
 
2434
  }
 
2435
  else
 
2436
  {
 
2437
    wxLogError(wxString(wxT("wxPdfDocument::SetDrawColour: ")) +
 
2438
               wxString::Format(_("Undefined spot colour: '%s'."), name.c_str()));
 
2439
  }
 
2440
}
 
2441
 
 
2442
void
 
2443
wxPdfDocument::SetDrawPattern(const wxString& name)
 
2444
{
 
2445
  wxPdfPatternMap::iterator pattern = m_patterns->find(name);
 
2446
  if (pattern != m_patterns->end())
 
2447
  {
 
2448
    wxPdfColour tempColour(*(pattern->second));
 
2449
    m_drawColour = tempColour;
 
2450
    if (m_page > 0)
 
2451
    {
 
2452
      OutAscii(m_drawColour.GetColour(true));
 
2453
    }
 
2454
  }
 
2455
  else
 
2456
  {
 
2457
    wxLogError(wxString(wxT("wxPdfDocument::SetDrawPattern: ")) +
 
2458
               wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
 
2459
  }
 
2460
}
 
2461
 
 
2462
const wxPdfColour
 
2463
wxPdfDocument::GetDrawColour()
 
2464
{
 
2465
  return wxPdfColour(m_drawColour);
 
2466
}
 
2467
 
 
2468
void
 
2469
wxPdfDocument::SetFillColour(const wxColour& colour)
 
2470
{
 
2471
  wxPdfColour tempColour(colour);
 
2472
  m_fillColour = tempColour;
 
2473
  m_colourFlag = (m_fillColour != m_textColour);
 
2474
  if (m_page > 0)
 
2475
  {
 
2476
    OutAscii(m_fillColour.GetColour(false));
 
2477
  }
 
2478
}
 
2479
 
 
2480
void
 
2481
wxPdfDocument::SetFillColour(const unsigned char grayscale)
 
2482
{
 
2483
  wxPdfColour tempColour(grayscale);
 
2484
  m_fillColour = tempColour;
 
2485
  m_colourFlag = (m_fillColour != m_textColour);
 
2486
  if (m_page > 0)
 
2487
  {
 
2488
    OutAscii(m_fillColour.GetColour(false));
 
2489
  }
 
2490
}
 
2491
 
 
2492
void
 
2493
wxPdfDocument::SetFillColour(const wxPdfColour& colour)
 
2494
{
 
2495
  m_fillColour = colour;
 
2496
  m_colourFlag = (m_fillColour != m_textColour);
 
2497
  if (m_page > 0)
 
2498
  {
 
2499
    OutAscii(m_fillColour.GetColour(false));
 
2500
  }
 
2501
}
 
2502
 
 
2503
void
 
2504
wxPdfDocument::SetFillColour(const unsigned char red, const unsigned char green, const unsigned char blue)
 
2505
{
 
2506
  SetFillColour(wxColour(red, green, blue));
 
2507
}
 
2508
 
 
2509
void
 
2510
wxPdfDocument::SetFillColour(double cyan, double magenta, double yellow, double black)
 
2511
{
 
2512
  SetFillColour(wxPdfColour(cyan, magenta, yellow, black));
 
2513
}
 
2514
 
 
2515
void
 
2516
wxPdfDocument::SetFillColour(const wxString& name, double tint)
 
2517
{
 
2518
  wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
 
2519
  if (spotColour != (*m_spotColours).end())
 
2520
  {
 
2521
    wxPdfColour tempColour(*(spotColour->second), tint);
 
2522
    m_fillColour = tempColour;
 
2523
    m_colourFlag = (m_fillColour != m_textColour);
 
2524
    if (m_page > 0)
 
2525
    {
 
2526
      OutAscii(m_fillColour.GetColour(false));
 
2527
    }
 
2528
  }
 
2529
  else
 
2530
  {
 
2531
    wxLogError(wxString(wxT("wxPdfDocument::SetFillColour: ")) +
 
2532
               wxString::Format(_("Undefined spot colour: '%s'."), name.c_str()));
 
2533
  }
 
2534
}
 
2535
 
 
2536
void
 
2537
wxPdfDocument::SetFillPattern(const wxString& name)
 
2538
{
 
2539
  wxPdfPatternMap::iterator pattern = m_patterns->find(name);
 
2540
  if (pattern != m_patterns->end())
 
2541
  {
 
2542
    wxPdfColour tempColour(*(pattern->second));
 
2543
    m_fillColour = tempColour;
 
2544
    m_colourFlag = (m_fillColour != m_textColour);
 
2545
    if (m_page > 0)
 
2546
    {
 
2547
      OutAscii(m_fillColour.GetColour(false));
 
2548
    }
 
2549
  }
 
2550
  else
 
2551
  {
 
2552
    wxLogError(wxString(wxT("wxPdfDocument::SetFillPattern: ")) +
 
2553
               wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
 
2554
  }
 
2555
}
 
2556
 
 
2557
const wxPdfColour
 
2558
wxPdfDocument::GetPatternColour(const wxString& name)
 
2559
{
 
2560
  wxPdfColour colour(0);
 
2561
  wxPdfPatternMap::iterator pattern = m_patterns->find(name);
 
2562
  if (pattern != m_patterns->end())
 
2563
  {
 
2564
    wxPdfColour tempColour(*(pattern->second));
 
2565
    colour = tempColour;
 
2566
  }
 
2567
  else
 
2568
  {
 
2569
    wxLogError(wxString(wxT("wxPdfDocument::GetPatternColour: ")) +
 
2570
               wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
 
2571
  }
 
2572
  return colour;
 
2573
}
 
2574
 
 
2575
const wxPdfColour
 
2576
wxPdfDocument::GetFillColour()
 
2577
{
 
2578
  return wxPdfColour(m_fillColour);
 
2579
}
 
2580
 
 
2581
void
 
2582
wxPdfDocument::SetTextColour(const wxColour& colour)
 
2583
{
 
2584
  wxPdfColour tempColour(colour);
 
2585
  m_textColour = tempColour;
 
2586
  m_colourFlag = (m_fillColour != m_textColour);
 
2587
}
 
2588
 
 
2589
void
 
2590
wxPdfDocument::SetTextColour(const unsigned char grayscale)
 
2591
{
 
2592
  wxPdfColour tempColour(grayscale);
 
2593
  m_textColour = tempColour;
 
2594
  m_colourFlag = (m_fillColour != m_textColour);
 
2595
}
 
2596
 
 
2597
void
 
2598
wxPdfDocument::SetTextColour(const wxPdfColour& colour)
 
2599
{
 
2600
  m_textColour = colour;
 
2601
  m_colourFlag = (m_fillColour != m_textColour);
 
2602
}
 
2603
 
 
2604
void
 
2605
wxPdfDocument::SetTextColour(const unsigned char red, const unsigned char green, const unsigned char blue)
 
2606
{
 
2607
  SetTextColour(wxColour(red, green, blue));
 
2608
}
 
2609
 
 
2610
void
 
2611
wxPdfDocument::SetTextColour(double cyan, double magenta, double yellow, double black)
 
2612
{
 
2613
  SetTextColour(wxPdfColour(cyan, magenta, yellow, black));
 
2614
}
 
2615
 
 
2616
void
 
2617
wxPdfDocument::SetTextColour(const wxString& name, double tint)
 
2618
{
 
2619
  wxPdfSpotColourMap::iterator spotColour = (*m_spotColours).find(name);
 
2620
  if (spotColour != (*m_spotColours).end())
 
2621
  {
 
2622
    wxPdfColour tempColour(*(spotColour->second), tint);
 
2623
    m_textColour = tempColour;
 
2624
    m_colourFlag = (m_fillColour != m_textColour);
 
2625
  }
 
2626
  else
 
2627
  {
 
2628
    wxLogError(wxString(wxT("wxPdfDocument::SetTextColour: ")) +
 
2629
               wxString::Format(_("Undefined spot colour: '%s'."), name.c_str()));
 
2630
  }
 
2631
}
 
2632
 
 
2633
void
 
2634
wxPdfDocument::SetTextPattern(const wxString& name)
 
2635
{
 
2636
  wxPdfPatternMap::iterator pattern = m_patterns->find(name);
 
2637
  if (pattern != m_patterns->end())
 
2638
  {
 
2639
    wxPdfColour tempColour(*(pattern->second));
 
2640
    m_textColour = tempColour;
 
2641
    m_colourFlag = (m_fillColour != m_textColour);
 
2642
  }
 
2643
  else
 
2644
  {
 
2645
    wxLogError(wxString(wxT("wxPdfDocument::SetFillPattern: ")) +
 
2646
               wxString::Format(_("Undefined pattern: '%s'."), name.c_str()));
 
2647
  }
 
2648
}
 
2649
 
 
2650
const wxPdfColour
 
2651
wxPdfDocument::GetTextColour()
 
2652
{
 
2653
  return wxPdfColour(m_textColour);
 
2654
}
 
2655
 
 
2656
void
 
2657
wxPdfDocument::SetTextRenderMode(wxPdfTextRenderMode mode)
 
2658
{
 
2659
  m_textRenderMode = mode;
 
2660
}
 
2661
  
 
2662
wxPdfTextRenderMode
 
2663
wxPdfDocument::GetTextRenderMode() const
 
2664
{
 
2665
  return m_textRenderMode;
 
2666
}