کشیدن گرافیک‌های برداری روی صفحه PDF

کشیدن گرافیک‌های برداری روی صفحه PDF

رسم گرافیک‌های برداری بر روی صفحه PDF

Aspose.PDF FOSS برای C++ شامل یک API گرافیک برداری کوچک برای رسم اشکال مستقیماً روی صفحه PDF هنگام ساخت سند است. نقطهٔ ورودی Graph است، یک کانتینر قرار گرفته بر روی صفحه که مجموعه‌ای از اشیاء Shape را نگه می‌دارد؛ سه شکل ثابت — Circle، Ellipse و Line — از Shape ارث می‌برند و هر کدام هندسهٔ خود را به شکل متفاوتی بیان می‌کنند. سبک‌گذاری خط و پر شدن برای هر شکل از GraphInfo می‌آید، و خود کانتینر Graph یک BorderInfo برای قاب‌بندی دارد. این موضوع با رسترسازی صفحه (BmpDevice، JpegDevice، TiffDevice) مرتبط نیست، که محتوای موجود صفحه را به فرمت‌های تصویر رستری تبدیل می‌کند نه اینکه هندسهٔ جدیدی رسم کند.


کانتینر گراف و افزودن اشکال به صفحه

Graph موقعیت و اندازهٔ خود را در صفحه از طریق Left()، Top()، Width() و Height() تنظیم می‌کند و پرچم IsChangePosition() آن کنترل می‌کند که آیا آن موقعیت می‌تواند نسبت به سایر محتویات صفحه جابه‌جا شود یا خیر. اشکالی که رسم می‌کند در برداری که توسط Shapes() برگردانده می‌شود — std::vector<std::unique_ptr<Shape>> — زندگی می‌کنند؛ این بردار با ساخت یک شکل، پیکربندی آن و انتقال به آن بردار پر می‌شود. پس از ساخت، خود Graph از طریق Page.Paragraphs().Add() بر روی صفحه قرار می‌گیرد، همان مجموعه‌ای که برای سایر محتوای سطح صفحه استفاده می‌شود.

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/drawing/graph.hpp>
#include <aspose/pdf/drawing/circle.hpp>

using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Drawing;

Document doc;
Page page = doc.Pages().Add();

auto graph = std::make_shared<Graph>();
graph->Left(36.0);
graph->Top(36.0);
graph->Width(500.0);
graph->Height(300.0);

auto marker = std::make_unique<Circle>();
marker->PosX(60.0);
marker->PosY(60.0);
marker->Radius(30.0);
graph->Shapes().push_back(std::move(marker));

page.Paragraphs().Add(graph);
doc.Save("shapes.pdf");

رسم دایره‌ها و بیضی‌ها

Circle و Ellipse هر کدام هندسه را به عنوان ویژگی‌های عددی ساده بیان می‌کنند نه به عنوان یک نوع نقطه یا مستطیل مشترک. Circle یک نقطهٔ مرکز و شعاع است — PosX()، PosY()، Radius() — در حالی که Ellipse یک جعبهٔ محدودکننده است — Left()، Bottom()، Width()، Height(). هر دو CheckBounds(containerWidth, containerHeight) را از Shape ارث می‌برند، که گزارش می‌دهد آیا هندسهٔ فعلی شکل در داخل یک کانتینر با اندازهٔ داده‌شده جا می‌گیرد بدون این که خود شکل تغییر کند.

#include <aspose/pdf/drawing/circle.hpp>
#include <aspose/pdf/drawing/ellipse.hpp>

using namespace Aspose::Pdf::Drawing;

Circle circle;
circle.PosX(120.0);
circle.PosY(120.0);
circle.Radius(60.0);
bool circleFits = circle.CheckBounds(500.0, 300.0);

Ellipse ellipse;
ellipse.Left(220.0);
ellipse.Bottom(20.0);
ellipse.Width(250.0);
ellipse.Height(100.0);
bool ellipseFits = ellipse.CheckBounds(500.0, 300.0);

رسم خطوط با PositionArray

Line هندسه خود را به‌صورت متفاوتی نسبت به Circle و Ellipse ذخیره می‌کند: PositionArray() یک std::vector<float> صاف برمی‌گرداند که یک جفت x, y برای هر نقطه‌ای که خط از آن عبور می‌کند، نگه می‌دارد، نه یک مجموعه ثابت از ویژگی‌های نام‌دار. دو نقطه (چهار مقدار) یک قطعه مستقیم می‌کشند؛ جفت‌های اضافه مسیر چند-قطعه‌ای را از طریق آن نقاط به ترتیب می‌کشند. مشابه اشکال دیگر، Line CheckBounds(containerWidth, containerHeight) را از Shape بازنویسی می‌کند.

#include <aspose/pdf/drawing/line.hpp>

using namespace Aspose::Pdf::Drawing;

Line path;
path.PositionArray({0.0f, 0.0f, 250.0f, 0.0f, 125.0f, 200.0f});
bool pathFits = path.CheckBounds(500.0, 300.0);

استایل‌دهی به اشکال با GraphInfo و BorderInfo

هر شکل استایل خط و پر کردن خود را از طریق Shape.GraphInfo() / GraphInfo(value) می‌خواند و می‌نویسد. پیش‌فرض GraphInfo یک LineWidth() از 1.0f با یک DashArray() خالی است و همچنین Color()، FillColor()، DashArray()/DashPhase() را برای خطوط نقطه‌دار، IsDoubled() برای خط دوگانه، و SkewAngleX()/SkewAngleY()، ScalingRateX()/ScalingRateY() و RotationAngle() را برای تبدیل خط در دسترس قرار می‌دهد. خود Graph یک BorderInfo دارد که از طریق Border() تنظیم می‌شود و یک GraphInfo برای هر لبه گروه‌بندی می‌کند — Left()، Right()، Top()، Bottom() — به‌علاوه یک RoundedBorderRadius()، و می‌تواند با نام‌گذاری لبه‌هایی که باید استایل شوند با پرچم BorderSide ساخته شود (BorderSide::Left | BorderSide::Right یا BorderSide::All برای هر لبه).

#include <aspose/pdf/graph_info.hpp>
#include <aspose/pdf/border_info.hpp>
#include <aspose/pdf/border_side.hpp>
#include <aspose/pdf/color.hpp>

using namespace Aspose::Pdf;

GraphInfo stroke;
stroke.LineWidth(2.5f);
stroke.Color(Color::FromRgb(1.0, 0.0, 0.0));
stroke.DashArray({3, 2});
stroke.DashPhase(1);
stroke.IsDoubled(true);

// Style only the left and right edges of the container border.
BorderInfo border{BorderSide::Left | BorderSide::Right, 3.0f};
border.RoundedBorderRadius(4.0);

graph->GraphInfo(stroke);
graph->Border(border);

نکات و بهترین روش‌ها

  • تابع CheckBounds را نسبت به Width()/Height() خود Graph مالک صدا کنید، نه جعبه رسانه کامل صفحه — این بررسی هندسه یک شکل را نسبت به هر اندازهٔ ظرفی که به آن پاس می‌دهید اعتبارسنجی می‌کند و به‌صورت خودکار به صفحه نگاه نمی‌کند.
  • قبل از افزودن Graph به Page.Paragraphs()، اشکال را به Shapes() اضافه کنید — ساختن یک Circle، Ellipse یا Line تا زمانی که هم به Graph مالک خود اضافه نشود و هم آن Graph به صفحه اضافه نشود، تأثیر قابل مشاهده‌ای ندارد.
  • اشکال مرتبط را زیر یک Graph واحد گروه‌بندی کنید نه یک Graph برای هر شکل؛ Left()/Top()/Width()/Height() یک‌بار موقعیت کل ظرف را تنظیم می‌کنند و هر شکل در Shapes() نسبت به آن رسم می‌شود.
  • برای اشکالی که به پر شدن قابل مشاهده یا خطی غیر پیش‌فرض نیاز دارند، Shape.GraphInfo() را به‌صورت صریح تنظیم کنید — GraphInfo پیش‌فرض دارای عرض خط 1.0f، بدون پر، و یک DashArray() خالی است.
  • ساخت Line.PositionArray() به عنوان جفت‌های x0, y0, x1, y1, … به ترتیب کشیده شدن مسیر — یک بردار با طول فرد یک نقطه ناقص را توصیف می‌کند.

مشکلات رایج

مشکلدلیلراه‌حل
یک Circle، Ellipse یا Line هرگز در صفحه ذخیره‌شده ظاهر نمی‌شودشکل ساخته شد اما هرگز به Graph‌Shapes() آن اضافه نشد، یا Graph هرگز به صفحه اضافه نشدشکل را به graph->Shapes() اضافه کنید و page.Paragraphs().Add(graph) را فراخوانی کنید
شکل با یک خط نازک سیاه پیش‌فرض رسم می‌شودShape.GraphInfo() هرگز تنظیم نشدقبل از افزودن شکل به Shapes()، shape->GraphInfo(customGraphInfo) را فراخوانی کنید
Line وجود ندارد یا شبیه یک نقطه واحد به نظر می‌رسدPositionArray() کمتر از دو جفت (x, y) دارد یا تعداد مقادیر آن عدد فرد استحداقل چهار مقدار به عنوان x0, y0, x1, y1 فراهم کنید
فقط برخی از لبه‌های مرزی کانتینر استایل داده شده‌اندBorderInfo با یک ماسک BorderSide ساخته شد که برخی لبه‌ها را حذف می‌کنداز BorderSide::All استفاده کنید، یا تمام پرچم‌های BorderSide مورد نیاز را با عملگر OR ترکیب کنید
CheckBounds به طور غیرمنتظره false را برمی‌گرداندابعاد ارسال‌شده به CheckBounds با کانتینری که شکل در آن واقعاً رسم می‌شود مطابقت ندارندمقدار فعلی Width()/Height() متعلق به Graph را ارسال کنید

FAQ

تفاوت بین Circle و AnnotationType::Circle چیست؟

Circle (این راهنما) یک شکل رسم است که مستقیماً از طریق Graph به محتوای صفحه می‌کشد. AnnotationType::Circle و CircleAnnotation به یک API حاشیه‌نویسی جداگانه تعلق دارند و به‌جای آن یک حاشیه‌نویسی علامت‌گذاری به شکل دایره را نشان می‌دهند — این دو علیرغم داشتن نام مشترک مرتبط نیستند.

آیا یک Graph واحد می‌تواند بیش از یک شکل داشته باشد؟

بله. Graph.Shapes() کل std::vector<std::unique_ptr<Shape>> برای آن کانتینر را برمی‌گرداند و هر ترکیبی از نمونه‌های Circle، Ellipse و Line می‌تواند قبل از افزودن Graph به صفحه به آن اضافه شود.

آیا Circle و Ellipse یک نوع هندسی مشترک دارند؟

خیر. Circle یک نقطه مرکزی و شعاع است (PosX, PosY, Radius); Ellipse یک جعبه محدود کننده است (Left, Bottom, Width, Height). هر دو از Shape مشتق می‌شوند، اما هیچ‌کدام نقطه یا نوع مستطیلی مشترکی با دیگری ندارند.

آیا رسم شکل‌ها با Graph همانند رندر کردن یک صفحه به تصویر است؟

خیر. Graph، Shape، Circle، Ellipse و Line هندسه برداری جدیدی را در محتوای صفحه هنگام تولید سند می‌سازند. تبدیل یک صفحه موجود به تصویر رستر یک قابلیت جداگانه است که توسط BmpDevice، JpegDevice و TiffDevice انجام می‌شود.

متد GraphInfo.IsDoubled() چه کاری انجام می‌دهد؟

این خط را به عنوان یک خط دوگانه علامت‌گذاری می‌کند و هیچ ویژگی دیگری از خط را تغییر نمی‌دهد. این یک پرچم بولی است که از طریق IsDoubled() / IsDoubled(value) خوانده و تنظیم می‌شود، همراه با سایر ویژگی‌های خط GraphInfo.


API Reference خلاصه

کلاس/متدتوضیح
Graphکانتینر شکل در صفحه قرار می‌گیرد؛ خود را با Left()، Top()، Width()، Height() موقعیت می‌دهد
Graph.Shapes()مقدار std::vector<std::unique_ptr<Shape>> ترسیم‌شده توسط این کانتینر را برمی‌گرداند
Graph.GraphInfo() / GraphInfo(value)دریافت/تنظیم استایل stroke و fill خود کانتینر
Graph.Border() / Border(value)دریافت/تنظیم BorderInfo که چارچوب کانتینر را تعیین می‌کند
Shapeپایهٔ انتزاعی برای Circle، Ellipse و Line؛ GraphInfo() و CheckBounds() را در دسترس می‌گذارد
Shape.CheckBounds(w, h)گزارش می‌دهد که آیا هندسهٔ شکل در داخل یک محفظه با عرض/ارتفاع داده شده جا می‌گیرد یا خیر
Circleشکل دایره: PosX()، PosY()، Radius()
Ellipseشکل بیضی: جعبهٔ محدوده از طریق Left()، Bottom()، Width()، Height()
Lineشکل خط/مسیر: PositionArray(), یک std::vector<float> تخت از مختصات x, y
GraphInfoاستایل خط/پر: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY()
BorderInfoحاشیهٔ کانتینر به ازای هر لبه: Left(), Right(), Top(), Bottom() (هر کدام یک GraphInfo)، به‌علاوه RoundedBorderRadius()
BorderSideEnum انتخاب لبه‌ها هنگام ساختن یک BorderInfo: None, Left, Top, Right, Bottom, All, Box

همچنین ببینید:

 فارسی