1 /**
2  * Describes a page.
3  */
4 module harud.page;
5 
6 import std.conv;
7 import std.exception; // for ErrNoException
8 import std.stdio;
9 import std.string;
10 
11 import harud.annotation;
12 import harud.c;
13 import harud.destination;
14 import harud.encoder;
15 import harud.font;
16 import harud.haruobject;
17 import harud.image;
18 import harud.types;
19 
20 /**
21  * The Page class.
22  *
23  * The Page class is used to manipulate an individual page.
24  * To create new pages use $(LINK2 harud/doc/Doc.addPage.html, `addPage()`) or
25  * $(LINK2 harud/doc/Doc.insertPage.html, `insertPage()`) methods of $(LINK2 harud/doc/Doc.html, Doc)  class
26  */
27 class Page : IHaruObject {
28    protected HPDF_Page _page;
29 
30    this(HPDF_Page page) {
31       _page = page;
32    }
33 
34    /**
35     * Gets the width of a page.
36     *
37     * Returns:
38     * When succeed, it returns the width of a page. Otherwise it returns 0.
39     */
40    float getWidth() {
41       return HPDF_Page_GetWidth(this._page);
42    }
43 
44    /**
45     * Changes the width of a page
46     *
47     * Params:
48     *  value = the new page width. Valid value are between 3 and 14400
49     */
50    void setWidth(float value) {
51       HPDF_Page_SetWidth(this._page, value);
52    }
53 
54    /**
55     * Gets the height of a page.
56     *
57     * Returns:
58     * when succeed, it returns the height of a page. Otherwise it returns 0.
59     */
60    float getHeight() {
61       return HPDF_Page_GetHeight(this._page);
62    }
63 
64    /**
65     * Changes the height of a page
66     *
67     * Params:
68     *  value = the new page height. Valid value are between 3 and 14400
69     */
70    void setHeight(float value) {
71       HPDF_Page_SetHeight(this._page, value);
72    }
73 
74    /**
75     * Changes the size and direction of a page to a predefined size
76     *
77     * Params:
78     *  size = Specify a predefined page-size value. The following values are available:
79     *  $(UL
80     *    $(LI PageSizes.LETTER)
81     *    $(LI PageSizes.LEGAL)
82     *    $(LI PageSizes.A3)
83     *    $(LI PageSizes.A4)
84     *    $(LI PageSizes.A5)
85     *    $(LI PageSizes.B4)
86     *    $(LI PageSizes.B5)
87     *    $(LI PageSizes.EXECUTIVE)
88     *    $(LI PageSizes.US4x6)
89     *    $(LI PageSizes.US4x8)
90     *    $(LI PageSizes.US5x7)
91     *    $(LI PageSizes.COMM10)
92     * )
93     * direction = specify the direction of the page:
94     * $(UL
95     *   $(LI PageDirection.PORTRAIT)
96     *   $(LI PageDirection.LANDSCAPE)
97     * )
98     */
99    HPDF_STATUS setSize(PageSizes size, PageDirection direction) {
100       return HPDF_Page_SetSize(this._page, size, direction);
101    }
102 
103    /**
104     * Sets rotation angle of the page.
105     *
106     * Params:
107     *  angle = Specify the rotation angle of the page. It must be a multiple of 90 Degrees.
108     */
109    HPDF_STATUS setRotate(ushort angle) {
110       return HPDF_Page_SetRotate(this._page, angle);
111    }
112 
113    /**
114     * Creates a new `Destination` instance for the page
115     *
116     * Returns:
117     *  Returns an instance of a Destination object. If it failed, it returns null.
118     */
119    Destination createDestination() {
120       HPDF_Destination destination = HPDF_Page_CreateDestination(this._page);
121       return new Destination(destination);
122    }
123 
124    /**
125     * Creates a new Annotation instance for the page.
126     *
127     * Params:
128     *  rect = A Rectangle where the annotation is displayed.
129     *  text = The text to be displayed.
130     *  encoder = An Encoder instance which is used to encode the text. If it is null, PDFDocEncoding is used.
131     *
132     * Returns:
133     *  returns an instance of a Annotation object. If it failed, it returns null.
134     */
135    Annotation createTextAnnot(Rect rect, string text, Encoder encoder = null) {
136       HPDF_Encoder _encoder = null;
137       if (encoder !is null) {
138          _encoder = encoder.getHandle();
139       }
140 
141       HPDF_Annotation annotation = HPDF_Page_CreateTextAnnot(this._page, rect, text.toStringz(), _encoder);
142       return new Annotation(annotation);
143    }
144 
145    /**
146     * Creates a new link Annotation instance object for the page.
147     *
148     * Params:
149     *  rect = A rectangle of clickable area.
150     *  dst = A handle of destination object to jump to.
151     *
152     * Returns:
153     *  returns an instance of a Annotation object. If it failed, it returns null.
154     */
155    Annotation createLinkAnnot(Rect rect, Destination dst) {
156       HPDF_Annotation annotation = HPDF_Page_CreateLinkAnnot(this._page, rect, dst.destinationHandle);
157       return new Annotation(annotation);
158    }
159 
160    /**
161     * Creates a new web link Annotation instance object for the page.
162     *
163     * Params:
164     *  rect = A rectangle of clickable area.
165     *  uri = A handle of destination object to jump to.
166     *
167     * Returns:
168     *  returns an instance of a Annotation object. If it failed, it returns null.
169     */
170    Annotation createURILinkAnnot(Rect rect, string uri) {
171       HPDF_Annotation annotation = HPDF_Page_CreateURILinkAnnot(this._page, rect, uri.toStringz());
172       return new Annotation(annotation);
173    }
174 
175    /**
176     * Gets the width of the text in current fontsize, character spacing and word spacing.
177     *
178     * Params:
179     *  text = the text to get width.
180     *
181     * Returns:
182     *  When  succeed, it returns the width of the text in current fontsize,
183     *  character spacing and word spacing.
184     *  Otherwise it returns ZERO and error-handler is called.
185     */
186    float getTextWidth(string text) {
187       return HPDF_Page_TextWidth(this._page, text.toStringz());
188    }
189 
190    /**
191     * Calculates the byte length which can be included within the specified width.
192     *
193     * Params:
194     *  text = The text to get width.
195     *  width = The width of the area to put the text.
196     *  wordWrap = When there are three words of "ABCDE", "FGH", and "IJKL", and the substring until "J" can be included within the width,
197     *    if wordWrap parameter is false it returns 12, and if word_wrap parameter is true, it returns 10 (the end of the previous word).
198     *  realWidth = If this parameter is not null, the real widths of the text is set. An application can set it to null, if it is unnecessary.
199     *
200     * Returns:
201     *  When succeed it returns the byte length which can be included within the specified width in current fontsize, character spacing and word spacing.
202     *  Otherwise it returns ZERO and error-handler is called.
203     */
204    uint measureText(string text, float width, bool wordWrap, float* realWidth) {
205       return HPDF_Page_MeasureText(this._page, text.toStringz(), width, cast(uint)wordWrap, realWidth);
206    }
207 
208    /**
209     * Gets the current graphics mode.
210     *
211     * Returns:
212     *  when succeed, it returns the current graphics mode of the page. Otherwise
213     *  it returns GMode.unknown.
214     */
215    GMode getGMode() {
216       return to!GMode(HPDF_Page_GetGMode(this._page));
217    }
218 
219    /**
220     * Gets the current position for path painting.
221     *
222     * An application can invoke `currentPos` only when graphics mode is GMode.pathObject.
223     *
224     * Returns:
225     *  when succeed, it returns a Point struct indicating the current position for path painting of the page.
226     *  Otherwise it returns a Point struct of {0, 0}.
227     */
228    Point getCurrentPos() {
229       return HPDF_Page_GetCurrentPos(this._page);
230    }
231 
232    /**
233     * Gets the current position for text showing.
234     *
235     * An application can invoke getCurrentTextPos() only when graphics mode is
236     * GMode.textObject
237     *
238     * Returns:
239     *  when succeed, it returns a Point struct indicating the current position for text showing of the page.
240     *  Otherwise it returns a Point struct of {0, 0}.
241     */
242    Point getCurrentTextPos() {
243       return HPDF_Page_GetCurrentTextPos(this._page);
244    }
245 
246    /**
247     * Gets a Font instance of the page's current font.
248     *
249     * Returns:
250     *  when succeed, it returns a Font instance of the page's current font.
251     *  Otherwise it returns null.
252     */
253    Font getCurrentFont() {
254       HPDF_Font font = HPDF_Page_GetCurrentFont(this._page);
255       return new Font(font);
256    }
257 
258    /**
259     * Gets the size of the page's current font.
260     *
261     * Returns:
262     *  when succeed, it returns the size of the page's current font.
263     *  Otherwise it returns 0.
264     */
265    float getCurrentFontSize() {
266       return HPDF_Page_GetCurrentFontSize(this._page);
267    }
268 
269    /**
270     * Gets the current transformation matrix of the page.
271     *
272     * Returns:
273     *  when succeed, it returns a `TransMatrix` struct of current transformation matrix of the page
274     */
275    TransMatrix getTransMatrix() {
276       return HPDF_Page_GetTransMatrix(this._page);
277    }
278 
279    /**
280     * Gets the current line cap style of the page.
281     *
282     * Returns:
283     *  when getLineCap() succeed, it returns the current line cap style of the page.
284     *  Otherwise it returns HaruLineCap.buttEnd
285     */
286    HaruLineCap getLineCap() {
287       return HPDF_Page_GetLineCap(this._page);
288    }
289 
290    /**
291     * Sets the shape to be used at the ends of lines.
292     *
293     * Params:
294     *  lineCap = The line cap style.
295     */
296    void setLineCap(HaruLineCap lineCap) {
297       HPDF_Page_SetLineCap(this._page, lineCap);
298    }
299 
300    /**
301     * Gets the current line join style of the page.
302     *
303     * Returns:
304     *  when succeed, it returns the current line join style of the page.
305     *  Otherwise it returns HaruLineJoin.miterJoin
306     */
307    HaruLineJoin getLineJoin() {
308       return HPDF_Page_GetLineJoin(this._page);
309    }
310 
311    /**
312     * Sets the line join style in the page.
313     *
314     * Params:
315     *  join = The line join style.
316     */
317    void setLineJoin(HaruLineJoin join) {
318       HPDF_Page_SetLineJoin(this._page, join);
319    }
320 
321    unittest {
322       import harud.doc : Doc;
323 
324       Doc pdf = new Doc();
325       Page page = pdf.addPage();
326       writeln("lineJoin: ", page.getLineJoin);
327       page.setLineJoin(HaruLineJoin.roundJoin);
328       writeln("lineJoin: ", page.getLineJoin);
329    }
330 
331    /**
332     * Gets the current value of the page's miter limit.
333     *
334     * Returns:
335     *  when succeed, it returns the current value of the page's miter limit.
336     *  Otherwise it returns HPDF_DEF_MITERLIMIT.
337     */
338    float getMiterLimit() {
339       return HPDF_Page_GetMiterLimit(this._page);
340    }
341 
342    /**
343     * Sets the miter limit
344     */
345    void setMiterLimit(float miterLim) {
346       HPDF_Page_SetMiterLimit(this._page, miterLim);
347    }
348 
349    /**
350     * Gets the current pattern of the page.
351     *
352     * Returns:
353     *  when succeeds, it returns a DashMode struct of the current pattern of the page.
354     */
355    DashMode getDash() {
356       return HPDF_Page_GetDash(this._page);
357    }
358 
359    /**
360     * Sets the dash pattern for lines in the page.
361     *
362     *
363     * Params:
364     *  dashPattern = Pattern of dashes and gaps used to stroke paths. It's a
365     *  repeating sequence of dash length, gap length, dash length etc, which are cycled through when stroking the line.
366     *  phase = Initial offset in which the pattern begins (default is 0).
367     */
368    HPDF_STATUS setDash(ushort[] dashPattern, uint phase)
369    in {
370       assert(dashPattern !is null);
371       assert(dashPattern.length < 9, "numElem should be lesser than 9");
372    }
373    do {
374       return HPDF_Page_SetDash(this._page, dashPattern.ptr, to!(uint)(dashPattern.length), phase);
375    }
376 
377    /**
378     * Sets the dash pattern to solid line
379     */
380    HPDF_STATUS setSolid() {
381       enum ushort[] NN = [0, 0, 0, 0, 0, 0, 0, 0];
382       return HPDF_Page_SetDash(this._page, NN.ptr, 0, 0);
383    }
384 
385    /**
386     * Sets the dash pattern to dotted line
387     */
388    HPDF_STATUS setDotted() {
389       enum ushort[] DOTTED = [2];
390       return setDash(DOTTED, 0);
391    }
392 
393    /**
394     * Sets the dash pattern to dash-dash-dot line
395     */
396    HPDF_STATUS setDashDashDot() {
397       enum ushort[] DASH_DASH_DOT = [2, 2, 2, 2, 8, 2];
398       return setDash(DASH_DASH_DOT, 0);
399    }
400 
401    /**
402     * Sets the dash pattern to dash-dot line
403     */
404    HPDF_STATUS setDashDot() {
405       enum ushort[] DASH_DOT = [2, 2, 8, 2];
406       return setDash(DASH_DOT, 0);
407    }
408 
409    /**
410     * Sets the dash pattern to dashed line
411     */
412    HPDF_STATUS setDashed() {
413       enum ushort[] DASHED = [4];
414       return setDash(DASHED, 0);
415    }
416 
417    /**
418     * Gets the current value of the page's flatness.
419     *
420     * Returns:
421     *  when succeed, it returns the current value of the page's miter limit.
422     *  Otherwise it returns HPDF_DEF_FLATNESS.
423     */
424    float getFlat() {
425       return HPDF_Page_GetFlat(this._page);
426    }
427 
428    /**
429     * Gets the current value of the page's character spacing.
430     *
431     * Returns:
432     *  when succeed, it returns the current value of the page's character spacing.
433     *  Otherwise it returns 0.
434     */
435    float getCharSpace() {
436       return HPDF_Page_GetCharSpace(this._page);
437    }
438 
439    /**
440     * Sets the character spacing for text.
441     *
442     * Params:
443     *  value = The character spacing (initial value is 0).
444     *
445     * $(DL $(B Graphics Mode)
446     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.pathObject`)
447     * )
448     */
449    void setCharSpace(float value) {
450       HPDF_Page_SetCharSpace(this._page, value);
451    }
452 
453    /**
454     * Get the current value of the page's word spacing.
455     *
456     * Returns:
457     *  when succeed, it returns the current value of the page's word spacing.
458     *  Otherwise it returns 0.
459     */
460    float getWordSpace() {
461       return HPDF_Page_GetWordSpace(this._page);
462    }
463 
464    /**
465     * Sets the word spacing for text.
466     *
467     * Params:
468     * value = The value of word spacing (initial value is 0).
469     *
470     * $(DL $(B Graphics Mode)
471     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
472     * )
473     */
474    void setWordSpace(float value) {
475       HPDF_Page_SetWordSpace(this._page, value);
476    }
477 
478    /**
479     * Gets the current value of the page's horizontal scalling for text showing.
480     *
481     * Returns:
482     *  when succeed, it returns the current value of the page's horizontal scalling.
483     *  Otherwise it returns HPDF_DEF_HSCALING.
484     */
485    float getHorizontalScalling() {
486       return HPDF_Page_GetHorizontalScalling(this._page);
487    }
488 
489    /**
490     * Sets the horizontal scalling (scaling) for text showing.
491     *
492     * Params:
493     *  value = The value of horizontal scalling (scaling) (initially 100).
494     *
495     * $(DL $(B Graphics Mode)
496     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
497     * )
498     */
499    void setHorizontalScalling(float value) {
500       HPDF_Page_SetHorizontalScalling(this._page, value);
501    }
502 
503    /**
504     * Gets the current value of the page's line spacing.
505     *
506     * Returns:
507     *  when succeed, it returns the current value of the line spacing.
508     *  Otherwise it returns 0.
509     */
510    float getTextLeading() {
511       return HPDF_Page_GetTextLeading(this._page);
512    }
513 
514    /**
515     * Sets the text leading (line spacing) for text showing.
516     *
517     * Params:
518     *  value = The value of text leading (initial value is 0).
519     */
520    void setTextLeading(float value) {
521       HPDF_Page_SetTextLeading(this._page, value);
522    }
523 
524    /**
525     * Gets the current value of the page's text rendering mode.
526     *
527     * Returns:
528     *  when succeed, it returns the current value of the text rendering mode.
529     *  Otherwise it returns 0.
530     */
531    HaruTextRenderingMode getTextRenderingMode() {
532       return HPDF_Page_GetTextRenderingMode(this._page);
533    }
534 
535    /**
536     * Sets the text rendering mode. The initial value of text rendering mode is HPDF_FILL.
537     *
538     * Params:
539     *  mode = The text rendering mode (one of the following values)
540     *
541     * $(DL $(B Graphics Mode)
542     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
543     * )
544     */
545    void setTextRenderingMode(HaruTextRenderingMode mode) {
546       HPDF_Page_SetTextRenderingMode(this._page, mode);
547    }
548 
549    unittest {
550       import harud.doc : Doc;
551 
552       Doc pdf = new Doc();
553       Page page = pdf.addPage();
554       writeln(page.getTextRenderingMode());
555       page.setTextRenderingMode(HaruTextRenderingMode.stroke);
556       writeln(page.getTextRenderingMode);
557       assert(page.getTextRenderingMode == HaruTextRenderingMode.stroke);
558       page.setTextRenderingMode(HaruTextRenderingMode.clipping);
559       assert(page.getTextRenderingMode == HaruTextRenderingMode.clipping);
560       writeln(page.getTextRenderingMode);
561    }
562 
563    /**
564     * Gets the current value of the page's text rising.
565     *
566     * Returns:
567     *  when succeed, it returns the current value of the text rising.
568     *  Otherwise it returns 0.
569     */
570    float getTextRise() {
571       return HPDF_Page_GetTextRise(this._page);
572    }
573 
574    /**
575     * Moves the text position in vertical direction by the amount of value. Useful for making subscripts or superscripts.
576     *
577     * Params:
578     *  value = Text rise, in user space units.
579     *
580     * $(DL $(B Graphics Mode)
581     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
582     * )
583     */
584    void setTextRise(float value) {
585       HPDF_Page_SetTextRise(this._page, value);
586    }
587 
588    /**
589     * Gets the current value of the page's filling color.
590     *
591     * getRGBFill() is valid only when the page's filling color space is HPDF_CS_DEVICE_RGB.
592     *
593     * Returns:
594     *  when getRGBFill() succeed, it returns the current value of the page's filling color. Otherwise it returns {0, 0, 0}.
595     */
596    HaruRGBColor getRGBFill() {
597       return HPDF_Page_GetRGBFill(this._page);
598    }
599 
600    /**
601     * Sets the filling color.
602     *
603     * Params:
604     *  r = The level of red color element. They must be between 0 and 1. (See `Colors`)
605     *  g = The level of green color element. They must be between 0 and 1. (See "Colors")
606     *  b = The level of blue color element. They must be between 0 and 1. (See "Colors")
607     *
608     * $(DL $(B Graphics Mode)
609     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
610     * )
611     */
612    HPDF_STATUS setRGBFill(float r, float g, float b) {
613       return HPDF_Page_SetRGBFill(this._page, r, g, b);
614    }
615 
616    /**
617     * Gets the current value of the page's stroking color.
618     *
619     * getRGBStroke() is valid only when the page's stroking color space is HPDF_CS_DEVICE_RGB.
620     *
621     * Returns:
622     *  when getRGBStroke() succeed, it returns the current value of the page's stroking color.
623     *  Otherwise it returns {0, 0, 0}.
624     */
625    HaruRGBColor getRGBStroke() {
626       return HPDF_Page_GetRGBStroke(this._page);
627    }
628 
629    /**
630     * Sets the stroking color.
631     *
632     * Params:
633     *  r = The level of red color element. They must be between 0 and 1. (See "Colors")
634     *  g = The level of green color element. They must be between 0 and 1. (See "Colors")
635     *  b = The level of blue color element. They must be between 0 and 1. (See "Colors")
636     *
637     * $(DL $(B Graphics Mode)
638     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
639     * )
640     */
641    HPDF_STATUS setRGBStroke(float r, float g, float b) {
642       return HPDF_Page_SetRGBStroke(this._page, r, g, b);
643    }
644 
645    /**
646     * Gets the current value of the page's filling color.
647     *
648     * getCMYKFill() is valid only when the page's filling color space is HPDF_CS_DEVICE_CMYK.
649     *
650     * Returns:
651     *  when getCMYKFill() succeed, it returns the current value of the page's filling color.
652     *  Otherwise it returns {0, 0, 0, 0}.
653     */
654    HaruCMYKColor getCMYKFill() {
655       return HPDF_Page_GetCMYKFill(this._page);
656    }
657 
658    /**
659     * Gets the current value of the page's stroking color.
660     *
661     * getCMYKStroke() is valid only when the page's stroking color space is HPDF_CS_DEVICE_CMYK.
662     *
663     * Returns:
664     *  when getCMYKStroke() succeed, it returns the current value of the page's stroking color.
665     *  Otherwise it returns {0, 0, 0, 0}.
666     */
667    HaruCMYKColor getCMYKStroke() {
668       return HPDF_Page_GetCMYKStroke(this._page);
669    }
670 
671    /**
672     * Gets the current value of the page's filling color.
673     *
674     * grayFill() is valid only when the page's stroking color space is HPDF_CS_DEVICE_GRAY.
675     *
676     * Returns:
677     *  when getGrayFill() succeed, it returns the current value of the page's filling color.
678     *  Otherwise it returns 0.
679     */
680    float getGrayFill() {
681       return HPDF_Page_GetGrayFill(this._page);
682    }
683 
684    /**
685     * Sets the filling color.
686     *
687     * Params:
688     *  gray = The value of the gray level between 0 and 1.
689     *
690     * $(DL $(B Graphics Mode)
691     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
692     * )
693     */
694    void setGrayFill(float gray) {
695       HPDF_Page_SetGrayFill(this._page, gray);
696    }
697 
698    /**
699     * Gets the current value of the page's stroking color.
700     *
701     * grayStroke() is valid only when the page's stroking color space is HPDF_CS_DEVICE_GRAY.
702     *
703     * Returns:
704     *  when succeed, it returns the current value of the page's stroking color.
705     *  Otherwise it returns 0.
706     */
707    float getGrayStroke() {
708       return HPDF_Page_GetGrayStroke(this._page);
709    }
710 
711    /**
712     * Sets the stroking color.
713     *
714     * Params:
715     *  gray = The value of the gray level between 0 and 1.
716     *
717     * $(DL $(B Graphics Mode)
718     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
719     * )
720     */
721    void setGrayStroke(float gray) {
722       HPDF_Page_SetGrayStroke(this._page, gray);
723    }
724 
725    /**
726     * Gets the current value of the page's stroking color space.
727     *
728     * Returns:
729     *  when getStrokingColorSpace() succeed, it returns the current value of the page's stroking color space. Otherwise it returns HPDF_CS_EOF.
730     */
731    ColorSpace getStrokingColorSpace() {
732       return HPDF_Page_GetStrokingColorSpace(this._page);
733    }
734 
735    /**
736     * Gets the current value of the page's stroking color space.
737     *
738     * Returns:
739     *  when getFillingColorSpace() succeed, it returns the current value of the page's stroking color space.
740     *  Otherwise it returns HPDF_CS_EOF.
741     */
742    ColorSpace getFillingColorSpace() {
743       return HPDF_Page_GetFillingColorSpace(this._page);
744    }
745 
746    /**
747     * Gets the current text transformation matrix of the page.
748     *
749     * Returns:
750     *  when getTextMatrix() succeed, it returns a TransMatrix struct of current text transformation matrix of the page.
751     */
752    TransMatrix getTextMatrix() {
753       return HPDF_Page_GetTextMatrix(this._page);
754    }
755 
756    /**
757     * Gets the number of the page's graphics state stack.
758     *
759     * Returns:
760     *  when getGStateDepth() succeed, it returns the number of the page's graphics state stack.
761     *  Otherwise it returns 0.
762     */
763    uint getGStateDepth() {
764       return HPDF_Page_GetGStateDepth(this._page);
765    }
766 
767    /**
768     * Configures the setting for slide transition of the page.
769     *
770     * Params:
771     *  type = The transition style. The following values are available.
772     *  $(UL
773     *     $(LI HaruTransitionStyle.WIPE_RIGHT)
774     *     $(LI HaruTransitionStyle.WIPE_UP)
775     *     $(LI HaruTransitionStyle.WIPE_LEFT)
776     *     $(LI HaruTransitionStyle.WIPE_DOWN)
777     *     $(LI HaruTransitionStyle.BARN_DOORS_HORIZONTAL_OUT)
778     *     $(LI HaruTransitionStyle.BARN_DOORS_HORIZONTAL_IN)
779     *     $(LI HaruTransitionStyle.BARN_DOORS_VERTICAL_OUT)
780     *     $(LI HaruTransitionStyle.BARN_DOORS_VERTICAL_IN)
781     *     $(LI HaruTransitionStyle.BOX_OUT)
782     *     $(LI HaruTransitionStyle.BOX_IN)
783     *     $(LI HaruTransitionStyle.BLINDS_HORIZONTAL)
784     *     $(LI HaruTransitionStyle.BLINDS_VERTICAL)
785     *     $(LI HaruTransitionStyle.DISSOLVE)
786     *     $(LI HaruTransitionStyle.GLITTER_RIGHT)
787     *     $(LI HaruTransitionStyle.GLITTER_DOWN)
788     *     $(LI HaruTransitionStyle.GLITTER_TOP_LEFT_TO_BOTTOM_RIGHT)
789     *     $(LI HaruTransitionStyle.REPLACE)
790     * )
791     * disp_time = The display duration of the page. (in seconds)
792     * trans_time = The duration of the transition effect. Default value is 1(second).
793     *
794     */
795    HPDF_STATUS setSlideShow(HaruTransitionStyle type, float disp_time, float trans_time) {
796       return HPDF_Page_SetSlideShow(this._page, type, disp_time, trans_time);
797    }
798 
799    /**
800     * Appends a circle arc to the current path.
801     *
802     *
803     * Params:
804     *  x = X coordinate of  center point of the circle.
805     *  y = Y coordinate of center point of the circle.
806     *  ray = The radius of the circle.
807     *  ang1 = The angle of the begining of the arc.
808     *  ang2 = The angle of the end of the arc. It must be greater than ang1.
809     *
810     * $(DL $(B Graphics Mode)
811     *   $(DT Before) $(DD `GMode.pageDescription` or `GMode.pathObject`)
812     *   $(DT After) $(DD `GMode.pathObject`)
813     * )
814     */
815    HPDF_STATUS arc(float x, float y, float ray, float ang1, float ang2) {
816       return HPDF_Page_Arc(this._page, x, y, ray, ang1, ang2);
817    }
818 
819    /**
820     * Begins a text object and sets the text position to (0, 0).
821     *
822     * $(DL $(B Graphics Mode)
823     *   $(DT Before) $(DD `GMode.pageDescription`)
824     *   $(DT After) $(DD `GMode.textObject`)
825     * )
826     */
827    HPDF_STATUS beginText() {
828       return HPDF_Page_BeginText(this._page);
829    }
830 
831    /**
832     * Appends a circle to the current path.
833     *
834     * Params:
835     *  x = X coordinate of  center point of the circle.
836     *  y = Y coordinate of center point of the circle.
837     *  ray = The radius of the circle.
838     *
839     * $(DL $(B Graphics Mode)
840     *   $(DT Before) $(DD `GMode.pageDescription` or `GMode.pathObject`)
841     *   $(DT After) $(DD `GMode.pathObject`)
842     * )
843     */
844    HPDF_STATUS circle(float x, float y, float ray) {
845       return HPDF_Page_Circle(this._page, x, y, ray);
846    }
847 
848    /**
849     * Modifies the current clipping path by intersecting it with the current path using the nonzero winding number rule.
850     *
851     * The clipping path is only modified after the succeeding painting operator.
852     * To avoid painting the current path, use the function HPDF_Page_EndPath().
853     *
854     * Following painting operations will only affect the regions of the page contained by the clipping path.
855     * Initially, the clipping path includes the entire page.
856     * There is no way to enlarge the current clipping path, or to replace the clipping path with a new one.
857     * The functions HPDF_Page_GSave() and HPDF_Page_GRestore() may be used to save and restore the current graphics state, including the clipping path.
858     *
859     * $(DL $(B Graphics Mode)
860     *   $(DT Before and after) $(DD `GMode.pathObject`)
861     * )
862     *
863     * Returns:
864     *  HPDF_OK on success. Otherwise, returns error code and error-handler is invoked.
865     */
866    HPDF_STATUS clip() {
867       return HPDF_Page_Clip(this._page);
868    }
869 
870    /**
871     * Appends a straight line from the current point to the start point of sub path. The current point is moved to the start point of sub path
872     *
873     * $(DL $(B Graphics Mode)
874     *   $(DT Before and after) $(DD `GMode.pathObject`)
875     * )
876     */
877    HPDF_STATUS closePath() {
878       return HPDF_Page_ClosePath(this._page);
879    }
880 
881    /**
882     * Closes the current path. Then, it paints the path.
883     *
884     * $(DL $(B Graphics Mode)
885     *   $(DT Before) $(DD `GMode.pathObject`)
886     *   $(DT After) $(DD `GMode.pageDescription`)
887     * )
888     */
889    HPDF_STATUS closePathStroke() {
890       return HPDF_Page_ClosePathStroke(this._page);
891    }
892 
893    /**
894     * Closes the current path, fills the current path using the nonzero winding number rule, then paints the path.
895     *
896     * $(DL $(B Graphics Mode)
897     *   $(DT Before) $(DD `GMode.pathObject`)
898     *   $(DT After) $(DD `GMode.pageDescription`)
899     * )
900     */
901    HPDF_STATUS closePathFillStroke() {
902       return HPDF_Page_ClosePathFillStroke(this._page);
903    }
904 
905    /**
906     * Concatenates the page's current transformation matrix and specified matrix.
907     *
908     * Params:
909     *  a = The transformation matrix to concatenate.
910     *  b = The transformation matrix to concatenate.
911     *  c = The transformation matrix to concatenate.
912     *  d = The transformation matrix to concatenate.
913     *  x = The transformation matrix to concatenate.
914     *  y = The transformation matrix to concatenate.
915     */
916    HPDF_STATUS concat(float a, float b, float c, float d, float x, float y) {
917       return HPDF_Page_Concat(this._page, a, b, c, d, x, y);
918    }
919 
920    /**
921     * Appends a Bézier curve to the current path using the control points (x1, y1) and (x2, y2) and (x3, y3), then sets the current point to (x3, y3).
922     *
923     * Params:
924     *  x1 = The control points for a Bézier curve.
925     *  y1 = The control points for a Bézier curve.
926     *  x2 = The control points for a Bézier curve.
927     *  y2 = The control points for a Bézier curve.
928     *  x3 = The control points for a Bézier curve.
929     *  y3 = The control points for a Bézier curve.
930     *
931     * $(DL $(B Graphics Mode)
932     *   $(DT Before and after) $(DD `GMode.pathObject`)
933     * )
934     */
935    HPDF_STATUS curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
936       return HPDF_Page_CurveTo(this._page, x1, y1, x2, y2, x3, y3);
937    }
938 
939    /**
940     * Appends a Bézier curve to the current path using the current point and (x2, y2) and (x3, y3) as control points. Then, the current point is set to (x3, y3).
941     *
942     * Params:
943     *  x2= Control points for Bézier curve, along with current point.
944     *  y2= Control points for Bézier curve, along with current point.
945     *  x3= Control points for Bézier curve, along with current point.
946     *  y3 = Control points for Bézier curve, along with current point.
947     *
948     * $(DL $(B Graphics Mode)
949     *   $(DT Before and after) $(DD `GMode.pathObject`)
950     * )
951     */
952    HPDF_STATUS curveTo2(float x2, float y2, float x3, float y3) {
953       return HPDF_Page_CurveTo2(this._page, x2, y2, x3, y3);
954    }
955 
956    /**
957     * Appends a Bézier curve to the current path using two spesified points.
958     *
959     * The point (x1, y1) and the point (x3, y3) are used as the control points for a Bézier curve and current point is moved to the point (x3, y3)
960     *
961     * Params:
962     *  x1= The control points for a Bézier curve.
963     *  y1= The control points for a Bézier curve.
964     *  x3= The control points for a Bézier curve.
965     *  y3= The control points for a Bézier curve.
966     *
967     * $(DL $(B Graphics Mode)
968     *   $(DT Before and after) $(DD `GMode.pathObject`)
969     * )
970     */
971    HPDF_STATUS curveTo3(float x1, float y1, float x3, float y3) {
972       return HPDF_Page_CurveTo3(this._page, x1, y1, x3, y3);
973    }
974 
975    /**
976     * Shows an image in one operation.
977     *
978     * Params:
979     *  image = The handle of an image object.
980     *  x = The lower-left point of the region where image is displayed.
981     *  y = The lower-left point of the region where image is displayed.
982     *  width = The width of the region where image is displayed.
983     *  height = The width of the region where image is displayed.
984     *
985     * $(DL $(B Graphics Mode)
986     *   $(DT Before and after) $(DD `GMode.pageDescription`)
987     * )
988     */
989    HPDF_STATUS drawImage(Image image, float x, float y, float width, float height) {
990       return HPDF_Page_DrawImage(this._page, image.getHandle(), x, y, width, height);
991    }
992 
993    /**
994     * Appends an ellipse to the current path.
995     *
996     * Params:
997     *  x = The center point of the ellipse.
998     *  y = The center point of the ellipse.
999     *  xray = Horizontal and vertical radii of the ellipse.
1000     *  yray = Horizontal and vertical radii of the ellipse.
1001     *
1002     * $(DL $(B Graphics Mode)
1003     *   $(DT Before and after) $(DD `GMode.pathObject`)
1004     * )
1005     */
1006    HPDF_STATUS ellipse(float x, float y, float xray, float yray) {
1007       return HPDF_Page_Ellipse(this._page, x, y, xray, yray);
1008    }
1009 
1010    /**
1011     * Ends the path object without filling or painting.
1012     *
1013     * $(DL $(B Graphics Mode)
1014     *   $(DT Before) $(DD `GMode.pathObject`)
1015     *   $(DT After) $(DD `GMode.pageDescription`)
1016     * )
1017     */
1018    HPDF_STATUS endPath() {
1019       return HPDF_Page_EndPath(this._page);
1020    }
1021 
1022    /**
1023     * Ends a text object.
1024     *
1025     * $(DL $(B Graphics Mode)
1026     *   $(DT Before) $(DD `GMode.textObject`)
1027     *   $(DT After) $(DD `GMode.pageDescription`)
1028     * )
1029     */
1030    HPDF_STATUS endText() {
1031       return HPDF_Page_EndText(this._page);
1032    }
1033 
1034    HPDF_STATUS eoclip() {
1035       return HPDF_Page_Eoclip(this._page);
1036    }
1037 
1038    /**
1039     * Fills the current path using the even-odd rule.
1040     *
1041     * $(DL $(B Graphics Mode)
1042     *   $(DT Before) $(DD `GMode.textObject`)
1043     *   $(DT After) $(DD `GMode.pageDescription`)
1044     * )
1045     */
1046    HPDF_STATUS eofill() {
1047       return HPDF_Page_Eofill(this._page);
1048    }
1049 
1050    /**
1051     * Fills the current path using the even-odd rule, then paints the path.
1052     *
1053     * $(DL $(B Graphics Mode)
1054     *   $(DT Before) $(DD `GMode.pathObject`)
1055     *   $(DT After) $(DD `GMode.pageDescription`)
1056     * )
1057     */
1058    HPDF_STATUS eofillStroke() {
1059       return HPDF_Page_EofillStroke(this._page);
1060    }
1061 
1062    HPDF_STATUS executeXObject(Image image) {
1063       return HPDF_Page_ExecuteXObject(this._page, image.getHandle());
1064    }
1065 
1066    /**
1067     * Fills the current path using the nonzero winding number rule.
1068     *
1069     * $(DL $(B Graphics Mode)
1070     *   $(DT Before) $(DD `GMode.pathObject`)
1071     *   $(DT After) $(DD `GMode.pageDescription`)
1072     * )
1073     */
1074    HPDF_STATUS fill() {
1075       return HPDF_Page_Fill(this._page);
1076    }
1077 
1078    /**
1079     * Fills the current path using the nonzero winding number rule, then paints the path.
1080     *
1081     * $(DL $(B Graphics Mode)
1082     *   $(DT Before) $(DD `GMode.pathObject`)
1083     *   $(DT After) $(DD `GMode.pageDescription`)
1084     * )
1085     */
1086    HPDF_STATUS fillStroke() {
1087       return HPDF_Page_FillStroke(this._page);
1088    }
1089 
1090    /**
1091     * Restore (pop) the graphics state which is saved by `graphicSave`.
1092     *
1093     * $(DL $(B Graphics Mode)
1094     *   $(DT Before and after) $(DD `GMode.pageDescription`)
1095     * )
1096     */
1097    HPDF_STATUS graphicRestore() {
1098       return HPDF_Page_GRestore(this._page);
1099    }
1100 
1101    /**
1102     * Saves (push) the page's current graphics parameter to the stack.
1103     * An application can invoke gSave() up to 28 (???) and can restore the saved parameter by invoking gRestore().
1104     *
1105     * The parameters that are saved by `graphicSave` are:
1106     * $(UL
1107     *   $(LI Character Spacing)
1108     *   $(LI Dash Mode)
1109     *   $(LI Filling Color)
1110     *   $(LI Flatness)
1111     *   $(LI Font)
1112     *   $(LI Font Size)
1113     *   $(LI Horizontal Scalling)
1114     *   $(LI Line Width)
1115     *   $(LI Line Cap Style)
1116     *   $(LI Line Join Style)
1117     *   $(LI Miter Limit)
1118     *   $(LI Rendering Mode)
1119     *   $(LI Stroking Color)
1120     *   $(LI Text Leading)
1121     *   $(LI Text Rise)
1122     *   $(LI Transformation Matrix)
1123     *   $(LI Word Spacing)
1124     * )
1125     *
1126     * $(DL $(B Graphics Mode)
1127     *   $(DT Before and after) $(DD `GMode.pageDescription`)
1128     * )
1129     */
1130    HPDF_STATUS graphicSave() {
1131       return HPDF_Page_GSave(this._page);
1132    }
1133 
1134    /**
1135     * Appends a path from the current point to the specified point.
1136     *
1137     * Params:
1138     *  x = The end point of the path
1139     *  y = The end point of the path
1140     *
1141     * $(DL $(B Graphics Mode)
1142     *   $(DT Before and after) $(DD `GMode.pathObject`)
1143     * )
1144     */
1145    HPDF_STATUS lineTo(float x, float y) {
1146       return HPDF_Page_LineTo(this._page, x, y);
1147    }
1148 
1149    /**
1150     * Changes the current text position, using the specified offset values. If the current text position is (x1, y1), the new text position will be (x1 + x, y1 + y).
1151     *
1152     * Params:
1153     *  x = The offset to new text position.
1154     *  y = The offset to new text position.
1155     *  setLeading = ?
1156     *
1157     * $(DL $(B Graphics Mode)
1158     *   $(DT Before and after) $(DD `GMode.textObject`)
1159     * )
1160     */
1161    HPDF_STATUS moveTextPos(float x, float y, bool setLeading = false) {
1162       if (setLeading) {
1163          return HPDF_Page_MoveTextPos2(this._page, x, y);
1164       }
1165 
1166       return HPDF_Page_MoveTextPos(this._page, x, y);
1167    }
1168 
1169    /**
1170     * Starts a new subpath and move the current point for drawing path,
1171     * moveTo() sets the start point for the path to the point (x, y).
1172     *
1173     * Params:
1174     *  x = The x coordinate of start point for drawing path
1175     *  y = The y coordinate of start point for drawing path
1176     *
1177     * $(DL $(B Graphics Mode)
1178     *   $(DT Before) $(DD `GMode.pageDescription` or `GMode.pathObject`)
1179     *   $(DT After) $(DD `GMode.pathObject`)
1180     * )
1181     */
1182    HPDF_STATUS moveTo(float x, float y) {
1183       return HPDF_Page_MoveTo(this._page, x, y);
1184    }
1185 
1186    /**
1187     * Moves to the next line.
1188     */
1189    HPDF_STATUS moveToNextLine() {
1190       return HPDF_Page_MoveToNextLine(this._page);
1191    }
1192 
1193    /**
1194     * Appends a rectangle to the current path.
1195     *
1196     * $(DL $(B Graphics Mode)
1197     *   $(DT Before) $(DD GMode.pageDescription` or `GMode.pathObject`)
1198     *   $(DT After) $(DD `GMode.pathObject`)
1199     * )
1200     *
1201     * Params:
1202     *  x = The x coordinate of lower-left point of the rectangle.
1203     *  y = The y coordinate of lower-left point of the rectangle.
1204     *  width = The width of the rectangle.
1205     *  height = The height of the rectangle.
1206     */
1207    HPDF_STATUS rectangle(float x, float y, float width, float height) {
1208       return HPDF_Page_Rectangle(this._page, x, y, width, height);
1209    }
1210 
1211    /**
1212     * Sets the filling color.
1213     *
1214     * See $(LINK2 https://en.wikipedia.org/wiki/CMYK_color_model, CMYK color model)
1215     *
1216     * Params:
1217     *  c = The level of cyan color element. They must be between 0 and 1.
1218     *  m = The level of magenta color element. They must be between 0 and 1.
1219     *  y = The level of yellow color element. They must be between 0 and 1.
1220     *  k = The level of key  element. They must be between 0 and 1.
1221     *
1222     * $(DL $(B Graphics Mode)
1223     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
1224     * )
1225     */
1226    HPDF_STATUS setCMYKFill(float c, float m, float y, float k) {
1227       return HPDF_Page_SetCMYKFill(this._page, c, m, y, k);
1228    }
1229 
1230    /**
1231     * Sets the stroking color.
1232     *
1233     * $(DL $(B Graphics Mode)
1234     *   $(DT Before and after) $(DD `GMode.pageDescription` or `GMode.textObject`)
1235     * )
1236     *
1237     * Params:
1238     *  c = The level of each color element. They must be between 0 and 1.
1239     *  m = The level of each color element. They must be between 0 and 1.
1240     *  y = The level of each color element. They must be between 0 and 1.
1241     *  k = The level of each color element. They must be between 0 and 1.
1242     */
1243    HPDF_STATUS setCMYKStroke(float c, float m, float y, float k) {
1244       return HPDF_Page_SetCMYKStroke(this._page, c, m, y, k);
1245    }
1246 
1247    /**
1248     * Applyies the graphics state to the page.
1249     *
1250     * Params:
1251     *  ext_gstate = The handle of an extended graphics state object.
1252     *
1253     * $(DL $(B Graphics Mode)
1254     *   $(DT Before and after) $(DD GMode.pageDescription)
1255     * )
1256     */
1257    HPDF_STATUS setExtGState(HPDF_ExtGState ext_gstate) {
1258       return HPDF_Page_SetExtGState(this._page, ext_gstate);
1259    }
1260 
1261    /**
1262     * Sets the type of font and size leading.
1263     *
1264     * Params:
1265     *  font = The handle of a font object.
1266     *  size = The size of a font.
1267     *
1268     * $(DL $(B Graphics Mode)
1269     *   $(DT Before and after) $(DD GMode.pageDescription or GMode.textObject)
1270     * )
1271     */
1272    HPDF_STATUS setFontAndSize(Font font, float size) {
1273       return HPDF_Page_SetFontAndSize(this._page, font.getHandle(), size);
1274    }
1275 
1276    /**
1277     * Gets the current line width of the page.
1278     *
1279     * Returns:
1280     * when getLineWidth() succeed, it returns the current line width for path painting of the page.
1281     * Otherwise it returns HPDF_DEF_LINEWIDTH.
1282     */
1283    float getLineWidth() {
1284       return HPDF_Page_GetLineWidth(this._page);
1285    }
1286 
1287    /**
1288     * Sets the width of the line used to stroke a path.
1289     *
1290     * Params:
1291     *  lineWidth = The line width to use (default is 1).
1292     *
1293     * $(DL $(B Graphics Mode)
1294     *   $(DT Before and after) $(DD GMode.pageDescription or GMode.textObject)
1295     * )
1296     */
1297    void setLineWidth(float lineWidth) {
1298       HPDF_Page_SetLineWidth(this._page, lineWidth);
1299    }
1300 
1301    /**
1302     * Sets the text matrix
1303     */
1304    HPDF_STATUS setTextMatrix(float a, float b, float c, float d, float x, float y) {
1305       return HPDF_Page_SetTextMatrix(this._page, a, b, c, d, x, y);
1306    }
1307 
1308    /**
1309     * Prints the text at the current position on the page.
1310     *
1311     * Params:
1312     *  text = The text to print.
1313     *
1314     * Returns: Returns HPDF_OK on success. Otherwise, returns error code and error-handler is invoked.
1315     *
1316     * $(DL $(B Graphics Mode)
1317     *   $(DT Before and after) $(DD GMode.textObject)
1318     * )
1319     */
1320    HPDF_STATUS showText(string text) {
1321       return HPDF_Page_ShowText(this._page, text.toStringz());
1322    }
1323 
1324    /**
1325     * Moves the current text position to the start of the next line,
1326     * then prints the text at the current position on the page.
1327     *
1328     * Params:
1329     *  text = The text to print.
1330     *  wordSpace = ?
1331     *  charSpace = ?
1332     *
1333     * $(DL $(B Graphics Mode)
1334     *   $(DT Before and after) $(DD GMode.textObject)
1335     * )
1336     */
1337    HPDF_STATUS showTextNextLine(string text, float wordSpace = 0.0, float charSpace = 0.0) {
1338       return HPDF_Page_ShowTextNextLine(this._page, text.toStringz());
1339    }
1340 
1341    /**
1342     * Paints the current path.
1343     *
1344     * $(DL $(B Graphics Mode)
1345     *   $(DT Before) $(DD `GMode.pathObject`)
1346     *   $(DT After) $(DD `GMode.pageDescription`)
1347     * )
1348     */
1349    HPDF_STATUS stroke() {
1350       return HPDF_Page_Stroke(this._page);
1351    }
1352 
1353    /**
1354     * Prints the text on the specified position.
1355     *
1356     * Params:
1357     *  xpos = The x position where the text is displayed.
1358     *  ypos = The y position where the text is displayed.
1359     *  text = The text to show.
1360     *
1361     * Returns:
1362     *  Zero when succeed, otherwise it returns error code.
1363     *
1364     * $(DL $(B Graphics Mode)
1365     *   $(DT Before and after) $(DD GMode.textObject)
1366     * )
1367     */
1368    HPDF_STATUS textOut(float xpos, float ypos, string text)
1369    in {
1370       assert(text.length > 0);
1371    }
1372    do {
1373       return HPDF_Page_TextOut(this._page, xpos, ypos, text.toStringz());
1374    }
1375 
1376    /**
1377     * Prints the text inside the specified region.
1378     *
1379     * $(DL $(B Graphics Mode)
1380     *   $(DT Before and after) $(DD GMode.textObject)
1381     * )
1382     *
1383     *
1384     * Params:
1385     *  left = Coordinates of corners of the region to output text.
1386     *  top = Coordinates of corners of the region to output text.
1387     *  right = Coordinates of corners of the region to output text.
1388     *  bottom = Coordinates of corners of the region to output text.
1389     *  text = The text to show.
1390     *  alignment = The alignment of the text.
1391     *  len = If not NULL, the number of characters printed in the area is returned.
1392     *
1393     *
1394     */
1395    HPDF_STATUS textRect(float left, float top, float right, float bottom, string text, HaruTextAlignment alignment, uint* len) {
1396       return HPDF_Page_TextRect(this._page, left, top, right, bottom, text.toStringz(), alignment, len);
1397    }
1398 
1399    HPDF_HANDLE getHandle() {
1400       return _page;
1401    }
1402 }