PDF SDK Documentation

Comprehensive Guide for Developers: Features, Integration, and API Reference

Loading...
Searching...
No Matches
graphics.h
1// Copyright (c) 2009-2025 Avanquest Software. All rights reserved.
2
3#ifndef PDFSDK_CXX_GRAPHICS_H_INCLUDED_
4#define PDFSDK_CXX_GRAPHICS_H_INCLUDED_
5
6#include <filesystem>
7#include <functional>
8#include <optional>
9#include <string>
10
11#include <pdfsdk/cxx/exception.h>
12#include <pdfsdk/cxx/math.h>
13#include <pdfsdk/graphics.h>
14
15#include "wrapper_base.h"
16
17namespace PDF {
18namespace Graphics {
19
24class Palette : public detail::RefCountedHandle<GXPalette> {
25public:
26 static Palette New(const GXColorValue* colors, size_t num_colors) {
27 Palette palette;
28 auto ec = GXCreatePalette(colors, num_colors, &palette);
29 PDF_CHECK_SUCCESS(ec, "Failed to create a palette");
30 return palette;
31 }
32
33 const GXColorValue* GetColorsPtr() const {
34 const GXColorValue* colors = nullptr;
35 auto ec = GXPaletteGetColors(m_handle, &colors);
36 PDF_CHECK_SUCCESS(ec, "Failed to get palette colors");
37 return colors;
38 }
39
40 size_t GetNumColors() const {
41 size_t num_colors = 0;
42 auto ec = GXPaletteGetNumColors(m_handle, &num_colors);
43 PDF_CHECK_SUCCESS(ec, "Failed to get the number of palette colors");
44 return num_colors;
45 }
46
47 GXColorValue GetColor(size_t index) const {
48 GXColorValue color = 0;
49 auto ec = GXPaletteGetColor(m_handle, index, &color);
50 PDF_CHECK_SUCCESS(ec, "Failed to get palette color by index");
51 return color;
52 }
53
54 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(Palette, GXPalette)
55};
56
61class Bitmap : public detail::RefCountedHandle<GXBitmap> {
62public:
63 static Bitmap New(const SizeI& size, GXPixelFormat format, float dpiX = 96, float dpiY = 96) {
64 Bitmap bitmap;
65 GXBitmapAttrs attrs = {size, format, dpiX, dpiY};
66 auto ec = GXCreateBitmap(&attrs, &bitmap);
67 PDF_CHECK_SUCCESS(ec, "Failed to create a bitmap");
68 return bitmap;
69 }
70
71 static Bitmap LoadFromFile(const std::filesystem::path& path, uint32_t frame_index = 0, uint32_t* ptotal_frames = nullptr) {
72 Bitmap bitmap;
73 auto path_string = path.wstring();
74 auto ec = GXCreateBitmapFromFileFrame(path_string.c_str(), frame_index, ptotal_frames, &bitmap);
75 PDF_CHECK_SUCCESS(ec, "Failed to load a bitmap from file");
76 return bitmap;
77 }
78
79 static Bitmap LoadFromMemory(const void* data, size_t size, uint32_t frame_index = 0, uint32_t* ptotal_frames = nullptr) {
80 Bitmap bitmap;
81 auto ec = GXCreateBitmapFromMemoryFrame(data, size, frame_index, ptotal_frames, &bitmap);
82 PDF_CHECK_SUCCESS(ec, "Failed to load a bitmap from memory");
83 return bitmap;
84 }
85
86#if defined(WIN32)
87 static Bitmap NewFromHBITMAP(void* hbitmap) {
88 Bitmap bitmap;
89 auto ec = GXCreateBitmapFromHBITMAP(hbitmap, &bitmap);
90 PDF_CHECK_SUCCESS(ec, "Failed to create a bitmap from HBITMAP");
91 return bitmap;
92 }
93#endif
94
95 void SaveToFile(const std::filesystem::path& path) const {
96 auto path_string = path.wstring();
97 auto ec = GXBitmapSaveToFile(m_handle, path_string.c_str());
98 PDF_CHECK_SUCCESS(ec, "Failed to save the bitmap to file");
99 }
100
101#if defined(WIN32)
102 void* SaveToHBITMAP() const {
103 void* hbitmap = NULL;
104 auto ec = GXBitmapSaveToHBITMAP(m_handle, &hbitmap);
105 PDF_CHECK_SUCCESS(ec, "Failed to save the bitmap to HBITMAP");
106 return hbitmap;
107 }
108#endif
109
110 GXPixelFormat GetPixelFormat() const {
112 auto ec = GXBitmapGetPixelFormat(m_handle, &format);
113 PDF_CHECK_SUCCESS(ec, "Failed to get the bitmap pixel format");
114 return format;
115 }
116
117 SizeI GetSize() const {
118 SizeI size;
119 auto ec = GXBitmapGetSize(m_handle, &size);
120 PDF_CHECK_SUCCESS(ec, "Failed to get the bitmap size");
121 return size;
122 }
123
124 float GetDpiX() const {
125 float dpix = 0.f;
126 auto ec = GXBitmapGetDpiX(m_handle, &dpix);
127 PDF_CHECK_SUCCESS(ec, "Failed to get the bitmap horz dpi");
128 return dpix;
129 }
130
131 float GetDpiY() const {
132 float dpiy = 0.f;
133 auto ec = GXBitmapGetDpiY(m_handle, &dpiy);
134 PDF_CHECK_SUCCESS(ec, "Failed to get the bitmap vert dpi");
135 return dpiy;
136 }
137
138 int GetBitsPerPixel() const {
139 GXPixelFormat format = GetPixelFormat();
140
141 switch (format) {
143 return 24;
144
148 return 32;
149
150 case kGXPixelFormatA8:
151 case kGXPixelFormatP8:
152 case kGXPixelFormatL8:
153 return 8;
154
155 case kGXPixelFormatA1:
156 case kGXPixelFormatP1:
157 case kGXPixelFormatL1:
158 return 1;
159
160 default:
161 return 32;
162 }
163 }
164
165 void SetPalette(const Palette& palette) {
166 auto ec = GXBitmapSetPalette(m_handle, palette.get());
167 PDF_CHECK_SUCCESS(ec, "Failed to set the bitmap palette");
168 }
169
170 Palette GetPalette() const {
171 Palette palette;
172 auto ec = GXBitmapGetPalette(m_handle, &palette);
173 PDF_CHECK_SUCCESS(ec, "Failed to get the bitmap palette");
174 return palette;
175 }
176
177 GXLockedData Lock(GXLockMode mode, const RectI* rect = nullptr) {
178 GXLockedData lockdata;
179 auto ec = GXBitmapLock(m_handle, rect, mode, &lockdata);
180 PDF_CHECK_SUCCESS(ec, "Failed to lock the bitmap");
181 return lockdata;
182 }
183
184 void Unlock() {
185 auto ec = GXBitmapUnlock(m_handle);
186 PDF_CHECK_SUCCESS(ec, "Failed to unlock the bitmap");
187 }
188
189 void CopyFromBitmap(const Bitmap& source, const RectI* source_rect = nullptr, const PointI* dest_point = nullptr) {
190 auto ec = GXBitmapCopyFromBitmap(m_handle, dest_point, source.get(), source_rect);
191 PDF_CHECK_SUCCESS(ec, "Failed to copy the bitmap");
192 }
193
194 void CopyFromMemory(const GXLockedData& memory, const RectI* dest_rect = nullptr) {
195 auto ec = GXBitmapCopyFromMemory(m_handle, dest_rect, &memory);
196 PDF_CHECK_SUCCESS(ec, "Failed to copy the bitmap");
197 }
198
199 void CopyToMemory(const GXLockedData& memory, const RectI* source_rect = nullptr) const {
200 auto ec = GXBitmapCopyToMemory(m_handle, source_rect, &memory);
201 PDF_CHECK_SUCCESS(ec, "Failed to copy the bitmap");
202 }
203
204 void ColorFill(GXColorValue color, const RectI* fill_rect = nullptr) {
205 auto ec = GXBitmapColorFill(m_handle, fill_rect, color);
206 PDF_CHECK_SUCCESS(ec, "Failed to fill the bitmap");
207 }
208
209 void NotifyChanged() {
210 auto ec = GXBitmapNotifyChanged(m_handle);
211 PDF_CHECK_SUCCESS(ec, "Failed to notify the bitmap change");
212 }
213
214 void SetOffscreenPainting(bool offscreen) {
215 auto ec = GXBitmapSetOffscreenPainting(m_handle, offscreen);
216 PDF_CHECK_SUCCESS(ec, "Failed to set the bitmap offscreen");
217 }
218
219 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(Bitmap, GXBitmap)
220};
221
223 BitmapScopedLock(const Bitmap& bm, GXLockMode mode = kGXLockModeRead, const PDF::RectI* rectp = nullptr)
224 : bitmap(bm) {
225 data = bitmap.Lock(mode, rectp);
226 }
228 try {
229 bitmap.Unlock();
230 } catch (...) {
231 /* ignore */
232 }
233 }
234 Bitmap bitmap;
235 GXLockedData data;
236};
237
242class FontFace : public detail::RefCountedHandle<GXFontFace> {
243public:
244 static FontFace New(const std::wstring& family, GXFontStyle style) {
245 FontFace fontface;
246 auto ec = GXCreateSystemFontFace(family.c_str(), style, &fontface);
247 PDF_CHECK_SUCCESS(ec, "Failed to create a font face");
248 return fontface;
249 }
250
251 static FontFace LoadFromFile(const std::filesystem::path& path, uint32_t faceindex = 0, uint32_t* ptotalfaces = nullptr) {
252 FontFace fontface;
253 auto path_string = path.wstring();
254 auto ec = GXCreateFontFaceFromFile(path_string.c_str(), faceindex, ptotalfaces, &fontface);
255 PDF_CHECK_SUCCESS(ec, "Failed to load a bitmap from file");
256 return fontface;
257 }
258
259 static FontFace LoadFromMemory(const void* data, size_t size, bool copyData = true, uint32_t faceindex = 0, uint32_t* ptotalfaces = nullptr) {
260 FontFace fontface;
261 auto ec = GXCreateFontFaceFromMemory(data, size, copyData, faceindex, ptotalfaces, &fontface);
262 PDF_CHECK_SUCCESS(ec, "Failed to load a bitmap from memory");
263 return fontface;
264 }
265
266 SizeF CalculateTextBound(float fontSize, const std::wstring& text) const {
267 SizeF bound;
268 auto ec = GXFontFaceCalculateTextBound(m_handle, fontSize, text.c_str(), &bound);
269 PDF_CHECK_SUCCESS(ec, "Failed to calculate the text bound");
270 return bound;
271 }
272
273 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(FontFace, GXFontFace)
274};
275
280class Geometry : public detail::RefCountedHandle<GXGeometry> {
281public:
282 static Geometry New() {
283 Geometry geom;
284 auto ec = GXCreateGeometry(&geom);
285 PDF_CHECK_SUCCESS(ec, "Failed to create a geometry");
286 return geom;
287 }
288
289 static Geometry NewFromRectangle(const PDF::RectF& rect) {
290 Geometry geom = New();
291 geom.Rectangle(rect);
292 return geom;
293 }
294
295 void SetFillRule(GXFillRule fillrule) {
296 auto ec = GXGeometrySetFillRule(m_handle, fillrule);
297 PDF_CHECK_SUCCESS(ec, "Failed to set the geometry fill rule");
298 }
299
300 GXFillRule GetFillRule() const {
302 auto ec = GXGeometryGetFillRule(m_handle, &fillrule);
303 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry fill rule");
304 return fillrule;
305 }
306
307 bool IsPointsEmpty() const {
308 bool empty = false;
309 auto ec = GXGeometryEmpty(m_handle, &empty);
310 PDF_CHECK_SUCCESS(ec, "Failed to check the geometry points");
311 return empty;
312 }
313
314 bool IsPointsEqual(const Geometry& rhs) const {
315 bool empty = false;
316 auto ec = GXGeometryPointsEqual(m_handle, rhs.get(), &empty);
317 PDF_CHECK_SUCCESS(ec, "Failed to check the geometry points");
318 return empty;
319 }
320
321 bool GetCurrentPoint(PointF* presult) const {
322 auto ec = GXGeometryGetCurrentPoint(m_handle, presult);
323 if (ec == kPDErrNotFound)
324 return false;
325 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry points");
326 return true;
327 }
328
329 RectF GetBound(const Matrix* xform = nullptr) const {
330 RectF bound;
331 auto ec = GXGeometryGetBound(m_handle, xform, &bound);
332 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry bound");
333 return bound;
334 }
335
336 RectF GetWidenBound(float lineWidth, const GXStrokeParams& params, const Matrix* xform = nullptr, float flatness = 0.75f) const {
337 if (Math::FloatEq(lineWidth, 0.0f))
338 lineWidth = flatness;
339 auto widenGeometry = Widen(lineWidth, params);
340 return widenGeometry.GetBound(xform);
341 }
342
343 void BeginFigure(const PointF& point) {
344 auto ec = GXGeometryBeginFigure(m_handle, &point);
345 PDF_CHECK_SUCCESS(ec, "Failed to begin figure");
346 }
347
348 void EndFigure() {
349 auto ec = GXGeometryEndFigure(m_handle);
350 PDF_CHECK_SUCCESS(ec, "Failed to end figure");
351 }
352
353 void EndFigureClose() {
354 auto ec = GXGeometryEndFigureClose(m_handle);
355 PDF_CHECK_SUCCESS(ec, "Failed to close figure");
356 }
357
358 void LineTo(const PointF& to) {
359 auto ec = GXGeometryLineTo(m_handle, &to);
360 PDF_CHECK_SUCCESS(ec, "Failed to add points to the geometry");
361 }
362
363 void CurveTo(const PointF& c, const PointF& to) {
364 auto ec = GXGeometryConicCurveTo(m_handle, &c, &to);
365 PDF_CHECK_SUCCESS(ec, "Failed to add points to the geometry");
366 }
367
368 void CurveTo(const PointF& c0, const PointF& c1, const PointF& to) {
369 auto ec = GXGeometryCubicCurveTo(m_handle, &c0, &c1, &to);
370 PDF_CHECK_SUCCESS(ec, "Failed to add points to the geometry");
371 }
372
373 void Rectangle(const RectF& rect) {
374 auto ec = GXGeometryRectangle(m_handle, &rect);
375 PDF_CHECK_SUCCESS(ec, "Failed to add points to the geometry");
376 }
377
378 void Ellipse(const RectF& bound) {
379 auto ec = GXGeometryEllipse(m_handle, &bound);
380 PDF_CHECK_SUCCESS(ec, "Failed to add points to the geometry");
381 }
382
383 void RoundRectangle(const RectF& rect, float xradii, float yradii) {
384 auto ec = GXGeometryRoundRectangle(m_handle, &rect, xradii, yradii);
385 PDF_CHECK_SUCCESS(ec, "Failed to add points to the geometry");
386 }
387
388 Geometry Copy() const {
389 Geometry copy;
390 auto ec = GXGeometryCopy(m_handle, &copy);
391 PDF_CHECK_SUCCESS(ec, "Failed to copy the geometry");
392 return copy;
393 }
394
395 Geometry Transform(const Matrix& xform) const {
396 Geometry result;
397 auto ec = GXGeometryTransform(m_handle, &xform, &result);
398 PDF_CHECK_SUCCESS(ec, "Failed to transform the geometry");
399 return result;
400 }
401
402 Geometry Widen(float width, const GXStrokeParams& params, float flatness = 0.75) const {
403 Geometry result;
404 auto ec = GXGeometryWiden(m_handle, width, &params, flatness, &result);
405 PDF_CHECK_SUCCESS(ec, "Failed to widen the geometry");
406 return result;
407 }
408
409 Geometry Combine(GXCombineMode mode,
410 const Geometry& rhs,
411 const Matrix* xform = nullptr,
412 float flatness = 0.75) const {
413 Geometry result;
414 auto ec = GXGeometryCombine(m_handle, rhs.get(), xform, mode, flatness, &result);
415 PDF_CHECK_SUCCESS(ec, "Failed to combine the geometries");
416 return result;
417 }
418
419 bool HitTest(const PointF& point) const {
420 bool hit = false;
421 auto ec = GXGeometryHitTest(m_handle, &point, &hit);
422 PDF_CHECK_SUCCESS(ec, "Failed to hit test the geometry");
423 return hit;
424 }
425
426 Geometry Simplify(float flatness = 0.75) const {
427 Geometry result;
428 auto ec = GXGeometrySimplify(m_handle, flatness, &result);
429 PDF_CHECK_SUCCESS(ec, "Failed to simplify the geometries");
430 return result;
431 }
432
433 std::optional<RectF> IsRectangle(const Matrix& xform = Matrix{}) const {
434 bool isrectangle = false;
435 RectF rectangle;
436 auto ec = GXGeometryIsRectangle(m_handle, &xform, &isrectangle, &rectangle);
437 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry rectangle");
438 if (!isrectangle)
439 return std::nullopt;
440 return rectangle;
441 }
442
443 bool IsSingleLine() const {
444 if (GetNumFigures() > 1)
445 return false;
446
447 if (GetFigureNumPoints(0) != 2)
448 return false;
449
450 return true;
451 }
452
453 size_t GetNumFigures() const {
454 size_t numfigures = 0;
455 auto ec = GXGeometryGetNumFigures(m_handle, &numfigures);
456 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figures");
457 return numfigures;
458 }
459
460 size_t GetFigureNumSegments(size_t figureindex) const {
461 size_t numsegs = 0;
462 auto ec = GXGeometryGetFigureNumSegments(m_handle, figureindex, &numsegs);
463 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figure segments");
464 return numsegs;
465 }
466
467 size_t GetFigureNumPoints(size_t figureindex) const {
468 size_t numpoints = 0;
469 auto ec = GXGeometryGetFigureNumPoints(m_handle, figureindex, &numpoints);
470 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figure points");
471 return numpoints;
472 }
473
474 const PointF* GetFigurePointsPtr(size_t figureindex) const {
475 const PDPointF* points = nullptr;
476 auto ec = GXGeometryGetFigurePointsPtr(m_handle, figureindex, &points);
477 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figure start point");
478 static_assert(sizeof(PointF) == sizeof(PDPointF), "Size of PointF and PDPointF must be equal");
479 return reinterpret_cast<const PointF*>(points);
480 }
481
482 bool IsFigureSegmentCurve(size_t figureindex, size_t segindex) const {
483 bool iscurve = false;
484 auto ec = GXGeometryIsFigureSegmentCurve(m_handle, figureindex, segindex, &iscurve);
485 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figure segment points");
486 return iscurve;
487 }
488
489 size_t GetFigureSegmentPointsIndex(size_t figureindex, size_t segindex) const {
490 size_t pointsindex = 0;
491 auto ec = GXGeometryGetFigureSegmentPointsIndex(m_handle, figureindex, segindex, &pointsindex);
492 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figure segment points");
493 return pointsindex;
494 }
495
496 bool IsFigureClosed(size_t figureindex) const {
497 bool isclosed = false;
498 auto ec = GXGeometryIsFigureClosed(m_handle, figureindex, &isclosed);
499 PDF_CHECK_SUCCESS(ec, "Failed to get the geometry figure closed");
500 return isclosed;
501 }
502
503 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(Geometry, GXGeometry)
504};
505
510class Gradient : public detail::RefCountedHandle<GXGradient> {
511public:
512 static Gradient NewLinearGradient(const GXLinearGradientAttrs& attrs) {
513 Gradient gradient;
514 auto ec = GXCreateGradientLinear(&attrs, &gradient);
515 PDF_CHECK_SUCCESS(ec, "Failed to create a gradient");
516 return gradient;
517 }
518
519 static Gradient NewRadialGradient(const GXRadialGradientAttrs& attrs) {
520 Gradient gradient;
521 auto ec = GXCreateGradientRadial(&attrs, &gradient);
522 PDF_CHECK_SUCCESS(ec, "Failed to create a gradient");
523 return gradient;
524 }
525
526 static Gradient NewTriMeshGradient(const GXMeshVertex* vertices, size_t num_vertices, GXColorValue bgcolor) {
527 Gradient gradient;
528 auto ec = GXCreateGradientTriMesh(vertices, num_vertices, bgcolor, &gradient);
529 PDF_CHECK_SUCCESS(ec, "Failed to create a gradient");
530 return gradient;
531 }
532
533 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(Gradient, GXGradient)
534};
535
540class Brush : public detail::RefCountedHandle<GXBrush> {
541public:
542 static Brush NewSolidBrush(const GXColor& color) {
543 Brush brush;
544 auto ec = GXCreateBrushSolid(&color, &brush);
545 PDF_CHECK_SUCCESS(ec, "Failed to create a brush");
546 return brush;
547 }
548
549 static Brush NewSolidBrush(GXColorValue argb) {
550 Brush brush;
551 auto ec = GXCreateBrushSolidARGB(argb, &brush);
552 PDF_CHECK_SUCCESS(ec, "Failed to create a brush");
553 return brush;
554 }
555
556 static Brush NewBitmapBrush(const Bitmap& bitmap,
557 const GXBitmapBrushAttrs& attrs,
558 float opacity = 1,
559 const Matrix* xform = nullptr) {
560 Brush brush;
561 auto ec = GXCreateBrushBitmap(bitmap.get(), opacity, &attrs, xform, &brush);
562 PDF_CHECK_SUCCESS(ec, "Failed to create a brush");
563 return brush;
564 }
565
566 static Brush NewGradientBrush(const Gradient& gradient, float opacity = 1, const Matrix* xform = nullptr) {
567 Brush brush;
568 auto ec = GXCreateBrushGradient(gradient.get(), opacity, xform, &brush);
569 PDF_CHECK_SUCCESS(ec, "Failed to create a brush");
570 return brush;
571 }
572
573 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(Brush, GXBrush)
574};
575
580class Region : public detail::RefCountedHandle<GXRegion> {
581public:
582 static Region New() {
583 Region region;
584 auto ec = GXCreateRegion(&region);
585 PDF_CHECK_SUCCESS(ec, "Failed to create a region");
586 return region;
587 }
588
589 static Region NewFromRect(const RectI& rect) {
590 Region region;
591 auto ec = GXCreateRegionFromRect(&rect, &region);
592 PDF_CHECK_SUCCESS(ec, "Failed to create a region");
593 return region;
594 }
595
596 bool IsAreaEmpty() const {
597 bool empty = false;
598 auto ec = GXRegionIsAreaEmpty(m_handle, &empty);
599 PDF_CHECK_SUCCESS(ec, "Failed to check the region area");
600 return empty;
601 }
602
603 RectI GetBound() const {
604 RectI bound;
605 auto ec = GXRegionGetBound(m_handle, &bound);
606 PDF_CHECK_SUCCESS(ec, "Failed to get the region bound");
607 return bound;
608 }
609
610 bool Contains(const PointI& point) const {
611 bool contains = false;
612 auto ec = GXRegionContainsPoint(m_handle, &point, &contains);
613 PDF_CHECK_SUCCESS(ec, "Failed to hit test the region");
614 return contains;
615 }
616
617 bool Contains(const RectI& rect) const {
618 bool contains = false;
619 auto ec = GXRegionContainsRect(m_handle, &rect, &contains);
620 PDF_CHECK_SUCCESS(ec, "Failed to hit test the region");
621 return contains;
622 }
623
624 bool Contains(const Region& region) const {
625 bool contains = false;
626 auto ec = GXRegionContains(m_handle, region.get(), &contains);
627 PDF_CHECK_SUCCESS(ec, "Failed to hit test the region");
628 return contains;
629 }
630
631 bool HasIntersection(const RectI& rect) const {
632 bool isects = false;
633 auto ec = GXRegionHasIntersectionWithRect(m_handle, &rect, &isects);
634 PDF_CHECK_SUCCESS(ec, "Failed to check the regions intersection");
635 return isects;
636 }
637
638 bool HasIntersection(const Region& region) const {
639 bool isects = false;
640 auto ec = GXRegionHasIntersection(m_handle, region.get(), &isects);
641 PDF_CHECK_SUCCESS(ec, "Failed to check the regions intersection");
642 return isects;
643 }
644
645 void Offset(int dx, int dy) {
646 auto ec = GXRegionOffset(m_handle, dx, dy);
647 PDF_CHECK_SUCCESS(ec, "Failed to offset the region");
648 }
649
650 void Combine(GXCombineMode mode, const Region& region) {
651 GXRegion result = nullptr;
652 auto ec = GXRegionCombine(m_handle, region.get(), mode, &result);
653 PDF_CHECK_SUCCESS(ec, "Failed to combine the regions");
654 reset(result, true);
655 }
656
657 void Combine(GXCombineMode mode, const RectI& rect) {
658 GXRegion result = nullptr;
659 auto ec = GXRegionCombineRect(m_handle, &rect, mode, &result);
660 PDF_CHECK_SUCCESS(ec, "Failed to combine the regions");
661 reset(result, true);
662 }
663
664 using RectEnumFunc = std::function<bool(const RectI&)>;
665
666 static PDErrCode PDFSDK_CALLCONV RectEnumProc_(void* userdata, const PDRectI* rect) {
667 auto& func = *reinterpret_cast<RectEnumFunc*>(userdata);
668 return func(*rect) ? kPDErrSuccess : kPDErrCanceled;
669 }
670
671 void EnumRects(RectEnumFunc func) const {
672 auto ec = GXRegionEnumRects(m_handle, RectEnumProc_, &func);
673 if (ec != kPDErrCanceled)
674 PDF_CHECK_SUCCESS(ec, "Failed to enum the region rects");
675 }
676
677 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(Region, GXRegion)
678};
679
684class RenderTarget : public detail::RefCountedHandle<GXRenderTarget> {
685public:
686 static RenderTarget NewBitmapRenderTarget(const Bitmap& bitmap) {
687 RenderTarget target;
688 auto ec = GXCreateRenderTargetBitmap(bitmap.get(), &target);
689 PDF_CHECK_SUCCESS(ec, "Failed to create the render target");
690 return target;
691 }
692
693 static RenderTarget NewExtBufRenderTarget(void* pixels,
694 int stride,
695 const SizeI& size,
696 GXPixelFormat format,
697 float dpiX = 96,
698 float dpiY = 96) {
699 RenderTarget target;
700 GXBitmapAttrs attrs = {size, format, dpiX, dpiY};
701 auto ec = GXCreateRenderTargetExtBuf(pixels, stride, &attrs, &target);
702 PDF_CHECK_SUCCESS(ec, "Failed to create the render target");
703 return target;
704 }
705
706#ifdef _WIN32
707
708 static RenderTarget NewHwndRenderTarget(void* hwnd, GXRuntimeMode mode = kGXRuntimeModeHardware) {
709 RenderTarget target;
710 auto ec = GXCreateRenderTargetHWND(hwnd, mode, &target);
711 PDF_CHECK_SUCCESS(ec, "Failed to create the render target");
712 return target;
713 }
714
715 static RenderTarget NewPrintRenderTarget(void* hdc) {
716 RenderTarget target;
717 auto ec = GXCreateRenderTargetPrintDC(hdc, &target);
718 PDF_CHECK_SUCCESS(ec, "Failed to create the render target");
719 return target;
720 }
721
722 static RenderTarget NewHdcRenderTarget(void* hdc, const RectI* rect = nullptr) {
723 RenderTarget target;
724 auto ec = GXCreateRenderTargetHDC(hdc, rect, &target);
725 PDF_CHECK_SUCCESS(ec, "Failed to create the render target");
726 return target;
727 }
728
729#endif // _WIN32
730
731#ifdef __APPLE__
732
733 static RenderTarget NewNSViewRenderTarget(void* nsview, GXRuntimeMode mode = kGXXRuntimeModeHardware) {
734 RenderTarget target;
735 auto ec = GXCreateRenderTargetNSView(nsview, mode, &target);
736 PDF_CHECK_SUCCESS(ec, "Failed to create the render target");
737 return target;
738 }
739
740#endif // __APPLE__
741
742 GXPixelFormat GetPixelFormat() {
744 auto ec = GXRenderTargetGetPixelFormat(m_handle, &format);
745 PDF_CHECK_SUCCESS(ec, "Failed to get the render target pixel format");
746 return format;
747 }
748
749 SizeI GetSize() {
750 SizeI size;
751 auto ec = GXRenderTargetGetSize(m_handle, &size);
752 PDF_CHECK_SUCCESS(ec, "Failed to get the render target size");
753 return size;
754 }
755
756 void Clear(GXColorValue clrcolor) {
757 auto ec = GXRenderTargetClear(m_handle, clrcolor);
758 PDF_CHECK_SUCCESS(ec, "Failed to clear the render target");
759 }
760
762 public:
763 PaintScope(RenderTarget& target)
764 : m_target(target) {
765 m_target.BeginPaint();
766 }
767
768 ~PaintScope() {
769 try {
770 m_target.EndPaint();
771 } catch (...) {
772 }
773 }
774
775 PaintScope(const PaintScope&) = delete;
776 PaintScope& operator=(const PaintScope&) = delete;
777
778 private:
779 RenderTarget& m_target;
780 };
781
782 void BeginPaint() {
783 auto ec = GXRenderTargetBeginPaint(m_handle);
784 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
785 }
786
787 bool EndPaint() {
788 auto ec = GXRenderTargetEndPaint(m_handle);
789 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
790 return true;
791 }
792
794 public:
795 StateScope(RenderTarget& target)
796 : m_target(target) {
797 m_target.PushState();
798 }
799
800 ~StateScope() {
801 try {
802 m_target.PopState();
803 } catch (...) {
804 }
805 }
806
807 StateScope(const StateScope&) = delete;
808 StateScope& operator=(const StateScope&) = delete;
809
810 private:
811 RenderTarget& m_target;
812 };
813
814 void PushState() {
815 auto ec = GXRenderTargetPushState(m_handle);
816 PDF_CHECK_SUCCESS(ec, "Failed to push the render target state");
817 }
818
819 void PopState() {
820 auto ec = GXRenderTargetPopState(m_handle);
821 PDF_CHECK_SUCCESS(ec, "Failed to pop the render target state");
822 }
823
824 class CTMScope {
825 public:
826 CTMScope(RenderTarget& target)
827 : m_target(target) {
828 m_ctm = m_target.GetCTM();
829 }
830
831 ~CTMScope() {
832 try {
833 m_target.SetCTM(m_ctm);
834 } catch (...) {
835 }
836 }
837
838 CTMScope(const CTMScope&) = delete;
839 CTMScope& operator=(const CTMScope&) = delete;
840
841 private:
842 RenderTarget& m_target;
843 Matrix m_ctm;
844 };
845
846 Matrix GetCTM() const {
847 Matrix ctm;
848 auto ec = GXRenderTargetGetCTM(m_handle, &ctm);
849 PDF_CHECK_SUCCESS(ec, "Failed to get the render target CTM");
850 return ctm;
851 }
852
853 void SetCTM(const Matrix& ctm) {
854 auto ec = GXRenderTargetSetCTM(m_handle, &ctm);
855 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
856 }
857
858 void ConcatCTM(const Matrix& xform) {
859 auto ec = GXRenderTargetConcatCTM(m_handle, &xform);
860 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
861 }
862
863 void RotateCTM(float radians) {
864 auto ec = GXRenderTargetRotateCTM(m_handle, radians);
865 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
866 }
867
868 void ScaleCTM(float scale) {
869 auto ec = GXRenderTargetScaleCTM(m_handle, scale, scale);
870 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
871 }
872
873 void ScaleCTM(float sx, float sy) {
874 auto ec = GXRenderTargetScaleCTM(m_handle, sx, sy);
875 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
876 }
877
878 void ScaleCTM(const SizeF& scale) {
879 auto ec = GXRenderTargetScaleCTM(m_handle, scale.width, scale.height);
880 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
881 }
882
883 void TranslateCTM(float dx, float dy) {
884 auto ec = GXRenderTargetTranslateCTM(m_handle, dx, dy);
885 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
886 }
887
888 void TranslateCTM(const PointF& delta) {
889 auto ec = GXRenderTargetTranslateCTM(m_handle, delta.x, delta.y);
890 PDF_CHECK_SUCCESS(ec, "Failed to modify the render target CTM");
891 }
892
893 void SetBlendMode(GXBlendMode mode) {
894 auto ec = GXRenderTargetSetBlendMode(m_handle, mode);
895 PDF_CHECK_SUCCESS(ec, "Failed to set the render target blend mode");
896 }
897
898 void SetStrokeAdjustment(bool adjust) {
899 auto ec = GXRenderTargetSetStrokeAdjustment(m_handle, adjust);
900 PDF_CHECK_SUCCESS(ec, "Failed to set the render target stroke adjust");
901 }
902
903 bool GetStrokeAdjustment() const {
904 bool adjust = false;
905 auto ec = GXRenderTargetGetStrokeAdjustment(m_handle, &adjust);
906 PDF_CHECK_SUCCESS(ec, "Failed to get the render target stroke adjust");
907 return adjust;
908 }
909
910 void SetOpacityMask(GXMaskMode mode, const Brush& mask) {
911 auto ec = GXRenderTargetSetOpacityMask(m_handle, mode, mask.get());
912 PDF_CHECK_SUCCESS(ec, "Failed to set the render target mask");
913 }
914
915 void SetShapeMask(GXMaskMode mode, const Brush& mask) {
916 auto ec = GXRenderTargetSetShapeMask(m_handle, mode, mask.get());
917 PDF_CHECK_SUCCESS(ec, "Failed to set the render target mask");
918 }
919
920 void BeginLayer(const GXLayerParams& params) {
921 auto ec = GXRenderTargetBeginLayer(m_handle, &params);
922 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
923 }
924
925 void EndLayer() {
926 auto ec = GXRenderTargetEndLayer(m_handle);
927 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
928 }
929
930 void FillGeometry(const Geometry& geom, const Brush& brush) {
931 auto ec = GXRenderTargetFillGeometry(m_handle, geom.get(), brush.get());
932 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
933 }
934
935 void FillTextGeometry(const Geometry& geom, const Brush& brush) {
936 auto ec = GXRenderTargetFillTextGeometry(m_handle, geom.get(), brush.get());
937 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
938 }
939
940 void FillRect(const RectF& rect, const Brush& brush) {
941 auto ec = GXRenderTargetFillRect(m_handle, &rect, brush.get());
942 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
943 }
944
945 void FillEllipse(const RectF& bound, const Brush& brush) {
946 auto ec = GXRenderTargetFillEllipse(m_handle, &bound, brush.get());
947 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
948 }
949
950 void StrokeGeometry(const Geometry& geom, const Brush& brush, float width, const GXStrokeParams* params = nullptr) {
951 auto ec = GXRenderTargetStrokeGeometry(m_handle, geom.get(), brush.get(), width, params);
952 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
953 }
954
955 void StrokeLine(const PointF& start,
956 const PointF& end,
957 const Brush& brush,
958 float width,
959 const GXStrokeParams* params = nullptr) {
960 auto ec = GXRenderTargetStrokeLine(m_handle, &start, &end, brush.get(), width, params);
961 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
962 }
963
964 void StrokeRect(const RectF& rect, const Brush& brush, float width, const GXStrokeParams* params = nullptr) {
965 auto ec = GXRenderTargetStrokeRect(m_handle, &rect, brush.get(), width, params);
966 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
967 }
968
969 void StrokeEllipse(const RectF& bound, const Brush& brush, float width, const GXStrokeParams* params = nullptr) {
970 auto ec = GXRenderTargetStrokeEllipse(m_handle, &bound, brush.get(), width, params);
971 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
972 }
973
974 void ClipGeometry(const Geometry& geom) {
975 auto ec = GXRenderTargetClipGeometry(m_handle, geom.get());
976 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
977 }
978
979 void ClipRect(const RectF& rect) {
980 auto ec = GXRenderTargetClipRect(m_handle, &rect);
981 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
982 }
983
984 void ClipEllipse(const RectF& bound) {
985 auto ec = GXRenderTargetClipEllipse(m_handle, &bound);
986 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
987 }
988
989 void DrawBitmap(const Bitmap& bitmap,
990 float opacity = 1,
992 auto ec = GXRenderTargetDrawBitmap(m_handle, bitmap.get(), opacity, imode);
993 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
994 }
995
996 void StretchBitmap(const Bitmap& bitmap,
997 const RectF& target_rect,
998 float opacity = 1,
1000 auto ec = GXRenderTargetStretchBitmap(m_handle, bitmap.get(), &target_rect, opacity, imode);
1001 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
1002 }
1003
1004 void DrawGradient(const Gradient& gradient, float opacity) {
1005 auto ec = GXRenderTargetDrawGradient(m_handle, gradient.get(), opacity);
1006 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
1007 }
1008
1009 void FillMask(const Bitmap& mask,
1010 const Brush& brush,
1012 auto ec = GXRenderTargetFillMask(m_handle, mask.get(), brush.get(), imode);
1013 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
1014 }
1015
1016 void InvertRect(const RectF& rect) {
1017 auto ec = GXRenderTargetInvertRect(m_handle, &rect);
1018 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
1019 }
1020
1021 void InvertLine(const PointI& start, const PointI& end) {
1022 auto ec = GXRenderTargetInvertLine(m_handle, &start, &end);
1023 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
1024 }
1025
1026 void FillText(const FontFace& font, float fontSize, const std::wstring& text, const Brush& brush) {
1027 auto ec = GXRenderTargetFillText(m_handle, font.get(), fontSize, text.c_str(), brush.get());
1028 PDF_CHECK_SUCCESS(ec, "Failed to paint the render target");
1029 }
1030
1031 RectI GetDrawBounds() {
1032 RectI bounds;
1033 auto ec = GXRenderTargetGetDrawBounds(m_handle, &bounds);
1034 PDF_CHECK_SUCCESS(ec, "Failed to get the render target draw bounds");
1035 return bounds;
1036 }
1037
1038 PDF_CXX_CORE_WRAPPER_DEFINE_MEMBERS_(RenderTarget, GXRenderTarget)
1039};
1040
1041} // namespace Graphics
1042} // namespace PDF
1043
1044#endif // PDFSDK_CXX_GRAPHICS_H_INCLUDED_
Represents a bitmap.
Definition graphics.h:61
Represents a brush.
Definition graphics.h:540
Represents a font face.
Definition graphics.h:242
Represents a geometry.
Definition graphics.h:280
Represents a gradient.
Definition graphics.h:510
Represents a color palette.
Definition graphics.h:24
Represents a region.
Definition graphics.h:580
Definition graphics.h:824
Represents a render target.
Definition graphics.h:684
@ kPDErrSuccess
Operation was successful.
Definition errors.h:18
@ kPDErrNotFound
Object not found.
Definition errors.h:21
@ kPDErrCanceled
Operation was cancelled by user.
Definition errors.h:17
int32_t PDErrCode
Definition errors.h:44
Graphics API.
GXLockMode
Defines the level of access and control over the graphics content.
Definition graphics.h:75
@ kGXLockModeRead
Definition graphics.h:76
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateRenderTargetBitmap(GXBitmap bitmap, GXRenderTarget *ptarget)
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateBitmap(const GXBitmapAttrs *attrs, GXBitmap *pbitmap)
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateSystemFontFace(const wchar_t *family, GXFontStyle style, GXFontFace *pfontface)
GXFillRule
Determines how a path (a series or points that define a shape) is filled with color.
Definition graphics.h:105
@ kGXFillRuleNonZero
Definition graphics.h:106
GXInterpolationMode
Defines the way through which pixel values are estimated or interpolated.
Definition graphics.h:92
@ kGXInterpolationModeAreaAverage
Definition graphics.h:95
GXRuntimeMode
Defines the runtime modes for the Graphics application.
Definition graphics.h:27
@ kGXRuntimeModeHardware
Definition graphics.h:28
GXBlendMode
Determines the way in which colors of overlapping objects are combined.
Definition graphics.h:124
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateBrushSolid(const GXColor *color, GXBrush *pbrush)
GXCombineMode
Determines how the areas of different graphics interact with each other.
Definition graphics.h:178
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreatePalette(const GXColorValue *colors, size_t num_colors, GXPalette *ppalette)
GXFontStyle
Defines the various styles that can be applied to text within a PDF document.
Definition graphics.h:304
GXMaskMode
Determines the type of mask used to control which parts of an image or graphical element are visible ...
Definition graphics.h:159
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateGradientLinear(const GXLinearGradientAttrs *attrs, GXGradient *pgradient)
GXPixelFormat
Defines the pixel format of the graphics application.
Definition graphics.h:52
@ kGXPixelFormatP8
Definition graphics.h:63
@ kGXPixelFormatA8
Definition graphics.h:62
@ kGXPixelFormatXRGB8
Definition graphics.h:60
@ kGXPixelFormatARGB8p
Definition graphics.h:55
@ kGXPixelFormatUnknown
Definition graphics.h:53
@ kGXPixelFormatL1
Definition graphics.h:67
@ kGXPixelFormatRGB8
Definition graphics.h:54
@ kGXPixelFormatA1
Definition graphics.h:65
@ kGXPixelFormatL8
Definition graphics.h:64
@ kGXPixelFormatP1
Definition graphics.h:66
@ kGXPixelFormatARGB8
Definition graphics.h:58
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateRegion(GXRegion *pregion)
PDF_CORE_API PDErrCode PDFSDK_CALLCONV GXCreateGeometry(GXGeometry *pgeom)
Definition graphics.h:241
Definition graphics.h:293
Definition graphics.h:33
Definition graphics.h:186
Definition graphics.h:253
Definition graphics.h:81
Definition graphics.h:275
Definition graphics.h:263
Definition graphics.h:234
Definition graphics.h:222
Definition math.h:1053
Definition math.h:132
Definition math.h:54
Definition math.h:545
Definition math.h:347
Definition math.h:313
Definition math.h:279
Definition math_types.h:12
Definition math_types.h:44