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