IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Affichage d'un texte de hauteur identique sous XP et Seven


Sujet :

Windows

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 15
    Points : 5
    Points
    5
    Par défaut Affichage d'un texte de hauteur identique sous XP et Seven
    Bonjour,

    J'affiche un texte qui doit respecter des contraintes de rendu indépendement de l'OS et de l'écran :
    - affichage de la hauteur et la largeur des caractères au millimètre près.

    Je demande à l'utilisateur de me donner la taille réelle de l'écran afin de pouvoir le caliber par rapport à la taille connue de Windows (::GetDeviceCaps(hDeviceContext, VERTSIZE)).

    J'utilise DirectX 9. Il me semble logique que le calcul des tailles de caractères avec DirectX soit le même qu'avec la GDI.

    Le code répond bien aux exigences sous XP et Seven.
    Mais j'ai deux questions :

    - pourquoi j'ai un rapport de 72/96 entre la taille affichée sous XP et celle affichée sous Seven?

    - comment calculer la taille d'un caractère sans passer par une phase manuelle?

    En fait, cela correspond aux deux constantes que j'ai du mettre dans mon code!
    Et j'aimerai bien les remplacer par une valeur dynamique (base de registre?) ou un calcul!

    L'essentiel est dans FontSize().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    void Text3D::CreateFont(void)
    {
    	HRESULT hr;
    
    	int nLogPixelsY = DeviceCaps();
    	hr = D3DXCreateFont(D3DDevice,
    		FontSize(nLogPixelsY),	// The height of the characters in logical units. 
    		0,	// The width of the characters in logical units.
    		FW_NORMAL,	// Weight FW_BOLD
    		1,	// MipLevels, 0 = autogen mipmaps
    		FALSE,	// Italic
    		DEFAULT_CHARSET,//Charset 
    		OUT_DEFAULT_PRECIS,  //Output Precision OUT_TT_ONLY_PRECIS
    		PROOF_QUALITY,     //Quality, ANTIALIASED_QUALITY
    		DEFAULT_PITCH|FF_DONTCARE, //Pitch and Family
    		L"Arial",
    		&D3DXFont);
    	if ( FAILED( hr ) ){
    		throw ExceptionE(false,std::string("Text3D::Initialize() D3DXCreateFont()"),DXGetErrorDescriptionW(hr));
    	}
    }
    
    int Text3D::DeviceCaps(void)
    {
    	HDC hDC = ::GetDC( NULL );
    	// http://support.microsoft.com/kb/74299/fr
    	// Pour créer une police dans l'environnement de graphique de Microsoft Windows ne donne que la 
    	// taille d'un point. Une application doit calculer la hauteur logique de la police, étant donné 
    	// que les fonctions CreateFont() et CreateFontIndirect() utilisent des unités logiques pour 
    	// spécifier la hauteur.
    	// Pour décrire une police à l'utilisateur, une application peut calculer la taille d'un point d'une police, 
    	// donnée par sa hauteur. Cet article fournit les formules requis pour effectuer ces calculs pour 
    	// le mode de mise en correspondance MM_TEXT. 
    	if (!::SetMapMode(hDC,MM_TEXT)){
    		throw ExceptionE(true,std::string("Text3D::Initialize() SetMapMode()"));
    	}
    	int nLogPixelsY = ::GetDeviceCaps( hDC, LOGPIXELSY );
    	::ReleaseDC( NULL, hDC );
    	return nLogPixelsY;
    }
    
    int Text3D::FontSize(const int nLogPixelsY)
    {
    	// Fonctionne bien avec Arial comme police de caractères.
    	// La taille sur l'écran est proportionnelle à la taille de la fonte.
    
            // La première constante!!
    	double taillePoint = 39.5;
    
    	double nPointSize = HeightWithScreenAdjuster(taillePoint);
    	// http://support.microsoft.com/kb/74299/fr
    	// Cet article s'applique à NT. Je ne sais pas s'il est valable pour XP, Vista et Seven.
    	// Calcul de la hauteur logique de la police:
    	//			  -(Point Size * LOGPIXELSY)
    	//   height = --------------------------
    	//						 DPI
            // DPI est la valeur provenant de la base de registre:
            // \\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontDPI\\LogPixels
            // Soit 96 par défaut sur XP et Seven.
    	double nHeight = (-nPointSize * (double)nLogPixelsY) / (double)DPI;
    	
    	// Ratio d'affichage pour Vista et Seven.
            // La deuxième constante : 0.75!!
    	if (isWindowsVistaOrMore==true)	nHeight = nHeight * 72.0/96.0;
    
    	return (int)nHeight;
    }
    
    double Text3D::HeightWithScreenAdjuster(const double height) const
    {
            // heightPhysicalScreenReal est la hauteur de l'écran en mm réelle.
            // C'est à dire mesuré avec un mètre sur l'écran!
    	return (height * (double)::GetDeviceCaps(hDeviceContext, VERTSIZE)) / (double)heightPhysicalScreenReal;
    }

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Pourquoi ne pas utiliser WPF avec ces fonctionnalités vectorielles ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Pourquoi ne pas utiliser WPF avec ces fonctionnalités vectorielles ?
    Nous avons différentes contraintes :
    - durée d'affichage de certains textes à l'écran : 33 milli-secondes
    - support de Windows 2000
    - taille du binaire réduite

    Comme nous ne maitrisons pas WPF et que nous ne savions pas si toutes les contraintes seraient effectivement respectée ... nous avons opté pour une approche pragmatique.
    D'un autre coté, je ne sais pas s'il est possible avec WPF de demander l'affichage d'une lettre d'une hauteur de 7 millimètres...

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    - durée d'affichage de certains textes à l'écran : 33 milli-secondes
    Cela dépend de la complexité des choses à afficher. Il n'y pas de garantie temps réels, mais en DirectX non plus.

    WPF de demander l'affichage d'une lettre d'une hauteur de 7 millimètres
    C'est là tous l'avantage du vectoriel.

    - support de Windows 2000
    Là, je suis coincé. C'est XPSP2 minimum.

    C'est bon, je sèche. J'espère que d'autres auront la réponse.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Cela dépend de la complexité des choses à afficher. Il n'y pas de garantie temps réels, mais en DirectX non plus.

    C'est là tous l'avantage du vectoriel.

    Là, je suis coincé. C'est XPSP2 minimum.

    C'est bon, je sèche. J'espère que d'autres auront la réponse.
    C'est vrai qu'avec DirectX ce n'est pas du temps réel ... d'ailleurs avec Windows ce n'est pas possible! Par contre, il est possible de préparer les frames et de se synchroniser sur le balayage vertical. Une finesse d'une milliseconde, ce n'est pas du temps réel.

    Pour le vectoriel, cela te permet d'augmenter la taille de l'objet et d'avoir toujours un excellent rendu. Mais est-ce que tu peux avoir une taille exacte?
    Quand je demande à Windows la taille de l'écran en millimètre ... C'est une vaste rigolade! Sur un notebook Acer, pour Windows Seven, j'ai un 21 pouces! Donc pour que Windows puisse calculer une taille réelle, je ne sais pas comment il peut faire.

    En tout cas, tes réponses m'incite à regarder du coté de WPF ... pour un autre projet! Pour celui-ci, il est quasi-bouclé.
    J'ai bien envie aussi pour un projet similaire de regarder du coté de Qt!

    Yves

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Ce n'est pas possible de garantir une taille réelle pour la simple raison que le rendu se fait en pouce "logique". Il n'y a aucune notion physique au niveau écran, contrairement à une imprimante.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Ce n'est pas possible de garantir une taille réelle pour la simple raison que le rendu se fait en pouce "logique". Il n'y a aucune notion physique au niveau écran, contrairement à une imprimante.
    Je suis d'accord avec toi sur le pouce logique.
    Mais Windows permet :
    - de connaitre la hauteur de l'écran via GetDeviceCaps(hDeviceContext, VERTSIZE),
    - d'utiliser un mapping en millimètre via SetMapMode(hDC,MM_TEXT).

    Le problème vient uniquement du fait que la taille retournée est fantaisiste!
    Sur un notebook, Windows me retourne la taille d'un écran de 21 pouces!
    Avec mes différents tests, Dell semble être le seul à retourner une taille correcte.

    Pour régler cet aspect, je demande aux utilisateurs de dimensionner une mire pour qu'elle ait 10 cm de coté.

    Par contre, je ne comprends pas l'écart entre XP et Seven...

    Par exemple, dans Word, en utilisant une fonte Arial de 30 ... avec un DPI identique sur XP et Seven, la taille affichée n'est pas identique ....


    Yves

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    SetMapMode y compris se base sur des unités logiques. La "référence" est 72, mais Windows utilise 96. Il y aura toujours une différence 1/3 sur les valeurs renvoyées.

    Dans le passé (est-ce que ça a changé ?) et les écrans CRT, la taille renvoyée était la taille du tube sans tenir compte du boîtier qui le recouvrait en partie. La taille visible n'était donc pas déterminable précisément (toujours plus petite et dépendait de la construction mécanique).

    Pour le texte, depuis Vista, une résolution par défaut de 120ppp est appliquée au texte. (96 sous XP)

    Pour ajuster ton texte, tu devrais récupérer cette valeur dans la base des registres et ne pas t'occuper de ce qui est renvoyé par GetDeviceCaps.

    La clé est:
    HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics -> AppliedDPI.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2002
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    SetMapMode y compris se base sur des unités logiques. La "référence" est 72, mais Windows utilise 96. Il y aura toujours une différence 1/3 sur les valeurs renvoyées.

    Dans le passé (est-ce que ça a changé ?) et les écrans CRT, la taille renvoyée était la taille du tube sans tenir compte du boîtier qui le recouvrait en partie. La taille visible n'était donc pas déterminable précisément (toujours plus petite et dépendait de la construction mécanique).

    Pour le texte, depuis Vista, une résolution par défaut de 120ppp est appliquée au texte. (96 sous XP)

    Pour ajuster ton texte, tu devrais récupérer cette valeur dans la base des registres et ne pas t'occuper de ce qui est renvoyé par GetDeviceCaps.

    La clé est:
    HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics -> AppliedDPI.
    Merci pour ces précisions.
    Je garde donc une calibration manuelle.

    Pour mes tests, je suis passé de 96 PPP à 192 PPP (200%).
    Il existe trois clés dans la base de registre sous XP et deux clés sous SEVEN.

    • La clé OriginalDPI n'existe plus sous SEVEN.
    • AppliedDPI contient le réglage courant
    • Sous SEVEN, LogPixels reste constant à 96 PPP indépendamment du réglage.
    • GetDeviceCaps( hDC, LOGPIXELSY ) contient le réglage courant


    XP with the standard parameter : 96 PPP
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ ./dpi.sh
    kernel: 5.1
    /reg/current_user/Control Panel/Desktop/WindowMetrics
    AppliedDPI=0x60
    /reg/local_machine/SOFTWARE/Microsoft/Windows NT/CurrentVersion/FontDPI
    LogPixels=0x60
    /reg/local_machine/SOFTWARE/Microsoft/Windows/CurrentVersion/Control Panel
    OriginalDPI=0x60
    Si j'essaie de comprendre :
    • valeur de référence : LogPixels sous Seven et OriginalDPI sous XP
    • valeur courante : AppliedDPI ou GetDeviceCaps(hDC, LOGPIXELSY) sous Seven et XP


    Par contre la valeur 120 PPP n'apparait.
    Est-ce que la valeur de référence pour afficher le texte ne serait pas 72 sous XP et 96 sous Seven?

    Qu'en pensez-vous?

Discussions similaires

  1. [MySQL] affichage zone de texte sous mozilla
    Par kamnouz dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 16/01/2009, 10h08
  2. [HTML] affichage d'un text brut dans un tableau
    Par fren2809 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 07/10/2005, 13h57
  3. CSS: affichage d'un texte verticlament
    Par ReunionIsland dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 30/09/2005, 16h26
  4. Affichage d'un texte dans la barre d'état!
    Par chuart dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 12/04/2005, 12h47
  5. Recherche de texte dans un blob sous oracle
    Par nesbla dans le forum Bases de données
    Réponses: 5
    Dernier message: 25/05/2004, 11h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo