Subversion Repositories Scribus

Rev

Rev 25123 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
22514 jghali 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
#ifndef SLAOUTPUT_H
8
#define SLAOUTPUT_H
9
 
10
#include <QBuffer>
11
#include <QColor>
12
#include <QBrush>
13
#include <QDebug>
14
#include <QImage>
15
#include <QPen>
16
#include <QList>
17
#include <QSizeF>
18
#include <QStack>
19
#include <QString>
20
#include <QTextStream>
21
#include <QTransform>
22
 
23478 jghali 23
#include <memory>
24
 
22514 jghali 25
#include "fpointarray.h"
26
#include "importpdfconfig.h"
27
#include "pageitem.h"
28
#include "scribusdoc.h"
29
#include "scribusview.h"
30
#include "selection.h"
31
#include "vgradient.h"
32
 
33
#include <poppler/Object.h>
34
#include <poppler/OutputDev.h>
35
#include <poppler/Gfx.h>
36
#include <poppler/GfxState.h>
37
#include <poppler/Stream.h>
38
#include <poppler/GfxFont.h>
39
#include <poppler/Link.h>
40
#include <poppler/PDFDoc.h>
41
#include <poppler/Error.h>
42
#include <poppler/Form.h>
43
#include <poppler/Page.h>
44
#include <poppler/Catalog.h>
45
#include <poppler/CharCodeToUnicode.h>
46
#include <poppler/FontEncodingTables.h>
47
#include <poppler/splash/SplashFontFileID.h>
48
#include <poppler/splash/SplashFontFile.h>
49
#include <poppler/splash/SplashFontEngine.h>
50
#include <poppler/splash/SplashFont.h>
51
#include <poppler/splash/SplashMath.h>
52
#include <poppler/splash/SplashPath.h>
53
#include <poppler/splash/SplashGlyphBitmap.h>
54
 
55
//------------------------------------------------------------------------
56
// LinkSubmitData
57
//------------------------------------------------------------------------
58
 
59
class LinkSubmitForm: public LinkAction
60
{
61
public:
62
        // Build a LinkImportData from an action dictionary.
63
        LinkSubmitForm(Object *actionObj);
64
        // Destructor.
65
        virtual ~LinkSubmitForm();
22918 jghali 66
 
22514 jghali 67
        // Was the LinkImportData created successfully?
25123 jghali 68
        bool isOk() const override { return fileName != nullptr; }
22514 jghali 69
        // Accessors.
25123 jghali 70
        LinkActionKind getKind() const override { return actionUnknown; }
22514 jghali 71
        GooString *getFileName() { return fileName; }
72
        int getFlags() { return m_flags; }
22918 jghali 73
 
22514 jghali 74
private:
23478 jghali 75
        GooString *fileName {nullptr};          // file name
76
        int m_flags {0};
22514 jghali 77
};
78
 
79
//------------------------------------------------------------------------
80
// LinkImportData
81
//------------------------------------------------------------------------
82
 
83
class LinkImportData: public LinkAction
84
{
85
public:
86
        // Build a LinkImportData from an action dictionary.
87
        LinkImportData(Object *actionObj);
88
        // Destructor.
89
        virtual ~LinkImportData();
22918 jghali 90
 
22514 jghali 91
        // Was the LinkImportData created successfully?
25123 jghali 92
        bool isOk() const override { return fileName != nullptr; }
22514 jghali 93
        // Accessors.
25123 jghali 94
        LinkActionKind getKind() const override { return actionUnknown; }
22514 jghali 95
        GooString *getFileName() { return fileName; }
22918 jghali 96
 
22514 jghali 97
private:
23478 jghali 98
        GooString *fileName {nullptr};          // file name
22514 jghali 99
};
24181 jghali 100
 
22514 jghali 101
//------------------------------------------------------------------------
24181 jghali 102
// SlaOutFontFileID
22514 jghali 103
//------------------------------------------------------------------------
104
 
24181 jghali 105
class SlaOutFontFileID: public SplashFontFileID
22514 jghali 106
{
107
public:
24181 jghali 108
        SlaOutFontFileID(const Ref *rA) { r = *rA; }
109
        ~SlaOutFontFileID() {}
22514 jghali 110
 
25123 jghali 111
        bool matches(SplashFontFileID *id) override
22514 jghali 112
        {
24181 jghali 113
                return ((SlaOutFontFileID*) id)->r.num == r.num && ((SlaOutFontFileID *) id)->r.gen == r.gen;
22514 jghali 114
        }
115
 
116
private:
117
        Ref r;
118
};
119
 
120
 
121
class AnoOutputDev : public OutputDev
122
{
123
public:
124
        AnoOutputDev(ScribusDoc* doc, QStringList *importedColors);
125
        virtual ~AnoOutputDev();
22916 jghali 126
 
25123 jghali 127
        bool isOk() { return true; }
128
        bool upsideDown() override { return true; }
129
        bool useDrawChar() override { return false; }
130
        bool interpretType3Chars() override { return false; }
131
        bool useTilingPatternFill() override  { return false; }
132
        bool useShadedFills(int type) override { return false; }
133
        bool useFillColorStop() override { return false; }
134
        bool useDrawForm() override { return false; }
22514 jghali 135
 
22916 jghali 136
        void stroke(GfxState *state) override;
137
        void eoFill(GfxState *state) override;
138
        void fill(GfxState *state) override;
25123 jghali 139
        void drawString(GfxState *state, const GooString *s) override;
22916 jghali 140
 
24374 jghali 141
        QString currColorText;
142
        QString currColorFill;
143
        QString currColorStroke;
144
        double  fontSize {12};
145
        GooString *fontName {nullptr};
146
        GooString *itemText {nullptr};
22918 jghali 147
 
22514 jghali 148
private:
25123 jghali 149
        QString getColor(GfxColorSpace *color_space, const GfxColor *color, int *shade);
22514 jghali 150
        ScribusDoc* m_doc;
151
        QStringList *m_importedColors;
152
};
153
 
154
 
24374 jghali 155
 
22514 jghali 156
class SlaOutputDev : public OutputDev
157
{
158
public:
159
        SlaOutputDev(ScribusDoc* doc, QList<PageItem*> *Elements, QStringList *importedColors, int flags);
160
        virtual ~SlaOutputDev();
161
 
162
        LinkAction* SC_getAction(AnnotWidget *ano);
23478 jghali 163
        std::unique_ptr<LinkAction> SC_getAdditionalAction(const char *key, AnnotWidget *ano);
25123 jghali 164
        static bool annotations_callback(Annot *annota, void *user_data);
22514 jghali 165
        bool handleTextAnnot(Annot* annota, double xCoor, double yCoor, double width, double height);
166
        bool handleLinkAnnot(Annot* annota, double xCoor, double yCoor, double width, double height);
167
        bool handleWidgetAnnot(Annot* annota, double xCoor, double yCoor, double width, double height);
22609 craig 168
        void applyTextStyle(PageItem* ite, const QString& fontName, const QString& textColor, double fontSize);
22514 jghali 169
        void handleActions(PageItem* ite, AnnotWidget *ano);
170
        void startDoc(PDFDoc *doc, XRef *xrefA, Catalog *catA);
171
 
25123 jghali 172
        bool isOk() { return true; }
173
        bool upsideDown() override { return true; }
174
        bool useDrawChar() override { return true; }
175
        bool interpretType3Chars() override { return true; }
176
        bool useTilingPatternFill() override { return true; }
177
        bool useShadedFills(int type) override { return type <= 7; }
178
        bool useFillColorStop() override { return true; }
179
        bool useDrawForm() override { return false; }
22916 jghali 180
 
25123 jghali 181
//      virtual bool needClipToCropBox() { return true; }
22916 jghali 182
        void startPage(int pageNum, GfxState *, XRef *) override;
183
        void endPage() override;
22917 jghali 184
 
22514 jghali 185
        // graphics state
22917 jghali 186
        void saveState(GfxState *state) override;
187
        void restoreState(GfxState *state) override;
22514 jghali 188
 
189
        //----- path painting
22916 jghali 190
        void stroke(GfxState *state) override;
191
        void fill(GfxState *state) override;
192
        void eoFill(GfxState *state) override;
24537 jghali 193
        bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, GfxTilingPattern *tPat, const double *mat, int x0, int y0, int x1, int y1, double xStep, double yStep) override;
25123 jghali 194
        bool functionShadedFill(GfxState * /*state*/, GfxFunctionShading * /*shading*/) override { qDebug() << "Function Shaded Fill";  return false; }
195
        bool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) override;
196
        bool axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading)  override { return (shading->getExtend0() == shading->getExtend1()); }
197
        bool radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax) override;
198
        bool radialShadedSupportExtend(GfxState *state, GfxRadialShading *shading) override { return (shading->getExtend0() == shading->getExtend1()); }
199
        bool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading) override;
200
        bool patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading) override;
22916 jghali 201
 
22514 jghali 202
        //----- path clipping
22916 jghali 203
        void clip(GfxState *state) override;
204
        void eoClip(GfxState *state) override;
205
        void clipToStrokePath(GfxState * /*state*/) override { qDebug() << "Clip to StrokePath"; }
25123 jghali 206
        virtual bool deviceHasTextClip(GfxState *state) { return false; }
22514 jghali 207
 
208
  // If current colorspace is pattern,
209
  // does this device support text in pattern colorspace?
25123 jghali 210
        virtual bool supportTextCSPattern(GfxState *state)
22514 jghali 211
        {
212
                return state->getFillColorSpace()->getMode() == csPattern;
213
        }
214
 
215
  // If current colorspace is pattern,
216
  // need this device special handling for masks in pattern colorspace?
25123 jghali 217
        virtual bool fillMaskCSPattern(GfxState * state)
22514 jghali 218
        {
219
                return state->getFillColorSpace()->getMode() == csPattern;
220
        }
221
 
222
        virtual void endMaskClip(GfxState *state) { qDebug() << "End Mask Clip"; }
223
 
224
  //----- grouping operators
25123 jghali 225
        void beginMarkedContent(const char *name, Dict *properties) override;
226
        virtual void beginMarkedContent(const char *name, Object *dictRef);
22916 jghali 227
        void endMarkedContent(GfxState *state) override;
25123 jghali 228
        void markPoint(const char *name) override;
229
        void markPoint(const char *name, Dict *properties) override;
22916 jghali 230
 
22514 jghali 231
        //----- image drawing
25123 jghali 232
        void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg) override;
233
        void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg) override;
22916 jghali 234
        void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
22514 jghali 235
                                   int width, int height,
236
                                   GfxImageColorMap *colorMap,
25123 jghali 237
                                   bool interpolate,
22514 jghali 238
                                   Stream *maskStr,
239
                                   int maskWidth, int maskHeight,
240
                                   GfxImageColorMap *maskColorMap,
25123 jghali 241
                                   bool maskInterpolate) override;
22514 jghali 242
 
22916 jghali 243
        void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
22514 jghali 244
                                   int width, int height,
245
                                   GfxImageColorMap *colorMap,
25123 jghali 246
                                   bool interpolate,
22514 jghali 247
                                   Stream *maskStr,
248
                                   int maskWidth, int maskHeight,
25123 jghali 249
                                   bool maskInvert, bool maskInterpolate) override; // { qDebug() << "Draw Masked Image"; }
22514 jghali 250
 
251
        //----- transparency groups and soft masks
25123 jghali 252
        void beginTransparencyGroup(GfxState *state, const double *bbox, GfxColorSpace * /*blendingColorSpace*/, bool /*isolated*/, bool /*knockout*/, bool /*forSoftMask*/) override;
253
        void paintTransparencyGroup(GfxState *state, const double *bbox) override;
22916 jghali 254
        void endTransparencyGroup(GfxState *state) override;
25123 jghali 255
        void setSoftMask(GfxState * /*state*/, const double * /*bbox*/, bool /*alpha*/, Function * /*transferFunc*/, GfxColor * /*backdropColor*/) override;
22916 jghali 256
        void clearSoftMask(GfxState * /*state*/) override;
22514 jghali 257
 
22916 jghali 258
        void updateFillColor(GfxState *state) override;
259
        void updateStrokeColor(GfxState *state) override;
24374 jghali 260
        void updateFont(GfxState* state) override;
22916 jghali 261
 
22514 jghali 262
        //----- text drawing
22916 jghali 263
        void  beginTextObject(GfxState *state) override;
264
        void  endTextObject(GfxState *state) override;
25123 jghali 265
        void  drawChar(GfxState *state, double /*x*/, double /*y*/, double /*dx*/, double /*dy*/, double /*originX*/, double /*originY*/, CharCode /*code*/, int /*nBytes*/, const Unicode * /*u*/, int /*uLen*/) override;
266
        bool  beginType3Char(GfxState * /*state*/, double /*x*/, double /*y*/, double /*dx*/, double /*dy*/, CharCode /*code*/, const Unicode * /*u*/, int /*uLen*/) override;
22916 jghali 267
        void  endType3Char(GfxState * /*state*/) override;
268
        void  type3D0(GfxState * /*state*/, double /*wx*/, double /*wy*/) override;
269
        void  type3D1(GfxState * /*state*/, double /*wx*/, double /*wy*/, double /*llx*/, double /*lly*/, double /*urx*/, double /*ury*/) override;
270
 
22514 jghali 271
        //----- form XObjects
22916 jghali 272
        void drawForm(Ref /*id*/) override { qDebug() << "Draw Form"; }
273
 
22514 jghali 274
        //----- links
22916 jghali 275
        void processLink(AnnotLink * /*link*/) override { qDebug() << "Draw Link"; }
276
 
24605 jghali 277
        bool layersSetByOCG { false };
278
        double cropOffsetX { 0.0 };
279
        double cropOffsetY { 0.0 };
280
        int rotate { 0 };
22514 jghali 281
 
24374 jghali 282
protected:
283
        void setItemFillAndStroke(GfxState* state, PageItem* textNode);
284
        void applyMask(PageItem* ite);
25123 jghali 285
        void pushGroup(const QString& maskName = "", bool forSoftMask = false, bool alpha = false, bool inverted = false);
24374 jghali 286
 
287
        ScribusDoc* m_doc;
24605 jghali 288
        Qt::PenCapStyle m_lineEnd { Qt::FlatCap };
289
        Qt::PenJoinStyle m_lineJoin { Qt::MiterJoin };
24374 jghali 290
        QList<PageItem*>* m_Elements;
291
 
25120 jghali 292
        class GraphicState
293
        {
294
        public:
295
                QString fillColor { "Black" };
296
                int     fillShade { 100 };
297
                QString strokeColor { "Black "};
298
                int     strokeShade { 100 };
299
 
300
                // The currently visible area. If it is empty, everything is visible.
301
                // QPainterPath has the drawback that it sometimes approximates Bezier curves
302
                // by line segments for numerical stability. If available, a better class
303
                // should be used. However, it is important that the used class knows which
304
                // areas are covered and does not rely on external information about the fill
305
                // rule to use.
306
                QPainterPath clipPath;
307
        };
308
 
309
        class GraphicStack
310
        {
311
        public:
312
                GraphicStack()
313
                {
314
                        m_stack.push(GraphicState());
315
                }
316
 
317
                void clear()
318
                {
319
                        m_stack.clear();
320
                        m_stack.push(GraphicState());
321
                }
322
 
323
                void save()
324
                {
325
                        m_stack.push(m_stack.top());
326
                }
327
 
328
                void restore()
329
                {
330
                        if (m_stack.count() > 0)
331
                                m_stack.pop();
332
                        if (m_stack.count() == 0)
333
                                m_stack.push(GraphicState());
334
                }
335
 
336
                GraphicState& top() { return m_stack.top(); }
337
                const GraphicState& top() const  { return m_stack.top(); }
338
 
339
        private:
340
                QStack<GraphicState> m_stack;
341
        };
342
 
24374 jghali 343
        struct groupEntry
344
        {
345
                QList<PageItem*> Items;
25123 jghali 346
                bool forSoftMask { false };
347
                bool isolated { false };
348
                bool alpha { false };
24374 jghali 349
                QString maskName;
350
                QPointF maskPos;
24605 jghali 351
                bool inverted { false };
24374 jghali 352
        };
353
 
354
        QStack<groupEntry> m_groupStack;
25120 jghali 355
        GraphicStack m_graphicStack;
24374 jghali 356
 
22514 jghali 357
private:
358
        void getPenState(GfxState *state);
25123 jghali 359
        QString getColor(GfxColorSpace *color_space, const GfxColor *color, int *shade);
22514 jghali 360
        QString getAnnotationColor(const AnnotColor *color);
25123 jghali 361
        QString convertPath(const GfxPath *path);
22514 jghali 362
        int getBlendMode(GfxState *state);
25123 jghali 363
        QString UnicodeParsedString(const GooString *s1);
23478 jghali 364
        QString UnicodeParsedString(const std::string& s1);
22514 jghali 365
        bool checkClip();
23525 jghali 366
 
23536 jghali 367
        // Intersect the current clip path with the new path in state where filled areas
368
        // are interpreted according to fillRule.
369
        void adjustClip(GfxState *state, Qt::FillRule fillRule);
370
 
371
        // Take the current path of state and interpret it according to fillRule,
372
        // intersect it with the clipping path and create a new pageitem for it.
373
        void createFillItem(GfxState *state, Qt::FillRule fillRule);
374
 
23525 jghali 375
        void createImageFrame(QImage& image, GfxState *state, int numColorComponents);
376
 
25123 jghali 377
        bool m_pathIsClosed { false };
25122 jghali 378
        QVector<double> m_dashValues;
379
        double m_dashOffset { 0.0 };
380
        QString m_coords;
25120 jghali 381
 
23588 jghali 382
        // Collect the paths of character glyphs for clipping of a whole text group.
383
        QPainterPath  m_clipTextPath;
23536 jghali 384
 
22514 jghali 385
        QString m_currentMask;
23550 jghali 386
        QPointF m_currentMaskPosition;
25122 jghali 387
        Selection* m_tmpSel { nullptr };
22514 jghali 388
        QStringList *m_importedColors;
389
        QTransform m_ctm;
390
        struct F3Entry
391
        {
392
                bool colored;
393
        };
394
        QStack<F3Entry> m_F3Stack;
395
        struct mContent
396
        {
397
                QString name;
398
                QString ocgName;
399
        };
400
        QStack<mContent> m_mcStack;
25122 jghali 401
        int m_inPattern {0};
402
        int m_layerNum {1};
403
        int m_currentLayer { 0 };
404
        bool m_firstLayer {true};
405
        int m_importerFlags;
406
        int m_updateGUICounter {0};
407
        XRef *m_xref {nullptr};         // xref table for current document
408
        PDFDoc *m_pdfDoc {nullptr};
409
        Catalog *m_catalog {nullptr};
23377 craig 410
        SplashFontEngine *m_fontEngine {nullptr};
411
        SplashFont *m_font {nullptr};
24599 jghali 412
#if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(21, 4, 0)
413
        std::unique_ptr<FormPageWidgets> m_formWidgets;
414
#else
23377 craig 415
        FormPageWidgets *m_formWidgets {nullptr};
24599 jghali 416
#endif
22514 jghali 417
        QHash<QString, QList<int> > m_radioMap;
418
        QHash<int, PageItem*> m_radioButtons;
24605 jghali 419
        int m_actPage { 1 };
22514 jghali 420
};
421
#endif