-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathartefact-fr.pillar
845 lines (599 loc) · 47.8 KB
/
artefact-fr.pillar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
! Générer des documents PDF avec Artefact
Le format PDF d'Adobe est probablement l'un des formats de documents electroniques le plus répandu. Utilisé quotidiennement, il rend quantité de services en permettant la production de documents graphiques, lisibles et échangeables entre pratiquement toutes les plate-formes matérielles ou logicielles existantes. Si vous recevez une facture, suite à un achat sur un site de e-commerce ou si vous téléchargez un rapport, un livre, une thèse ou encore un formulaire administratif, ces fichiers seront fort probablement des documents PDF consultables sur votre ordinateur, votre téléphone ou votre tablette. Sur l'ensemble de ces supports, ils conserveront une apparence identique. Pour les programmeurs, ce format est devenu incontournable et générer du PDF fait partie de la trousse à outils de base d'un outil de développement. Pour Pharo, c'est le framework Artefact qui prend en charge la conception et la génération de documents PDF. Artefact est développé par O. Auverlot et G. Larcheveque.
!!Aux sources du projet
Artefact est un framework PDF original. Il base la définition d'un document PDF sur une description objet. Pour lui, l'intégralité des éléments composant un fichier PDF se résume à une arborescence d'objets. Le document est un objet contenant d'autres objets correspondant à des pages. Sur chacune des pages, les éléments imprimables ou non visibles sont également des objets. Ceux ci ont ainsi la possibilité d'être réutilisés dans un même document mais aussi dans plusieurs documents. Ces éléments peuvent être aussi simple qu'un texte ou une image mais également, être un composant complexe doté d'un comportement évolué et d'une apparence particulière. Artefact propose ainsi par défaut des éléments tels que des paragraphes ou encore des tableaux permettant de générer rapidement des rapports. La force de ces éléments est qu'ils sont indépendants les uns des autres. L'ordre dans lequel vous les positionnez dans le document n'influe pas sur leur apparence. Contrairement à de nombreux frameworks PDF qui exploitent une notion de flux dans la définition des styles (un texte bleu sera suivi d'un autre texte bleu en l'absence d'une directive de style différente), Artefact considère que chaque élément intègre une feuille de style qui lui est propre. Si un attribut n'est pas défini dans l'élément, Artefact exploite alors une feuille de style par défaut définie au niveau du document.
Cette autonomie des éléments et cette gestion des styles sont une caractéristique forte d'Artefact. Elles permettent de générer facilement un document et de le personnaliser rapidement pour une exploitation particulière. Efficacité, productivité et extensibilité ont été les mots clés qui ont guidé la conception du framework.
!!Concept, caractéristiques et limitations
Les concepts d'Artefact sont maintenant stabilisés et il est déjà utilisé dans le monde professionnel par des entreprises utilisant Pharo. Pourtant, c'est encore un frameworks jeune. Pour cette raison, il est important d'énumérer ses fonctionnalités actuelles et de connaître ses limitations.
Artefact offre la définition d'un document PDF, permet de définir des meta informations telles que le titre ou encore l'auteur, gère les options d'affichage lors de l'ouverture du document dans un lecteur compatible avec cette fonctionnalité et sait générer des documents PDF compressés.
Chaque page d'un document PDF peut se voir attribuer un format et une orientation particulière. Artefact propose par défaut un ensemble de formats de documents couvrant les besoins courants et il vous est possible de l'étendre pour des usages particuliers. Une page obtient sa position définitive dans un document qu'à partir du moment ou elle a été ajoutée au document. Chaque page est autonome et cela permet donc de générer des documents à architecture variable.
Sur chaque page, Artefact dispose des éléments simples ou complexes. Un élément complexe est généralement défini à l'aide des éléments simples ou d'autres éléments complexes. Chaque élément est indépendant et se positionne par rapport au coin supérieur gauche d'une page. Artefact offre une gestion des niveaux de gris ou l'utilisation de couleurs définies selon le modèle RVB (chaque composante de la couleur est représentée par un octet). Les fontes de caractères sont celles imposées par la spécification PDF mais Artefact ne supporte pas les fontes true type (TTF). Il est possible d'insérer des images dans un document PDF mais seul le format JPEG est actuellement géré. Artefact ne gère pas la définition de champs interactifs de saisie, l'intégration de code Javascript ou encore les aspects sécurités de PDF tels que les certificats.
Bien évidemment, ces spécification sont susceptibles d'évoluer au fur et à mesure des évolutions du framework. Artefact possède une architecture simple facilitant l'extensibilité et le support de nouvelles fonctionnalités. Restez connecté, le meilleur reste à venir.
!!Prise en main d'Artefact en 10 minutes
Vous programmez en Pharo et vous voulez générer des documents PDF dans votre application. Vous ne savez pas comment faire ? Ne soyez pas inquiet, dans quelques minutes, vous aurez produit votre premier document PDF.
Tout d'abord, il vous faut ajouter le framework Artefact à votre environnement de travail Pharo. La bonne nouvelle est qu'aucune librairie native n'est nécessaire pour faire fonctionner Artefact. Celui ci est écrit entièrement en Pharo. Quelque soit votre plateforme d'exécution (Microsoft Windows, Mac OS X, Linux, Android, IOS, etc.), Artefact sera disponible et utilisable.
!!!Installation du projet Artefact
Le projet Artefact est disponible sur le site web de dépot SmalltalkHub. Pour installer Artefact, executez les expressions suivantes:
La configuration déclenche le téléchargement d'Artefact ainsi que celui du projet Unit destiné à la manipulation des différentes unités de mesure. Par défaut, la version récupérée sera une version stable (#stable) destinée à la mise en production.
[[[
Gofer new
smalltalkhubUser: '' project: 'RMoD/Artefact';
package: 'ConfigurationOfArtefact';
load.
ConfigurationOfArtefact load
]]]
Vous pouvez maintenant parcourir les principaux paquets et classes composant Artefact. Le paquet Artefact-Demos contient de nombreux exemples d'utilisation et permet une prise en main en douceur du framework. Le paquet Artefact contient les éléments principaux tels que les documents, les pages ou encore les feuilles de styles mais également une documentation électronique accessible via le Help Browser. Dans Artefact-Elements-Basic et Artefact-Elements-Composites, vous trouvez les différents composants (texte, formes géométriques, images, etc) proposés de base par le framework. Les fontes sont définies dans le paquet Artefact-Fonts et les formats de documents (A4, A3, ebook, etc.) dans le paquet Artefact-Formats.
!!! First Demoes
The best way to start with Artefact is to look at Artefact-Demos package and to run each ==PDFDemos== class methods.
By default each generation result is written in the default pharo directory but you can define your own in the ==demoPath== method
example:
[[[
PDFDemos>>demoPath
^ '/Users/pharo/pdf/'
]]]
If you want to run all demos, just execute: ==PDFDemos runAllDemos==
!!!"Hello World!"
Vous allez maintenant créer votre premier document PDF, le plus simple qui soit, un texte sur une page. Pour cela, vous devez définir une instance d'un document PDF contenant une page, sur laquelle vous positionnerez un composant texte.
[[[
PDFDocument new
exportTo: 'helloworld.pdf' asFileReference writeStream
]]]
Une fois l'instance de PDFDocument créée, celle ci est exportée à l'aide d'un flot vers un fichier nommé ==helloworld.pdf==. Par défaut, le document PDF produit est placé dans le répertoire de Pharo. L'ouverture de ce fichier à l'aide d'un lecteur PDF indique que le document est vide. C'est un résultat normal puisque vous n'avez pas encore défini et ajouté une page au contenu du document.
Enrichissons le code précédent en ajoutant un page au document.
[[[
PDFDocument new
add: PDFPage new;
exportTo: 'helloworld.pdf' asFileReference writeStream
]]]
L'ouverture de ce fichier donne un résultat différent puisque votre document contient maintenant une page vierge. Artefact suit la philosophie "Convention over configuration". Seuls les paramètres spécifiques doivent être définis. Ainsi, par défaut, Artefact a attribué un format A4 à votre document, fixé l'orientation en portrait et initialisé les méta informations avec des valeurs par défaut.
Nous terminons notre premier document en ajoutant un composant texte sur la page.
[[[
PDFDocument new add:
(PDFPage new add:
(PDFTextElement new text: 'Hello World!'; from: 10mm @ 10mm));
exportTo: 'helloworld.pdf' asFileReference writeStream
]]]
Pour contenir le texte, nous avons besoin d'un composant de type ==PDFTextElement== que nous ajoutons sur la page. Nous définissons ensuite sa position à l'aide du message ==from:==. L'utilisation du framework Unit autorise l'utilisation d'unités métriques tels que les millimètres (mm), les centimètres (cm) ou encore les pouces (inch). Ces coordonnées sont définies à partir de l'angle supérieur gauche de la page.
Artefact utilise un ensemble de valeurs par défaut afin de réduire au maximum le nombre de lignes de code nécessaires à la production d'un document. Le texte est donc écrit en noir, utilise une fonte (Helvetica) et une taille par défaut.
Ce premier exemple a permis d'introduire les concepts de bases d'Artefact et a démontré la facilité avec laquelle il vous est possible de générer un document PDF à partir de Pharo. Dans la suite de ce chapitre, nous allons approfondir vos connaissances sur le framework Artefact et vous permettre de créer des documents PDF complexes.
!!Définir un document
Artefact représente un document PDF à l'aide de l'objet PDFDocument. Cet objet est un conteneur destiné à recevoir des pages. C'est l'ordre dans lequel ces pages sont ajoutées qui définit l'organisation des données au sein de l'objet ==PDFDocument== et non pas l'ordre dans lequel les pages sont créées. Ce mode de fonctionnement vous permet donc de générer des documents dont le contenu sera dans un premier temps dynamiquement produit puis organisé dans un second temps. L'objet ==PDFDocument== dispose également d'options avancées portant sur le format du document, la gestion de la compression, l'ouverture dans le lecteur PDF ou encore la définition de méta informations.
!!!!Ajouter des pages
Pour ajouter des pages dans un document, vous disposez d'un message nommée ==add:== qui ajoute la page à la suite de celles déjà présentes dans le document. Le fonctionnement est proche d'une pile FIFO (First In First Out). Lors de la génération du document, Artefact parcoure la liste des pages en partant de la plus anciennement ajoutée jusqu'à la dernière. Le script suivant définit un document d'une seule page vide.
[[[
PDFDocument new
add: PDFPage new;
exportTo: 'EmptyPage.pdf' asFileReference writeStream
]]]
!!!!Spécifier les propriétés du documents
Un document PDF peut être configuré pour choisir le format utilisé et gérer la compression.
!!!!!Format et orientation du document
Par défaut, un document est généré en respectant le format A4 mais celui ci n'est pas le seul disponible dans Artefact. Dans le paquet Artefact-Formats, une liste de formats a été définie et couvre de nombreux besoins. Vous pouvez ainsi produire des documents en A3 (==PDFA3Format==), au format Letter (==PDFLetterFormat==) mais aussi dans un format adapté aux liseuses électroniques (==PDFEbookFormat==). Si vous avez besoin d'un format particulier, il vous suffit de le définir. Un format est simplement exprimé par la valeur de retour du message ==defaultSize==.
L'objet ==PDFDocument== accepte le message ==format:== permettant de spécifier le format de toutes les pages du document. Pour chaque page, cette valeur sera prise par défaut si aucun format particulier n'est défini à son propre format. L'exemple suivant génère un document utilisant le format A3:
[[[
PDFDocument new
format: PDFA3Format new;
add: PDFPage new;
exportTo: 'A3.pdf' asFileReference writeStream
]]]
Ces formats sont également utilisés pour spécifier l'orientation des pages en choisissant entre le mode portrait ou le mode paysage. Les deux méthodes sont ==setPortrait== et ==setLandscape==.
L'exemple suivant génère un document dans lequel les pages sont au format A3 et orientées en mode paysage.
[[[
PDFDocument new
format: PDFA3Format new setLandscape;
add: PDFPage new;
exportTo: 'A3landscape.pdf' asFileReference writeStream
]]]
La sélection par défaut du mode paysage n'exclut pas la possibilité pour une page particulière d'être orientée en mode portrait. Artefact supporte parfaitement des pages de différents formats et de différentes orientations au sein d'un seul et même document.
!!!!!Gestion de la compression
Le format PDF permet de comprimer les données et c'est une bonne chose. Un document PDF peut contenir d'importants volumes de données dont la présentation graphique doit être décrite avec précision. Afin de réduire au maximum le poids des documents générés, Artefact applique par défaut un algorithme de compression. Si par curiosité, vous voulez désactiver cette option et analyser les données produites, vous disposez de la méthode ==uncompressed== qui désactive la compression.
L'exemple suivant génère un fichier PDF non compressé:
[[[
PDFDocument new
uncompressed;
add: PDFPage new;
exportTo: 'uncompressed.pdf' asFileReference writeStream
]]]
Une autre message, nommé ==compressed==, réactive la compression si celle ci a été préalablement désactivée.
!!!!!Contrôler l'ouverture du document
Le lecteur Adobe Acrobat supporte différents modes d'affichage à l'ouverture d'un document PDF. Le mode sélectionné est renseigné directement dans le document PDF. Artefact permet de spécifier les différentes directives d'affichage à destination du lecteur PDF. Notez que si votre lecteur PDF n'est pas compatible avec ces options, elles seront ignorées.
Les directives fixant le mode d'affichage à l'ouverture d'un document PDF sont réparties en deux catégories: celles fixant la dimension des pages (==fullPage==, ==fullWidth==, ==real== et ==zoom:==) et celles fixant l'organisation des pages sur l'écran (==singlePage==, ==twoPages== et ==continuousPages==). Ces différentes méthodes s'appliquent directement à une instance de l'objet ==PDFDocument==.
Avec ==fullPage==, chaque page du document occupe l'intégralité de l'espace d'affichage disponible. Avec ==fullWidth==, l'affichage est optimisé en fonction de la largeur des pages. Avec ==real==, l'affichage respecte les dimensions fixées dans le document PDF.
L'exemple suivant génère un document qui occupera tout l'espace d'affichage disponible:
[[[
pdfdoc := PDFDocument new fullPage.
]]]
Avec le message ==zoom:==, vous fixez un rapport d'agrandissement exprimé en pourcentage. L'exemple suivant applique un zoom de 400% à l'ouverture du document:
[[[
pdfdoc := PDFDocument new zoom: 400.
]]]
Vous pouvez également choisir d'afficher les pages une par une (==singlePage==), deux par deux (==twoPages==) ou les unes à la suite des autres (==continousPages==) comme dans l'exemple suivant:
[[[
pdfdoc := PDFDocument new continousPages.
]]]
Ces différentes messages sont également utilisables conjointement. L'exemple suivant demande l'affichage du document avec un zoom de 200% et un affichage continu des pages:
[[[
pdfdoc := PDFDocument new zoom: 200; continuousPages.
]]]
Ces différentes options sont pratiques mais n'oubliez pas que leur fonctionnement dépend des capacités du lecteur PDF que vous utilisez.
!!!!Renseigner les méta informations
Chaque document PDF contient un ensemble d'informations sur ses origines. Ces données ne sont pas à négliger, en particulier si votre document est destiné à alimenter une solution de type GED (Gestion Electronique de Documents) ou fait parti d'un workflow éditorial. Grâce à ces informations, il est possible de faire des recherches parmi un ensemble de documents PDF et de sélectionner par exemple, ceux écrits par un auteur précis ou encore ceux pour lesquels certains mots clés ont été spécifiés.
Artefact implémente ces informations à l'aide de l'objet PDFMetaData. A chaque nouvelle instance de PDFDocument, une instance de PDFMetaData est associée et est accessible via la variable d'instance metaData. Par défaut, le producteur est fixé à 'Artefact' pour renseigner la nature du logiciel utilisé pour générer le fichier PDF. Vous pouvez indiquer le titre du document, un sujet ou un court résumé, préciser le nom du ou des auteurs, fixer une liste de mots clés et enfin définir le créateur du document.
L'exemple suivant génére un nouveau document et renseigne ses méta informations:
[[[
pdfdoc := PDFDocument new.
pdfdoc metaData
title: 'Document title';
subject: 'subject of the document';
author: 'The Pasta Team';
keywords: 'cool rock best';
creator: 'Pharo'.
]]]
!!Pages, formats et modèles
Les pages sont les supports d'écriture et de dessin présents dans vos documents PDF. Une page a une dimension, une orientation et une position au sein du document PDF. Une page peut être construite à partir d'un modèle qui fournit un fond de page sur lequel est déposé le contenu.
!!!Création des pages
Une page est représentée par une instance de l'objet ==PDFPage==. La façon la plus simple de construire une nouvelle page est donc:
[[[
page := PDFPage new.
]]]
A ce stade, vous pouvez écrire et dessiner sur la page à l'aide des composants graphiques fournis par Artefact. Une fois le contenu de la page défini, il vous faut ajouter la page dans le document PDF. Une page est ajoutée à l'aide du message ==add:== à la suite des pages déjà présentes dans le document.
[[[
pdfdoc := PDFDocument new.
page := PDFPage new.
pdfdoc add: page.
]]]
Par défaut, une page adopte les dimensions et l'orientation du document. Si votre document PDF est en A4 paysage, toutes les pages ajoutées utiliseront ces paramètres. Artefact permet d'attribuer à chaque page des dimensions et une orientation spécifiques. Vous pouvez ainsi mélanger dans un même document des pages ayant des caractèristiques différentes. Certaines seront en portrait, d'autres en paysage. D'autres seront en A3 alors que le document sera en A4.
Pour cela, chaque instance de ==PDFPage== sait répondre au message ==format:== qui reçoit une instance de ==PDFFormat==. L'exemple qui suit génère un document de deux pages. La première utilise le format par défaut du document, la seconde est en A4 paysage.
[[[
pdfdoc := PDFDocument new.
page1 := PDFPage new.
page2 := PDFPage new format: (PDFA3Format new setLandscape).
pdfdoc add: page1; add: page2.
]]]
!!!Modèle
Un modèle (==PDFTemplate==) hérite de la classe ==PDFPage==. Il s'agit d'une page ayant un contenu prédéfini et constituant le fond de page sur lequel vous écrivez ou dessinez. Un fond de page peut être constitué par un entête de lettre, un haut et un bas de page pour un rapport, une surface délimitée pour des travaux de mise en page. Le paquet Artefact-Templates propose deux exemples de modèles pour produire la pochette d'un disque compact ou d'un DVD. Le code suivant produit une page A4 sur laquelle sont dessinés les contours d'une pochette d'un CD.
[[[
pdfdoc := PDFDocument new.
cover := PDFCompactDiscTemplate new.
]]]
Un modèle est défini à l'aide de la méthode ==drawTemplate== qui ajoute les composants graphiques d'Artefact à la page et constitue ainsi le fond de page.
+Page and Document Elements>file://figures/PDFPage.png|width=60|label=figElements+
!! Elements
A ==PDFElement== is a reusable component that represent a text, an image, a geometric shape or even a complex graph or table.
There are two kinds of ==PDFElement== (see Figure *figElements*):
- Simple elements inherit from ==PDFBasic== (primitive operation in the pdf specification)
- Composite elements inherit from ==PDFComposite== (a wrap between multiple ==PDFElements== whether they are basic or composite)
Simple elements:
- ==PDFBezierCurveElement==
- ==PDFCircleElement==
- ==PDFLineElement==
- ==PDFPolygonElement==
- ==PDFRectElement==
- ==PDFJpegElement==
- ==PDFTextElement==
+Composite Elements>file://figures/PDFComposite.png|width=60|label=figComposite+
Composite elements (see Figure *figElements*):
- ==PDFFormattedTextElement==
- ==PDFParagraphElement==
- ==PDFArrowElement==
- ==PDFDoubleArrowElement==
- ==PDFCellElement==
- ==PDFDataTableElement==
- ==PDFDataTableWithColumnsCaptionElement==
- ==PDFDataTableWithRowsCaptionElement==
Each ==PDFElement== have a set of properties that define its appearance (text color, font, dots,...).
Those properties are grouped in a stylesheet owned by each element. Every element controls its own appearance and doesn't
affect other (in opposition as many PDF framework that use a flow logic). This behavior allow you to move or even use in
multiple pages or document the same element.
!!Composition et agencement du contenu rédactorial
Le contenu des pages est défini à l'aide de composants graphiques. C'est une idée forte dans Artefact qui est basé sur le concept de composants réutilisables permettant d'écrire et de dessiner sur une page. Artefact dispose de composants elémentaires qui réalisent des opération simples tel que dessiner une ligne, mais également, de composants complexes pouvant, par exemple, afficher des données dans un tableau ou encore générer un code barre. Bien évidemment, il est possible de définir et de diffuser de nouveaux composants. Artefact utilisant le principe de composition, un composant complexe est logiquement un assemblage d'autres composants.
!!!Comportement générique des composants
Les composants graphiques d'Artefact adoptent un comportement générique afin de gérer leur positionnement sur la page ainsi que leur dimensionnement. Un repère orthonormé, dont l'origine est en haut à gauche de la page, est utilisé pour indiquer l'emplacement d'un composant. Les valeurs sont exprimées à l'aide d'unités telles que mm, cm ou inch.
!!!!Positionnement des composants
La méthode de classe ==from:== permet d'instancier un composant graphique et de fixer sa position. L'exemple suivant utilise un composant ==PDFTextElement== et la place à 15 mm du bord gauche et à 30 mm du haut de la page:
[[[
PDFTextElement from: 15mm @ 30 mm
]]]
En complément du positionnement, Artefact propose également des constructeurs fixant simultanément l'emplacement et la dimension d'un composant.
!!!!Dimensionnement des composants
Vous disposez de deux moyens pour indiquer les dimensions d'un composant. Avec le message ==from:to:==, vous préciser la position de départ et la position de fin d'un composant. L'exemple suivant dessine un rectangle, dont l'origine est 15 mm du bord gauche de la page et 30 mm du haut de la page. Son dessin se termine à 90 mm du bord gauche de la page età 80 mm du haut de la page:
[[[
PDFRectElement from: 15mm @ 30 mm to: 90mm @ 80mm
]]]
Avec le message ==from:dimension:==, vous fixez la position de départ du composant et indiquez ses dimensions.
[[[
PDFRectElement from: 15mm @ 30 mm dimension: 50mm @ 40mm
]]]
Les messages ==width== et ==height== retournent la largeur et la hauteur d'un composant.
!!!Les composants élémentaires
Le paquet Artefact-Elements-Basic contient les composants graphiques de base. Ils sont répartis dans trois catégories:
l'écriture de texte, le dessin de forme géométrique et l'insertion d'une image.
Pour écrire du texte sur une page, vous devez utiliser le composant ==PDFTextElement==. Le texte à écrire est renseigné à
l'aide de la méthode ==text==. La méthode de classe ==from:text:== permet faire ces opérations rapidement:
[[[
PDFTextElement from: 15mm @ 30mm text: 'hello!'
]]]
Artefact dispose de composants pour les principales formes géométriques. La classe ==PDFLineElement== dessine une ligne dont les coordonnées de départ et de fin sont fixées à l'aide ==from:to:==
[[[
PDFLineElement from: 15mm @ 30mm to: 90mm@170mm
]]]
La méthode de class ==from:angle:length:== permet de dessiner une ligne à partir d'une coordonnée de départ, d'un angle et d'une longueur de tracé.
[[[
PDFLineElement from: 10mm @ 20mm angle: 70 length: 50mm
]]]
Un rectangle est représenté à l'aide de ==PDFRectElement==. La hauteur et la largeur du rectangle peuvent être spécifiés en fournissant les dimensions ou en fixant la position de fin du tracé. Les deux exemples qui suivent sont équivalents:
[[[
PDFRectElement from: 10 mm@10mm dimension: 100 mm @ 30 mm.
]]]
[[[
PDFRectElement from: 10mm@10mm to: 110mm@40mm
]]]
Artefact fourni également une classe ==PDFPolygonElement== destinée au dessin de polygones. Cette forme géométrique est définie par une position de départ et une suite de points composant les différents segments.
[[[
PDFPolygonElement from: 10mm@10mm points: {
30mm@30mm.
15mm@40mm.
5mm@20mm
}
]]]
Les cercles sont définis à l'aide de la classe ==PDFCircleElement== et de la méthode de classe ==center:radius:== qui spécifie la position du centre du cercle et son rayon.
[[[
PDFCircleElement center: 100mm@100mm radius: 50mm
]]]
Une courbe de Bezier est représentée par la classe ==PDFBezierCurveElement== et est définie par une position de départ et une suite de points.
[[[
PDFBezierCurveElement from: 10 mm @ 50 mm points:{
0 mm @ 0 mm.
100 mm @ 20 mm.
150 mm @ 0 mm.
50 mm @ 50 mm
}
]]]
Artefact autorise l'insertion d'images au format JPEG dans un document PDF. Un objet ==PDFJpegElement== peut être instancié facilement à l'aide des messages de classe ==fromStream:== et ==from:dimension:fromStream:==. A l'aide des messages ==width== et ==height==, il est possible de fixer les dimensions d'une image tout en respectant le ratio hauteur/largeur de l'image d'origine. L'exemple qui suit génère un document PDF contenant une page. Sur celle-ci, une image est positionnée en deux endroits différents. Dans le premier cas, l'image mesure 80mm de largeur sur 30mm de hauteur. Dans le second cas, la largeur est fixée à 80mm et la hauteur est automatiquement calculée pour ne pas déformer l'image.
[[[
| pdf page |
pdf := PDFDocument new.
page := PDFPage new.
page
add:
(PDFJpegElement
from: 10 mm @ 10 mm
dimension: 80 mm @ 30 mm
fromStream: (FileStream fileNamed: '/home/enterprise/image.jpg')).
page
add:
((PDFJpegElement fromStream: (FileStream fileNamed: '/home/enterprise/image.jpg'))
from: 10 mm @ 50 mm;
width: 80 mm).
pdf add: page.
pdf exportTo: (FileStream forceNewFileNamed: '/home/enterprise/image.pdf')
]]]
Les composants élémentaires réalisent des opérations graphiques extrémement simples tel que placer un texte sur une page ou dessiner une ligne. Ils constituent les briques essentielles pour la constitution des composants de haut niveau.
!!!Les composants de haut niveau
Artefact est livré avec un ensemble de composants riches, regroupés dans le paquet Artefact-Elements-Composites. Ces composants sont le résultat de l'assemblage de composants simples et d'autres composants de haut niveau. Ces éléments permettent de créer des mises en page et des contenus complexes avec un minimum de code et avec un fort niveau de factorisation. Ces composants peuvent ainsi être utilisés dans différents documents et par plusieurs applications. Les éléments fournis de base couvrent trois domaines: la gestion du texte, le dessin de flêches et la création de rapports.
!!!!Gestion avancée des blocs de texte
Jusqu'ici, vous n'avez utilisé que la classe ==PDFTextElement== pour placer un texte sur une page. Ce composant est limité en terme de fonctionnalité puisqu'il ne gère que la position sur le support. Pour vous aider, Artefact propose trois composants de haut niveau qui supportent des fonctionnalités avancées.
Le composant ==PDFFormatedTextElement== est très proche de ==PDFTextElement== mais apporte en plus la gestion de l'alignement (à gauche, au centre, à droite). Un composant ==PDFCellElement== est un ==PDFFormatedTextElement== pouvant être doté d'une bordure. Enfin, un PDFParagrapElement permet l'insertion d'un paragraphe de texte et gère automatiquement la rupture en fin de ligne.
!!!!Dessiner des fléches
Les flèches sont très utiles pour générer des schémas à l'aide d'Artefact. Le composant ==PDFArrowElement== dessine une flèche pour laquelle la pointe se situe à sa terminaison. Le composant ==PDFDoubleArrowElement== dessine deux pointes: une est au départ de la flèche, l'autre à sa terminaison.
[[[
PDFArrowElement from: 10 mm @ 10 mm to: 100 mm @ 30 mm
PDFDoubleArrowElement from: 10 mm @ 80 mm to: 100 mm @ 150 mm
]]]
!!!!Créer des rapports
Les composants héritant de ==PDFDatatable== sont la parfaite illustration de la puissance et du confort apporté par les éléments composites d'Artefact. Avec ces tables de données, il vous est possible de générer rapidement des rapports et de les personnaliser selon vos besoins.
Avec la classe ==PDFDatatableElement==, vous définissez un rapport ayant des dimensions précises sur la page et portant sur un jeu de données. Ces données sont organisées de manière tabulaire: un tableau représentant le rapport, contient un certain nombre d'autres tableaux, représentant chacun une ligne du rapport.
[[[
PDFDataTableElement new
data: #(
#('Smith' 'Peter' 43)
#('Jones' 'Mickael' 25)
#('washington' 'robert' 30)
);
from: 10 mm @ 20 mm;
dimension: 150 mm @ 60 mm
]]]
La classe ==PDFDataTableWithColumnsCaptionElement== apportent une nouvelle variable d'instance nommée captions dont le contenu est un tableau. Cette variable permet de définir les titres de chaque colonne de votre rapport. Il est important de noter que le nombre de titres de colonne doit être le même que le nombre de colonnes et que chaque ligne doit comporter le même nombre de colonnes.
[[[
PDFDataTableWithColumnsCaptionElement new
captions: #('Name' 'Surname' 'Age');
data: #(
#('Smith' 'Peter' 43)
#('Jones' 'Mickael' 25)
#('washington' 'robert' 30)
);
from: 10 mm @ 20 mm;
dimension: 150 mm @ 60 mm
]]]
Artefact propose également la classe ==PDFDataTableWithRowsCaptionElement== qui est une variante de ==PDFDataTableWithColumnsCaptionElement==. Son comportement est différent puisque la propriété captions est utilisée pour donner un titre à chaque ligne. Dans ce cas de figure, le tableau contenu dans la propriété caption doit avoir un nombre d'éléments égal au nombre de lignes du tableau.
Les rapports mettent souvent en évidence l'une ou l'autre information afin de faciliter leur lecture. Artefact dispose d'un mécanisme de déclencheur défini par le message ==customizationBlock:== et activé à chaque dessin d'une cellule. Cette méthode reçoit quatre paramètres qui sont la cellule en cours de dessin, la position horizontale et verticale de la cellule dans le tableau et la donnée présente dans la cellule. A l'aide d'un bloc de code, il vous est alors possible de modifier son aspect ou de déclencher un traitement particulier.
La liste des personnes qui illustre cette partie contient l'age de chaque individu. L'exemple qui suit utilise le message ==customizationBlock:== pour remplacer l'age d'une personne par le texte "Older than 30" si cet individu a plus de trente ans. Le code exécuté ne prend en compte que la troisième cellule de chaque ligne et en excluant le titre de chaque colonne. Si l'age est supérieur à trente, la variable d'instance text de la cellule en cours de dessin est modifiée:
[[[
(PDFDataTableWithColumnsCaptionElement new
captions: #('Name' 'Surname' 'Age');
data: #(
#('Smith' 'Peter' 43)
#('Jones' 'Mickael' 25)
#('washington' 'robert' 30)
);
from: 10 mm @ 20 mm;
dimension: 150 mm @ 60 mm;
customizationBlock: [ :cell :x :y :data |
(x = 3 and: [ y > 1 ]) ifTrue: [
(data > 30) ifTrue: [ cell text: 'Older than 30' ]
]
])
]]]
Les éléments composites d'Artefact apportent beaucoup de souplesse à la création de documents PDF. Bien évidemment, ceux fournis par défaut ne couvrent pas tous les besoins et il vous sera probablement nécessaire de créer vos propres composants.
!!Stylesheet for the newbies
A ==PDFStyleSheet== is a dictionary that maps rendering properties. A default stylesheet is defined at the document level when this one is created.
Consequently, you don't have to specify every values if you want a generic rendering.
Following the hierarchy logic, a stylesheet defined at a lower level will surcharge properties.
For example, if you define a textColor in the document stylesheet, every text will be written in that color except elements where textColor is
defined in their stylesheet. Like pages and elements, the same stylesheet can be used with different elements or documents.
Artefact introduces a style context. Every ==PDFElement== can be associated to a specific style:
[[[
PDFText from: 10mm@15mm text: 'My title' style: #title
]]]
Then, at any upper level (document, page, etc), you can express the specific title style context using the message ==>==
[[[
myDocument stylesheet > #title at: #font put: PDFCourierFont size: 32 pt
]]]
The message ==>== gives access to the style attribute of ==PDFStyleSheet==. Here we specify the title attribute of the document.
!!!Les éléments manipulables avec une feuille de style
La définition d'une feuille de style permet de spécifier des attributs de présentation particuliers pour un ensemble d'élements.
!!!!Fonts
Artefact supports integrated PDF fonts (==PDFCourierFont==, ==PDFHelveticaFont==, ==PDFSymbolFont==, ==PDFTimesFont== and ==PDFZapfdingbatsFont==).
These fonts are available in any PDF viewer. A PDFFont object supports the basic style: bold and italic.
[[[
PDFText from: 10mm@15mm text: 'My title' font: ((PDFTimesFont size: 24 pt) bold).
]]]
La classe ==PDFFont== propose deux messages extrémement pratiques lors de la création d'un document. Avec le message ==getStringWidth:==, vous
obtenez la largeur d'une chaîne de caractères calculée en fonction des attributs de la fonte utilisée. L'exemple suivant retourne la largeur
de la chaine =="hello"== avec une fonte Courier mesurant 20 points:
[[[
(PDFCourierFont size: 20 pt) getStringWidth: 'hello'
]]]
Le message ==getIdealFontSizeForTheString:width:== retourne la taille optimale de la fonte utilisée en fonction de la largeur voulue.
L'exemple suivant détermine la taille nécessaire d'une fonte Courier si l'on désire que le texte "hello" ait une largeur de 15 cm:
[[[
(PDFCourierFont new) getIdealFontSizeForTheString: 'hello' width: 15 cm
]]]
!!!!Dots
All the geometric shapes can use a dotted style. It is defined by a PDFDotted object that specify the length of each segment and the space between them.
[[[
((PDFArrowElement from: 125 mm @ 40 mm to: 100 mm @ 80 mm)
dotted:
(PDFDotted new
length: 2 mm;
space: 3 mm)).
]]]
!!!!Couleurs et niveaux de gris
Les couleurs et les niveaux de gris sont représentés par la classe ==PDFColor==. Pour définir une couleur, Artefact utilise le mode RGB basé
sur le mélange de rouge, de vert et de bleu. La proportion dans le mélange de chacune de ces couleurs est exprimée à l'aide d'une valeur
entre 0 et 255. Un noir profond correspond donc au triplé (0,0,0) , la couleur rouge à (255,0,0), la couleur verte à (0,255,0), la couleur
bleu à (0,0,255) et le blanc à (255,255,255).
[[[
PDFColor r:255 g: 128 b: 64
]]]
Les niveaux de gris sont exprimés sur une seule valeur allant de 0 à 255. Plus cette valeur est basse, plus le niveau de gris s'assombrit.
Une valeur égale à 0 correspond donc à du blanc alors que la valeur 255 équivaut à du noir.
[[[
PDFColor greyLevel: 128
]]]
Pour spécifier la couleur ou le niveau de gris utilisé, vous diposez des méthodes ==drawcolor:==, ==fillColor:== et ==textColor:== qui
gèrent respectivement la couleur de dessin, la couleur de remplissage et la couleur du texte. L'exemple qui suit dessine un rectangle
dont la bordure sera en bleu et le contenu en rouge:
[[[
PDFRectElement new
from: 10 mm @ 10 mm;
dimension: 100 mm @ 30 mm;
fillColor: (PDFColor r: 255 g: 0 b: 0);
drawColor: (PDFColor r: 0 g: 0 b: 255).
]]]
Cet autre exemple produit un texte écrit en bleu:
[[[
PDFTextElement new
textColor: (PDFColor r: 0 g: 0 b: 255);
from: 10 mm @ 50 mm;
text: 'A text in blue';
]]]
!!!!Epaisseur des tracés
L'épaisseur de dessin d'une ligne, d'un segment ou d'une bordure, est controlée par le message ==thickness:==
[[[
(PDFRectElement from: 10 mm @ 10 mm dimension: 50 mm @ 50 mm)
thickness: 2 mm
]]]
!!!!Alignement
L'alignement du texte est géré à l'aide de la classe PDFAlignment. Un texte peut être aligné à gauche, au centre ou à droite.
Les messages sont ==left==, ==center== et ==right==. L'exemple qui suit génère un texte aligné à droite:
[[[
(PDFFormattedTextElement from: 0 mm @ 0 mm dimension: 100 mm @ 10 mm)
alignment: (PDFAlignment right);
text: 'At right!'
]]]
!!!Généraliser un style
!!!!Changer le style par défaut du document
Le document embarque une feuille de styles dont les propriétés s'appliquent sur tout élément ne spécifiant pas ses propres propriétés.
Par exemple, si vous créez un ==PDFTextElement== sans définir une fonte et une couleur de texte, ce seront les couleurs de texte et de
fonte du document qui seront appliquées. De plus, cette feuille de style est systématiquement remplie par Artefact avec des valeurs par défaut.
C'est pourquoi vous n'avez pas eu à préciser des valeurs de style lors de votre précédente découverte des éléments.
Pour changer ces valeurs de style du document, il vous suffit de modifier les propriétés de sa feuille de style de la façon suivante:
[[[
myDocument := PDFDocument new.
myDocument styleSheet textColor: (PDFColor r: 0 g: 100 b: 200);
font: (PDFHelveticaFont size: 32pt) italic.
]]]
!!!!Appliquer un style sur un ensemble d'éléments
Souvent vous avez envie d'appliquer un style sur un ensemble d'éléments mais pas sur tous les éléments d'un document. Artefact vous permet de
définir un style et de le nommer afin de pouvoir ensuite, déclarer les éléments devant respecter ce style personnalisé.
Par exemple, si vous désirez que certains éléments de texte soit des citations, vous pouvez définir le style ==#quote== comme suit:
[[[
myDocument := PDFDocument new.
myDocument styleSheet > #quote
textColor: (PDFColor r: 0 g: 50 b: 200);
font: (PDFCourierFont size: 8pt) italic.
]]]
Ainsi, le style des citations est maintenant associé au symbole ==#quote==. Ce style est ici défini en tant que sous-style de celui du document
afin de s'appliquer sur tous les éléments de style #quote du document.
Ensuite, il nous reste plus qu'à attribuer le style #quote aux éléments qui sont des citations.
[[[
(PDFTextElement from: 5cm @ 5cm)
text: 'my Quote with the quote style';
style: #quote
]]]
Dans l'exemple ci-desssus, nous n'avons qu'un seul niveau de style. Cependant, Artefact gère autant de niveaux de styles que vous le souhaiter.
Ce comportement est indispensable dans le cadre des éléments composites dans lesquels l'imbrication des éléments impose l'imbrication des styles.
Dans l'exemple ci-dessous, nous créons une table de données avec un titre à chaque colonne.
[[[
(PDFDataTableWithColumnsCaptionElement from: 10 mm @ 20 mm dimension: 190 mm @ 60 mm)
captions: #('Name' 'Surname' 'email');
data: #(
#('Smith' 'Peter' 'peter.smith@mail.org')
#('Jones' 'Mickael' 'mickael.jones@epr.com')
#('washington' 'robert' 'robert.washington@blif.com'));
style: #dataTableWithColoredCaption;
yourself).
]]]
L'apparence de cette table suit les spécifications du style #dataTableWithColoredCaption.
==Artefact>>PDFDataTableWithColumnsCaptionElement== est un élément composite fourni par Artefact. Cet élément défini le style de ses sous-éléments
==#caption== et ==#cell==, respectivement associés aux titres et aux cellules.
Par imbrication des styles, nous pouvons suivre l'imbrication des éléments et donc définir les styles des cellules uniquement dans le
contexte ==#dataTableWithColoredCaption==:
[[[
pdfdoc := PDFDocument new.
pdfdoc styleSheet > #dataTableWithColoredCaption > #caption
fillColor: (PDFColor r: 158 g: 158 b: 79);
drawColor: (PDFColor r: 158 g: 158 b: 79).
pdfdoc styleSheet > #dataTableWithColoredCaption margin: 4 pt.
pdfdoc styleSheet > #dataTableWithColoredCaption > #cell alignment: PDFAlignment right.
]]]
Ici on voit que l'on peut modifier les attributs imbriqués d'un element: On change l'alignement d'une cellule dans la table par une séquence de ==>==.
L'usage du mécanisme de gestion des styles apporte beaucoup de souplesse pour la production d'un document. Il permet de séparer l'aspect présentation
de la définition des composants. Cette distinction entre le fond et la forme permet à l'utilisateur de créer facilement ses propres composants,
tout aussi personnalisables que ceux fournis avec Artefact.
!!Create your own PDF composite elements
The spirit of Artefact is to reduce the complexity of pdf generation. When you have to create a document, a good
idea is to avoid wasting time to reinvent the wheel. When you create a composite element, if your component is based around a string, inherit
from ==PDFCompositeText==. Elsewhere, your component must be a subclass of ==PDFComposite==.
In this tutorial, we will create a clock, which is basically a circle and two arrows. This element will be
drawn depending on the provided time and properties (size, colors, thickness).
!!!Create the clock
First create the class of your element:
[[[
PDFComposite subclass: #PDFClockElement
instanceVariableNames: 'time'
classVariableNames: ''
poolDictionaries: ''
category: 'Artefact-Tutorial'
]]]
As you can see, we create an instance variable that will contain the time to display. Then, create or generate accessors methods to this variable.
The only two required methods by Artefact are ==getSubElementsWith:styleSheet:== and ==defaultStyle==. The first one must return a collection of
==PDFElements== (basics or composites). The second one must return a symbol that associate the composite element with a style definition.
However it's not necessary to define this style in your document, Artefact will use the default style instead.
Define the default style:
[[[
PDFClockElement>>defaultStyle
^ #clock
]]]
Then define the method that will draw the clock. At the beginning, this method will just return the circle:
[[[
PDFClockElement>>getSubElementsWith: aGenerator styleSheet: aStyleSheet
^ { PDFCircleElement from: self from to: self to }
]]]
The circle will be drawn depending on this composite position and size. We are using from: to: for the circle instead of ==center:radius:== because
it's easier for us to create a clock using the boundary box of the circle.
Now we will create the clock hands with two ==PDFArrowElement==s and a filled little circle in the middle:
[[[
PDFClockElement>>getSubElementsWith: aGenerator styleSheet: aStyleSheet
| hourAngle minuteAngle |
hourAngle := Float pi / 2 - (time hour12 * 2 * Float pi / 12).
minuteAngle := Float pi / 2 - (time minute * 2 * Float pi / 60).
^ {
(PDFCircleElement from: self from to: self to).
(PDFCircleElement center: self center radius: self dimension x * 0.05).
(PDFArrowElement from: self center angle: hourAngle length: dimension x * 0.25).
(PDFArrowElement from: self center angle: minuteAngle length: dimension x * 0.45)
}
]]]
Don't be afraid about the two angle calculus, it's just to convert hours and minutes to radian angles.
At this time, your ==PDFClockElement== is already usable and fully integrated into Artefact. We can insert it into a PDF document and export it:
[[[
PDFDocument new
add: (PDFPage new add: ((PDFClockElement from: 2 cm @ 2 cm to: 10 cm @ 10 cm) time: Time current));
exportTo: 'clockTutorialStep1.pdf' asFileReference writeStream
]]]
!!! Make the clock personnalizable
Your clock is already personnalizable independently of other elements because you previously define its style as ==#clock==.
[[[
| doc |
doc := PDFDocument new.
doc add: (PDFPage new add: ((PDFClockElement from: 2 cm @ 2 cm to: 10 cm @ 10 cm) time: Time current)).
doc styleSheet > #clock drawColor: (PDFColor r:180 g: 24 b:24); fillColor: (PDFColor r:230 g: 230 b:10).
doc exportTo: 'clockTutorialStep2.pdf' asFileReference writeStream
]]]
You can also personnalize the subelements of your clock by their own default style.
[[[
| doc |
doc := PDFDocument new.
doc add: (PDFPage new add: ((PDFClockElement from: 2 cm @ 2 cm to: 10 cm @ 10 cm) time: Time current)).
doc styleSheet > #clock drawColor: (PDFColor r:180 g: 24 b:24); fillColor: (PDFColor r:230 g: 230 b:10).
doc styleSheet > #clock > #arrow drawColor: (PDFColor r:0 g: 45 b:200).
doc exportTo: 'clockTutorialStep3.pdf' asFileReference writeStream
]]]
At this time, you don't have defined specific styles for sub elements of your clock. Consequently, you will not be able to
personnalize each element with different styles (so you cannot have hands of differents colors for example). To increase personnalization
possibilities, you should define specific styles for sub elements you reuse.
[[[
PDFClockElement>>getSubElementsWith: aGenerator styleSheet: aStyleSheet
| hourAngle minuteAngle |
hourAngle := Float pi / 2 - (time hour12 * 2 * Float pi / 12).
minuteAngle := Float pi / 2 - (time minute * 2 * Float pi / 60).
^ {
(PDFCircleElement from: self from to: self to).
(PDFCircleElement center: self center radius: self dimension min * 0.05).
((PDFArrowElement from: self center angle: hourAngle length: dimension min * 0.25) style: #hourHand).
((PDFArrowElement from: self center angle: minuteAngle length: dimension min * 0.45) style: #minuteHand)
}
]]]
As you can see, we just send the message ==style:== on each subelement that we want to define a specific style.
Now, we can personnalize each hand like that:
[[[
| doc |
doc := PDFDocument new.
doc add: (PDFPage new add: ((PDFClockElement from: 2 cm @ 2 cm to: 10 cm @ 10 cm) time: Time current)).
doc styleSheet > #clock drawColor: (PDFColor r:180 g: 24 b:24); fillColor: (PDFColor r:230 g: 230 b:10).
doc styleSheet > #clock > #hourHand drawColor: (PDFColor r:0 g: 45 b:200).
doc styleSheet > #clock > #minuteHand drawColor: (PDFColor r:0 g: 200 b:45).
doc exportTo: 'clockTutorialStep4.pdf' asFileReference writeStream
]]]
As you can see, the clock hands have different colors. Moreover, like any element in Artefact, you can specify a style on an
instance of a ==PDFClockElement== that allow you to reuse and adapt each clock:
[[[
| doc |
doc := PDFDocument new.
doc add:
(PDFPage new
add: ((PDFClockElement from: 2 cm @ 2 cm to: 10 cm @ 10 cm) time: Time current);
add: ((PDFClockElement from: 12 cm @ 2 cm to: 20 cm @ 10 cm)
time: Time current;
style: #apocalypseClock)).
doc styleSheet > #clock
drawColor: (PDFColor r: 180 g: 24 b: 24);
fillColor: (PDFColor r: 230 g: 230 b: 10).
doc styleSheet > #clock > #hourHand drawColor: (PDFColor r: 0 g: 45 b: 200).
doc styleSheet > #clock > #minuteHand drawColor: (PDFColor r: 0 g: 200 b: 45).
doc styleSheet > #apocalypseClock
fillColor: (PDFColor r: 244 g: 221 b: 25);
thickness: 2 mm;
roundCap: true.
doc styleSheet > #apocalypseClock > #minuteHand
drawColor: (PDFColor r: 240 g: 6 b: 7);
thickness: 1 mm.
doc exportTo: 'clockTutorialStep5.pdf' asFileReference writeStream
]]]
!!Conclusion
We presented the key aspects of Artefact. Artefact is a powerful framework to generate PDF.
It is based on innovative design points: its object-oriented design where each element defined its own attributes
supports a much stronger reuse possibility than traditional stream-based approaches.
With Artefact you can be freely compose, customize and reuse your PDF elements.