Ecriture d'un mot avec path.addstring

Description

Cette source permet d'étudier le décalage existant entre l'endroit où on demande l'écriture du mot et l'endroit où le mot est obtenu à l'écran !
Il existe en effet un décalage inattendu entre l'instruction qui dessine le mot et celle qui dessine un rectangle de la même taille au même endroit...

C'est important de maitriser ce décalage si on veut un affichage précis du mot pour des raisons graphiques (et esthétiques)

Ce décalage dépend :
- des caractères du mot (e,p,t,i,E,5,...)
- de la taille (hauteur) de la fonte utilisée (il y a proportionnalité)

L'étude est faite avec deux types de paramètres :
- une translation absolue (X transl et Y transl) qui donne l'écart en pixels
- une translation proportionnelle à la taille de la fonte utilisée (Xcoeff et Ycoeff), plus utilisable dans un programme

Et en résumé :
X transl = Xcoeff * taille_fonte et Y transl = Ycoeff * taille_fonte

Je n'ai pas étudié en comparant les fontes, mais cet outil peut être complété pour le faire...

Source / Exemple :


Imports System.Windows.Forms.Application
Imports System.Drawing.Drawing2D

Public Class Form1
    Dim mot As String 'mot
    Dim hauteur_mot As Integer
    Dim x, y As Double 'position demandée du mot
    Dim xcoeff, ycoeff As Double 'pour placer le mot ds le rectangle !
    Dim xt, yt As Double 'translation pour placer le mot

    'Events
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        mot = "Essai"
        hauteur_mot = 250
        TextBoxHauteur.Text = CStr(hauteur_mot)
        x = 150
        y = 20
        xcoeff = 0.085
        TextBoxXCoeff.Text = CStr(xcoeff)
        ycoeff = 0.2
        TextBoxYCoeff.Text = CStr(ycoeff)
        xt = 0
        TextBoxXTransl.Text = CStr(xt)
        yt = 0
        TextBoxYTransl.Text = CStr(yt)
    End Sub
    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

    End Sub
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        Dessin(e.Graphics)
    End Sub

    Private Sub ButtonMot_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonMot.Click
        Dim s As String

        s = InputBox("Chaine à dessiner :", , mot)
        mot = IIf(s <> "", s, mot)

        Me.Refresh()
        DoEvents()

    End Sub

    Private Sub ButtonHauteurPlus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonHauteurPlus.Click
        hauteur_mot += 1
        TextBoxHauteur.Text = CStr(hauteur_mot)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub ButtonHauteurMoins_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonHauteurMoins.Click
        hauteur_mot -= 1
        TextBoxHauteur.Text = CStr(hauteur_mot)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub TextBoxHauteur_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxHauteur.TextChanged
        hauteur_mot = Val(TextBoxHauteur.Text)
        Me.Refresh()
        DoEvents()
    End Sub

    Private Sub ButtonXCoeffPlus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonXCoeffPlus.Click
        xcoeff = CType(TextBoxXCoeff.Text, Single)
        xcoeff *= 1.01
        TextBoxXCoeff.Text = CStr(xcoeff)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub ButtonXCoeffMoins_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonXCoeffMoins.Click
        xcoeff = CType(TextBoxXCoeff.Text, Single)
        xcoeff *= 0.99
        TextBoxXCoeff.Text = CStr(xcoeff)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub TextBoxXCoeff_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxXCoeff.TextChanged
        xcoeff = CType(TextBoxXCoeff.Text, Single)
        Me.Refresh()
        DoEvents()
    End Sub

    Private Sub ButtonYCoeffPlus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonYCoeffPlus.Click
        ycoeff = CType(TextBoxYCoeff.Text, Single)
        ycoeff *= 1.01
        TextBoxYCoeff.Text = CStr(ycoeff)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub ButtonYCoeffMoins_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonYCoeffMoins.Click
        ycoeff = CType(TextBoxYCoeff.Text, Single)
        ycoeff *= 0.99
        TextBoxYCoeff.Text = CStr(ycoeff)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub TextBoxYCoeff_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxYCoeff.TextChanged
        ycoeff = CType(TextBoxYCoeff.Text, Single)
        Me.Refresh()
        DoEvents()
    End Sub

    Private Sub ButtonXTranslPlus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonXTranslPlus.Click
        xt = CType(TextBoxXTransl.Text, Single)
        xt += 1
        TextBoxXTransl.Text = CStr(xt)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub ButtonXTranslMoins_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonXTranslMoins.Click
        xt = CType(TextBoxXTransl.Text, Single)
        xt -= 1
        TextBoxXTransl.Text = CStr(xt)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub TextBoxXTransl_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxXTransl.TextChanged
        xt = CType(TextBoxXTransl.Text, Single)
        Me.Refresh()
        DoEvents()
    End Sub

    Private Sub ButtonYTranslPlus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonYTranslPlus.Click
        yt = CType(TextBoxYTransl.Text, Single)
        yt += 1
        TextBoxYTransl.Text = CStr(yt)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub ButtonYTranslMoins_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonYTranslMoins.Click
        yt = CType(TextBoxYTransl.Text, Single)
        yt -= 1
        TextBoxYTransl.Text = CStr(yt)
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub TextBoxYTransl_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxYTransl.TextChanged
        yt = CType(TextBoxYTransl.Text, Single)
        Me.Refresh()
        DoEvents()
    End Sub

    Private Sub CheckBoxCoeff_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBoxCoeff.CheckedChanged
        Me.Refresh()
        DoEvents()
    End Sub
    Private Sub CheckBoxTranslation_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBoxTranslation.CheckedChanged
        Me.Refresh()
        DoEvents()
    End Sub

    'Routines
    Public Sub DrawString(ByVal g As Graphics, ByVal s As String, ByVal hauteur As Integer, _
                         ByVal x1 As Double, ByVal y1 As Double)

        Dim Origine As PointF = New PointF(x1, y1) ' position demandée : (x1,y1)
        Dim SF As StringFormat = New StringFormat(0)
        Dim path As New System.Drawing.Drawing2D.GraphicsPath ' Create a GraphicsPath.

        ' Set the SmoothingMode to high quality for best readability.
        g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality

        ' Add the string to the path; declare the font, font style, size :
        path.AddString(s, Me.Font.FontFamily, FontStyle.Bold, hauteur, Origine, SF)

        g.FillPath(Brushes.Black, path) 'tracé lettres pleines

        path.Dispose()
        SF.Dispose()

    End Sub
    Public Function GetStringWidth(ByVal s As String, ByVal hauteur As Integer) As RectangleF
        'détermine la longueur d'un texte écrit avec Path.AddString()
        Dim BoundRect As RectangleF
        Dim SF As StringFormat = New StringFormat(0)
        Dim path As New GraphicsPath ' Create a GraphicsPath.
        Dim Origine As PointF = New PointF(50, 50) 'peu importe, il n'est pas dessiné

        ' Add the string to the path; declare the font, font style, size :
        path.AddString(s, Me.Font.FontFamily, FontStyle.Bold, hauteur, Origine, SF)
        BoundRect = path.GetBounds() 'dimensions du path avant la matrice de rotation

        path.Dispose()
        SF.Dispose()

        Return BoundRect
    End Function 'détermine la longueur d'un texte écrit avec Path.AddString()
    Private Sub Dessin(ByVal g As Graphics)
        Dim BoundRect As RectangleF 'limites du texte écrit ds chaque part
        Dim larg, haut As Single

        DrawString(g, mot, hauteur_mot, x, y)

        BoundRect = GetStringWidth(mot, hauteur_mot)
        larg = BoundRect.Width
        ButtonLargeurMot.Text = "Largeur mot " & CStr(larg)
        haut = BoundRect.Height
        ButtonHauteurMot.Text = "Hauteur mot " & CStr(haut)
        If CheckBoxCoeff.Checked Then
            g.DrawRectangle(Pens.Green, _
                            CType(x + xcoeff * hauteur_mot, Single), CType(y + ycoeff * hauteur_mot, Single), _
                            larg, haut)
        End If
        If CheckBoxTranslation.Checked Then
            g.DrawRectangle(Pens.Red, CType(x + xt, Single), CType(y + yt, Single), larg, haut)
        End If

    End Sub

End Class

Conclusion :


Si la documentation existe sur cette fonction (et ce décalage !) merci d'indiquer le lien...

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.