2009-07-23 8 views
2

Dans certains RightToLeft langues (comme l'arabe, le persan, l'ourdou, etc.) chaque lettre peut avoir différentes formes. Il y a une forme isolée, une forme initiale et une forme intermédiaire (vous pouvez simplement la trouver sur la carte de caractères des fenêtres pour n'importe quelle police unicode). Imaginez que vous ayez besoin des caractères exacts que l'utilisateur a saisis dans une zone de texte. Par défaut, lorsque vous convertissez String en CharArray, il convertit chaque caractère en forme isolée. (Parce que lorsque l'utilisateur entre les caractères au clavier, il est sous forme isolée et quand il est affiché à l'écran, il sera converti au format approprié, c'est juste une supposition. en utilisant des codes de caractères exacts, il générera le tableau approprié).Comment puis-je obtenir les caractères pour une entrée en forme de contexte dans un script complexe?

Ma question est, comment nous pouvons obtenir cette forme de la chaîne, le formulaire qui a été affiché dans la zone de texte.

S'il n'y a aucun moyen dans .NET cela signifie que je dois faire ma propre classe pour convertir cette T_T

+0

Je viens de résoudre ce problème. Voir http://www.cheraq.com/post/2009/08/06/Text-to-image-converter-and-Complex-Scripts-Awareness.aspx –

Répondre

3

Windows utilise Uniscribe pour effectuer Mise en forme contextuelle pour les scripts complexes (qui peut demander à l à r ainsi que langues r-à-l). Le texte affiché dans une zone de texte est basé sur les informations glyphes après que les caractères ont été introduits dans Uniscribe. Bien que la norme Unicode définisse des points de code pour chacune des formes isolées, initiales, intermédiaires et finales d'un caractère, toutes les polices ne les supportent pas forcément, mais elles peuvent avoir des glyphes préformés ou utiliser une combinaison de glyphes. Uniscribe utilise un moteur de mise en forme. le module linguistique Windows pour déterminer le (s) glyphe (s) à utiliser, en fonction du cmap de la police.Voici quelques liens pertinents:

Le TextRenderer .DrawText() Méthode utilise Uniscribe via le Win32 DrawTextExW() fonction, en utilisant la P/Invoke suivante:

[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)] 
public static extern int DrawTextExW(HandleRef hDC 
            ,string lpszString 
            ,int nCount 
            ,ref RECT lpRect 
            ,int nFormat 
            ,[In, Out] DRAWTEXTPARAMS lpDTParams); 

[StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int left; 
    public int top; 
    public int right; 
    public int bottom; 
} 

[StructLayout(LayoutKind.Sequential)] 
public class DRAWTEXTPARAMS 
{ 
    public int iTabLength; 
    public int iLeftMargin; 
    public int iRightMargin; 
    public int uiLengthDrawn; 
} 
+0

Merci pour votre réponse. Mais ma question est comment je peux convertir le texte entré, au texte formé et obtenir le résultat en tant que tableau de char ou chaîne. –

+0

J'ai ajouté plus d'informations sur Uniscribe et pourquoi il n'est pas trivial d'obtenir les caractères (points de code) qui sont affichés dans la zone de texte. Il semble que vos seules options sont d'utiliser Uniscribe en recherchant des index dans les polices de caractères, ou de lancer votre propre moteur d'information. –

0

Alors, comment vous créez la chaîne « mauvais »? Si vous ne faites que le mettre dans un littéral de chaîne, alors il est tout à fait possible que ce soit juste la méthode d'entrée qui est mauvaise. Si vous copiez la "bonne" chaîne après l'avoir affichée, puis collez-la dans un littéral de chaîne, que se passe-t-il? Vous pouvez également vérifier l'encodage que Visual Studio utilise pour vos fichiers source. Si vous êtes pas en mettant la chaîne dans votre code source comme un littéral, comment créez-vous?

Compte tenu de la possibilité de confusion, je pense que je veux soit garder ces chaînes dans une ressource ou un code difficile de les utiliser Escaping unicode:

string text = "\ufb64\ufea0\ufe91\feea"; 

(alors peut-être mettre un commentaire montrant après le non -correspondant à la valeur, au moins, si elle semble à peu près juste, il ne sera pas trop trompeur, il est donc facile pour les deux de se désynchroniser ...)

+0

La chaîne d'entrée provient de l'entrée utilisateur et n'est pas statique . C'est par exemple le titre d'une page ou d'un menu. Donc, il ne peut pas être codé en dur. vous pouvez essayer l'événement en utilisant le contrôle TextBox et vous obtiendrez le même résultat. –

+0

À droite, dans ce cas, c'est une limitation de la méthode d'entrée. Vous * pouvez * constater que changer la police de la TextBox aide ... Je ne suis pas sûr. Je vais voir si j'ai assez de polices etc installé pour le vérifier. –

+0

Je pense que cela se produit parce que lorsque vous entrez le texte en utilisant le clavier, il entrera le caractère par défaut, qui est le formulaire isolé, mais sur les fenêtres de la boîte de texte le convertira en forme appropriée sur l'affichage. –

0

Ceci est un peu sauvage Devinez, mais est-ce que String.Normalize() aide ici? Il n'est pas clair pour moi si cela ne couvre que la composition de caractères ou si elle inclut aussi des formes positionnelles.

+0

En fait, j'ai essayé celui-là aussi, mais aucun résultat T_T –