Dessiner un texte avec plusieurs polices avec Drawing.

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Shadow
Messages : 1373
Inscription : mer. 04/nov./2015 17:39

Dessiner un texte avec plusieurs polices avec Drawing.

Message par Shadow »

Salut,

Ce code permet d'afficher du Texte multicolord en Drawing.

Code : Tout sélectionner

; Code créé par Dieppedalle David le 23/08/2021.
; Première version : 1.00.00 le 23/08/2021.
; Version actuelle : 1.01.03.

; Version : 1.00.01 le 24/08/2021 > Ajoute du code pour libérer les polices utilisées pour dessiner le texte.

; Version : 1.01.02 le 30/08/2021 > Refonte, utilise maintenant des listes liées au lieu de tableaux, le code est plus facile à lire et à gérer.
; Ajout de la possibilité de choisir le rendu de l'image du texte MultiFont, soit en dessin (par défaut)
; meilleur rendu (texte plus épais) mais un peu plus lent, ou en Vecteur, moins bon rendu (texte plus fin) mais un peu plus rapide.

; Version : 1.01.03 le 30/08/2021 > Quelques petites corrections sur le fond du texte ainsi que sur le texte, la position et les couleurs.
; Version : 1.02.04 le 31/08/2021 > Ajout de 2 fonction pour améliorer d'environ 33% la rapidité du code: InitVectorTextMultiFont() et CloseVectorTextMultiFont().

; Traduit avec www.DeepL.com/Translator (version gratuite).

; ----------------

; Code created by Dieppedalle David on 23/08/2021.
; First version: 1.00.00 on 23/08/2021.
; Current Version: 1.01.03.

; Version: 1.00.01 on 24/08/2021 > Adds code to free the fonts used to draw the text.

; Version: 1.01.02 on 30/08/2021 > Redesign, now uses linked lists instead of arrays, the code is easier to read and to manage.
; Added the possibility To choose the rendering of the MultiFont Text image, either in Drawing (Default)
; better rendering (thicker text) but a bit slower, Or in Vector, less good rendering (thinner text) but a bit faster.

; Version: 1.01.03 on 30/08/2021 > Some small corrections on the background of the text as well as the text, position and colors.
; Version : 1.02.04 on 31/08/2021 > Added 2 functions to improve code speed by about 33%: InitVectorTextMultiFont() and CloseVectorTextMultiFont().

; ----------------

EnableExplicit

; Structure qui contient les propriétés de tous les mots.
; Structure that contains the properties of all words.
Structure Text
  
  TextMultiFontID.i
  Text.s
  TextFontName.s
  TextFontID.i
  TextStyle.i
  TextSize.i
  TextColor.i
  TextColorBackround.i
  TextX.i
  TextY.i
  TextWidth.i
  TextHeight.i
  TextBaseLine.i
  TextLastNewLine.b
  
EndStructure

EnableExplicit

; Structure qui contient les propriétés de chaque ligne du Texte MultiFont.
; Structure that contains the properties of each line of the MultiFont Text.
Structure Line
  
  LineX.i
  LineY.i
  LineWidth.i
  LineHeight.i
  
  NextPositionX.i
  
  List Location.Text()
  
EndStructure

; Structure qui contient les propriétés du Texte MultiFont.
; Structure that contains the properties of the MultiFont text.
Structure MyText
  
  MyTextMultiFontID.i
  MyTextImageID.i
  MyTextImageWidth.i
  MyTextImageHeight.i
  MyTextAutoSize.b
  Interline.i
  
  List Line.Line()
  
EndStructure

; Sert à stocker le numéro réel du Texte MultiFont, TextMultiFontID.i est un numéro raccourci (ID) qui pointe vers un emplacement de liste, ex: TextMultiFontID.i = 3 (ID), 3 = 24 (Element 24 de la liste).
; Chaque Texte MultiFont est ajouter à la suite dans la liste.

; Used to store the actual number of the MultiFont Text, TextMultiFontID.i is a shortened number (ID) that points to a list location, e.g. TextMultiFontID.i = 3 (ID), 3 = 24 (Element 24 in the list).
; Each MultiFont Text is added in sequence To the List.
Global NewMap Map_VectorTextMultiFont_TextMultiFontID_ID.i() 

; Liste qui contient tous les Texte MultiFonts, chaque élément est un Texte MultiFont.
; List that contains all the MultiFont texts, each element is a MultiFont text.
Global NewList List_VectorTextMultiFont_Text.MyText()

; Image temporaire pour les calcules sur le Texte.
; Temporary image for calculations on Text.
Global TemporaryDrawingSurface.i

; Option pour la fonction CreateVectorTextMultiFont() pour automatiquement créer un Texte MultiFont de la taille de celui-ci.
; Option for the CreateVectorTextMultiFont() function to automatically create a MultiFont Text of the size of this one.
#VectorTextMultiFontAutoSize = 1024

; Option pour le rendu de l'image l'or de la création du Texte MultiFont.
; Option for rendering the image when creating the MultiFont Text.
#VectorTextMultiFontImageRenderingDrawing = 2048 ; Plus long, meilleur rendu.
#VectorTextMultiFontImageRenderingVector = 4096  ; Plus rapide, moin bon rendu.

; Intitialise le Texte MultiFont en créent une image pour les futures opérations de dessins.
; Ouvre un canal de dessin sur cette image, il sera automatiquement fermer.

; Intializes the MultiFont Text by creating an image for future drawing operations.
; Open a drawing channel on this image, it will be automatically closed.
Procedure.i InitVectorTextMultiFont()
  
  If Not IsImage(TemporaryDrawingSurface.i)
    
    TemporaryDrawingSurface.i = CreateImage(#PB_Any, 10, 10)
    
    If Not (IsImage(TemporaryDrawingSurface.i) And StartVectorDrawing(ImageVectorOutput(TemporaryDrawingSurface.i))) ; Ouvre un canal de dessin pour calculer les dimention du Texte futur.
      Debug "InitVectorTextMultiFont >>> Impossible d'initialiser le VectorTextMultiFont !"
      ProcedureReturn -1
      
    Else
      ProcedureReturn #True
      
    EndIf
    
  Else
    Debug "InitVectorTextMultiFont >>> Cette fonction a déjà été utilisé !"
    
  EndIf
  
EndProcedure

; Libère le Texte MultiFont en supprimant l'image temporaire.
; Pas de StopVectorDrawing(), fonctionne pas, ne sais pas pourquoi, ne sais pas ou est passé le Canal de dessin.

; Free the MultiFont Text by deleting the temporary image.
; No StopVectorDrawing(), doesn't work, don't know why, don't know where the drawing channel went.
Procedure.i CloseVectorTextMultiFont()
  
  If Not IsImage(TemporaryDrawingSurface.i)
    
    Debug "CreateVectorTextMultiFont >>> Veuillez Initialiser le VectorTextMultiFont 'InitVectorTextMultiFont()' avant d'utiliser cette fonction !"
    ProcedureReturn -1
    
  Else
    FreeImage(TemporaryDrawingSurface.i)
    ProcedureReturn #True
    
  EndIf
  
EndProcedure

; Initialise le nouveau Texte, doit être utilisé avant d'ajouter du Texte à un Texte MultiFont.
; Utilisez #PB_Any pour automatiquement attribuer un numéro au Texte MultiFont (Aléatoire entre 0 et 10 000 si disponible.)
; TextMultiFontID.i commence à partir de 0, maximal 10 000, c'est le numéro d'identification du Texte MultiFont.
; Width.i = La Largeur du Texte MultiFont entier Maximal, sera utilisé pour définir la Largeur de l'image qui contiendra ce Texte MultiFont, dois être compris entre 1 et 2000.
; Height.i = La Hauteur du Texte MultiFont entier Maximal, sera utilisé pour définir la Hauteur de l'image qui contiendra ce Texte MultiFont, dois être compris entre 1 et 2000.
; Interline.i = L'espace entre les lignes du Texte MultiFont.
; Option.i = Utilisez #VectorTextMultiFontAutoSize, pour automatiquement redimensionner l'image qui contiendra ce Texte MultiFont, Width.i ainsi que Height.i seront ignorés.
; Retourne si tous c'est bien passé, le numéro du Texte MultiFont (Utile si #PB_Any est utiliser à la place du numéro du Texte MultiFont), Sinon -1.

; Initializes the new Text, must be used before adding Text to a MultiFont Text.
; Use #PB_Any To automatically assign a number To the MultiFont Text (Random between 0 And 10 000 If available.)
; TextMultiFontID.i starts from 0, maximum 10 000, this is the identification number of the MultiFont Text.
; Width.i = The Width of the MultiFont Text integer Maximal, will be used To Define the Width of the image that will contain this MultiFont Text, must be between 1 And 2000.
; Height.i = The Height of the Maximal integer MultiFont Text, will be used To Define the Height of the image that will contain this MultiFont Text, must be between 1 And 2000.
; Interline.i = The space between the lines of the MultiFont Text.
; Option.i = Use #VectorTextMultiFontAutoSize, To automatically resize the image that will contain this MultiFont Text, Width.i And Height.i will be ignored.
; Returns if all went well, the MultiFont Text number (Useful if #PB_Any is used instead of the MultiFont Text number), Otherwise -1.
Procedure.i CreateVectorTextMultiFont(TextMultiFontID.i, Width.i, Height.i, Interline.i = 0, Option.i = 0)
  
  If Not IsImage(TemporaryDrawingSurface.i)
    
    Debug "CreateVectorTextMultiFont >>> Veuillez Initialiser le VectorTextMultiFont 'InitVectorTextMultiFont()' avant d'utiliser cette fonction !"
    ProcedureReturn -1
    
  EndIf
  
  ; Vériffications diverses.
  If TextMultiFontID.i = #PB_Any
    
    ; Attribue un numéro aléatoire entre 0 et 10 000 et vérifie qu'il n'existe pas déjà, sinon, boucle jusqu'a ce que un numéro non utilisé soit trouvé.
    Repeat
      
      TextMultiFontID.i = Random(10000)
      
      If Not FindMapElement(Map_VectorTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
        Break
      EndIf
      
    ForEver
    
  ElseIf TextMultiFontID.i < 0
    Debug "CreateVectorTextMultiFont >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "CreateVectorTextMultiFont >>> TextMultiFontID.i est supérieur à 10 000, dois être 10 000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  ; Vériffications diverses.
  If Width.i <= 0
    Debug "CreateVectorTextMultiFont >>> Width.i est inférieur à 0, dois être 1 Minimum !"
    ProcedureReturn -1
    
  ElseIf Width.i > 2000
    Debug "CreateVectorTextMultiFont >>> Width.i est Supérieur à 2000, dois être 2000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  If Height.i <= 0
    Debug "CreateVectorTextMultiFont >>> Height.i est inférieur à 0, dois être 1 Minimum !"
    ProcedureReturn -1
    
  ElseIf Height.i > 2000
    Debug "CreateVectorTextMultiFont >>> Height.i est Supérieur à 2000, dois être 2000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  ; Cherche si le Texte MultiFont existe, grace à ça clef Str(TextMultiFontID.i), si oui alors l'élément courant de la Map est celui-ci.
  Define *IsTextMultiFontID = FindMapElement(Map_VectorTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Element non trouvé.
    
    ; Ajoute un élément dans la liste de Texte MultiFont.
    AddElement(List_VectorTextMultiFont_Text.i())
    
    ; Ajoute et définie l'élément de la Map, la clef est le numéro du Texte MultiFont (TextMultiFontID.i)
    AddMapElement(Map_VectorTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
    
    ; Défini la valeur de la clef de la Map, qui sera égale à la position actuel dans la liste de Texte MultiFont (Nombre de Texte MultiFont dans la liste -1), chaque TextMultiFontID.i pointe sur un élément de la liste Texte MultiFont.
    ; Ex: TextMultiFontID.i = 24, a été ajouté à la position 3 de la liste = 24-2 (La liste commance à 0).
    Map_VectorTextMultiFont_TextMultiFontID_ID.i() = ListIndex(List_VectorTextMultiFont_Text.i())
    
    ; Création de l'image du Texte MultiFont.
    Define TextImageID.i = CreateImage(#PB_Any, Width.i, Height.i, 32, #PB_Image_Transparent)
    
    If Not IsImage(TextImageID.i)
      Debug "CreateVectorTextMultiFont >>> Erreur, impossible de créer l'image pour le Texte MultiFont !"
      ProcedureReturn -1
    EndIf
    
  ElseIf *IsTextMultiFontID <> 0 ; Element trouvé, il existe déjà.
    
    ; Ici on selectionne dans la liste la position ou se trouve le Texte MultiFont, pour ça, ont récupère la valeur qu'il y à dans la Map.
    SelectElement(List_VectorTextMultiFont_Text.i(), Map_VectorTextMultiFont_TextMultiFontID_ID.i())
    
    ; Vérifie si l'image du Texte MultiFont existe.
    If IsImage(List_VectorTextMultiFont_Text.i()\MyTextImageID)
      FreeImage(List_VectorTextMultiFont_Text.i()\MyTextImageID) ; Supprime cette image.
    EndIf
    
    ResetStructure(@List_VectorTextMultiFont_Text.i(), MyText) ; Réinitialise entierement la structure de cet élément Texte MultiFont, pas la liste qui contient les Texte MultiFonts.
    
    ; Création de l'image du Texte MultiFont.
    Define TextImageID.i = CreateImage(#PB_Any, Width.i, Height.i, 32, #PB_Image_Transparent)
    
    ; Si l'image n'est pas initialisé.
    If Not IsImage(TextImageID.i)
      Debug "CreateVectorTextMultiFont >>> Erreur, impossible de créer l'image pour le Texte MultiFont !"
      ProcedureReturn -1
    EndIf
    
    Debug "CreateVectorTextMultiFont >>> TextMultiFontID.i (" + Str(TextMultiFontID.i) + ") Existe déjà et a été remplacé !"
    Debug "-----------------------------------"
    
  EndIf
  
  If Option.i = #VectorTextMultiFontAutoSize
    List_VectorTextMultiFont_Text.i()\MyTextAutoSize = #True
  Else
    List_VectorTextMultiFont_Text.i()\MyTextAutoSize = 0
  EndIf
  
  List_VectorTextMultiFont_Text.i()\MyTextMultiFontID = TextMultiFontID.i
  List_VectorTextMultiFont_Text.i()\MyTextImageID = TextImageID.i
  
  List_VectorTextMultiFont_Text.i()\MyTextImageWidth = Width.i
  List_VectorTextMultiFont_Text.i()\MyTextImageHeight = Height.i
  
  List_VectorTextMultiFont_Text.i()\Interline = Interline.i
  
  ; Ajout d'une nouvelle ligne
  AddElement(List_VectorTextMultiFont_Text.i()\Line())
  
  List_VectorTextMultiFont_Text.i()\Line()\LineHeight = 10
  
  ProcedureReturn TextMultiFontID.i
  
EndProcedure

; Ajoute un Texte au Texte MultiFont existant à la suite du précédent.
; TextMultiFontID.i commence à partir de 0, maximal 10 000, c'est le numéro d'identification du Texte.
; Retourne si tous c'est bien passé, #True (1), sinon -1.

; Adds a Text to the existing MultiFont Text following the previous one.
; TextMultiFontID.i starts from 0, maximum 10 000, it is the identification number of the Text.
; Returns If all went well, #True (1), otherwise -1.
Procedure.i VectorTextMultiFontAddText(TextMultiFontID.i, Text.s, Font.s = "", Style.i = 0, Size.i = 12, Color.i = -16777216, ColorBackround.i = -1)
  
  If Not IsImage(TemporaryDrawingSurface.i)
    
    Debug "VectorTextMultiFontAddText >>> Veuillez Initialiser le VectorTextMultiFont 'InitVectorTextMultiFont()' avant d'utiliser cette fonction !"
    ProcedureReturn -1
    
  EndIf
  
  ; Vériffications diverses.
  If TextMultiFontID.i < 0
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i est supérieur à 10 000, dois être 10 000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  ; Cherche si le numéro du Texte MultiFont (TextMultiFontID.i) existe.
  Define *IsTextMultiFontID = FindMapElement(Map_VectorTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Le Texte MultiFont (TextMultiFontID) n'as pas été trouvé.
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i (" + Str(TextMultiFontID.i) + "), n'existe pas !"
    ProcedureReturn -1
    
  ElseIf *IsTextMultiFontID <> 0 ; Le Texte MultiFont (TextMultiFontID) a été trouvé.
    
    ; Ont vérifie que le Texte MultiFont à bien une image.
    
    ; Si l'image n'est pas initialisé.
    If Not IsImage(List_VectorTextMultiFont_Text.i()\MyTextImageID)
      Debug "VectorTextMultiFontAddText >>> Erreur, impossible de trouver l'image pour le Texte MultiFont !"
      ProcedureReturn -1
    EndIf
    
    ; Ajoute un nouvel élément dans la Liste Location().
    AddElement(List_VectorTextMultiFont_Text.i()\Line()\Location())
    
    If Size.i < 6
      Size.i = 6
      
    ElseIf Size.i > 500
      Size.i = 500
      
    EndIf
    
    ; Enregistre la taille du Texte dans la Liste Location().
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextSize = Size.i
    
    ; Enregistre le style du Texte dans la Liste Location().
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextStyle = Style.i
    
    ; Enregistre le Texte qu'il faut écrire dans la Liste Location().
    List_VectorTextMultiFont_Text.i()\Line()\Location()\Text = Text.s
    
    ; Chargement de la police à partir des élément indiqué: Font.s, Size.i, Style.i.
    Define FontID.i = LoadFont(#PB_Any, Font.s, Size.i, Style.i | #PB_Font_HighQuality)
    
    ; Enregistre le nom de la Police du Texte dans la Liste Location().
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextFontName = Font.s
    
    ; Enregistre le numéro ID de la Police du Texte dans la Liste Location().
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextFontID = FontID.i
    
    ; Couleur du Texte.
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextColor = Color.i
    
    ; Couleur de l'arrière plant du Texte
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextColorBackround = ColorBackround.i
    
    ; Utilise le Font (FontID.i) pour écrire le Texte.
    VectorFont(FontID(FontID.i))
    
    ; Enregistrement de la Largeur et Hauteur du Texte dans la Liste Location().
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextWidth = Round(VectorTextWidth(Text.s), #PB_Round_Up) ; Largeur du Texte.
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextHeight = Round(VectorTextHeight(Text.s), #PB_Round_Up) ; Hauteur du Texte.
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextBaseLine = Round(VectorTextHeight(Text.s, #PB_VectorText_Baseline), #PB_Round_Up) ; Hauteur du Texte depuis ça base.
    
    ; Si la Hauteur de la ligne du Texte est plus petite que la Hauteur du Texte dans la Liste Line().
    ; Alors définie et enregistre la Hauteur de la ligne depuis la Hauteur du Texte.
    If List_VectorTextMultiFont_Text.i()\Line()\LineHeight < List_VectorTextMultiFont_Text.i()\Line()\Location()\TextHeight
      List_VectorTextMultiFont_Text.i()\Line()\LineHeight = List_VectorTextMultiFont_Text.i()\Line()\Location()\TextHeight + 3.00000000
    EndIf
    
    ; Enregistre la position X de la Location() actuel.
    List_VectorTextMultiFont_Text.i()\Line()\Location()\TextX = List_VectorTextMultiFont_Text.i()\Line()\NextPositionX
    
    ; NextPositionX.i va sauvegarder la position en X, ce sera très utile pour écrire les prochain mots à la suite des autres.
    List_VectorTextMultiFont_Text.i()\Line()\NextPositionX + List_VectorTextMultiFont_Text.i()\Line()\Location()\TextWidth ; Ajoute dans NextPositionX.i, la Largeur du mot.
    
  EndIf
  
  ProcedureReturn #True
  
EndProcedure

; Ajoute une ligne de Texte au Texte MultiFont Existant.
; TextMultiFontID.i commence à partir de 0, maximal 10 000, c'est le numéro d'identification du Texte.
; Retourne si tous c'est bien passé, #True (1), sinon -1.

; Adds a line of text to the existing MultiFont text.
; TextMultiFontID.i starts from 0, maximum 10 000, it is the identification number of the Text.
; Returns If all went well, #True (1), otherwise -1.
Procedure.i VectorTextMultiFontAddLine(TextMultiFontID.i)
  
  If Not IsImage(TemporaryDrawingSurface.i)
    
    Debug "VectorTextMultiFontAddLine >>> Veuillez Initialiser le VectorTextMultiFont 'InitVectorTextMultiFont()' avant d'utiliser cette fonction !"
    ProcedureReturn -1
    
  EndIf
  
  ; Vériffications diverses.
  If TextMultiFontID.i < 0
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i est supérieur à 10 000, dois être 10 000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  ; Cherche si le numéro du Texte MultiFont (TextMultiFontID.i) existe.
  Define *IsTextMultiFontID = FindMapElement(Map_VectorTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Le Texte MultiFont (TextMultiFontID) n'as pas été trouvé.
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i (" + Str(TextMultiFontID.i) + "), n'existe pas !"
    ProcedureReturn -1
    
  ElseIf *IsTextMultiFontID <> 0 ; Le Texte MultiFont (TextMultiFontID) a été trouvé.
    
    ; Calcule la position de la prochaine Ligne en Y.
    Define NextPositionY.i = List_VectorTextMultiFont_Text.i()\Line()\LineY + List_VectorTextMultiFont_Text.i()\Line()\LineHeight + List_VectorTextMultiFont_Text.i()\Interline
    
    ; Ont ajoute un élément dans la Liste Line() pour la prochaine ligne.
    AddElement(List_VectorTextMultiFont_Text.i()\Line())
    
    ; Définie et enregistre la hauteur de la prochaine ligne.
    List_VectorTextMultiFont_Text.i()\Line()\LineHeight = 10
    
    ; Définie et enregistre la position Y de la prochaine ligne, depuis la position Y et la hauteur de la ligne actuel.
    List_VectorTextMultiFont_Text.i()\Line()\LineY = NextPositionY.i
    
  EndIf
  
  ProcedureReturn #True
  
EndProcedure

; Dessine le Texte MultiFont sur une image avec le rendu voulu et renvois le numéro de celle-ci.
; TextMultiFontID.i commence à partir de 0, maximal 10 000, c'est le numéro d'identification du Texte.
; ImageRendering.i est l'option de rendus (Drawing par defaut), #VectorTextMultiFontImageRenderingDrawing pour un rendu type Drawing, #VectorTextMultiFontImageRenderingVector pour un rendu type Vecteur.
; Retourne si tous c'est bien passé le numéro de l'image ou le Texte MultiFont a été dessiné, sinon -1.

; Draws the MultiFont Text on an image With the desired rendering And returns the number of the image.
; TextMultiFontID.i starts from 0, maximum 10 000, it is the identification number of the Text.
; ImageRendering.i is the rendering option (Drawing by Default), #VectorTextMultiFontImageRenderingDrawing For a drawing type rendering, #VectorTextMultiFontImageRenderingVector For a vector type rendering.
; Returns if all went well the number of the image where the MultiFont Text was drawn, otherwise -1.
Procedure.i VectorTextMultiFontDrawTextToImage(TextMultiFontID.i, ImageRendering.i = #VectorTextMultiFontImageRenderingDrawing)
  
  If Not IsImage(TemporaryDrawingSurface.i)
    
    Debug "VectorTextMultiFontDrawTextToImage >>> Veuillez Initialiser le VectorTextMultiFont 'InitVectorTextMultiFont()' avant d'utiliser cette fonction !"
    ProcedureReturn -1
    
  EndIf
  
  Define LineWidth.i ; La largeur de la ligne en court d'inspection.
  Define LineLargest.i ; La ligne de texte la plus grande.
  Define TextHeight.i  ; La hauteur totale du texte.
  
  If ImageRendering.i <> #VectorTextMultiFontImageRenderingDrawing And ImageRendering.i <> #VectorTextMultiFontImageRenderingVector
    ImageRendering.i = #VectorTextMultiFontImageRenderingDrawing
  EndIf
  
  ; Vériffications diverses.
  If TextMultiFontID.i < 0
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i est supérieur à 10 000, dois être 10 000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  ; Cherche si le numéro du Texte MultiFont (TextMultiFontID.i) existe.
  Define *IsTextMultiFontID = FindMapElement(Map_VectorTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Le Texte MultiFont (TextMultiFontID) n'as pas été trouvé.
    Debug "VectorTextMultiFontAddText >>> TextMultiFontID.i (" + Str(TextMultiFontID.i) + "), n'existe pas !"
    ProcedureReturn -1
    
  ElseIf *IsTextMultiFontID <> 0 ; Le Texte MultiFont (TextMultiFontID) a été trouvé.
    
    SelectElement(List_VectorTextMultiFont_Text.i(), Map_VectorTextMultiFont_TextMultiFontID_ID.i())
    
    ; Récuperer le nombre de lignes que contienent la Listex Line().
    Define LineNumber.i = ListSize(List_VectorTextMultiFont_Text.i()\Line())
    Define LocationNumber.i = 0 ; Variable pour compter le nombre d'emplacement que contienent la Liste Location() de la ligne actuellement inspecté.
    
    ; Variables pour calculer la position Y de justification du mot.
    Define LocationTextBaseLine.i ; La hauteur maximal des mots depuis leur base, seule le mot le plus grand en hauteur sera retenue.
    
    ; Variable pour sauvegarder la Base Line du Texte le plus haut.
    Define LocationTextBaseLine.i
    
    ; Boucle For pour chaque ligne.
    ; Calcule et Ajuste la position Y des mots.
    ForEach List_VectorTextMultiFont_Text.i()\Line()
      
      ; Réinitialise la hauteur du mot maximal à chaque nouvelle ligne.
      LocationTextBaseLine.i = 0 
      
      ; Boucle For pour chaque mot de la ligne.
      ; Récuperation des valeurs de hauteur du mot le plus grand en hauteur.
      ForEach List_VectorTextMultiFont_Text.i()\Line()\Location()
        
        ; Récupere la hauteur maximal des mots depuis leur base.
        If LocationTextBaseLine.i < List_VectorTextMultiFont_Text.i()\Line()\Location()\TextBaseLine
          LocationTextBaseLine.i = List_VectorTextMultiFont_Text.i()\Line()\Location()\TextBaseLine
        EndIf
        
      Next
      
      ; Boucle For pour chaque mot de la ligne.
      ; Corrige la position Y des mots pour les alignier par apport à leur hauteur.
      ForEach List_VectorTextMultiFont_Text.i()\Line()\Location()
        
        ; Si la hauteur de la base du mot actuel est plus petite que la base du mot le plus grand enregistré.
        If List_VectorTextMultiFont_Text.i()\Line()\Location()\TextBaseLine < LocationTextBaseLine.i
          ; Ajuste la position Y du mot actuel pour l'aligné par apport au mot le plus grand en hauteur.
          List_VectorTextMultiFont_Text.i()\Line()\Location()\TextY = LocationTextBaseLine.i - List_VectorTextMultiFont_Text.i()\Line()\Location()\TextBaseLine
        EndIf
        
      Next
      
    Next
    
    If List_VectorTextMultiFont_Text.i()\MyTextAutoSize = #True
      
      ; Boucle For pour chaque ligne.
      ; Récupere la ligne la plus grande.
      ForEach List_VectorTextMultiFont_Text.i()\Line()
        
        ; Récuperer le nombre d'emplacements que contienent la Liste Location() de la ligne actuel.
        LineWidth.i = List_VectorTextMultiFont_Text.i()\Line()\NextPositionX ; LineWidth.i sera à la dernière position sur la ligne .
        
        ; Si la largeur totale de la ligne est plus petite que la valeur enregistré.
        If LineLargest.i < LineWidth.i
          LineLargest.i = LineWidth.i ; Enregistre la largeur de la ligne.
        EndIf
        
      Next
      
      ; Récupere la position ainsi que la taille de la dernière ligne + l'interligne.
      TextHeight.i = List_VectorTextMultiFont_Text.i()\Line()\LineY + List_VectorTextMultiFont_Text.i()\Line()\LineHeight + List_VectorTextMultiFont_Text.i()\Interline
      
      ; Si l'image est initialisé.
      If IsImage(List_VectorTextMultiFont_Text.i()\MyTextImageID)
        
        ; Redimentionnement de l'image du texte.
        ResizeImage(List_VectorTextMultiFont_Text.i()\MyTextImageID, LineLargest.i, TextHeight.i)
        
      Else
        ; Si l'image n'est pas initialisé.
        Debug "VectorTextMultiFontDrawTextToImage >>> Erreur, impossible de trouver l'image pour le Texte MultiFont !"
        ProcedureReturn -1
        
      EndIf
      
    EndIf
    
    ; Si l'image est initialisé.
    If IsImage(List_VectorTextMultiFont_Text.i()\MyTextImageID)
      
      Define DrawNextPositionX.i = 0
      Define DrawNextPositionY.i = 0
      
      If ImageRendering.i = #VectorTextMultiFontImageRenderingVector
        
        ; Boucle For pour chaque ligne.
        ForEach List_VectorTextMultiFont_Text.i()\Line()
          
          DrawNextPositionX.i = List_VectorTextMultiFont_Text.i()\Line()\LineX
          DrawNextPositionY.i = List_VectorTextMultiFont_Text.i()\Line()\LineY
          
          ; Récuperer le nombre d'emplacements que contienent la Liste Location() de la ligne actuel.
          LocationNumber.i = ListSize(List_VectorTextMultiFont_Text.i()\Line()\Location())
          
          ; Boucle For pour chaque mot de la ligne actuel.
          ForEach List_VectorTextMultiFont_Text.i()\Line()\Location()
            
            If List_VectorTextMultiFont_Text.i()\Line()\Location()\Text > ""
              
              ; Si ont peux dessiner sur l'image.
              If StartVectorDrawing(ImageVectorOutput(List_VectorTextMultiFont_Text.i()\MyTextImageID))
                
                ; Utilise le font.
                VectorFont(FontID(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextFontID))
                
                ; Définie la couleur du font du texte.
                VectorSourceColor(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextColorBackround)
                
                ; Dessine le font du texte avec la couleur du font du texte.
                AddPathBox(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextX, List_VectorTextMultiFont_Text.i()\Line()\LineY, List_VectorTextMultiFont_Text.i()\Line()\Location()\TextWidth, List_VectorTextMultiFont_Text.i()\Line()\LineHeight)
                FillPath(#PB_Path_Preserve)
                
                ; Dessine le texte.
                MovePathCursor(DrawNextPositionX.i + List_VectorTextMultiFont_Text.i()\Line()\Location()\TextX, DrawNextPositionY.i + List_VectorTextMultiFont_Text.i()\Line()\Location()\TextY + 0.5 + 2.000000)
                VectorSourceColor(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextColor)
                DrawVectorText(List_VectorTextMultiFont_Text.i()\Line()\Location()\Text)
                
                StopVectorDrawing()
                
              EndIf
              
            EndIf
            
          Next
          
        Next
        
      ElseIf ImageRendering.i = #VectorTextMultiFontImageRenderingDrawing
        
        ; Si ont peux dessiner sur l'image.
        If StartDrawing(ImageOutput(List_VectorTextMultiFont_Text.i()\MyTextImageID))
          
          DrawingMode(#PB_2DDrawing_AlphaBlend)
          
          ; Boucle For pour chaque ligne.
          ForEach List_VectorTextMultiFont_Text.i()\Line()
            
            DrawNextPositionX.i = List_VectorTextMultiFont_Text.i()\Line()\LineX
            DrawNextPositionY.i = List_VectorTextMultiFont_Text.i()\Line()\LineY
            
            ; Récuperer le nombre d'emplacements que contienent la Liste Location() de la ligne actuel.
            LocationNumber.i = ListSize(List_VectorTextMultiFont_Text.i()\Line()\Location())
            
            ; Boucle For pour chaque mot de la ligne actuel.
            ForEach List_VectorTextMultiFont_Text.i()\Line()\Location()
              
              If List_VectorTextMultiFont_Text.i()\Line()\Location()\Text > ""
                
                ; Dessine le font du Texte.
                FrontColor(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextColorBackround)
                Box(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextX, List_VectorTextMultiFont_Text.i()\Line()\LineY, List_VectorTextMultiFont_Text.i()\Line()\Location()\TextWidth, List_VectorTextMultiFont_Text.i()\Line()\LineHeight)
                
                ; Utilise le font.
                DrawingFont(FontID(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextFontID))
                
                ; Définie la couleur du texte.
                FrontColor(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextColor)
                BackColor(RGBA(0, 0, 0, 0))
                
                ; Dessine le texte.
                DrawText(DrawNextPositionX.i + List_VectorTextMultiFont_Text.i()\Line()\Location()\TextX, DrawNextPositionY.i + List_VectorTextMultiFont_Text.i()\Line()\Location()\TextY + 1, List_VectorTextMultiFont_Text.i()\Line()\Location()\Text)
                
              EndIf
              
            Next
            
          Next
          
          StopDrawing()
          
        EndIf
        
      EndIf
      
      ; Sinon si l'image n'est pas initialié.
    Else
      Debug "VectorTextMultiFontDrawTextToImage >>> Erreur, Image n'est pas initialisé !"
      ProcedureReturn -1
      
    EndIf
    
    ForEach List_VectorTextMultiFont_Text.i()\Line()
      
      ForEach List_VectorTextMultiFont_Text.i()\Line()\Location()
        
        If IsFont(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextFontID)
          FreeFont(List_VectorTextMultiFont_Text.i()\Line()\Location()\TextFontID)
        EndIf
        
      Next
      
    Next
    
    ProcedureReturn List_VectorTextMultiFont_Text.i()\MyTextImageID
    
  EndIf
  
EndProcedure

DisableExplicit

; --------------------------Exemple----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Enumeration 1
  #Window
  #MyCanvasGadget
EndEnumeration

Enumeration 1
  #MyText1
  #MyText2
  #MyText3
EndEnumeration

If OpenWindow(#Window, 0, 0, 800, 600, "CreateVectorTextMultiFont...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(#MyCanvasGadget, 0, 0, 800, 600)
  
  ;{ Create Text
  TimeStart.i = ElapsedMilliseconds()
  
  If InitVectorTextMultiFont()
    
    If CreateVectorTextMultiFont(#MyText1, 200, 200, 10, #VectorTextMultiFontAutoSize)
      
      VectorTextMultiFontAddText(#MyText1, "This ", "Arial", 0, 12, RGBA(0, 0, 0, 150), RGBA(0, 255, 0, 200))
      VectorTextMultiFontAddText(#MyText1, "Is ", "Cambria", #PB_Font_Underline, 25, RGBA(255, 0, 0, 255), RGBA(255, 200, 0, 255))
      VectorTextMultiFontAddText(#MyText1, "A ", "Times New Roman", #PB_Font_StrikeOut, 40, RGBA(255, 0, 255, 255), RGBA(0, 0, 255, 255))
      VectorTextMultiFontAddText(#MyText1, "Text ", "Courier New", #PB_Font_Italic | #PB_Font_Bold, 16, RGBA(0, 0, 255, 255), RGBA(150, 150, 150, 255)) ; Manorly
      VectorTextMultiFontAddText(#MyText1, "MultiFont", "Verdana", #PB_Font_Underline | #PB_Font_StrikeOut | #PB_Font_Italic, 32, RGBA(255, 200, 0, 255), RGBA(0, 0, 0, 255)) ; Manorly
      
    EndIf
    
    If CreateVectorTextMultiFont(#MyText2, 100, 100, 0, #VectorTextMultiFontAutoSize)
      
      VectorTextMultiFontAddText(#MyText2, "The Fox", "Arial", #PB_Font_Bold | #PB_Font_Underline, 17, RGBA(255, 130, 0, 255), RGBA(255, 255, 255, 255))
      
      VectorTextMultiFontAddLine(#MyText2)
      VectorTextMultiFontAddLine(#MyText2)
      
      VectorTextMultiFontAddText(#MyText2, "Fox ", "Cambria", #PB_Font_Bold, 12, RGBA(255, 0, 0, 255), RGBA(255, 255, 255, 255))
      VectorTextMultiFontAddText(#MyText2, "is an ambiguous term that most often refers to ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
      VectorTextMultiFontAddText(#MyText2, "Canids", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), RGBA(255, 255, 255, 255))
      VectorTextMultiFontAddText(#MyText2, " of the", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
      VectorTextMultiFontAddLine(#MyText2)
      
      VectorTextMultiFontAddText(#MyText2, "genus Vulpes, the most common being the ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
      VectorTextMultiFontAddText(#MyText2, "Red Fox ", "Cambria", #PB_Font_Italic, 10, RGBA(255, 0, 0, 255), RGBA(255, 255, 255, 255))
      VectorTextMultiFontAddText(#MyText2, "(Vulpes vulpes).", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
      
      VectorTextMultiFontAddLine(#MyText2)
      VectorTextMultiFontAddLine(#MyText2)
      
      VectorTextMultiFontAddText(#MyText2, "However, by physical similarity, the term is also used to", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddLine(#MyText2)
      
      VectorTextMultiFontAddText(#MyText2, "designate ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      VectorTextMultiFontAddText(#MyText2, "Canids ", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      VectorTextMultiFontAddText(#MyText2, "belonging to other genera such As:", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddLine(#MyText2)
      
      VectorTextMultiFontAddText(#MyText2, "Atelocynus", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      VectorTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddText(#MyText2, "Cerdocyon", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      VectorTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddText(#MyText2, "Dusicyon", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      VectorTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddText(#MyText2, "Otocyon", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      VectorTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddText(#MyText2, "Lycalopex", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      VectorTextMultiFontAddText(#MyText2, " And, ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
      
      VectorTextMultiFontAddText(#MyText2, "Urocyon.", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
      
      VectorTextMultiFontAddLine(#MyText2)
      VectorTextMultiFontAddLine(#MyText2)
      
      VectorTextMultiFontAddText(#MyText2, "                      You will not see this text because it is invisible !                    ", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 0), RGBA(255, 200, 0, 255))
      
    EndIf
    
    If CreateVectorTextMultiFont(#MyText3, 50, 50, 0, #VectorTextMultiFontAutoSize)
      
      For Line.i = 1 To 13
        
        For Letter.i = 1 To 100
          VectorTextMultiFontAddText(#MyText3, Chr(Random(122, 97)), "Belwe Lt BT", 0, Random(12, 8), RGBA(Random(255), Random(255), Random(255), 255), RGBA(255, 255, 255, 255))
        Next
        
        If Line.i < 13
          VectorTextMultiFontAddLine(#MyText3)
        EndIf
        
      Next
      
    EndIf
    
    TimeAnd.i = ElapsedMilliseconds()
    
    Debug "Filling Time: " + Str(TimeAnd.i - TimeStart.i) + " Ms"
    
    TimeTotal.i = TimeAnd.i - TimeStart.i
    
    TimeStart.i = ElapsedMilliseconds()
    
    MyImageVectorTexte1.i = VectorTextMultiFontDrawTextToImage(#MyText1)
    MyImageVectorTexte2.i = VectorTextMultiFontDrawTextToImage(#MyText2, #VectorTextMultiFontImageRenderingVector)
    MyImageVectorTexte3.i = VectorTextMultiFontDrawTextToImage(#MyText3, #VectorTextMultiFontImageRenderingVector)
    
    TimeAnd.i = ElapsedMilliseconds()
    
    TimeTotal.i + TimeAnd.i - TimeStart.i
    
    Debug "Creation Time: " + Str(TimeAnd.i - TimeStart.i) + " Ms"
    
    CloseVectorTextMultiFont()
    
  EndIf
  
  ;}
  ;{ Draw Text
  
  TimeStart.i = ElapsedMilliseconds()
  
  If StartDrawing(CanvasOutput(#MyCanvasGadget))
    FrontColor(RGBA(200, 200, 200, 255))
    Box(0, 0, GadgetWidth(#MyCanvasGadget), GadgetHeight(#MyCanvasGadget))
    StopDrawing()
  EndIf
  
  If IsImage(MyImageVectorTexte1.i)
    
    If StartDrawing(CanvasOutput(#MyCanvasGadget))
      
      DrawingMode(#PB_2DDrawing_Outlined)
      FrontColor(RGBA(0, 0, 0, 255))
      Box(10, 10, ImageWidth(MyImageVectorTexte1.i) + 10, ImageHeight(MyImageVectorTexte1.i) + 10)
      
      DrawAlphaImage(ImageID(MyImageVectorTexte1.i), 15, 15, 255)
      StopDrawing()
      
    EndIf
    
  Else
    Debug "Miss !"
    
  EndIf
  
  
  If IsImage(MyImageVectorTexte2.i)
    
    If StartDrawing(CanvasOutput(#MyCanvasGadget))
      
      DrawingMode(#PB_2DDrawing_Outlined)
      FrontColor(RGBA(0, 0, 0, 255))
      Box(10, 100, ImageWidth(MyImageVectorTexte2.i) + 10, ImageHeight(MyImageVectorTexte2.i) + 10)
      
      DrawAlphaImage(ImageID(MyImageVectorTexte2.i), 15, 105, 255)
      StopDrawing()
      
    EndIf
    
  Else
    Debug "Miss !"
    
  EndIf

  
  If IsImage(MyImageVectorTexte3.i)
    
    If StartDrawing(CanvasOutput(#MyCanvasGadget))
      
      DrawingMode(#PB_2DDrawing_Outlined)
      FrontColor(RGBA(0, 0, 0, 255))
      Box(10, 294, ImageWidth(MyImageVectorTexte3.i) + 10, ImageHeight(MyImageVectorTexte3.i) + 10)
      
      DrawAlphaImage(ImageID(MyImageVectorTexte3.i), 15, 299, 255)
      StopDrawing()
      
    EndIf
    
  Else
    Debug "Miss !"
    
  EndIf
  
  TimeAnd.i = ElapsedMilliseconds()
  
  TimeTotal.i + TimeAnd.i - TimeStart.i
  
  Debug "Drawing Time: " + Str(TimeAnd.i - TimeStart.i) + " Ms"
  Debug "------------------"
  Debug "Totale Time: " + Str(TimeTotal.i) + " Ms"
  ;}
  
  Repeat
    
    Event = WaitWindowEvent()
    
  Until Event = #PB_Event_CloseWindow
  
EndIf
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.