PoDoFo 1.2.0
Loading...
Searching...
No Matches
PdfPainter.h
1// SPDX-FileCopyrightText: 2005 Dominik Seichter <domseichter@web.de>
2// SPDX-FileCopyrightText: 2020 Francesco Pretto <ceztko@gmail.com>
3// SPDX-License-Identifier: LGPL-2.0-or-later OR MPL-2.0
4
5#ifndef PDF_PAINTER_H
6#define PDF_PAINTER_H
7
8#include "PdfCanvas.h"
9#include "PdfTextState.h"
10#include "PdfGraphicsState.h"
11#include "PdfPainterPath.h"
12#include "PdfPainterTextObject.h"
13#include "PdfColorSpace.h"
14#include "PdfPattern.h"
15#include "PdfContentStreamOperators.h"
16
17#include <podofo/auxiliary/StateStack.h>
18
19namespace PoDoFo {
20
21class PdfExtGState;
22class PdfFont;
23class PdfImage;
24class PdfObjectStream;
25class PdfXObject;
26class PdfPainter;
27
29{
30 None = 0,
31 Prepend = 1,
32 NoSaveRestorePrior = 2,
33 NoSaveRestore = 4,
34 RawCoordinates = 8,
35};
36
39{
40 Stroke = 1,
41 Fill = 2,
42 StrokeFill = 3,
43 FillEvenOdd = 4,
45};
46
47enum class PdfDrawTextStyle : uint8_t
48{
49 Regular = 0,
50 StrikeThrough = 1,
51 Underline = 2,
52};
53
54struct PODOFO_API PdfDrawTextMultiLineParams final
55{
56 PdfDrawTextStyle Style = PdfDrawTextStyle::Regular;
57 PdfHorizontalAlignment HorizontalAlignment = PdfHorizontalAlignment::Left;
58 PdfVerticalAlignment VerticalAlignment = PdfVerticalAlignment::Top;
59 bool SkipClip = false;
60 bool PreserveTrailingSpaces = false;
61};
62
63struct PODOFO_API PdfPainterState final
64{
65 PdfPainterState();
66
67 PdfGraphicsState GraphicsState;
68 PdfTextState TextState;
69 nullable<Vector2> FirstPoint;
70 nullable<Vector2> CurrentPoint;
71private:
72 friend class PdfPainter;
73private:
74 PdfTextState EmittedTextState;
75};
76
77using PdfPainterStateStack = StateStack<PdfPainterState>;
78
79class PODOFO_API PdfGraphicsStateWrapper final
80{
81 friend class PdfPainter;
82
83private:
84 PdfGraphicsStateWrapper(PdfPainter& painter, PdfGraphicsState& state);
85
86public:
89 void ConcatenateTransformationMatrix(const Matrix& matrix);
90 void SetLineWidth(double lineWidth);
91 void SetMiterLevel(double value);
92 void SetLineCapStyle(PdfLineCapStyle capStyle);
93 void SetLineJoinStyle(PdfLineJoinStyle joinStyle);
94 void SetRenderingIntent(const std::string_view& intent);
96 void SetNonStrokingColorSpace(PdfColorSpaceInitializer&& colorSpace);
98 void SetStrokingColorSpace(PdfColorSpaceInitializer&& color);
100 void SetNonStrokingColor(const PdfColor& color);
102 void SetStrokingColor(const PdfColor& color);
104 void SetNonStrokingColor(const PdfColorRaw& color);
106 void SetStrokingColor(const PdfColorRaw& color);
107 void SetExtGState(const PdfExtGState& extGState);
109 void SetStrokingUncolouredTilingPattern(const PdfUncolouredTilingPattern& pattern, const PdfColorRaw& color);
110
112 void SetNonStrokingUncolouredTilingPattern(const PdfUncolouredTilingPattern& pattern, const PdfColorRaw& color);
114 void SetStrokingPattern(const PdfPattern& pattern);
116 void SetNonStrokingPattern(const PdfPattern& pattern);
118 void SetShadingDictionary(const PdfShadingDictionary& shading);
119
120public:
122 const Matrix& GetCurrentMatrix() { return m_state->CTM; }
123 double GetLineWidth() const { return m_state->LineWidth; }
124 double GetMiterLevel() const { return m_state->MiterLimit; }
125 PdfLineCapStyle GetLineCapStyle() const { return m_state->LineCapStyle; }
126 PdfLineJoinStyle GetLineJoinStyle() const { return m_state->LineJoinStyle; }
127 const std::string& GetRenderingIntent() const { return m_state->RenderingIntent; }
128 const PdfColorRaw& GetNonStrokingColor() const { return m_state->NonStrokingColor; }
129 const PdfColorRaw& GetStrokingColor() const { return m_state->StrokingColor; }
130 PdfColorSpaceFilterPtr GetNonStrokingColorSpace() const { return m_state->NonStrokingColorSpaceFilter; }
131 PdfColorSpaceFilterPtr GetStrokingColorSpace() const { return m_state->StrokingColorSpaceFilter; }
132
133public:
134 operator const PdfGraphicsState&() const { return *m_state; }
135
136private:
137 void SetState(PdfGraphicsState& state) { m_state = &state; }
138
139private:
140 PdfPainter* m_painter;
141 PdfGraphicsState* m_state;
142};
143
144class PODOFO_API PdfTextStateWrapper final
145{
146 friend class PdfPainter;
147
148private:
149 PdfTextStateWrapper(PdfPainter& painter, PdfTextState& state);
150
151public:
152 void SetFont(const PdfFont& font, double fontSize);
153
157 void SetFontScale(double scale);
158
161 void SetCharSpacing(double charSpacing);
162
165 void SetWordSpacing(double wordSpacing);
166
167 void SetRenderingMode(PdfTextRenderingMode mode);
168
171 void SetMatrix(const Matrix& matrix);
172
173public:
174 inline const PdfFont* GetFont() const { return m_State->Font; }
175
178 inline double GetFontSize() const { return m_State->FontSize; }
179
182 inline double GetFontScale() const { return m_State->FontScale; }
183
186 inline double GetCharSpacing() const { return m_State->CharSpacing; }
187
190 inline double GetWordSpacing() const { return m_State->WordSpacing; }
191
192 inline PdfTextRenderingMode GetRenderingMode() const { return m_State->RenderingMode; }
193
194public:
195 const PdfTextState& GetState() const { return *m_State; }
196 operator const PdfTextState&() const { return *m_State; }
197
198private:
199 void SetState(PdfTextState& state) { m_State = &state; }
200
201private:
202 PdfPainter* m_painter;
203 PdfTextState* m_State;
204};
205
217{
218 friend class PdfGraphicsStateWrapper;
219 friend class PdfTextStateWrapper;
220 friend class PdfPainterPathContext;
221 friend class PdfPainterTextObject;
222
223public:
226 PdfPainter();
227
228 ~PdfPainter() noexcept(false);
229
241 void SetCanvas(PdfCanvas& canvas, PdfPainterFlags flags = PdfPainterFlags::None);
242
246 void FinishDrawing();
247
266 void SetStrokeStyle(PdfStrokeStyle strokeStyle, bool inverted = false, double scale = 1.0, bool subtractJoinCap = false);
267
268 void SetStrokeStyle(const cspan<double>& dashArray, double phase);
269
276 void SetClipRect(double x, double y, double width, double height);
277
281 void SetClipRect(const Rect& rect);
282
288 void DrawLine(double x1, double y1, double x2, double y2);
289
299 void DrawCubicBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
300
309 void DrawArc(double x, double y, double radius, double startAngle, double endAngle, bool clockwise = false);
310
315 void DrawCircle(double x, double y, double radius, PdfPathDrawMode mode = PdfPathDrawMode::Stroke);
316
322 void DrawEllipse(double x, double y, double width, double height,
323 PdfPathDrawMode mode = PdfPathDrawMode::Stroke);
324
332 void DrawRectangle(double x, double y, double width, double height,
333 PdfPathDrawMode mode = PdfPathDrawMode::Stroke, double roundX = 0.0, double roundY = 0.0);
334
339 void DrawRectangle(const Rect& rect, PdfPathDrawMode mode = PdfPathDrawMode::Stroke,
340 double roundX = 0.0, double roundY = 0.0);
341
347 void DrawText(const std::string_view& str, double x, double y,
348 PdfDrawTextStyle style = PdfDrawTextStyle::Regular);
349
360 void DrawTextMultiLine(const std::string_view& str, double x, double y, double width, double height,
361 const PdfDrawTextMultiLineParams& params = { });
362
370 void DrawTextMultiLine(const std::string_view& str, const Rect& rect,
371 const PdfDrawTextMultiLineParams& params = { });
372
380 void DrawTextAligned(const std::string_view& str, double x, double y,
382 PdfDrawTextStyle style = PdfDrawTextStyle::Regular);
383
390 void DrawImage(const PdfImage& obj, double x, double y, double scaleX = 1.0, double scaleY = 1.0);
391
401 void DrawXObject(const PdfXObject& obj, double x, double y, double scaleX = 1.0, double scaleY = 1.0);
402
404 void DrawPath(const PdfPainterPath& path, PdfPathDrawMode drawMode = PdfPathDrawMode::Stroke);
405
408 void ClipPath(const PdfPainterPath& path, bool useEvenOddRule = false);
409
411 void BeginMarkedContent(const std::string_view& tag);
412
414 void EndMarkedContent();
415
422 void Save();
423
430 void Restore();
431
435 void SetPrecision(unsigned short precision);
436
439 unsigned short GetPrecision() const;
440
442 std::string_view GetContent() const;
443
444public:
445 inline const PdfPainterStateStack& GetStateStack() const { return m_StateStack; }
446
455 inline void SetTabWidth(unsigned short tabWidth) { m_TabWidth = tabWidth; }
456
462 inline unsigned short GetTabWidth() const { return m_TabWidth; }
463
467 inline PdfCanvas* GetCanvas() const { return m_canvas; }
468
472 inline PdfObjectStream* GetStream() const { return m_objStream; }
473
474private:
475 // To be called by PdfPainterTextObject
476 void BeginText();
477 void EndText();
478 void TextMoveTo(double x, double y);
479 void AddText(const std::string_view& str);
480
481private:
482 // To be called by state wrappers
483 void SetLineWidth(double value);
484 void SetMiterLimit(double miterLimit);
485 void SetLineCapStyle(PdfLineCapStyle style);
486 void SetLineJoinStyle(PdfLineJoinStyle style);
487 void SetNonStrokingColor(const PdfColor& color);
488 void SetStrokingColor(const PdfColor& color);
489 void SetNonStrokingColor(const PdfColorRaw& color, const PdfColorSpaceFilter& colorSpace);
490 void SetStrokingColor(const PdfColorRaw& color, const PdfColorSpaceFilter& colorSpace);
491 void SetNonStrokingColorSpace(const PdfVariant& expVar);
492 void SetStrokingColorSpace(const PdfVariant& expVar);
493 void SetStrokingPattern(const PdfPattern& pattern, const PdfColorRaw* color, const PdfColorSpaceFilter* colorSpace);
494 void SetNonStrokingPattern(const PdfPattern& pattern, const PdfColorRaw* color, const PdfColorSpaceFilter* colorSpace);
495 void SetShadingDictionary(const PdfShadingDictionary& shading);
496 void SetRenderingIntent(const std::string_view& intent);
497 void SetTransformationMatrix(const Matrix& matrix);
498 void SetFont(const PdfFont& font, double fontSize);
499 void SetFontScale(double value);
500 void SetCharSpacing(double value);
501 void SetWordSpacing(double value);
502 void SetTextRenderingMode(PdfTextRenderingMode value);
503 void SetTextMatrix(const Matrix& matrix);
504 void SetExtGState(const PdfExtGState& extGState);
505
506private:
507 void writeTextState();
508 void setFont(const PdfFont& font, double fontSize);
509 void setFontScale(double value);
510 void setCharSpacing(double value);
511 void setWordSpacing(double value);
512 void setTextRenderingMode(PdfTextRenderingMode value);
513 void setTextMatrix(const Matrix& value);
514 void save();
515 void restore();
516 void reset();
517 void drawRectangle(double x, double y, double width, double height, PdfPathDrawMode mode, double roundX, double roundY);
518 void drawPath(PdfPathDrawMode mode);
519 void stroke();
520 void fill(bool useEvenOddRule);
521 void strokeAndFill(bool useEvenOddRule);
522 PdfName tryAddResource(const PdfObject& obj, PdfResourceType type);
523 PdfName tryAddResource(const PdfReference& ref, PdfResourceType type);
524 void drawLines(const std::vector<std::array<double, 4>>& lines);
525
526private:
527 // PdfContentStreamOperators implementation
528 void re_Operator(double x, double y, double width, double height) override;
529 void m_Operator(double x, double y) override;
530 void l_Operator(double x, double y) override;
531 void c_Operator(double c1x, double c1y, double c2x, double c2y, double x, double y) override;
532 void v_Operator(double cx, double cy, double x, double y) override;
533 void y_Operator(double cx, double cy, double x, double y) override;
534 void n_Operator() override;
535 void h_Operator() override;
536 void b_Operator() override;
537 void B_Operator() override;
538 void bStar_Operator() override;
539 void BStar_Operator() override;
540 void s_Operator() override;
541 void S_Operator() override;
542 void f_Operator() override;
543 void fStar_Operator() override;
544 void W_Operator() override;
545 void WStar_Operator() override;
546 void MP_Operator(const std::string_view& tag) override;
547 void DP_Operator(const std::string_view& tag, const PdfDictionary& properties) override;
548 void DP_Operator(const std::string_view& tag, const std::string_view& propertyDictName) override;
549 void BMC_Operator(const std::string_view& tag) override;
550 void BDC_Operator(const std::string_view& tag, const PdfDictionary& properties) override;
551 void BDC_Operator(const std::string_view& tag, const std::string_view& propertyDictName) override;
552 void EMC_Operator() override;
553 void q_Operator() override;
554 void Q_Operator() override;
555 void BT_Operator() override;
556 void ET_Operator() override;
557 void Td_Operator(double tx, double ty) override;
558 void TD_Operator(double tx, double ty) override;
559 void Tm_Operator(double a, double b, double c, double d, double e, double f) override;
560 void Tr_Operator(PdfTextRenderingMode mode) override;
561 void Ts_Operator(double rise) override;
562 void Tc_Operator(double charSpace) override;
563 void TL_Operator(double leading) override;
564 void Tf_Operator(const std::string_view& fontName, double fontSize) override;
565 void Tw_Operator(double wordSpace) override;
566 void Tz_Operator(double scale) override;
567 void Tj_Operator(const std::string_view& encoded, bool hex) override;
568 void TJ_Operator_Begin() override;
569 void TJ_Operator_Delta(double delta) override;
570 void TJ_Operator_Glyphs(const std::string_view& encoded, bool hex) override;
571 void TJ_Operator_End() override;
572 void cm_Operator(double a, double b, double c, double d, double e, double f) override;
573 void w_Operator(double lineWidth) override;
574 void J_Operator(PdfLineCapStyle style) override;
575 void j_Operator(PdfLineJoinStyle style) override;
576 void M_Operator(double miterLimit) override;
577 void d_Operator(const cspan<double>& dashArray, double fase) override;
578 void ri_Operator(const std::string_view& intent) override;
579 void i_Operator(double flatness) override;
580 void gs_Operator(const std::string_view& dictName) override;
581 void Do_Operator(const std::string_view& xobjname) override;
582 void cs_Operator(PdfColorSpaceType colorSpace) override;
583 void cs_Operator(const std::string_view& name) override;
584 void CS_Operator(PdfColorSpaceType colorSpace) override;
585 void CS_Operator(const std::string_view& name) override;
586 void sc_Operator(const cspan<double>& components) override;
587 void SC_Operator(const cspan<double>& components) override;
588 void scn_Operator(const cspan<double>& components) override;
589 void SCN_Operator(const cspan<double>& components) override;
590 void scn_Operator(const cspan<double>& components, const std::string_view& patternName) override;
591 void SCN_Operator(const cspan<double>& components, const std::string_view& patternName) override;
592 void scn_Operator(const std::string_view& patternName) override;
593 void SCN_Operator(const std::string_view& patternName) override;
594 void G_Operator(double gray) override;
595 void g_Operator(double gray) override;
596 void RG_Operator(double red, double green, double blue) override;
597 void rg_Operator(double red, double green, double blue) override;
598 void K_Operator(double cyan, double magenta, double yellow, double black) override;
599 void k_Operator(double cyan, double magenta, double yellow, double black) override;
600 void sh_Operator(const std::string_view& shadingDictName) override;
601 void BX_Operator() override;
602 void EX_Operator() override;
603 void Extension_Operator(const std::string_view& opName, const cspan<PdfVariant>& operands) override;
604
605private:
606 enum PainterStatus
607 {
608 StatusDefault = 1,
609 StatusTextObject = 2,
610 StatusTextArray = 4,
611 StatusExtension = 8,
612 };
613
614private:
615 void drawTextAligned(const std::string_view& str, double x, double y, double width,
616 PdfHorizontalAlignment hAlignment, PdfDrawTextStyle style, std::vector<std::array<double, 4>>& linesToDraw,
617 std::string_view encoded);
618
619 void drawText(const std::string_view& str, double x, double y,
620 bool isUnderline, bool isStrikeThrough, std::vector<std::array<double, 4>>& linesToDraw,
621 std::string_view encoded);
622
623 void drawMultiLineText(const std::string_view& str, double x, double y, double width, double height,
624 PdfHorizontalAlignment hAlignment, PdfVerticalAlignment vAlignment, bool skipClip, bool preserveTrailingSpaces,
625 PdfDrawTextStyle style);
626
627 void setLineWidth(double width);
628
635 std::string expandTabs(const std::string_view& str) const;
636 void checkStream();
637 void openPath(double x, double y);
638 void resetPath();
639 void checkPathOpened() const;
640 void checkFont() const;
641 void finishDrawing();
642 void checkStatus(int expectedStatus);
643 void enterTextObject();
644 void exitTextObject();
645
646private:
647 PdfPainter(const PdfPainter&) = delete;
648 PdfPainter& operator=(const PdfPainter&) = delete;
649
650private:
651 PdfPainterFlags m_flags;
652 PainterStatus m_painterStatus;
653 PdfPainterStateStack m_StateStack;
654 unsigned m_textStackCount;
655
656public:
657 PdfGraphicsStateWrapper GraphicsState;
658 PdfTextStateWrapper TextState;
659 PdfPainterTextObject TextObject;
660
661private:
665 PdfObjectStream* m_objStream;
666
669 PdfCanvas* m_canvas;
670
673 unsigned short m_TabWidth;
674
676 PdfStringStream m_stream;
677
678 std::unordered_map<PdfReference, PdfName> m_resNameCache;
679};
680
681}
682
683ENABLE_BITMASK_OPERATORS(PoDoFo::PdfPainterFlags);
684ENABLE_BITMASK_OPERATORS(PoDoFo::PdfDrawTextStyle);
685
686#endif // PDF_PAINTER_H
An interface that provides the necessary features for a painter to draw onto a PdfObject.
Definition PdfCanvas.h:25
A class that implements methods to sample colors from a scanline buffer.
Definition PdfColorSpaceFilter.h:27
A color object can represent either a grayscale value, a RGB color, a CMYK color.
Definition PdfColor.h:20
Pdf content stream callble operator interface ISO 32000 - 1:2008 "A.2 PDF Content Stream Operators".
Definition PdfContentStreamOperators.h:17
The PDF dictionary data type of PoDoFo (inherits from PdfDataContainer, the base class for such repre...
Definition PdfDictionary.h:77
This class wraps the ExtGState object used in the Resource Dictionary of a Content-supporting element...
Definition PdfExtGState.h:20
Before you can draw text on a PDF document, you have to create a font object first.
Definition PdfFont.h:42
A PdfImage object is needed when ever you want to embed an image file into a PDF document.
Definition PdfImage.h:68
This class represents a PdfName.
Definition PdfName.h:21
A PDF stream can be appended to any PdfObject and can contain arbitrary data.
Definition PdfObjectStream.h:82
This class represents a PDF indirect Object in memory.
Definition PdfObject.h:31
This class describes PDF paths being written to a PdfPainter.
Definition PdfPainterPath.h:15
This class describes a manually handled PDF text object (content stream operators surrounded by BT .
Definition PdfPainterTextObject.h:18
This class provides an easy to use painter object which allows you to draw on a PDF page object.
Definition PdfPainter.h:217
void SetTabWidth(unsigned short tabWidth)
Set the tab width for the DrawText operation.
Definition PdfPainter.h:455
void DrawTextMultiLine(const std::string_view &str, const Rect &rect, const PdfDrawTextMultiLineParams &params={ })
Draw multiline text into a rectangle doing automatic wordwrapping.
PdfCanvas * GetCanvas() const
Return the current page that is that on the painter.
Definition PdfPainter.h:467
unsigned short GetTabWidth() const
Get the currently set tab width.
Definition PdfPainter.h:462
void DrawTextMultiLine(const std::string_view &str, double x, double y, double width, double height, const PdfDrawTextMultiLineParams &params={ })
Draw multiline text into a rectangle doing automatic wordwrapping.
PdfObjectStream * GetStream() const
Return the current canvas stream that is set on the painter.
Definition PdfPainter.h:472
A reference is a pointer to a object in the PDF file of the form "4 0 R", where 4 is the object numbe...
Definition PdfReference.h:20
A variant data type which supports all data types supported by the PDF standard.
Definition PdfVariant.h:29
A XObject is a content stream with several drawing commands and data which can be used throughout a P...
Definition PdfXObject.h:28
An normalized rectangle defined by position (left-bottom) and size.
Definition Rect.h:17
Convenient type for char array storage and/or buffer with std::string compatibility.
Definition basetypes.h:30
All classes, functions, types and enums of PoDoFo are members of these namespace.
Definition basetypes.h:13
PdfLineJoinStyle
Enum for line join styles when drawing.
Definition PdfDeclarations.h:406
PdfStrokeStyle
Enum for the different stroke styles that can be set when drawing to a PDF file (mostly for line draw...
Definition PdfDeclarations.h:378
PdfPathDrawMode
An enum describing modes to draw paths and figures.
Definition PdfPainter.h:39
@ StrokeFill
Stroke and fill using the the even-odd rule to determine the region to fill.
@ StrokeFillEvenOdd
Stroke and fill using the the even-odd rule to determine the region to fill.
@ FillEvenOdd
Fill using the the even-odd rule to determine the region to fill.
std::shared_ptr< const PdfColorSpaceFilter > PdfColorSpaceFilterPtr
Convenience alias for a constant PdfColorSpaceFilter shared ptr.
Definition PdfColorSpaceFilter.h:71
PdfPainterFlags
Definition PdfPainter.h:29
@ NoSaveRestore
Do not perform a Save/Restore of added content in this painting session.
PdfHorizontalAlignment
Enum for text alignment.
Definition PdfDeclarations.h:422
@ None
Do not add a default appearance.
PdfLineCapStyle
Enum for line cap styles when drawing.
Definition PdfDeclarations.h:398
PdfTextRenderingMode
Enum for text rendering mode (Tr)
Definition PdfDeclarations.h:364
@ Fill
Default mode, fill text.
PdfColorSpaceType
Enum for the colorspaces supported by PDF.
Definition PdfDeclarations.h:333
PdfVerticalAlignment
Enum for vertical text alignment.
Definition PdfDeclarations.h:414