~ubuntu-branches/ubuntu/raring/luatex/raring

« back to all changes in this revision

Viewing changes to source/libs/poppler/poppler-0.12.4/poppler/ArthurOutputDev.cc

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2011-05-20 09:40:39 UTC
  • mfrom: (0.8.1) (1.8.1) (19.2.3 oneiric)
  • Revision ID: package-import@ubuntu.com-20110520094039-7sezr4kqonjqxqz6
Tags: 0.70.1-1
* new upstream release (probably) matching TeX Live 2011
* deactivate fix-luatex-build-with-old-libpng patch, included upstream

Show diffs side-by-side

added added

removed removed

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