Pergunta

Eu tive problemas em inúmeras ocasiões de usuários que não têm uma das fontes do Windows Core instaladas em sua máquina (Courier New, Comic Sans MS, Arial, por exemplo). Sempre que tento construir um deles, ele lança um erro em vez de voltar para um relacionado, ou realmente, algum outra fonte.

Qual é a melhor maneira de construir uma fonte se eu gostaria que fosse correio, mas não estou particularmente casado com ela?

Foi útil?

Solução

Você pode incorporar as fontes como recursos e usar o unsafe Palavra -chave (e deve ser compilada com 'inseguro') para obter as fontes ... aqui está um código de exemplo que eu usava para definir um controle de usuário para a fonte do tipo 'OCR'

private PrivateFontCollection pfc = new PrivateFontCollection();
private Font _fntOCRFont = null;
private enum FontEnum{
   OCR = 0
};

Isso declara uma coleção particular de fontes ... a fonte 'OCR' é incorporada como um recurso usando a convenção de nomenclatura em que 'foo' é um espaço para nome, portanto, o nome do recurso seria 'foo.ocraext.ttf' ... Veja 'Initocrfont' aqui, que carrega a fonte e a adiciona à coleção:

private void InitOCRFont(){
   try{
      System.IO.Stream streamFont = this.GetType().Assembly.GetManifestResourceStream("foo.ocraext.ttf");
      if (streamFont != null){
          byte[] fontData = new byte[streamFont.Length];
          streamFont.Read(fontData, 0, (int)streamFont.Length);
          streamFont.Close();
          unsafe{
                fixed(byte *pFontData = fontData){
                   this.pfc.AddMemoryFont((System.IntPtr)pFontData, fontData.Length);
                }
          }
      }else{
          throw new Exception("Error! Could not read built-in Font.");
      }
   }catch(Exception eX){
      throw new Exception("InitOCRFont Method - Exception occurred!\nException was: " + eX.Message);
   }
}

Aqui, eu defino os controles no controle do usuário para definir a fonte para a fonte 'OCR' iterando a coleção, consulte 'InitializectlFont', o tamanho da fonte é 10 e é um 'tipo-face' em negrito:

private void InitializeCtlFont(){
    this._fntOCRFont = new Font(this.pfc.Families[0], 10.0F, System.Drawing.FontStyle.Bold);
    if (this._fntOCRFont != null){
         foreach(Control ctl in this.Controls){
            if (ctl != null && ((ctl is Label) || (ctl is TextBox))){
                        ctl.Font = this._fntOCRFont;
                    }
         }
    }
}

Quando o controle do usuário é descartado, é imperativo liberar os recursos ocupados pela fonte, como mostrado aqui no Dispose método:

try{
   if (this._fntOCRFont != null) this._fntOCRFont.Dispose();
}catch{
}
try{
   if (this.pfc != null) this.pfc.Dispose();
}catch{
}

Espero que isso ajude, cumprimentos, Tom.

Outras dicas

Bem, você pode usar FontFamily.GenericMonospace para obter uma Fonte Monospace, em vez de especificamente Courier:

Font f = new Font(FontFamily.GenericMonospace, 12, FontStyle.Regular);

Mais algumas famílias de fontes genéricas também.

Você também pode usar isso como último recurso depois de tentar sua fonte preferida e ter uma exceção.

Isso é muito incomum. O Windows Font Mapper sempre fornecerá uma fonte substituta quando o seu programa solicitar uma fonte que não esteja disponível na máquina de destino. Essa fonte substituta geralmente será o Microsoft Sans Serif no XP, Ugoe UI em versões posteriores. Nenhum deles deve causar um problema.

Por outro lado, se a máquina estiver tão confusa que não possui as fontes principais disponíveis, ela pode não ter nenhuma fonte TrueType disponível. Sim, isso vai bombardear seu programa. Francamente, isso não é algo que você deve lidar, a menos que este seja um cliente realmente valioso. Caso contrário, é resolvido trivialmente pela equipe de suporte do seu cliente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top