~ubuntu-branches/ubuntu/precise/ipe/precise

« back to all changes in this revision

Viewing changes to src/ipelib/ipepswriter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2009-12-11 21:22:35 UTC
  • mfrom: (4.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20091211212235-5iio4nzpra64snab
Tags: 7.0.10-1
* New upstream.  Closes: #551192.
  - New build-depends: libcairo2-dev, liblua5.1-0-dev, gsfonts
  - patches/config.diff: Remove.  Upstream build system replaced.
  - Runtime lib package changed to libipe7.0.10 from libipe1c2a
  - Devel package renamed to libipe-dev (from libipe1-dev)
  - Package ipe depends on lua5.1 due to ipe-update-master.

* rules: Re-write to use dh.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
/*
5
5
 
6
6
    This file is part of the extensible drawing editor Ipe.
7
 
    Copyright (C) 1993-2007  Otfried Cheong
 
7
    Copyright (C) 1993-2009  Otfried Cheong
8
8
 
9
9
    Ipe is free software; you can redistribute it and/or modify it
10
10
    under the terms of the GNU General Public License as published by
11
 
    the Free Software Foundation; either version 2 of the License, or
 
11
    the Free Software Foundation; either version 3 of the License, or
12
12
    (at your option) any later version.
13
13
 
14
14
    As a special exception, you have permission to link Ipe with the
30
30
 
31
31
#include "ipeimage.h"
32
32
#include "ipetext.h"
33
 
#include "ipevisitor.h"
34
33
#include "ipepainter.h"
35
34
#include "ipegroup.h"
36
 
#include "iperef.h"
 
35
#include "ipereference.h"
37
36
#include "ipeutils.h"
38
37
#include "ipedoc.h"
39
38
 
40
39
#include "ipepswriter.h"
41
40
#include "ipefontpool.h"
42
41
 
 
42
using namespace ipe;
 
43
 
43
44
static const char hexChar[17] = "0123456789abcdef";
44
45
 
45
46
// --------------------------------------------------------------------
46
47
 
47
 
IpePsPainter::IpePsPainter(const IpeStyleSheet *style, IpeStream &stream)
48
 
  : IpePdfPainter(style, stream)
 
48
PsPainter::PsPainter(const Cascade *style, Stream &stream)
 
49
  : PdfPainter(style, stream)
49
50
{
50
51
  // Postscript has only one current color: we use iStroke for that
51
52
  iImageNumber = 1;
52
53
}
53
54
 
54
 
IpePsPainter::~IpePsPainter()
 
55
PsPainter::~PsPainter()
55
56
{
56
57
  //
57
58
}
58
59
 
59
 
void IpePsPainter::StrokePath()
 
60
void PsPainter::doNewPath()
 
61
{
 
62
  // nothing (override PDF implementation)
 
63
}
 
64
 
 
65
void PsPainter::strokePath()
60
66
{
61
67
  State &s = iState.back();
62
68
  State &sa = iActiveState.back();
63
 
  const IpeRepository *rep = StyleSheet()->Repository();
64
 
  if (s.iDashStyle && !s.iDashStyle.IsVoid()
65
 
      && s.iDashStyle != sa.iDashStyle) {
 
69
  if (s.iDashStyle != sa.iDashStyle) {
66
70
    sa.iDashStyle = s.iDashStyle;
67
 
    if (s.iDashStyle.IsSolid())
 
71
    if (s.iDashStyle.empty())
68
72
      iStream << "[] 0 d ";
69
73
    else
70
 
      iStream << rep->String(s.iDashStyle) << " d ";
71
 
  }
72
 
  if (s.iLineWidth && s.iLineWidth != sa.iLineWidth) {
73
 
    sa.iLineWidth = s.iLineWidth;
74
 
    iStream << rep->String(s.iLineWidth) << " w ";
75
 
  }
76
 
  IpeAttribute cap = s.iLineCap;
77
 
  if (!cap)
78
 
    cap = StyleSheet()->LineCap();
79
 
  if (cap != sa.iLineCap) {
80
 
    sa.iLineCap = cap;
81
 
    iStream << int(cap.Index()) << " J\n";
82
 
  }
83
 
  IpeAttribute join = s.iLineJoin;
84
 
  if (!join)
85
 
    join = StyleSheet()->LineJoin();
86
 
  if (join != sa.iLineJoin) {
87
 
    sa.iLineJoin = join;
88
 
    iStream << int(join.Index()) << " j\n";
 
74
      iStream << s.iDashStyle << " d ";
 
75
  }
 
76
  if (s.iPen != sa.iPen) {
 
77
    sa.iPen = s.iPen;
 
78
    iStream << s.iPen << " w ";
 
79
  }
 
80
  if (s.iLineCap != sa.iLineCap) {
 
81
    sa.iLineCap = s.iLineCap;
 
82
    iStream << s.iLineCap << " J\n";
 
83
  }
 
84
  if (s.iLineJoin != sa.iLineJoin) {
 
85
    sa.iLineJoin = s.iLineJoin;
 
86
    iStream << s.iLineJoin << " j\n";
89
87
  }
90
88
  if (s.iStroke != sa.iStroke) {
91
89
    sa.iStroke = s.iStroke;
92
 
    DrawColor(iStream, s.iStroke, "g", "rg");
 
90
    drawColor(iStream, s.iStroke, "g", "rg");
93
91
  }
94
92
  iStream << "S";
95
93
}
96
94
 
97
 
void IpePsPainter::FillPath(bool eoFill, bool preservePath)
 
95
void PsPainter::fillPath(bool eoFill, bool preservePath)
98
96
{
99
 
  State &s = iState.back();
100
 
  State &sa = iActiveState.back();
101
 
  if (s.iFill != sa.iStroke) {
102
 
    sa.iStroke = s.iFill;
103
 
    DrawColor(iStream, s.iFill, "g", "rg");
 
97
  if (tiling().isNormal()) {
 
98
    State &s = iState.back();
 
99
    State &sa = iActiveState.back();
 
100
    if (s.iFill != sa.iStroke) {
 
101
      sa.iStroke = s.iFill;
 
102
      drawColor(iStream, s.iFill, "g", "rg");
 
103
    }
 
104
  } else {
 
105
    State &s = iState.back();
 
106
    if (s.iFill.isGray())
 
107
      iStream << s.iFill.iRed << " Pat" << s.iTiling.index() << " patg\n";
 
108
    else
 
109
      iStream << s.iFill << " Pat" << s.iTiling.index() << " patrg\n";
 
110
    // set an impossible color
 
111
    iActiveState.back().iStroke.iRed = Fixed(2);
104
112
  }
105
113
  if (preservePath)
106
114
    iStream << "q ";
109
117
    iStream << " Q ";
110
118
}
111
119
 
112
 
void IpePsPainter::DoDrawPath()
 
120
void PsPainter::doDrawPath(TPathMode mode)
113
121
{
114
 
  bool noStroke = Stroke().IsNull() || DashStyle().IsVoid();
115
 
  bool noFill = Fill().IsNullOrVoid();
116
 
  IpeAttribute w = WindRule();
117
 
  if (!w)
118
 
    w = StyleSheet()->WindRule();
119
 
  bool eoFill = !w.Index();
120
 
  if (noStroke && noFill) {
121
 
    iStream << "np";  // flush path
122
 
  } else if (noStroke) {
123
 
    FillPath(eoFill, false);
124
 
  } else if (noFill) {
125
 
    StrokePath();
126
 
  } else {
127
 
    FillPath(eoFill, true);
128
 
    StrokePath();
 
122
  bool eofill = (fillRule() == EEvenOddRule);
 
123
  // if (!mode)
 
124
  // iStream << "np";  // flush path
 
125
  if (mode == EFilledOnly)
 
126
    fillPath(eofill, false);
 
127
  else if (mode == EStrokedOnly)
 
128
    strokePath();
 
129
  else {
 
130
    fillPath(eofill, true);
 
131
    strokePath();
129
132
  }
130
133
  iStream << "\n";
131
134
}
132
135
 
133
 
void IpePsPainter::DoDrawBitmap(IpeBitmap bitmap)
134
 
{
135
 
  switch (bitmap.ColorSpace()) {
136
 
  case IpeBitmap::EDeviceGray:
 
136
void PsPainter::doAddClipPath()
 
137
{
 
138
  iStream << "eoclip np\n";
 
139
}
 
140
 
 
141
void PsPainter::doDrawBitmap(Bitmap bitmap)
 
142
{
 
143
  switch (bitmap.colorSpace()) {
 
144
  case Bitmap::EDeviceGray:
137
145
    iStream << "/DeviceGray setcolorspace ";
138
146
    break;
139
 
  case IpeBitmap::EDeviceRGB:
 
147
  case Bitmap::EDeviceRGB:
140
148
    iStream << "/DeviceRGB setcolorspace ";
141
149
    break;
142
 
  case IpeBitmap::EDeviceCMYK:
 
150
  case Bitmap::EDeviceCMYK:
143
151
    iStream << "/DeviceCMYK setcolorspace ";
144
152
    break;
145
153
  }
146
 
  iStream << Matrix() << " cm\n";
 
154
  iStream << matrix() << " cm\n";
147
155
  iStream << "<< /ImageType 1\n";
148
 
  iStream << "   /Width " << bitmap.Width() << "\n";
149
 
  iStream << "   /Height " << bitmap.Height() << "\n";
150
 
  iStream << "   /BitsPerComponent " << bitmap.BitsPerComponent() << "\n";
 
156
  iStream << "   /Width " << bitmap.width() << "\n";
 
157
  iStream << "   /Height " << bitmap.height() << "\n";
 
158
  iStream << "   /BitsPerComponent " << bitmap.bitsPerComponent() << "\n";
151
159
  iStream << "   /Decode [ ";
152
 
  for (int i = 0; i < bitmap.Components(); ++i)
 
160
  for (int i = 0; i < bitmap.components(); ++i)
153
161
    iStream << "0 1 ";
154
162
  iStream << "]\n";
155
 
  iStream << "   /ImageMatrix [ " << bitmap.Width() << " 0 0 "
156
 
          << -bitmap.Height() << " 0 " << bitmap.Height() << " ]\n";
 
163
  iStream << "   /ImageMatrix [ " << bitmap.width() << " 0 0 "
 
164
          << -bitmap.height() << " 0 " << bitmap.height() << " ]\n";
157
165
  iStream << "   /DataSource currentfile /ASCII85Decode filter";
158
 
  if (bitmap.Filter() == IpeBitmap::EFlateDecode)
 
166
  if (bitmap.filter() == Bitmap::EFlateDecode)
159
167
    iStream << " /FlateDecode filter\n";
160
 
  else if (bitmap.Filter() == IpeBitmap::EDCTDecode)
 
168
  else if (bitmap.filter() == Bitmap::EDCTDecode)
161
169
    iStream << " /DCTDecode filter\n";
162
170
  else
163
171
    iStream << "\n";
164
172
  iStream << ">>\n";
165
 
  iStream << "%%BeginIpeImage: " << iImageNumber << " "
166
 
          << bitmap.Size() << "\n";
167
 
  bitmap.SetObjNum(iImageNumber++);
 
173
  iStream << "%%BeginIpeImage: " << iImageNumber
 
174
          << " " << bitmap.size() << "\n";
 
175
  bitmap.setObjNum(iImageNumber++);
168
176
  iStream << "image\n";
169
 
  const char *p = bitmap.Data();
170
 
  const char *p1 = p + bitmap.Size();
171
 
  IpeA85Stream a85(iStream);
 
177
  const char *p = bitmap.data();
 
178
  const char *p1 = p + bitmap.size();
 
179
  A85Stream a85(iStream);
172
180
  while (p < p1)
173
 
    a85.PutChar(*p++);
174
 
  a85.Close();
 
181
    a85.putChar(*p++);
 
182
  a85.close();
175
183
  iStream << "%%EndIpeImage\n";
176
184
}
177
185
 
178
186
// --------------------------------------------------------------------
179
187
 
180
 
/*! \class IpePsWriter
 
188
/*! \class ipe::PsWriter
181
189
  \brief Create Postscript file.
182
190
 
183
191
  This class is responsible for the creation of a Postscript file from the
184
 
  Ipe data. You have to create an IpePsWriter first, providing a stream
 
192
   data. You have to create an PsWriter first, providing a stream
185
193
  that has been opened for (binary) writing and is empty.
186
194
 
187
195
*/
188
196
 
189
197
//! Create Postscript writer operating on this (open and empty) file.
190
 
IpePsWriter::IpePsWriter(IpeTellStream &stream, const IpeDocument *doc,
191
 
                         bool noColor)
 
198
PsWriter::PsWriter(TellStream &stream, const Document *doc, bool noColor)
192
199
  : iStream(stream), iDoc(doc), iNoColor(noColor)
193
200
{
194
201
  // nothing
199
206
//! Create the document header and prolog (the resources).
200
207
/*! Embeds no fonts if \c pool is 0.
201
208
  Returns false if a TrueType font is present. */
202
 
bool IpePsWriter::CreateHeader(IpeString creator, int pno, int view)
 
209
bool PsWriter::createHeader(int pno, int view)
203
210
{
204
 
  const IpeFontPool *pool = iDoc->FontPool();
205
 
  const IpeDocument::SProperties &props = iDoc->Properties();
 
211
  const FontPool *pool = iDoc->fontPool();
 
212
  const Document::SProperties &props = iDoc->properties();
206
213
 
207
214
  // Check needed and supplied fonts, and reject Truetype fonts
208
 
  IpeString needed = "";
209
 
  IpeString neededSep = "%%DocumentNeededResources: font ";
210
 
  IpeString supplied = "";
211
 
  IpeString suppliedSep = "%%DocumentSuppliedResources: font ";
 
215
  String needed = "";
 
216
  String neededSep = "%%DocumentNeededResources: font ";
 
217
  String supplied = "";
 
218
  String suppliedSep = "%%DocumentSuppliedResources: font ";
212
219
  if (pool) {
213
 
    for (IpeFontPool::const_iterator font = pool->begin();
 
220
    for (FontPool::const_iterator font = pool->begin();
214
221
         font != pool->end(); ++font) {
215
 
      if (font->iType == IpeFont::ETrueType)
 
222
      if (font->iType == Font::ETrueType)
216
223
        return false;
217
224
      if (font->iStandardFont) {
218
225
        needed += neededSep;
231
238
  iStream << "%!PS-Adobe-3.0 EPSF-3.0\n";
232
239
 
233
240
  iStream << "%%Creator: Ipelib " << IPELIB_VERSION;
234
 
  if (!creator.empty())
235
 
    iStream << " (" << creator << ")";
 
241
  if (!props.iCreator.empty())
 
242
    iStream << " (" << props.iCreator << ")";
236
243
  iStream << "\n";
237
244
  // CreationDate is informational, no fixed format
238
245
  iStream << "%%CreationDate: " << props.iModified << "\n";
239
 
  // Should use level 1 if no images present?
 
246
  // Should use level 1 if no images or patterns present?
240
247
  iStream << "%%LanguageLevel: 2\n";
241
248
 
242
 
  const IpePage *page = iDoc->page(pno);
243
 
  std::vector<bool> layers;
244
 
  page->MakeLayerTable(layers, view, false);
245
 
  IpeBBoxPainter painter(iDoc->StyleSheet());
246
 
  for (IpePage::const_iterator it = page->begin(); it != page->end(); ++it) {
247
 
    if (layers[it->Layer()])
248
 
      it->Object()->Draw(painter);
249
 
  }
250
 
  IpeRect r = painter.BBox();
 
249
  const Page *page = iDoc->page(pno);
 
250
 
 
251
  int viewBBoxLayer = page->findLayer("VIEWBBOX");
 
252
  Rect r;
 
253
  if (viewBBoxLayer >= 0 && page->visible(view, viewBBoxLayer))
 
254
    r = page->viewBBox(iDoc->cascade(), view);
 
255
  else
 
256
    r = page->pageBBox(iDoc->cascade());
 
257
 
251
258
  iStream << "%%BoundingBox: " // (x0, y0) (x1, y1)
252
 
          << int(r.Min().iX) << " " << int(r.Min().iY) << " "
253
 
          << int(r.Max().iX + 1) << " " << int(r.Max().iY + 1) << "\n";
254
 
  iStream << "%%HiResBoundingBox: " << r.Min() << " " << r.Max() << "\n";
 
259
          << int(r.bottomLeft().x) << " " << int(r.bottomLeft().y) << " "
 
260
          << int(r.topRight().x + 1) << " " << int(r.topRight().y + 1)
 
261
          << "\n";
 
262
  iStream << "%%HiResBoundingBox: "
 
263
          << r.bottomLeft() << " " << r.topRight() << "\n";
255
264
 
256
265
  iStream << needed;
257
266
  iStream << supplied;
263
272
  iStream << "%%BeginProlog\n";
264
273
  // procset <name> <version (a real)> <revision (an integer)>
265
274
  // <revision> is upwards compatible, <version> not
266
 
  iStream << "%%BeginResource: procset ipe 6.0 " << IPELIB_VERSION << "\n";
 
275
  iStream << "%%BeginResource: procset ipe 7.0 " << IPELIB_VERSION << "\n";
267
276
  iStream << "/ipe 40 dict def ipe begin\n";
268
277
  iStream << "/np { newpath } def\n";
269
278
  iStream << "/m { moveto } def\n";
305
314
  iStream << "/TJ { 0 0 moveto { dup type /stringtype eq\n";
306
315
  iStream << " { show } { ipeFontSize mul -0.001 mul 0 rmoveto } ifelse\n";
307
316
  iStream << "} forall } def\n";
 
317
 
 
318
  // embed tiling patterns
 
319
  AttributeSeq ts;
 
320
  iDoc->cascade()->allNames(ETiling, ts);
 
321
  for (uint i = 0; i < ts.size(); ++i) {
 
322
    const Tiling *t = iDoc->cascade()->findTiling(ts[i]);
 
323
    Linear m(t->iAngle);
 
324
    iStream << "<<\n"
 
325
            << "/PatternType 1\n"  // tiling pattern
 
326
            << "/PaintType 2\n"    // uncolored pattern
 
327
            << "/TilingType 2\n"   // faster
 
328
            << "/BBox [ 0 0 100 " << t->iStep << " ]\n"
 
329
            << "/XStep 99\n"
 
330
            << "/YStep " << t->iStep << "\n"
 
331
            << "/PaintProc { pop 0 0 100 " << t->iWidth << " re fill} bind\n"
 
332
            << ">>\n"
 
333
            << "[ " << m << " 0 0 ]\n"
 
334
            << "makepattern\n"
 
335
            << "/Pat" << ts[i].index() << " exch def\n";
 
336
  }
 
337
  if (ts.size() > 0) {
 
338
    iStream << "/patg { [/Pattern /DeviceGray ] setcolorspace "
 
339
            << "setcolor } def\n";
 
340
    if (!iNoColor)
 
341
      iStream << "/patrg { [/Pattern /DeviceRGB ] setcolorspace "
 
342
              << "setcolor } def\n";
 
343
  }
 
344
 
308
345
  iStream << "end\n";
309
346
  iStream << "%%EndResource\n";
310
347
 
313
350
  iStream << "ipe begin\n";
314
351
 
315
352
  if (pool) {
316
 
    for (IpeFontPool::const_iterator font = pool->begin();
 
353
    for (FontPool::const_iterator font = pool->begin();
317
354
         font != pool->end(); ++font) {
318
355
 
319
356
      if (font->iStandardFont) {
320
357
        iStream << "%%IncludeResource: font " << font->iName << "\n";
321
358
      } else {
322
359
        iStream << "%%BeginResource: font " << font->iName << "\n";
323
 
        EmbedFont(*font);
 
360
        embedFont(*font);
324
361
        iStream << "%%EndResource\n";
325
362
      }
326
363
 
328
365
      iStream << "/F" << font->iLatexNumber
329
366
              << " /" << font->iName;
330
367
      if (font->iHasEncoding) {
331
 
        IpeString sep = "\n[ ";
 
368
        String sep = "\n[ ";
332
369
        for (int i = 0; i < 0x100; ++i) {
333
370
          if (i % 8 == 0) {
334
371
            iStream << sep;
348
385
}
349
386
 
350
387
//! Destructor.
351
 
IpePsWriter::~IpePsWriter()
 
388
PsWriter::~PsWriter()
352
389
{
353
390
  // nothing
354
391
}
355
392
 
356
393
//! Write all fonts to the Postscript file.
357
 
void IpePsWriter::EmbedFont(const IpeFont &font)
 
394
void PsWriter::embedFont(const Font &font)
358
395
{
359
396
  // write unencrypted front matter
360
 
  iStream.PutRaw(font.iStreamData.data(), font.iLength1);
 
397
  iStream.putRaw(font.iStreamData.data(), font.iLength1);
361
398
  // write encrypted section
362
399
  const char *p = font.iStreamData.data() + font.iLength1;
363
400
  const char *p1 = font.iStreamData.data() + font.iLength1 + font.iLength2;
364
401
  int i = 0;
365
402
  while (p < p1) {
366
 
    iStream.PutChar(hexChar[(*p >> 4) & 0x0f]);
367
 
    iStream.PutChar(hexChar[*p & 0x0f]);
 
403
    iStream.putChar(hexChar[(*p >> 4) & 0x0f]);
 
404
    iStream.putChar(hexChar[*p & 0x0f]);
368
405
    ++p;
369
406
    if (++i % 32 == 0)
370
407
      iStream << "\n";
373
410
    iStream << "\n";
374
411
  // write tail matter
375
412
  if (font.iLength3 > 0)
376
 
    iStream.PutRaw(p1, font.iLength3);
 
413
    iStream.putRaw(p1, font.iLength3);
377
414
  else {
378
415
    for (i = 0; i < 512; ++i) {
379
416
      if ((i & 63) == 0)
380
 
        iStream.PutChar('\n');
381
 
      iStream.PutChar('0');
 
417
        iStream.putChar('\n');
 
418
      iStream.putChar('0');
382
419
    }
383
420
    iStream << "\ncleartomark\n";
384
421
  }
386
423
 
387
424
// --------------------------------------------------------------------
388
425
 
389
 
//! Create contents and page stream for this page view.
390
 
void IpePsWriter::CreatePageView(int pno, int vno)
 
426
//! Create contents and page stream for this view.
 
427
/*! Background is not shown. */
 
428
void PsWriter::createPageView(int pno, int vno)
391
429
{
392
 
  const IpePage *page = iDoc->page(pno);
393
 
  // Create page stream
394
 
  IpePsPainter painter(iDoc->StyleSheet(), iStream);
395
 
  std::vector<bool> layers;
396
 
  page->MakeLayerTable(layers, vno, false);
397
 
  for (IpePage::const_iterator it = page->begin(); it != page->end(); ++it) {
398
 
    if (layers[it->Layer()])
399
 
      it->Object()->Draw(painter);
 
430
  const Page *page = iDoc->page(pno);
 
431
  PsPainter painter(iDoc->cascade(), iStream);
 
432
  for (int i = 0; i < page->count(); ++i) {
 
433
    if (page->objectVisible(vno, i))
 
434
      page->object(i)->draw(painter);
400
435
  }
401
436
  iStream << "showpage\n";
402
437
}
403
438
 
404
 
//! Create the trailer of the Postscsript file.
405
 
void IpePsWriter::CreateTrailer()
 
439
//! Create the trailer of the Postscript file.
 
440
void PsWriter::createTrailer()
406
441
{
407
442
  iStream << "%%Trailer\n";
408
443
  iStream << "end\n"; // to end ipe dictionary
411
446
 
412
447
// --------------------------------------------------------------------
413
448
 
414
 
class IpePercentStream : public IpeStream {
 
449
class PercentStream : public Stream {
415
450
public:
416
 
  IpePercentStream(IpeStream &stream)
 
451
  PercentStream(Stream &stream)
417
452
    : iStream(stream), iNeedPercent(true) { /* nothing */ }
418
 
  virtual void PutChar(char ch);
 
453
  virtual void putChar(char ch);
419
454
 
420
455
private:
421
 
  IpeStream &iStream;
 
456
  Stream &iStream;
422
457
  bool iNeedPercent;
423
458
};
424
459
 
425
 
void IpePercentStream::PutChar(char ch)
 
460
void PercentStream::putChar(char ch)
426
461
{
427
462
  if (iNeedPercent)
428
 
    iStream.PutChar('%');
429
 
  iStream.PutChar(ch);
 
463
    iStream.putChar('%');
 
464
  iStream.putChar(ch);
430
465
  iNeedPercent = (ch == '\n');
431
466
}
432
467
 
433
 
//! Save Ipe information in XML format.
434
 
void IpePsWriter::CreateXml(IpeString creator, int compressLevel)
 
468
//! Save  information in XML format.
 
469
void PsWriter::createXml(int compressLevel)
435
470
{
436
 
  IpePercentStream s1(iStream);
 
471
  PercentStream s1(iStream);
437
472
  if (compressLevel > 0) {
438
473
    iStream << "%%BeginIpeXml: /FlateDecode\n";
439
 
    IpeA85Stream a85(s1);
440
 
    IpeDeflateStream s2(a85, compressLevel);
441
 
    iDoc->SaveAsXml(s2, creator, true);
442
 
    s2.Close();
 
474
    A85Stream a85(s1);
 
475
    DeflateStream s2(a85, compressLevel);
 
476
    iDoc->saveAsXml(s2, true);
 
477
    s2.close();
443
478
  } else {
444
479
    iStream << "%%BeginIpeXml:\n";
445
 
    iDoc->SaveAsXml(s1, creator, true);
446
 
    s1.Close();
 
480
    iDoc->saveAsXml(s1, true);
 
481
    s1.close();
447
482
  }
448
483
  iStream << "%%EndIpeXml\n";
449
484
}
450
485
 
451
486
// --------------------------------------------------------------------
 
487