Draw a text with multiple fonts with VectorDrawing.

Share your advanced PureBasic knowledge/code with the community.
User avatar
jacdelad
Addict
Addict
Posts: 1418
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: Draw a text with multiple fonts with VectorDrawing.

Post by jacdelad »

What do you mean by not correctly aligned? Do you mean the text qithout underline being lower positioned? That is normal, because the underline is calculated in the height.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: Draw a text with multiple fonts with VectorDrawing.

Post by ShadowStorm »

I missed this post, the forum didn't tell me anything, and there was a topic move by myself in the meantime, I think.

The text was not well aligned because I could not calculate the baseline of the text, but it's fixed, thank you very much, you have to use Vector for that.
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: Draw a text with multiple fonts with VectorDrawing.

Post by ShadowStorm »

New version, I try to optimize the code, more later !

Code: Select all

; 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.

EnableExplicit

; Structure qui contient les propriétées de tous les mots.
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
  
EndStructure

EnableExplicit

; Structure qui contient les propriétées de chaque ligne du Texte MultiFont.
Structure Line
  
  LineX.i
  LineY.i
  LineWidth.i
  LineHeight.i
  
  NextPositionX.i
  
  List Location.Text()
  
EndStructure

; Structure qui contient les propriétées du Texte MultiFont.
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 racourci (ID) qui pointe vers un emplacement de liste, ex: TextMultiFontID.i = 3 (ID), 3 = 24 (Element 24 de la liste).
Global NewMap Map_VectorTextMultiFont_TextMultiFontID_ID.i() ; Chaque Texte MultiFont est ajouter à la suite dans la liste.

; Liste qui contient tous les Texte MultiFonts, chaque élément est un Texte MultiFont.
Global NewList List_VectorTextMultiFont_Text.MyText()

; Option pour la fonction Create_VectorTextMultiFont() pour automatiquement créer un Texte MultiFont de la taille de celui-ci.
#VectorTextMultiFontAutoSize = 1024

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

; 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)
  
  ; 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)
  
  ; 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
    
    ; Si ont peux dessiné sur l'image.
    If StartVectorDrawing(ImageVectorOutput(List_VectorTextMultiFont_Text.i()\MyTextImageID))
      
      ; 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
      
      StopVectorDrawing()
      
    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)
  
  ; 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)
  
  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_AllChannels)
          
          ; 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 > ""
                
                DrawingMode(#PB_2DDrawing_AlphaBlend)
                
                ; 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
  a = ElapsedMilliseconds()
  
  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 14
      
      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 < 14
        VectorTextMultiFontAddLine(#MyText3)
      EndIf
      
    Next
    
  EndIf
  
  b = ElapsedMilliseconds()
  Debug "Filling Time: " + Str(b - a) + " Ms"
  
  a = ElapsedMilliseconds()
  
  MyImageVectorTexte1.i = VectorTextMultiFontDrawTextToImage(#MyText1)
  MyImageVectorTexte2.i = VectorTextMultiFontDrawTextToImage(#MyText2, #VectorTextMultiFontImageRenderingVector)
  MyImageVectorTexte3.i = VectorTextMultiFontDrawTextToImage(#MyText3, #VectorTextMultiFontImageRenderingVector)
  
  b = ElapsedMilliseconds()
  Debug "Creation Time: " + Str(b - a) + " Ms"
  
  
  ;}
  ;{ Draw Text
  
  a = 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, 288, ImageWidth(MyImageVectorTexte3.i) + 10, ImageHeight(MyImageVectorTexte3.i) + 10)
      
      DrawAlphaImage(ImageID(MyImageVectorTexte3.i), 15, 293, 255)
      StopDrawing()
      
    EndIf
    
  Else
    Debug "Miss !"
    
  EndIf
  
  b = ElapsedMilliseconds()
  Debug "Drawing Time: " + Str(b - a) + " Ms"
  
  ;}
  
  Repeat
    
    Event = WaitWindowEvent()
    
  Until Event = #PB_Event_CloseWindow
  
EndIf
Edit: I have tried to improve but can't see how to make it faster.
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: Draw a text with multiple fonts with VectorDrawing.

Post by ShadowStorm »

Hello, I was able to improve a bit, but I don't see how I can do better!

Code: Select all

; 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
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
Post Reply