source: trunk/poppler/mypoppler/poppler/ArthurOutputDev.cc @ 250

Last change on this file since 250 was 250, checked in by Eugene Romanenko, 13 years ago

PDF plugin: poppler library updated to version 0.8.3

File size: 18.8 KB
Line 
1//========================================================================
2//
3// ArthurOutputDev.cc
4//
5// Copyright 2003 Glyph & Cog, LLC
6// Copyright 2004 Red Hat, Inc
7//
8//========================================================================
9
10#include <config.h>
11
12#ifdef USE_GCC_PRAGMAS
13#pragma implementation
14#endif
15
16#include <string.h>
17#include <math.h>
18
19#include "goo/gfile.h"
20#include "GlobalParams.h"
21#include "Error.h"
22#include "Object.h"
23#include "GfxState.h"
24#include "GfxFont.h"
25#include "Link.h"
26#include "CharCodeToUnicode.h"
27#include "FontEncodingTables.h"
28#include <fofi/FoFiTrueType.h>
29#include "ArthurOutputDev.h"
30
31#include <QtCore/QtDebug>
32#include <QtGui/QPainterPath>
33//------------------------------------------------------------------------
34
35#include "splash/SplashFontFileID.h"
36#include "splash/SplashFontFile.h"
37#include "splash/SplashFontEngine.h"
38#include "splash/SplashFont.h"
39#include "splash/SplashMath.h"
40#include "splash/SplashPath.h"
41#include "splash/SplashGlyphBitmap.h"
42//------------------------------------------------------------------------
43// SplashOutFontFileID
44//------------------------------------------------------------------------
45
46class SplashOutFontFileID: public SplashFontFileID {
47public:
48
49  SplashOutFontFileID(Ref *rA) { r = *rA; }
50
51  ~SplashOutFontFileID() {}
52
53  GBool matches(SplashFontFileID *id) {
54    return ((SplashOutFontFileID *)id)->r.num == r.num &&
55           ((SplashOutFontFileID *)id)->r.gen == r.gen;
56  }
57
58private:
59
60  Ref r;
61};
62
63
64
65//------------------------------------------------------------------------
66// ArthurOutputDev
67//------------------------------------------------------------------------
68
69ArthurOutputDev::ArthurOutputDev(QPainter *painter):
70  m_painter(painter)
71{
72  m_currentBrush = QBrush(Qt::SolidPattern);
73  m_fontEngine = 0;
74  m_font = 0;
75  m_image = 0;
76}
77
78ArthurOutputDev::~ArthurOutputDev()
79{
80  delete m_fontEngine;
81}
82
83void ArthurOutputDev::startDoc(XRef *xrefA) {
84  xref = xrefA;
85  delete m_fontEngine;
86  m_fontEngine = new SplashFontEngine(
87#if HAVE_T1LIB_H
88  globalParams->getEnableT1lib(),
89#endif
90#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
91  globalParams->getEnableFreeType(),
92#endif
93  globalParams->getAntialias());
94}
95
96void ArthurOutputDev::startPage(int pageNum, GfxState *state)
97{
98  // fill page with white background.
99  int w = static_cast<int>(state->getPageWidth());
100  int h = static_cast<int>(state->getPageHeight());
101  QColor fillColour(Qt::white);
102  QBrush fill(fillColour);
103  m_painter->save();
104  m_painter->setPen(fillColour);
105  m_painter->setBrush(fill);
106  m_painter->drawRect(0, 0, w, h);
107  m_painter->restore();
108}
109
110void ArthurOutputDev::endPage() {
111}
112
113void ArthurOutputDev::drawLink(Link *link, Catalog *catalog)
114{
115}
116
117void ArthurOutputDev::saveState(GfxState *state)
118{
119  m_painter->save();
120}
121
122void ArthurOutputDev::restoreState(GfxState *state)
123{
124  m_painter->restore();
125}
126
127void ArthurOutputDev::updateAll(GfxState *state)
128{
129  updateLineDash(state);
130  updateLineJoin(state);
131  updateLineCap(state);
132  updateLineWidth(state);
133  updateFlatness(state);
134  updateMiterLimit(state);
135  updateFillColor(state);
136  updateStrokeColor(state);
137  updateFillOpacity(state);
138  updateStrokeOpacity(state);
139  m_needFontUpdate = gTrue;
140}
141
142// This looks wrong - why aren't adjusting the matrix?
143void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12,
144                                double m21, double m22,
145                                double m31, double m32)
146{
147  updateLineDash(state);
148  updateLineJoin(state);
149  updateLineCap(state);
150  updateLineWidth(state);
151}
152
153void ArthurOutputDev::updateLineDash(GfxState *state)
154{
155  // qDebug() << "updateLineDash";
156}
157
158void ArthurOutputDev::updateFlatness(GfxState *state)
159{
160  // qDebug() << "updateFlatness";
161}
162
163void ArthurOutputDev::updateLineJoin(GfxState *state)
164{
165  switch (state->getLineJoin()) {
166  case 0:
167    m_currentPen.setJoinStyle(Qt::MiterJoin);
168    break;
169  case 1:
170    m_currentPen.setJoinStyle(Qt::RoundJoin);
171    break;
172  case 2:
173    m_currentPen.setJoinStyle(Qt::BevelJoin);
174    break;
175  }
176  m_painter->setPen(m_currentPen);
177}
178
179void ArthurOutputDev::updateLineCap(GfxState *state)
180{
181  switch (state->getLineCap()) {
182  case 0:
183    m_currentPen.setCapStyle(Qt::FlatCap);
184    break;
185  case 1:
186    m_currentPen.setCapStyle(Qt::RoundCap);
187    break;
188  case 2:
189    m_currentPen.setCapStyle(Qt::SquareCap);
190    break;
191  }
192  m_painter->setPen(m_currentPen);
193}
194
195void ArthurOutputDev::updateMiterLimit(GfxState *state)
196{
197  // We can't do mitre (or Miter) limit with Qt4 yet.
198  // the limit is in state->getMiterLimit() when we get there
199}
200
201void ArthurOutputDev::updateLineWidth(GfxState *state)
202{
203  m_currentPen.setWidthF(state->getTransformedLineWidth());
204  m_painter->setPen(m_currentPen);
205}
206
207void ArthurOutputDev::updateFillColor(GfxState *state)
208{
209  GfxRGB rgb;
210  QColor brushColour = m_currentBrush.color();
211  state->getFillRGB(&rgb);
212  brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
213  m_currentBrush.setColor(brushColour);
214}
215
216void ArthurOutputDev::updateStrokeColor(GfxState *state)
217{
218  GfxRGB rgb;
219  QColor penColour = m_currentPen.color();
220  state->getStrokeRGB(&rgb);
221  penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
222  m_currentPen.setColor(penColour);
223  m_painter->setPen(m_currentPen);
224}
225
226void ArthurOutputDev::updateFillOpacity(GfxState *state)
227{
228  QColor brushColour= m_currentBrush.color();
229  brushColour.setAlphaF(state->getFillOpacity());
230  m_currentBrush.setColor(brushColour);
231}
232
233void ArthurOutputDev::updateStrokeOpacity(GfxState *state)
234{
235  QColor penColour= m_currentPen.color();
236  penColour.setAlphaF(state->getStrokeOpacity());
237  m_currentPen.setColor(penColour);
238  m_painter->setPen(m_currentPen);
239}
240
241void ArthurOutputDev::updateFont(GfxState *state)
242{
243#ifdef __GNUC__
244#warning fix this, probably update with updated code from SplashOutputdev
245#endif
246/*
247  GfxFont *gfxFont;
248  GfxFontType fontType;
249  SplashOutFontFileID *id;
250  SplashFontFile *fontFile;
251  SplashFontSrc *fontsrc;
252  FoFiTrueType *ff;
253  Ref embRef;
254  Object refObj, strObj;
255  GooString *fileName, *substName;
256  char *tmpBuf;
257  int tmpBufLen;
258  Gushort *codeToGID;
259  DisplayFontParam *dfp;
260  double m11, m12, m21, m22, w1, w2;
261  SplashCoord mat[4];
262  char *name;
263  int c, substIdx, n, code;
264
265  m_needFontUpdate = false;
266  m_font = NULL;
267  fileName = NULL;
268  tmpBuf = NULL;
269  substIdx = -1;
270
271  if (!(gfxFont = state->getFont())) {
272    goto err1;
273  }
274  fontType = gfxFont->getType();
275  if (fontType == fontType3) {
276    goto err1;
277  }
278
279  // check the font file cache
280  id = new SplashOutFontFileID(gfxFont->getID());
281  if ((fontFile = m_fontEngine->getFontFile(id))) {
282    delete id;
283
284  } else {
285
286    // if there is an embedded font, write it to disk
287    if (gfxFont->getEmbeddedFontID(&embRef)) {
288      tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
289      if (! tmpBuf)
290        goto err2;
291    // if there is an external font file, use it
292    } else if (!(fileName = gfxFont->getExtFontFile())) {
293
294      // look for a display font mapping or a substitute font
295      dfp = NULL;
296      if (gfxFont->getName()) {
297        dfp = globalParams->getDisplayFont(gfxFont);
298      }
299      if (!dfp) {
300        error(-1, "Couldn't find a font for '%s'",
301              gfxFont->getName() ? gfxFont->getName()->getCString()
302                                 : "(unnamed)");
303        goto err2;
304      }
305      switch (dfp->kind) {
306      case displayFontT1:
307        fileName = dfp->t1.fileName;
308        fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1;
309        break;
310      case displayFontTT:
311        fileName = dfp->tt.fileName;
312        fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;
313        break;
314      }
315    }
316
317    fontsrc = new SplashFontSrc;
318    if (fileName)
319      fontsrc->setFile(fileName, gFalse);
320    else
321      fontsrc->setBuf(tmpBuf, tmpBufLen, gFalse);
322
323    // load the font file
324    switch (fontType) {
325    case fontType1:
326      if (!(fontFile = m_fontEngine->loadType1Font(
327                           id,
328                           fontsrc,
329                           ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
330        error(-1, "Couldn't create a font for '%s'",
331              gfxFont->getName() ? gfxFont->getName()->getCString()
332                                 : "(unnamed)");
333        goto err2;
334      }
335      break;
336    case fontType1C:
337      if (!(fontFile = m_fontEngine->loadType1CFont(
338                           id,
339                           fontsrc,
340                           ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
341        error(-1, "Couldn't create a font for '%s'",
342              gfxFont->getName() ? gfxFont->getName()->getCString()
343                                 : "(unnamed)");
344        goto err2;
345      }
346      break;
347    case fontTrueType:
348      if (!(ff = FoFiTrueType::load(fileName->getCString()))) {
349        goto err2;
350      }
351      codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
352      delete ff;
353      if (!(fontFile = m_fontEngine->loadTrueTypeFont(
354                           id,
355                           fontsrc,
356                           codeToGID, 256))) {
357        error(-1, "Couldn't create a font for '%s'",
358              gfxFont->getName() ? gfxFont->getName()->getCString()
359                                 : "(unnamed)");
360        goto err2;
361      }
362      break;
363    case fontCIDType0:
364    case fontCIDType0C:
365      if (!(fontFile = m_fontEngine->loadCIDFont(
366                           id,
367                           fontsrc))) {
368        error(-1, "Couldn't create a font for '%s'",
369              gfxFont->getName() ? gfxFont->getName()->getCString()
370                                 : "(unnamed)");
371        goto err2;
372      }
373      break;
374    case fontCIDType2:
375      n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
376      codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));
377      memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
378             n * sizeof(Gushort));
379      if (!(fontFile = m_fontEngine->loadTrueTypeFont(
380                           id,
381                           fontsrc,
382                           codeToGID, n))) {
383        error(-1, "Couldn't create a font for '%s'",
384              gfxFont->getName() ? gfxFont->getName()->getCString()
385                                 : "(unnamed)");
386        goto err2;
387      }
388      break;
389    default:
390      // this shouldn't happen
391      goto err2;
392    }
393  }
394
395  // get the font matrix
396  state->getFontTransMat(&m11, &m12, &m21, &m22);
397  m11 *= state->getHorizScaling();
398  m12 *= state->getHorizScaling();
399
400  // create the scaled font
401  mat[0] = m11;  mat[1] = -m12;
402  mat[2] = m21;  mat[3] = -m22;
403  m_font = m_fontEngine->getFont(fontFile, mat);
404
405  return;
406
407 err2:
408  delete id;
409 err1:*/
410  return;
411}
412
413static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule)
414{
415  GfxSubpath *subpath;
416  double x1, y1, x2, y2, x3, y3;
417  int i, j;
418
419  QPainterPath qPath;
420  qPath.setFillRule(fillRule);
421  for (i = 0; i < path->getNumSubpaths(); ++i) {
422    subpath = path->getSubpath(i);
423    if (subpath->getNumPoints() > 0) {
424      state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
425      qPath.moveTo(x1, y1);
426      j = 1;
427      while (j < subpath->getNumPoints()) {
428        if (subpath->getCurve(j)) {
429          state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
430          state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
431          state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
432          qPath.cubicTo( x1, y1, x2, y2, x3, y3);
433          j += 3;
434        } else {
435          state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
436          qPath.lineTo(x1, y1);
437          ++j;
438        }
439      }
440      if (subpath->isClosed()) {
441        qPath.closeSubpath();
442      }
443    }
444  }
445  return qPath;
446}
447
448void ArthurOutputDev::stroke(GfxState *state)
449{
450  m_painter->drawPath( convertPath( state, state->getPath(), Qt::OddEvenFill ) );
451}
452
453void ArthurOutputDev::fill(GfxState *state)
454{
455  m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
456}
457
458void ArthurOutputDev::eoFill(GfxState *state)
459{
460  m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
461}
462
463void ArthurOutputDev::clip(GfxState *state)
464{
465  m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
466}
467
468void ArthurOutputDev::eoClip(GfxState *state)
469{
470  m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) );
471}
472
473void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
474                               double dx, double dy,
475                               double originX, double originY,
476                               CharCode code, int nBytes, Unicode *u, int uLen) {
477  double x1, y1;
478//   SplashPath *path;
479  int render;
480
481  if (m_needFontUpdate) {
482    updateFont(state);
483  }
484  if (!m_font) {
485    return;
486  }
487
488  // check for invisible text -- this is used by Acrobat Capture
489  render = state->getRender();
490  if (render == 3) {
491    return;
492  }
493
494  x -= originX;
495  y -= originY;
496  state->transform(x, y, &x1, &y1);
497
498  // fill
499  if (!(render & 1)) {
500    int x0, y0, xFrac, yFrac;
501
502    x0 = static_cast<int>(floor(x1));
503    xFrac = splashFloor((x1 - x0) * splashFontFraction);
504    y0 = static_cast<int>(floor(y1));
505    yFrac = splashFloor((y1 - y0) * splashFontFraction);
506    SplashPath * fontPath;
507    fontPath = m_font->getGlyphPath(code);
508    if (fontPath) {
509      QPainterPath qPath;
510      qPath.setFillRule(Qt::WindingFill);
511      for (int i = 0; i < fontPath->length; ++i) {
512        if (fontPath->flags[i] & splashPathFirst) {
513          qPath.moveTo(fontPath->pts[i].x+x0, fontPath->pts[i].y+y0);
514        } else if (fontPath->flags[i] & splashPathCurve) {
515          qPath.quadTo(fontPath->pts[i].x+x0, fontPath->pts[i].y+y0,
516                       fontPath->pts[i+1].x+x0, fontPath->pts[i+1].y+y0);
517          ++i;
518        }
519#ifdef __GNUC__
520#warning FIX THIS
521#endif
522//      else if (fontPath->flags[i] & splashPathArcCW) {
523//        qDebug() << "Need to implement arc";
524//      }
525        else {
526          qPath.lineTo(fontPath->pts[i].x+x0, fontPath->pts[i].y+y0);
527        }
528        if (fontPath->flags[i] & splashPathLast) {
529          qPath.closeSubpath();
530        }
531      }
532      m_painter->save();
533      GfxRGB rgb;
534      QColor brushColour = m_currentBrush.color();
535      state->getFillRGB(&rgb);
536      brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getFillOpacity());
537      m_painter->setBrush(brushColour);
538      QColor penColour = m_currentPen.color();
539      state->getStrokeRGB(&rgb);
540      penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getStrokeOpacity());
541      m_painter->setPen(penColour);
542      m_painter->drawPath( qPath );
543      m_painter->restore();
544    }
545  }
546
547  // stroke
548  if ((render & 3) == 1 || (render & 3) == 2) {
549    qDebug() << "no stroke";
550    /*
551    if ((path = m_font->getGlyphPath(code))) {
552      path->offset((SplashCoord)x1, (SplashCoord)y1);
553      splash->stroke(path);
554      delete path;
555    }
556    */
557  }
558
559  // clip
560  if (render & 4) {
561    qDebug() << "no clip";
562    /*
563    path = m_font->getGlyphPath(code);
564    path->offset((SplashCoord)x1, (SplashCoord)y1);
565    if (textClipPath) {
566      textClipPath->append(path);
567      delete path;
568    } else {
569      textClipPath = path;
570    }
571    */
572  }
573}
574
575GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
576                                      double dx, double dy,
577                                      CharCode code, Unicode *u, int uLen)
578{
579  return gFalse;
580}
581
582void ArthurOutputDev::endType3Char(GfxState *state)
583{
584}
585
586void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
587{
588}
589
590void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
591                              double llx, double lly, double urx, double ury)
592{
593}
594
595void ArthurOutputDev::endTextObject(GfxState *state)
596{
597}
598
599
600void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
601                                    int width, int height, GBool invert,
602                                    GBool inlineImg)
603{
604  qDebug() << "drawImageMask";
605#if 0
606  unsigned char *buffer;
607  unsigned char *dest;
608  cairo_surface_t *image;
609  cairo_pattern_t *pattern;
610  int x, y;
611  ImageStream *imgStr;
612  Guchar *pix;
613  double *ctm;
614  cairo_matrix_t matrix;
615  int invert_bit;
616  int row_stride;
617
618  row_stride = (width + 3) & ~3;
619  buffer = (unsigned char *) malloc (height * row_stride);
620  if (buffer == NULL) {
621    error(-1, "Unable to allocate memory for image.");
622    return;
623  }
624
625  /* TODO: Do we want to cache these? */
626  imgStr = new ImageStream(str, width, 1, 1);
627  imgStr->reset();
628
629  invert_bit = invert ? 1 : 0;
630
631  for (y = 0; y < height; y++) {
632    pix = imgStr->getLine();
633    dest = buffer + y * row_stride;
634    for (x = 0; x < width; x++) {
635
636      if (pix[x] ^ invert_bit)
637        *dest++ = 0;
638      else
639        *dest++ = 255;
640    }
641  }
642
643  image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
644                                          width, height, row_stride);
645  if (image == NULL)
646    return;
647  pattern = cairo_pattern_create_for_surface (image);
648  if (pattern == NULL)
649    return;
650
651  ctm = state->getCTM();
652  LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
653               width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
654  matrix.xx = ctm[0] / width;
655  matrix.xy = -ctm[2] / height;
656  matrix.yx = ctm[1] / width;
657  matrix.yy = -ctm[3] / height;
658  matrix.x0 = ctm[2] + ctm[4];
659  matrix.y0 = ctm[3] + ctm[5];
660  cairo_matrix_invert (&matrix);
661  cairo_pattern_set_matrix (pattern, &matrix);
662
663  cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
664  /* FIXME: Doesn't the image mask support any colorspace? */
665  cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b);
666  cairo_mask (cairo, pattern);
667
668  cairo_pattern_destroy (pattern);
669  cairo_surface_destroy (image);
670  free (buffer);
671  delete imgStr;
672#endif
673}
674
675//TODO: lots more work here.
676void ArthurOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
677                                int width, int height,
678                                GfxImageColorMap *colorMap,
679                                int *maskColors, GBool inlineImg)
680{
681  unsigned char *buffer;
682  unsigned int *dest;
683  int x, y;
684  ImageStream *imgStr;
685  Guchar *pix;
686  int i;
687  double *ctm;
688  QMatrix matrix;
689  int is_identity_transform;
690 
691  buffer = (unsigned char *)gmalloc (width * height * 4);
692
693  /* TODO: Do we want to cache these? */
694  imgStr = new ImageStream(str, width,
695                           colorMap->getNumPixelComps(),
696                           colorMap->getBits());
697  imgStr->reset();
698 
699  /* ICCBased color space doesn't do any color correction
700   * so check its underlying color space as well */
701  is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
702                  colorMap->getColorSpace()->getMode() == csICCBased && 
703                  ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB;
704
705  if (maskColors) {
706    for (y = 0; y < height; y++) {
707      dest = (unsigned int *) (buffer + y * 4 * width);
708      pix = imgStr->getLine();
709      colorMap->getRGBLine (pix, dest, width);
710
711      for (x = 0; x < width; x++) {
712        for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
713         
714          if (pix[i] < maskColors[2*i] * 255||
715              pix[i] > maskColors[2*i+1] * 255) {
716            *dest = *dest | 0xff000000;
717            break;
718          }
719        }
720        pix += colorMap->getNumPixelComps();
721        dest++;
722      }
723    }
724
725    m_image = new QImage(buffer, width, height, QImage::Format_ARGB32);
726  }
727  else {
728    for (y = 0; y < height; y++) {
729      dest = (unsigned int *) (buffer + y * 4 * width);
730      pix = imgStr->getLine();
731      colorMap->getRGBLine (pix, dest, width);
732    }
733
734    m_image = new QImage(buffer, width, height, QImage::Format_RGB32);
735  }
736
737  if (m_image == NULL || m_image->isNull()) {
738    qDebug() << "Null image";
739    delete imgStr;
740    return;
741  }
742  ctm = state->getCTM();
743  matrix.setMatrix(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]);
744
745  m_painter->setMatrix(matrix, true);
746  m_painter->drawImage( QPoint(0,0), *m_image );
747  delete m_image;
748  m_image = 0;
749  free (buffer);
750  delete imgStr;
751
752}
Note: See TracBrowser for help on using the repository browser.