Dessiner des graphiques vectoriels sur une page PDF

Dessiner des graphiques vectoriels sur une page PDF

Dessiner des graphiques vectoriels sur une page PDF

Aspose.PDF FOSS pour C++ inclut un petit API de graphiques vectoriels pour dessiner des formes directement sur une page PDF pendant la construction d’un document. Le point d’entrée est Graph, un conteneur placé sur une page qui contient une collection d’objets Shape ; trois formes concrètes — Circle, Ellipse et Line — dérivent de Shape et chacune exprime sa géométrie différemment. Le style de trait et de remplissage par forme provient de GraphInfo, et le conteneur Graph lui-même possède un BorderInfo pour le cadrage. Cela n’est pas lié à la rasterisation de page (BmpDevice, JpegDevice, TiffDevice), qui convertit le contenu existant d’une page en formats d’images raster plutôt que de dessiner une nouvelle géométrie.


Le conteneur de graphe et l’ajout de formes à une page

Graph se positionne et se dimensionne sur la page via Left(), Top(), Width() et Height(), et son indicateur IsChangePosition() contrôle si cette position peut se déplacer par rapport au reste du contenu de la page. Les formes qu’il dessine résident dans le vecteur renvoyé par Shapes() — std::vector<std::unique_ptr<Shape>> — qui est rempli en construisant une forme, en la configurant, puis en la déplaçant dans ce vecteur. Une fois construite, la Graph elle-même est placée sur la page via Page.Paragraphs().Add(), la même collection utilisée pour les autres contenus au niveau de la page.

#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");

Dessiner des cercles et des ellipses

Circle et Ellipse expriment chacun la géométrie sous forme de propriétés numériques simples plutôt qu’un type point ou rectangle partagé. Circle est un point central et un rayon — PosX(), PosY(), Radius() — tandis que Ellipse est une boîte englobante — Left(), Bottom(), Width(), Height(). Les deux héritent de CheckBounds(containerWidth, containerHeight) depuis Shape, qui indique si la géométrie actuelle de la forme tient à l’intérieur d’un conteneur de la taille donnée sans modifier la forme elle-même.

#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);

Dessiner des lignes avec PositionArray

Line stocke sa géométrie différemment de Circle et Ellipse: PositionArray() renvoie un std::vector<float> plat contenant une paire x, y pour chaque point traversé par la ligne, plutôt qu’un ensemble fixe de propriétés nommées. Deux points (quatre valeurs) dessinent un segment droit; des paires supplémentaires dessinent un chemin à plusieurs segments à travers ces points dans l’ordre. Comme les autres formes, Line remplace CheckBounds(containerWidth, containerHeight) de 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);

Styliser les formes avec GraphInfo et BorderInfo

Chaque forme lit et écrit son style de contour et de remplissage via Shape.GraphInfo() / GraphInfo(value). GraphInfo utilise par défaut un LineWidth() de 1.0f avec un DashArray() vide, et expose également Color(), FillColor(), DashArray()/DashPhase() pour les contours pointillés, IsDoubled() pour une ligne doublée, et SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() et RotationAngle() pour transformer le contour. Graph possède lui-même un BorderInfo, défini via Border(), qui regroupe un GraphInfo par arête — Left(), Right(), Top(), Bottom() — plus un RoundedBorderRadius(), et peut être construit en nommant les arêtes à styliser avec un drapeau BorderSide (BorderSide::Left | BorderSide::Right, ou BorderSide::All pour chaque arête).

#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);

Conseils et meilleures pratiques

  • Appelez CheckBounds sur le Width()/Height() propre du Graph propriétaire, pas sur la boîte média complète de la page— la vérification valide la géométrie d’une forme par rapport à la taille du conteneur que vous fournissez, elle ne regarde pas automatiquement la page.
  • Ajoutez les formes à Shapes() avant d’ajouter le Graph à Page.Paragraphs()— la construction d’un Circle, Ellipse ou Line n’a aucun effet visible tant qu’elle n’est pas à la fois ajoutée à son Graph propriétaire et que ce Graph est ajouté à une page.
  • Regroupez les formes liées sous un seul Graph plutôt que sous un Graph par forme; Left()/Top()/Width()/Height() positionnent l’ensemble du conteneur une fois, et chaque forme dans Shapes() est dessinée par rapport à celui-ci.
  • Définissez Shape.GraphInfo() explicitement pour les formes qui nécessitent un remplissage visible ou un contour non par défaut— le GraphInfo par défaut a une largeur de ligne de 1.0f, aucun remplissage et un DashArray() vide.
  • Construisez Line.PositionArray() en tant que paires x0, y0, x1, y1, … dans l’ordre où le chemin doit être tracé — un vecteur de longueur impaire décrit un point incomplet.

Problèmes courants

ProblèmeCauseCorrection
Un Circle, Ellipse ou Line n’apparaît jamais sur la page enregistréeLa forme a été construite mais n’a jamais été ajoutée à son Graph’s Shapes(), ou le Graph n’a jamais été ajouté à la pagePoussez la forme sur graph->Shapes() et appelez page.Paragraphs().Add(graph)
La forme se dessine avec un trait noir fin par défautShape.GraphInfo() n’a jamais été définiAppelez shape->GraphInfo(customGraphInfo) avant d’ajouter la forme à Shapes()
Line est manquant ou ressemble à un point uniquePositionArray() contient moins de deux paires (x, y), ou un nombre impair de valeursFournissez au moins quatre valeurs en tant que x0, y0, x1, y1
Seules certaines arêtes de la bordure du conteneur sont styliséesBorderInfo a été construit avec un masque BorderSide qui exclut certaines arêtesUtilisez BorderSide::All, ou combinez avec OR chaque drapeau BorderSide nécessaire
CheckBounds renvoie de façon inattendue falseLes dimensions passées à CheckBounds ne correspondent pas au conteneur dans lequel la forme est réellement dessinéePassez le Width()/Height() actuel du Graph propriétaire

FAQ

Quelle est la différence entre Circle et AnnotationType::Circle?

Circle (ce guide) est une forme de dessin qui dessine directement dans le contenu de la page via un Graph. AnnotationType::Circle et CircleAnnotation appartiennent à un API d’annotations distinct et représentent une annotation de balisage en forme de cercle — les deux ne sont pas liés malgré le nom commun.

Un seul Graph peut-il contenir plus d’une forme?

Oui. Graph.Shapes() renvoie le std::vector<std::unique_ptr<Shape>> complet pour ce conteneur, et tout mélange d’instances Circle, Ellipse et Line peut être ajouté avant que le Graph ne soit ajouté à la page.

Circle et Ellipse partagent-ils un même type de géométrie?

Non. Circle est un point central et un rayon (PosX, PosY, Radius); Ellipse est une boîte englobante (Left, Bottom, Width, Height). Les deux dérivent de Shape, mais aucun ne partage un point ou un type de rectangle commun avec l’autre.

Le dessin de formes avec Graph est-il identique au rendu d’une page sous forme d’image?

Non. Graph, Shape, Circle, Ellipse et Line créent une nouvelle géométrie vectorielle dans le contenu d’une page lors de la génération du document. Convertir une page existante en image raster est une capacité distincte, gérée par BmpDevice, JpegDevice et TiffDevice.

Que fait GraphInfo.IsDoubled()?

Il marque le trait comme une ligne double plutôt que de modifier une autre propriété du trait. C’est un drapeau booléen lu et défini via IsDoubled()/IsDoubled(value) aux côtés des autres propriétés de trait GraphInfo.


Résumé API Reference

Classe/MéthodeDescription
GraphConteneur de forme placé sur une page ; se positionne avec Left(), Top(), Width(), Height()
Graph.Shapes()Renvoie le std::vector<std::unique_ptr<Shape>> dessiné par ce conteneur
Graph.GraphInfo() / GraphInfo(value)Obtient/définit le style de contour et de remplissage propre du conteneur
Graph.Border() / Border(value)Obtient/définit le BorderInfo encadrant le conteneur
ShapeBase abstraite pour Circle, Ellipse et Line; expose GraphInfo() et CheckBounds()
Shape.CheckBounds(w, h)Rapporte si la géométrie de la forme s’adapte à l’intérieur d’un conteneur de la largeur/hauteur donnée
CircleForme circulaire : PosX(), PosY(), Radius()
EllipseForme elliptique : boîte englobante via Left(), Bottom(), Width(), Height()
LineForme de ligne/chemin : PositionArray(), un std::vector<float> plat de coordonnées x, y
GraphInfoStyle du trait/remplissage: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY()
BorderInfoBordure du conteneur par arête: Left(), Right(), Top(), Bottom() (chacun étant un GraphInfo), plus RoundedBorderRadius()
BorderSideEnum sélectionnant les arêtes lors de la construction d’un BorderInfo: None, Left, Top, Right, Bottom, All, Box

Voir aussi

 Français