PoDoFo  1.0.0-dev
PdfPainter.h
1 
7 #ifndef PDF_PAINTER_H
8 #define PDF_PAINTER_H
9 
10 #include "PdfCanvas.h"
11 #include "PdfTextState.h"
12 #include "PdfGraphicsState.h"
13 #include "PdfPainterPath.h"
14 #include "PdfPainterTextObject.h"
15 #include "PdfColorSpace.h"
16 #include "PdfContentStreamOperators.h"
17 
18 #include <podofo/auxiliary/StateStack.h>
19 
20 namespace PoDoFo {
21 
22 class PdfExtGState;
23 class PdfFont;
24 class PdfImage;
25 class PdfObjectStream;
26 class PdfXObject;
27 class PdfPainter;
28 
29 enum class PdfPainterFlags
30 {
31  None = 0,
32  Prepend = 1,
33  NoSaveRestorePrior = 2,
34  NoSaveRestore = 4,
35  RawCoordinates = 8,
36 };
37 
41 enum class PdfPathDrawMode
42 {
43  Stroke = 1,
44  Fill = 2,
45  StrokeFill = 3,
46  FillEvenOdd = 4,
47  StrokeFillEvenOdd = 5,
48 };
49 
50 enum class PdfDrawTextStyle
51 {
52  Regular = 0,
53  StrikeThrough = 1,
54  Underline = 2,
55 };
56 
57 struct PODOFO_API PdfDrawTextMultiLineParams final
58 {
59  PdfDrawTextStyle Style = PdfDrawTextStyle::Regular;
60  PdfHorizontalAlignment HorizontalAlignment = PdfHorizontalAlignment::Left;
61  PdfVerticalAlignment VerticalAlignment = PdfVerticalAlignment::Top;
62  bool SkipClip = false;
63  bool PreserveTrailingSpaces = false;
64 };
65 
66 struct PODOFO_API PdfPainterState final
67 {
68  PdfGraphicsState GraphicsState;
69  PdfTextState TextState;
70  nullable<Vector2> FirstPoint;
71  nullable<Vector2> CurrentPoint;
72 private:
73  friend class PdfPainter;
74 private:
75  PdfTextState EmittedTextState;
76 };
77 
78 using PdfPainterStateStack = StateStack<PdfPainterState>;
79 
80 class PODOFO_API PdfGraphicsStateWrapper final
81 {
82  friend class PdfPainter;
83 
84 private:
85  PdfGraphicsStateWrapper(PdfPainter& painter, PdfGraphicsState& state);
86 
87 public:
91  void ConcatenateTransformationMatrix(const Matrix& matrix);
92  void SetLineWidth(double lineWidth);
93  void SetMiterLevel(double value);
94  void SetLineCapStyle(PdfLineCapStyle capStyle);
95  void SetLineJoinStyle(PdfLineJoinStyle joinStyle);
96  void SetRenderingIntent(const std::string_view& intent);
99  void SetNonStrokingColorSpace(PdfColorSpaceInitializer&& colorSpace);
102  void SetStrokingColorSpace(PdfColorSpaceInitializer&& color);
105  void SetNonStrokingColor(const PdfColor& color);
108  void SetStrokingColor(const PdfColor& color);
111  void SetNonStrokingColor(const PdfColorRaw& color);
114  void SetStrokingColor(const PdfColorRaw& color);
115  void SetExtGState(const PdfExtGState& extGState);
116 
117 public:
120  const Matrix& GetCurrentMatrix() { return m_state->CTM; }
121  double GetLineWidth() const { return m_state->LineWidth; }
122  double GetMiterLevel() const { return m_state->MiterLimit; }
123  PdfLineCapStyle GetLineCapStyle() const { return m_state->LineCapStyle; }
124  PdfLineJoinStyle GetLineJoinStyle() const { return m_state->LineJoinStyle; }
125  const std::string& GetRenderingIntent() const { return m_state->RenderingIntent; }
126  const PdfColorRaw& GetNonStrokingColor() const { return m_state->NonStrokingColor; }
127  const PdfColorRaw& GetStrokingColor() const { return m_state->StrokingColor; }
128  PdfColorSpaceFilterPtr GetNonStrokingColorSpace() const { return m_state->NonStrokingColorSpaceFilter; }
129  PdfColorSpaceFilterPtr GetStrokingColorSpace() const { return m_state->StrokingColorSpaceFilter; }
130 
131 public:
132  operator const PdfGraphicsState&() const { return *m_state; }
133 
134 private:
135  void SetState(PdfGraphicsState& state) { m_state = &state; }
136 
137 private:
138  PdfPainter* m_painter;
139  PdfGraphicsState* m_state;
140 };
141 
142 class PODOFO_API PdfTextStateWrapper final
143 {
144  friend class PdfPainter;
145 
146 private:
147  PdfTextStateWrapper(PdfPainter& painter, PdfTextState& state);
148 
149 public:
150  void SetFont(const PdfFont& font, double fontSize);
151 
156  void SetFontScale(double scale);
157 
161  void SetCharSpacing(double charSpacing);
162 
166  void SetWordSpacing(double wordSpacing);
167 
168  void SetRenderingMode(PdfTextRenderingMode mode);
169 
170 public:
171  inline const PdfFont* GetFont() const { return m_State->Font; }
172 
176  inline double GetFontSize() const { return m_State->FontSize; }
177 
181  inline double GetFontScale() const { return m_State->FontScale; }
182 
186  inline double GetCharSpacing() const { return m_State->CharSpacing; }
187 
191  inline double GetWordSpacing() const { return m_State->WordSpacing; }
192 
193  inline PdfTextRenderingMode GetRenderingMode() const { return m_State->RenderingMode; }
194 
195 public:
196  const PdfTextState& GetState() const { return *m_State; }
197  operator const PdfTextState&() const { return *m_State; }
198 
199 private:
200  void SetState(PdfTextState& state) { m_State = &state; }
201 
202 private:
203  PdfPainter* m_painter;
204  PdfTextState* m_State;
205 };
206 
219 class PODOFO_API PdfPainter final : public PdfContentStreamOperators
220 {
221  friend class PdfGraphicsStateWrapper;
222  friend class PdfTextStateWrapper;
223  friend class PdfPainterPathContext;
224  friend class PdfPainterTextObject;
225 
226 public:
231  PdfPainter(PdfPainterFlags flags = PdfPainterFlags::None);
232 
233  ~PdfPainter() noexcept(false);
234 
246  void SetCanvas(PdfCanvas& page);
247 
252  void FinishDrawing();
253 
275  void SetStrokeStyle(PdfStrokeStyle strokeStyle, bool inverted = false, double scale = 1.0, bool subtractJoinCap = false);
276 
277  void SetStrokeStyle(const cspan<double>& dashArray, double phase);
278 
286  void SetClipRect(double x, double y, double width, double height);
287 
292  void SetClipRect(const Rect& rect);
293 
300  void DrawLine(double x1, double y1, double x2, double y2);
301 
312  void DrawCubicBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
313 
323  void DrawArc(double x, double y, double radius, double startAngle, double endAngle, bool clockwise = false);
324 
330  void DrawCircle(double x, double y, double radius, PdfPathDrawMode mode = PdfPathDrawMode::Stroke);
331 
338  void DrawEllipse(double x, double y, double width, double height,
339  PdfPathDrawMode mode = PdfPathDrawMode::Stroke);
340 
349  void DrawRectangle(double x, double y, double width, double height,
350  PdfPathDrawMode mode = PdfPathDrawMode::Stroke, double roundX = 0.0, double roundY = 0.0);
351 
357  void DrawRectangle(const Rect& rect, PdfPathDrawMode mode = PdfPathDrawMode::Stroke,
358  double roundX = 0.0, double roundY = 0.0);
359 
366  void DrawText(const std::string_view& str, double x, double y,
367  PdfDrawTextStyle style = PdfDrawTextStyle::Regular);
368 
380  void DrawTextMultiLine(const std::string_view& str, double x, double y, double width, double height,
381  const PdfDrawTextMultiLineParams& params = { });
382 
391  void DrawTextMultiLine(const std::string_view& str, const Rect& rect,
392  const PdfDrawTextMultiLineParams& params = { });
393 
402  void DrawTextAligned(const std::string_view& str, double x, double y,
403  double width, PdfHorizontalAlignment hAlignment,
404  PdfDrawTextStyle style = PdfDrawTextStyle::Regular);
405 
413  void DrawImage(const PdfImage& obj, double x, double y, double scaleX = 1.0, double scaleY = 1.0);
414 
425  void DrawXObject(const PdfXObject& obj, double x, double y, double scaleX = 1.0, double scaleY = 1.0);
426 
430  void DrawPath(const PdfPainterPath& path, PdfPathDrawMode drawMode = PdfPathDrawMode::Stroke);
431 
435  void ClipPath(const PdfPainterPath& path, bool useEvenOddRule = false);
436 
440  void BeginMarkedContent(const std::string_view& tag);
441 
445  void EndMarkedContent();
446 
454  void Save();
455 
463  void Restore();
464 
469  void SetPrecision(unsigned short precision);
470 
474  unsigned short GetPrecision() const;
475 
479  std::string_view GetContent() const;
480 
481 public:
482  inline const PdfPainterStateStack& GetStateStack() const { return m_StateStack; }
483 
493  inline void SetTabWidth(unsigned short tabWidth) { m_TabWidth = tabWidth; }
494 
501  inline unsigned short GetTabWidth() const { return m_TabWidth; }
502 
507  inline PdfCanvas* GetCanvas() const { return m_canvas; }
508 
513  inline PdfObjectStream* GetStream() const { return m_objStream; }
514 
515 private:
516  // To be called by PdfPainterTextObject
517  void BeginText();
518  void EndText();
519  void TextMoveTo(double x, double y);
520  void AddText(const std::string_view& str);
521 
522 private:
523  // To be called by state wrappers
524  void SetLineWidth(double value);
525  void SetMiterLimit(double miterLimit);
526  void SetLineCapStyle(PdfLineCapStyle style);
527  void SetLineJoinStyle(PdfLineJoinStyle style);
528  void SetNonStrokingColor(const PdfColor& color);
529  void SetStrokingColor(const PdfColor& color);
530  void SetNonStrokingColor(const PdfColorRaw& color, const PdfColorSpaceFilter& colorSpace);
531  void SetStrokingColor(const PdfColorRaw& color, const PdfColorSpaceFilter& colorSpace);
532  void SetNonStrokingColorSpace(const PdfColorSpaceFilter&filter, const PdfColorSpace* colorSpace);
533  void SetStrokingColorSpace(const PdfColorSpaceFilter& filter, const PdfColorSpace* colorSpace);
534  void SetRenderingIntent(const std::string_view& intent);
535  void SetTransformationMatrix(const Matrix& matrix);
536  void SetFont(const PdfFont& font, double fontSize);
537  void SetFontScale(double value);
538  void SetCharSpacing(double value);
539  void SetWordSpacing(double value);
540  void SetTextRenderingMode(PdfTextRenderingMode value);
541  void SetExtGState(const PdfExtGState& extGState);
542 
543 private:
544  void writeTextState();
545  void setFont(const PdfFont& font, double fontSize);
546  void setFontScale(double value);
547  void setCharSpacing(double value);
548  void setWordSpacing(double value);
549  void setTextRenderingMode(PdfTextRenderingMode value);
550  void save();
551  void restore();
552  void reset();
553  void drawRectangle(double x, double y, double width, double height, PdfPathDrawMode mode, double roundX, double roundY);
554  void drawPath(PdfPathDrawMode mode);
555  void stroke();
556  void fill(bool useEvenOddRule);
557  void strokeAndFill(bool useEvenOddRule);
558  void setNonStrokingColorSpace(const PdfObject& csObj);
559  void setStrokingColorSpace(const PdfObject& csObj);
560  PdfName tryAddResource(const PdfObject& obj, PdfResourceType type);
561  void drawLines(const std::vector<std::array<double, 4>>& lines);
562 
563 private:
564  // PdfContentStreamOperators implementation
565  void re_Operator(double x, double y, double width, double height) override;
566  void m_Operator(double x, double y) override;
567  void l_Operator(double x, double y) override;
568  void c_Operator(double c1x, double c1y, double c2x, double c2y, double x, double y) override;
569  void n_Operator() override;
570  void h_Operator() override;
571  void b_Operator() override;
572  void B_Operator() override;
573  void bStar_Operator() override;
574  void BStar_Operator() override;
575  void s_Operator() override;
576  void S_Operator() override;
577  void f_Operator() override;
578  void fStar_Operator() override;
579  void W_Operator() override;
580  void WStar_Operator() override;
581  void MP_Operator(const std::string_view& tag) override;
582  void DP_Operator(const std::string_view& tag, const PdfDictionary& properties) override;
583  void DP_Operator(const std::string_view& tag, const std::string_view& propertyDictName) override;
584  void BMC_Operator(const std::string_view& tag) override;
585  void BDC_Operator(const std::string_view& tag, const PdfDictionary& properties) override;
586  void BDC_Operator(const std::string_view& tag, const std::string_view& propertyDictName) override;
587  void EMC_Operator() override;
588  void q_Operator() override;
589  void Q_Operator() override;
590  void BT_Operator() override;
591  void ET_Operator() override;
592  void Td_Operator(double tx, double ty) override;
593  void Tm_Operator(double a, double b, double c, double d, double e, double f) override;
594  void Tr_Operator(PdfTextRenderingMode mode) override;
595  void Ts_Operator(double rise) override;
596  void Tc_Operator(double charSpace) override;
597  void TL_Operator(double leading) override;
598  void Tf_Operator(const std::string_view& fontName, double fontSize) override;
599  void Tw_Operator(double wordSpace) override;
600  void Tz_Operator(double scale) override;
601  void Tj_Operator(const std::string_view& encoded, bool hex) override;
602  void TJ_Operator_Begin() override;
603  void TJ_Operator_Delta(double delta) override;
604  void TJ_Operator_Glyphs(const std::string_view& encoded, bool hex) override;
605  void TJ_Operator_End() override;
606  void cm_Operator(double a, double b, double c, double d, double e, double f) override;
607  void w_Operator(double lineWidth) override;
608  void J_Operator(PdfLineCapStyle style) override;
609  void j_Operator(PdfLineJoinStyle style) override;
610  void M_Operator(double miterLimit) override;
611  void d_Operator(const cspan<double>& dashArray, double fase) override;
612  void ri_Operator(const std::string_view& intent) override;
613  void i_Operator(double flatness) override;
614  void gs_Operator(const std::string_view& dictName) override;
615  void Do_Operator(const std::string_view& xobjname) override;
616  void cs_Operator(PdfColorSpaceType colorSpace) override;
617  void cs_Operator(const std::string_view& name) override;
618  void CS_Operator(PdfColorSpaceType colorSpace) override;
619  void CS_Operator(const std::string_view& name) override;
620  void sc_Operator(const cspan<double>& components) override;
621  void SC_Operator(const cspan<double>& components) override;
622  void scn_Operator(const cspan<double>& components) override;
623  void SCN_Operator(const cspan<double>& components) override;
624  void scn_Operator(const cspan<double>& components, const std::string_view& patternName) override;
625  void SCN_Operator(const cspan<double>& components, const std::string_view& patternName) override;
626  void scn_Operator(const std::string_view& patternName) override;
627  void SCN_Operator(const std::string_view& patternName) override;
628  void G_Operator(double gray) override;
629  void g_Operator(double gray) override;
630  void RG_Operator(double red, double green, double blue) override;
631  void rg_Operator(double red, double green, double blue) override;
632  void K_Operator(double cyan, double magenta, double yellow, double black) override;
633  void k_Operator(double cyan, double magenta, double yellow, double black) override;
634  void BX_Operator() override;
635  void EX_Operator() override;
636  void Extension_Operator(const std::string_view& opName, const cspan<PdfVariant>& operands) override;
637 
638 private:
639  enum PainterStatus
640  {
641  StatusDefault = 1,
642  StatusTextObject = 2,
643  StatusTextArray = 4,
644  StatusExtension = 8,
645  };
646 
647 private:
648  void drawTextAligned(const std::string_view& str, double x, double y, double width,
649  PdfHorizontalAlignment hAlignment, PdfDrawTextStyle style, std::vector<std::array<double, 4>>& linesToDraw);
650 
651  void drawText(const std::string_view& str, double x, double y,
652  bool isUnderline, bool isStrikeThrough, std::vector<std::array<double, 4>>& linesToDraw);
653 
654  void drawMultiLineText(const std::string_view& str, double x, double y, double width, double height,
655  PdfHorizontalAlignment hAlignment, PdfVerticalAlignment vAlignment, bool skipClip, bool preserveTrailingSpaces,
656  PdfDrawTextStyle style);
657 
658  void setLineWidth(double width);
659 
669  std::string expandTabs(const std::string_view& str) const;
670  void checkStream();
671  void openPath(double x, double y);
672  void resetPath();
673  void checkPathOpened() const;
674  void checkFont() const;
675  void finishDrawing();
676  void checkStatus(int expectedStatus);
677  void enterTextObject();
678  void exitTextObject();
679 
680 private:
681  PdfPainter(const PdfPainter&) = delete;
682  PdfPainter& operator=(const PdfPainter&) = delete;
683 
684 private:
685  PdfPainterFlags m_flags;
686  PainterStatus m_painterStatus;
687  PdfPainterStateStack m_StateStack;
688  unsigned m_textStackCount;
689 
690 public:
691  PdfGraphicsStateWrapper GraphicsState;
692  PdfTextStateWrapper TextState;
693  PdfPainterTextObject TextObject;
694 
695 private:
700  PdfObjectStream* m_objStream;
701 
705  PdfCanvas* m_canvas;
706 
710  unsigned short m_TabWidth;
711 
714  PdfStringStream m_stream;
715 
716  std::unordered_map<PdfReference, PdfName> m_resNameCache;
717 };
718 
719 }
720 
721 ENABLE_BITMASK_OPERATORS(PoDoFo::PdfPainterFlags);
722 ENABLE_BITMASK_OPERATORS(PoDoFo::PdfDrawTextStyle);
723 
724 #endif // PDF_PAINTER_H
A interface that provides the necessary features for a painter to draw onto a PdfObject.
Definition: PdfCanvas.h:28
A class that implements methods to sample colors from a scanline buffer.
Definition: PdfColorSpaceFilter.h:31
A color object can represent either a grayscale value, a RGB color, a CMYK color.
Definition: PdfColor.h:25
Pdf content stream callble operator interface ISO 32000 - 1:2008 "A.2 PDF Content Stream Operators".
Definition: PdfContentStreamOperators.h:22
The PDF dictionary data type of PoDoFo (inherits from PdfDataContainer, the base class for such repre...
Definition: PdfDictionary.h:82
This class wraps the ExtGState object used in the Resource Dictionary of a Content-supporting element...
Definition: PdfExtGState.h:22
Before you can draw text on a PDF document, you have to create a font object first.
Definition: PdfFont.h:49
A PdfImage object is needed when ever you want to embed an image file into a PDF document.
Definition: PdfImage.h:44
This class represents a PdfName.
Definition: PdfName.h:24
A PDF stream can be appended to any PdfObject and can contain arbitrary data.
Definition: PdfObjectStream.h:87
This class represents a PDF indirect Object in memory.
Definition: PdfObject.h:35
This class describes PDF paths being written to a PdfPainter.
Definition: PdfPainterPath.h:19
This class describes a manually handled PDF text object (content stream operators surrounded by BT .
Definition: PdfPainterTextObject.h:22
This class provides an easy to use painter object which allows you to draw on a PDF page object.
Definition: PdfPainter.h:220
void SetTabWidth(unsigned short tabWidth)
Set the tab width for the DrawText operation.
Definition: PdfPainter.h:493
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:507
unsigned short GetTabWidth() const
Get the currently set tab width.
Definition: PdfPainter.h:501
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:513
A XObject is a content stream with several drawing commands and data which can be used throughout a P...
Definition: PdfXObject.h:30
A rectangle defined by position and size.
Definition: Rect.h:20
SPDX-FileCopyrightText: (C) 2022 Francesco Pretto ceztko@gmail.com SPDX-License-Identifier: LGPL-2....
Definition: basetypes.h:16
PdfLineCapStyle
Enum for line cap styles when drawing.
Definition: PdfDeclarations.h:403
PdfTextRenderingMode
Enum for text rendering mode (Tr)
Definition: PdfDeclarations.h:363
std::shared_ptr< const PdfColorSpaceFilter > PdfColorSpaceFilterPtr
Convenience alias for a constant PdfColorSpaceFilter shared ptr.
Definition: PdfColorSpaceFilter.h:77
PdfPainterFlags
Definition: PdfPainter.h:30
@ NoSaveRestore
Do not perform a Save/Restore of added content in this painting session.
@ NoSaveRestorePrior
Do not perform a Save/Restore or previous content. Implies RawCoordinates.
@ Prepend
Does nothing for now.
@ RawCoordinates
Does nothing for now.
PdfHorizontalAlignment
Enum for text alignment.
Definition: PdfDeclarations.h:433
@ None
Do not add a default appearrance.
tcb::span< const T, Extent > cspan
Constant span.
Definition: span.h:13
PdfPathDrawMode
An enum describing modes to draw paths and figures.
Definition: PdfPainter.h:42
@ StrokeFill
Stroke and fill using the the even-odd rule to determine the region to fill.
@ Fill
Fill using the the non-zero winding number 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.
PdfStrokeStyle
Enum for the different stroke styles that can be set when drawing to a PDF file (mostly for line draw...
Definition: PdfDeclarations.h:379
PdfColorSpaceType
Enum for the colorspaces supported by PDF.
Definition: PdfDeclarations.h:330
PdfVerticalAlignment
Enum for vertical text alignment.
Definition: PdfDeclarations.h:423
PdfLineJoinStyle
Enum for line join styles when drawing.
Definition: PdfDeclarations.h:413