Draw a text with several fonts with Drawing.

Share your advanced PureBasic knowledge/code with the community.
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Draw a text with several fonts with Drawing.

Post by ShadowStorm »

Hello, here is a code to create multi-police text with the Drawing library.

Code: Select all

; Code created by Dieppedalle David on 29/08/2021.
; Current Version: 1.00.00.

; First version: 1.00.00 on 23/08/2021.

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_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.MyText()

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

; 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 #DrawingTextMultiFontAutoSize, 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 #DrawingTextMultiFontAutoSize, 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 CreateDrawingTextMultiFont(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_DrawingTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
        Break
      EndIf
    ForEver
    
  ElseIf TextMultiFontID.i < 0
    Debug "CreateDrawingTextMultiFont >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "CreateDrawingTextMultiFont >>> TextMultiFontID.i est supérieur à 10 000, dois être 10 000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  ; Vériffications diverses.
  If Width.i <= 0
    Debug "CreateDrawingTextMultiFont >>> Width.i est inférieur à 0, dois être 1 Minimum !"
    ProcedureReturn -1
    
  ElseIf Width.i > 2000
    Debug "CreateDrawingTextMultiFont >>> Width.i est Supérieur à 2000, dois être 2000 Maximum !"
    ProcedureReturn -1
    
  EndIf
  
  If Height.i <= 0
    Debug "CreateDrawingTextMultiFont >>> Height.i est inférieur à 0, dois être 1 Minimum !"
    ProcedureReturn -1
    
  ElseIf Height.i > 2000
    Debug "CreateDrawingTextMultiFont >>> 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_DrawingTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Element non trouvé.
    
    ; Ajoute un élément dans la liste de Texte MultiFont.
    AddElement(List_DrawingTextMultiFont_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_DrawingTextMultiFont_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_DrawingTextMultiFont_TextMultiFontID_ID.i() = ListIndex(List_DrawingTextMultiFont_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 "CreateDrawingTextMultiFont >>> Erreur, impossible de créer l'image pour le Texte MultiFont !"
      ProcedureReturn -1
    EndIf
    
  ElseIf *IsTextMultiFontID <> 0 ; Element trouvé, il existe déjà.
    
    Debug MapKey(Map_DrawingTextMultiFont_TextMultiFontID_ID.i()) + " = " + Str(Map_DrawingTextMultiFont_TextMultiFontID_ID.i())
    
    ; 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_DrawingTextMultiFont_Text.i(), Map_DrawingTextMultiFont_TextMultiFontID_ID.i())
    
    ; Vérifie si l'image du Texte MultiFont existe.
    If IsImage(List_DrawingTextMultiFont_Text.i()\MyTextImageID)
      FreeImage(List_DrawingTextMultiFont_Text.i()\MyTextImageID) ; Supprime cette image.
    EndIf
    
    ResetStructure(@List_DrawingTextMultiFont_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 "CreateDrawingTextMultiFont >>> Erreur, impossible de créer l'image pour le Texte MultiFont !"
      ProcedureReturn -1
    EndIf
    
    Debug "CreateDrawingTextMultiFont >>> TextMultiFontID.i (" + Str(TextMultiFontID.i) + ") Existe déjà et a été remplacé !"
    Debug "-----------------------------------"
    
  EndIf
  
  If Option.i = #DrawingTextMultiFontAutoSize
    List_DrawingTextMultiFont_Text.i()\MyTextAutoSize = #True
  Else
    List_DrawingTextMultiFont_Text.i()\MyTextAutoSize = 0
  EndIf
  
  List_DrawingTextMultiFont_Text.i()\MyTextMultiFontID = TextMultiFontID.i
  List_DrawingTextMultiFont_Text.i()\MyTextImageID = TextImageID.i
  
  List_DrawingTextMultiFont_Text.i()\MyTextImageWidth = Width.i
  List_DrawingTextMultiFont_Text.i()\MyTextImageHeight = Height.i
  
  List_DrawingTextMultiFont_Text.i()\Interline = Interline.i
  
  ; Ajout d'une nouvelle ligne
  AddElement(List_DrawingTextMultiFont_Text.i()\Line())
  
  List_DrawingTextMultiFont_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 DrawingTextMultiFontAddText(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 "DrawingTextMultiFontAddText >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "DrawingTextMultiFontAddText >>> 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_DrawingTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Le Texte MultiFont (TextMultiFontID) n'as pas été trouvé.
    Debug "DrawingTextMultiFontAddText >>> 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_DrawingTextMultiFont_Text.i()\MyTextImageID)
      Debug "DrawingTextMultiFontAddText >>> Erreur, impossible de trouver l'image pour le Texte MultiFont !"
      ProcedureReturn -1
    EndIf
    
    ; Ajoute un nouvel élément dans la Liste Location().
    AddElement(List_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\Location()\TextSize = Size.i
    
    ; Enregistre le style du Texte dans la Liste Location().
    List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextStyle = Style.i
    
    ; Enregistre le Texte qu'il faut écrire dans la Liste Location().
    List_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\Location()\TextFontName = Font.s
    
    ; Enregistre le numéro ID de la Police du Texte dans la Liste Location().
    List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextFontID = FontID.i
    
    ; Couleur du Texte.
    List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextColor = Color.i
    
    ; Couleur de l'arrière plant du Texte
    List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextColorBackround = ColorBackround.i
    
    ; Si ont peux dessiné sur l'image.
    If StartDrawing(ImageOutput(List_DrawingTextMultiFont_Text.i()\MyTextImageID))
      
      ; Utilise le Font (FontID.i) pour écrire le Texte.
      DrawingFont(FontID(FontID.i))
      
      ; Enregistrement de la Largeur et Hauteur du Texte dans la Liste Location().
      List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextWidth = Round(TextWidth(Text.s), #PB_Round_Up) ; Largeur du Texte.
      List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextHeight = Round(TextHeight(Text.s), #PB_Round_Up) ; Hauteur du Texte.
      
      ; 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_DrawingTextMultiFont_Text.i()\Line()\LineHeight < List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextHeight
        List_DrawingTextMultiFont_Text.i()\Line()\LineHeight = List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextHeight
      EndIf
      
      StopDrawing()
      
    EndIf
    
    ; Calcule la ligne de base du Texte avec VectorDrawing, impossible de faire autrement, ce sera utilisé pour aligné correctement le texte plus tard.
    If StartVectorDrawing(ImageVectorOutput(List_DrawingTextMultiFont_Text.i()\MyTextImageID))
      VectorFont(FontID(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextFontID))
      List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextBaseLine = VectorTextHeight("Q",#PB_VectorText_Baseline)
      StopVectorDrawing()
    EndIf
    
    ; Enregistre la position X de la Location() actuel.
    List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextX = List_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\NextPositionX + List_DrawingTextMultiFont_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 DrawingTextMultiFontAddLine(TextMultiFontID.i)
  
  ; Vériffications diverses.
  If TextMultiFontID.i < 0
    Debug "DrawingTextMultiFontAddText >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "DrawingTextMultiFontAddText >>> 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_DrawingTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Le Texte MultiFont (TextMultiFontID) n'as pas été trouvé.
    Debug "DrawingTextMultiFontAddText >>> 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_DrawingTextMultiFont_Text.i()\Line()\LineY + List_DrawingTextMultiFont_Text.i()\Line()\LineHeight + List_DrawingTextMultiFont_Text.i()\Interline
    
    ; Ont ajoute un élément dans la Liste Line() pour la prochaine ligne.
    AddElement(List_DrawingTextMultiFont_Text.i()\Line())
    
    ; Définie et enregistre la hauteur de la prochaine ligne.
    List_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\LineY = NextPositionY.i
    
  EndIf
  
  ProcedureReturn #True
  
EndProcedure

; Dessine le Texte MultiFont sur une image 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.
; Retourne si tous c'est bien passé le numéro de l'image ou le Texte MultiFont a été dessiné, sinon -1.

; Draw the MultiFont Text on an image and return the number of this one.
; TextMultiFontID.i starts from 0, maximum 10 000, it is the identification number of the Text.
; Returns If all went well the number of the image where the MultiFont Text was drawn, otherwise -1.
Procedure.i DrawingTextMultiFontDrawTextToImage(TextMultiFontID.i)
  
  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.
  
  ; Vériffications diverses.
  If TextMultiFontID.i < 0
    Debug "DrawingTextMultiFontAddText >>> TextMultiFontID.i est inférieur à 0, dois être 0 Minimum !"
    ProcedureReturn -1
    
  ElseIf TextMultiFontID.i > 10000
    Debug "DrawingTextMultiFontAddText >>> 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_DrawingTextMultiFont_TextMultiFontID_ID.i(), Str(TextMultiFontID.i))
  
  If *IsTextMultiFontID = 0 ; Le Texte MultiFont (TextMultiFontID) n'as pas été trouvé.
    Debug "DrawingTextMultiFontAddText >>> TextMultiFontID.i (" + Str(TextMultiFontID.i) + "), n'existe pas !"
    ProcedureReturn -1
    
  ElseIf *IsTextMultiFontID <> 0 ; Le Texte MultiFont (TextMultiFontID) a été trouvé.
    
    SelectElement(List_DrawingTextMultiFont_Text.i(), Map_DrawingTextMultiFont_TextMultiFontID_ID.i())
    
    ; Récuperer le nombre de lignes que contienent la Listex Line().
    Define LineNumber.i = ListSize(List_DrawingTextMultiFont_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_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\Location()
        
        ; Récupere la hauteur maximal des mots depuis leur base.
        If LocationTextBaseLine.i < List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextBaseLine
          LocationTextBaseLine.i = List_DrawingTextMultiFont_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_DrawingTextMultiFont_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_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\Location()\TextY = LocationTextBaseLine.i - List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextBaseLine
        EndIf
        
      Next
      
    Next
    
    If List_DrawingTextMultiFont_Text.i()\MyTextAutoSize = #True
      
      ; Boucle For pour chaque ligne.
      ; Récupere la ligne la plus grande.
      ForEach List_DrawingTextMultiFont_Text.i()\Line()
        
        ; Récuperer le nombre d'emplacements que contienent la Liste Location() de la ligne actuel.
        LineWidth.i = List_DrawingTextMultiFont_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_DrawingTextMultiFont_Text.i()\Line()\LineY + List_DrawingTextMultiFont_Text.i()\Line()\LineHeight + List_DrawingTextMultiFont_Text.i()\Interline
      
      ; Si l'image est initialisé.
      If IsImage(List_DrawingTextMultiFont_Text.i()\MyTextImageID)
        
        ; Redimentionnement de l'image du texte.
        ResizeImage(List_DrawingTextMultiFont_Text.i()\MyTextImageID, LineLargest.i, TextHeight.i)
        
      Else
        ; Si l'image n'est pas initialisé.
        Debug "DrawingTextMultiFontDrawTextToImage >>> Erreur, impossible de trouver l'image pour le Texte MultiFont !"
        ProcedureReturn -1
        
      EndIf
      
    EndIf
    
    ; Si l'image est initialisé.
    If IsImage(List_DrawingTextMultiFont_Text.i()\MyTextImageID)
      
      ; Si ont peux dessiner sur l'image.
      If StartDrawing(ImageOutput(List_DrawingTextMultiFont_Text.i()\MyTextImageID))
        
        DrawingMode(#PB_2DDrawing_AllChannels)
        
        Define DrawNextPositionX.i = 0
        Define DrawNextPositionY.i = 0
        
        ; Boucle For pour chaque ligne.
        ForEach List_DrawingTextMultiFont_Text.i()\Line()
          
          DrawNextPositionX.i = List_DrawingTextMultiFont_Text.i()\Line()\LineX
          DrawNextPositionY.i = List_DrawingTextMultiFont_Text.i()\Line()\LineY
          
          ; Récuperer le nombre d'emplacements que contienent la Liste Location() de la ligne actuel.
          LocationNumber.i = ListSize(List_DrawingTextMultiFont_Text.i()\Line()\Location())
          
          ; Boucle For pour chaque mot de la ligne actuel.
          ForEach List_DrawingTextMultiFont_Text.i()\Line()\Location()
            
            If List_DrawingTextMultiFont_Text.i()\Line()\Location()\Text > ""
              
              ; Dessine le font du Texte.
              FrontColor(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextColorBackround)
              Box(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextX, List_DrawingTextMultiFont_Text.i()\Line()\LineY, List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextWidth, List_DrawingTextMultiFont_Text.i()\Line()\LineHeight)
              
              ; Utilise le font.
              DrawingFont(FontID(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextFontID))
              
              ; Définie la couleur du texte.
              FrontColor(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextColor)
              BackColor(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextColorBackround)
              
              ; Dessine le texte.
              DrawText(DrawNextPositionX.i + List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextX, DrawNextPositionY.i + List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextY, List_DrawingTextMultiFont_Text.i()\Line()\Location()\Text)
              
            EndIf
            
          Next
          
        Next
        
        StopDrawing()
        
      EndIf
      
      ; Sinon si l'image n'est pas initialié.
    Else
      Debug "DrawingTextMultiFontDrawTextToImage >>> Erreur, Image n'est pas initialisé !"
      ProcedureReturn -1
      
    EndIf
    
    ForEach List_DrawingTextMultiFont_Text.i()\Line()
      
      ForEach List_DrawingTextMultiFont_Text.i()\Line()\Location()
        
        If IsFont(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextFontID)
          FreeFont(List_DrawingTextMultiFont_Text.i()\Line()\Location()\TextFontID)
        EndIf
        
      Next
      
    Next
    
    ProcedureReturn List_DrawingTextMultiFont_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, "CreateDrawingTextMultiFont", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(#MyCanvasGadget, 0, 0, 800, 600)
  
  ;{ Create Text
  
  If CreateDrawingTextMultiFont(#MyText1, 200, 200, 10, #DrawingTextMultiFontAutoSize)
    
    DrawingTextMultiFontAddText(#MyText1, "This ", "Arial", 0, 12, RGBA(0, 0, 0, 100), RGBA(0, 255, 0, 100))
    DrawingTextMultiFontAddText(#MyText1, "Is ", "Cambria", #PB_Font_Underline, 20, RGBA(255, 0, 0, 255), RGBA(255, 200, 0, 255))
    DrawingTextMultiFontAddText(#MyText1, "A ", "Times New Roman", #PB_Font_StrikeOut, 40, RGBA(255, 0, 255, 255), RGBA(0, 0, 255, 255))
    DrawingTextMultiFontAddText(#MyText1, "Text ", "Courier New", #PB_Font_Italic | #PB_Font_Bold, 16, RGBA(0, 0, 255, 255), RGBA(150, 150, 150, 255)) ; Manorly
    DrawingTextMultiFontAddText(#MyText1, "MultiFont", "Verdana", #PB_Font_Underline | #PB_Font_StrikeOut | #PB_Font_Italic, 24, RGBA(255, 200, 0, 255), RGBA(0, 0, 0, 255)) ; Manorly
    
    MyImageVectorTexte1.i = DrawingTextMultiFontDrawTextToImage(#MyText1)
    
  EndIf
  
  If CreateDrawingTextMultiFont(#MyText2, 100, 100, 0, #DrawingTextMultiFontAutoSize)
    
    DrawingTextMultiFontAddText(#MyText2, "The fox", "Arial", #PB_Font_Bold | #PB_Font_Underline, 17, RGBA(255, 130, 0, 255), RGBA(255, 255, 255, 255))
    
    DrawingTextMultiFontAddLine(#MyText2)
    DrawingTextMultiFontAddLine(#MyText2)
    
    DrawingTextMultiFontAddText(#MyText2, "Fox ", "Cambria", #PB_Font_Bold, 12, RGBA(255, 0, 0, 255), RGBA(255, 255, 255, 255))
    DrawingTextMultiFontAddText(#MyText2, "is an ambiguous term that most often refers to ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
    DrawingTextMultiFontAddText(#MyText2, "Canids", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), RGBA(255, 255, 255, 255))
    DrawingTextMultiFontAddText(#MyText2, " of the", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
    DrawingTextMultiFontAddLine(#MyText2)
    
    DrawingTextMultiFontAddText(#MyText2, "genus Vulpes, the most common being the ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
    DrawingTextMultiFontAddText(#MyText2, "Red Fox ", "Cambria", #PB_Font_Italic, 10, RGBA(255, 0, 0, 255), RGBA(255, 255, 255, 255))
    DrawingTextMultiFontAddText(#MyText2, "(Vulpes vulpes).", "Cambria", 0, 10, RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 255))
    
    DrawingTextMultiFontAddLine(#MyText2)
    DrawingTextMultiFontAddLine(#MyText2)
    
    DrawingTextMultiFontAddText(#MyText2, "However, by physical similarity, the term is also used to", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddLine(#MyText2)
    
    DrawingTextMultiFontAddText(#MyText2, "designate ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, "Canids ", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, "belonging to other genera such As:", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddLine(#MyText2)
    
    DrawingTextMultiFontAddText(#MyText2, "Atelocynus", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddText(#MyText2, "Cerdocyon", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddText(#MyText2, "Dusicyon", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddText(#MyText2, "Otocyon", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, ", ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddText(#MyText2, "Lycalopex", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    DrawingTextMultiFontAddText(#MyText2, " And, ", "Cambria", 0, 10, RGBA(0, 0, 0, 255), 0)
    
    DrawingTextMultiFontAddText(#MyText2, "Urocyon.", "Cambria", #PB_Font_Underline, 10, RGBA(0, 0, 255, 255), 0)
    
    DrawingTextMultiFontAddLine(#MyText2)
    DrawingTextMultiFontAddLine(#MyText2)
    
    DrawingTextMultiFontAddText(#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))
    
    MyImageVectorTexte2.i = DrawingTextMultiFontDrawTextToImage(#MyText2)
    
  EndIf
  
  If CreateDrawingTextMultiFont(#MyText3, 50, 50, 0, #DrawingTextMultiFontAutoSize)
    
    For Line.i = 1 To 14
      
      For Letter.i = 1 To 100
        DrawingTextMultiFontAddText(#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
        DrawingTextMultiFontAddLine(#MyText3)
      EndIf
      
    Next
    
    MyImageVectorTexte3.i = DrawingTextMultiFontDrawTextToImage(#MyText3)
    
  EndIf
  
  ;}
  ;{ Draw Text
  
  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, 270, ImageWidth(MyImageVectorTexte3.i) + 10, ImageHeight(MyImageVectorTexte3.i) + 10)
      
      DrawAlphaImage(ImageID(MyImageVectorTexte3.i), 15, 275, 255)
      StopDrawing()
      
    EndIf
    
  Else
    Debug "Miss !"
    
  EndIf
  
  ;}
  
  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.