رسم الرسومات المتجهية على صفحة PDF
رسم الرسومات المتجهية على صفحة PDF
Aspose.PDF FOSS for 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المالك، وليس صندوق الوسائط الكامل للصفحة — الفحص يتحقق من هندسة الشكل مقابل أي حجم حاوية تمرره، ولا ينظر إلى الصفحة تلقائيًا. - أضف الأشكال إلى
Shapes()قبل إضافةGraphإلىPage.Paragraphs()— إنشاء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’s Shapes()، أو لم يُضاف Graph إلى الصفحة | ادفع الشكل إلى graph->Shapes() واستدعِ page.Paragraphs().Add(graph) |
| يرسم الشكل بخط أسود رفيع افتراضي | لم يتم تعيين Shape.GraphInfo() | استدعِ shape->GraphInfo(customGraphInfo) قبل إلحاق الشكل بـ Shapes() |
الـ Line مفقود أو يبدو كنقطة واحدة | الـ PositionArray() يحتوي على أقل من زوجين (x, y)، أو عدد قيم فردي | قدّم على الأقل أربع قيم كـ x0, y0, x1, y1 |
| فقط بعض حواف حدود الحاوية مُنسقة | تم إنشاء الـ BorderInfo بقناع BorderSide يستبعد بعض الحواف | استخدم BorderSide::All، أو اجمع باستخدام OR كل علم BorderSide المطلوب |
الـ 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) | يحصل/يضبط نمط الحد والملء الخاص بالحاوية |
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() |
BorderSide | تعداد يختار الحواف عند إنشاء BorderInfo: None, Left, Top, Right, Bottom, All, Box |