oicìliS © - Assembly para Iniciantes
(ver 1.0 de 07.02.02)

FONTES

 

Neste tutorial vamos fazer a brincadeira da janela "fujona" ficar um pouco mais colorida. O projeto é o mesmo do tutorial anterior, o "Menu Malandro", onde incluiremos algumas funções que lidam especificamente com fontes.

 

O QUE SÃO FONTES

 

No Windows, uma fonte é uma coleção de caracteres e símbolos gráficos que compartilham um estilo (ou um design). Os três elementos mais importantes deste estilo são o tipo, o estilo e o tamanho.

 

O termo TIPO refere-se às características específicas dos caracteres e símbolos da fonte, como a largura das linhas finas e grossas que compõem os caracteres e a presença ou ausência de serifs. Um serif é uma pequena linha que serve como "acabamento" de linhas não conectadas (por exemplo, as pequenas linhas horizontais na primeira e na última linha vertical da letra M na fonte Times New Roman - M). Uma fonte sem serif geralmente é denominada sans-serif.

 

O termo ESTILO refere-se ao peso (espessura das linhas) e à inclinação de uma fonte. O peso pode variar de super-leve até super-pesado, ou seja: fino (Thin), extra leve (Extralight), leve (Light), normal (Normal), médio (Medium), semi-negrito (Semibold), negrito (Bold), extra-negrito (Extrabold) e pesado (Heavy). A inclinação pode ser romana, oblíqua ou itálica. Os caracteres de uma fonte romana ficam alinhados na vertical (diz-se que ficam "em pé"). Os de uma fonte oblíqua são inclinados artificialmente. Esta inclinação é obtida podando-se os caracteres de uma fonte romana. Os caracteres de uma fonte itálica são inclinados autênticos e aparecem como foram desenhados.

 

No Windows, o TAMANHO das fontes é um valor impreciso. Geralmente pode ser determinado medindo-se a distância da base de um "g" minúsculo até o topo de um "M" maiúsculo adjacente. O tamanho de uma fonte é especificado em numa unidade chamada ponto. De acordo com o sistema de pontos idealizado por Pierre Simon Fournier, um ponto corresponde a 0.013837 polegadas (ou 0,3514598 milímetros). A grosso modo, isto corresponde a 1/72 de polegada (ou 1/3 de milímetro).

 

O Windows organiza as fontes por família. Uma FAMÍLIA é um conjunto de fontes que possuem a mesma espessura e características serif. Existem cinco famílias com nomes específicos. Um sexto nome, o "Dontcare", permite que um aplicativo utilize a fonte padrão. A tabela a seguir descreve os nomes das famílias de fontes:

 

Nome da Família Descrição
Decorative Denomina uma fonte nobre. Um exemplo é a Old English.
Dontcare Um nome de família genérico. É usado quando não há informações sobre a fonte ou quando as informações não têm importância.
Modern Especifica uma fonte monospace com ou sem serifs. Fontes monospace geralmente são modernas. Exemplos: Pica, Elite, and Courier New®.
Roman Fonte proporcional com serifs. Um exemplo é a Times New Roman.
Script Especifica fontes desenhadas para se parecerem com escrita manual. São exemplos a Script e a Cursive.
Swiss Para fontes proporcionais sem serifs. Um exemplo é a Arial.

 

Estes nomes de famílias correspondem a constantes do Windows: FF_DECORATIVE, FF_DONTCARE, FF_MODERN, FF_ROMAN, FF_SCRIPT e FF_SWISS. Um aplicativo usa estas constantes quando cria uma fonte, seleciona uma fonte ou obtém informações sobre uma fonte.

As fontes de uma mesma família distinguem-se pelo tamanho (10 pontos, 24 pontos, etc) e pelo estilo (regular, itálico e assim por diante).

 

AS CORES NO WINDOWS

 

Esta pequena introdução ao sistema RGB é necessária para podermos criar o código fonte do nosso exemplo.

 

No Windows, as cores são expressas pela sua composição de vermelho, verde e azul. É o sistema RGB, onde R = Red (vermelho), G = Green (verde) e B = Blue (azul). Os valores para estas cores básicas podem variar de 0 a 255, onde 0 é nada e 255 é o máximo. Se quisermos indicar vermelho puro no máximo a composição será R = 255, G = 0 e B = 0. Branco é o resultado da composição do máximo das três cores básicas e indicado por 255,255,255. Preto, por sua vez, é a ausência de todas as cores - 0,0,0.

 

PROJETO MENU MALANDRO COLORIDO

 

Nosso planejamento é:

  1. Preparar as cores
  2. Definir a fonte
    1. Criar uma fonte lógica
    2. Selecionar a fonte lógica
  3. Definir a cor do texto e pintar o texto
  4. Destruir a fonte lógica (fazer faxina)
  5. A nova aparência do texto
  6. O exemplo Fontes II
  7. Atélogo e Download do exemplo
1. PREPARANDO AS CORES

 

Antes de iniciarmos a criação e o uso de fontes, vamos preparar um macro cuja função será devolver o valor correspondente a uma cor em RGB no registrador EAX. Mas o que são macros?

 

Uma das grandes vantagens do MASM é que ele é um "MACRO assembler", cuja tradução literal é "construtor de macros". Um macro assembler pre-processa o texto antes que o assembler leia e compile o código. Esta característica propicia ao programador a facilidade de escrever procedimentos MACRO que ampliam ou modificam o texto do código fonte. Com o uso de macros, o código fonte pode ser escrito de uma forma mais rápida e confiável. MACROS são as armas secretas na produção de código pois realizam tarefas específicas na manipulação de código. Podem ser usados com vários propósitos, desde uma simples substituição de texto até loops de expansões complexas de código repetitivo.

 

Vamos fazer do macro RGB o nosso exemplo:

...

RGB MACRO red, green, blue

xor eax, eax

mov ah, blue

shl eax, 8

mov ah, green

mov al, red

ENDM

 

.DATA

...

 

Cada vez que usarmos RGB seguido dos valores da intensidade das cores, por exemplo RGB 255,96,128, o texto marcado em vermelho será substituído pelo texto do macro definido acima. O que este macro faz é o seguinte:

  1. Zera o registrador EAX com a instrução XOR EAX,EAX.
  2. Transfere para o byte mais significativo (8 bits) de EAX o valor da cor azul (EAX = 00 00 80 00).
  3. Desloca os bits do byte mais significativo 8 posições para a esquerda (EAX = 00 80 00 00).
  4. Transfere para o byte mais significativo de EAX o valor da cor verde (EAX = 00 80 60 00).
  5. Transfere para o byte menos significativo de EAX o valor da cor vermelha (EAX = 00 80 60 FF).

Este macro tem uma ampla aplicação na programação assembly. Seu uso é tão frequente que é bom mantê-lo sempre à mão. Aqui na Aldeia, juntamente com outras utilidades, ele faz parte da Caixa de Ferramentas.

 

2. DEFININDO A FONTE A SER USADA

 

Para poder usar determinada fonte precisamos criá-la e selecioná-la. Só depois desses dois passos é que a fonte se encontra ativa e pronta para uso.

 

2A. Criando uma fonte lógica

 

Para poder criar uma fonte lógica utiliza-se uma das funções da API, a CreateFont. Esta função, dentre as funções do Windows, é a que possui o maior número de parâmetros:

 

HFONT CreateFont(

int nHeight, // altura lógica da fonte

int nWidth, // largura lógica média dos caracteres

int nEscapement, // ângulo de escape

int nOrientation, // ângulo de orientação da linha base

int fnWeight, // peso da fonte

DWORD fdwItalic, // indicador do atributo itálico

DWORD fdwUnderline, // indicador do atributo sublinhado

DWORD fdwStrikeOut, // indicador do atributo riscado (ou tachado)

DWORD fdwCharSet, // identificador do conjunto de caracteres

DWORD fdwOutputPrecision, // precisão de saída

DWORD fdwClipPrecision, // precisão de corte

DWORD fdwQuality, // qualidade da saída

DWORD fdwPitchAndFamily, // pitch (distanciamento) e família

LPCTSTR lpszFace // ponteiro para a string do nome do tipo

);

  • nHeight é a altura dos caracteres. Zero indica a altura padrão.
  • nWidth é a largura dos caracteres. Zero indica a largura padrão ( que o Windows ajusta de acordo com a altura dos caracteres).
  • nEscapement especifica a orientação do caracter seguinte em relação ao anterior, em décimos de grau. Normalmente indica-se 0 (zero). Se for 900, os caracteres vão sendo colocados um acima do outro; se for 1800, vão sendo colocados em ordem reversa (da direita para a esquerda); se for 2700, são colocados de cima para baixo.
  • nOrientation indica a rotação que os caracteres devem sofrer, em décimos de grau. Normalmente indica-se 0 (zero). Se for 900, rodam 90 graus e ficam "deitados"; se for 1800, ficam de "cabeça para baixo"; etc.
  • fnWeight indica a espessura dos caracteres: FW_DONTCARE (0), FW_THIN (100), FW_EXTRALIGHT ou FW_ULTRALIGHT (200), FW_LIGHT (300), FW_NORMAL ou FW_REGULAR (400), FW_MEDIUM (500), FW_SEMIBOLD ou FW_DEMIBOLD (600), FW_BOLD (700), FW_EXTRABOLD ou FW_ULTRABOLD (800) e FW_HEAVY ou FW_BLACK (900).
  • fdwItalic: zero indica normal, qualquer outro valor indica o estilo itálico.
  • fdwUnderline: zero indica normal, qualquer outro valor indica caracteres sublinhados.
  • fdwStrikeOut: zero indica normal, qualquer outro valor indica caracteres riscados.
  • fdwCharSet: o conjunto de caracteres da fonte. Normalmente, para obter caracteres com til e cedilha, usamos ANSI_CHARSET.
  • fdwOutputPrecision: especifica o quanto a fonte selecionada precisa se aproximar das características que desejamos. Normalmente deveria ser OUT_DEFAULT_PRECIS, que define um mapeamento padrão da fonte.
  • fdwClipPrecision: define a precisão de corte dos caracteres que estão parcialmente fora da região de corte. Geralmente se usa CLIP_DEFAULT_PRECIS, que define o comportamento de corte padrão.
  • fdwQuality: a qualidade da saída define o quanto a GDI precisa se preocupar em adequar os atributos da fonte lógica aos atributos da fonte física. Há três escolhas possíveis: DEFAULT_QUALITY (média), PROOF_QUALITY (alta) e DRAFT_QUALITY (baixa).
  • fdwPitchAndFamily: indica o distanciamento entre os caracteres e a família da fonte. Podem ser associados através de OR.
  • lpszFace: ponteiro para a string que contém o nome da fonte que queremos usar.

O valor de retorno desta função, como sempre no registrador EAX, é o manipulador para a fonte lógica criada. Tá certo que não ficou muito claro... é coisa demais mesmo. Talvez, fazendo uso da função, fique um pouco mais fácil. Vamos declarar uma variável global com o nome da fonte escolhida, uma variável local que receberá o manipulador da nova fonte e, na interceptação da mensagem WM_PAINT do procedimento gerenteMensagem, vamos criar a fonte Comic Sans MS. Se você não tiver esta fonte instalada no seu micro, escolha qualquer outra. Além disso, você precisa referenciar a biblioteca GDI, à qual pertencem a maioria das funções que serão adicionadas neste exemplo.

...

include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

include \masm32\include\gdi32.inc

 

includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\gdi32.lib

...

.DATA

...

Texto_fim db "Até outra hora...",0

NomeFonte db "Comic Sans MS",0

 

.CODE

inicio:

...

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

...

LOCAL mFonte:HFONT

 

.ELSEIF uMsg == WM_PAINT

invoke BeginPaint, hWnd, ADDR ps

mov mCM, eax

invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,

OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE,

ADDR FontName

mov mFonte, eax

...

 

2B. Selecionando a fonte lógica

 

Uma vez criada a fonte lógica podemos substituir a fonte do contexto modelo pela recém criada. A função SelectObject faz o serviço para nós e retorna o manipulador do objeto substituído. Vamos guardar este manipulador numa variável local. Após usarmos a nova fonte, este manipulador servirá para reverter a substituição da fonte (sempre é bom voltar para o contexto modelo original).

 

HGDIOBJ SelectObject(

HDC hdc, // manipulador do contexto modelo

HGDIOBJ hgdiobj // manipulador do objeto

);

 

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

...

LOCAL mFonte:HFONT

LOCAL mFonteOriginal:HFONT

 

.ELSEIF uMsg == WM_PAINT

invoke BeginPaint, hWnd, ADDR ps

mov mCM, eax

invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,

OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE,

ADDR FontName

mov mFonte, eax

invoke SelectObject, mCM, mFonte

mov mFonteOriginal, eax

...

 

3. DEFININDO A COR DO TEXTO

 

Chegou a hora de usarmos o nosso macro RGB. Sabendo que RGB devolve a cor no registrador EAX, o valor contido neste registrador será um dos parâmetros para a função SetTextColor. Em seguida pintamos o texto como habitual e, logo a seguir, retornamos a fonte original para o contexto modelo.

 

COLORREF SetTextColor(

HDC hdc, // manipulador do contexto modelo

COLORREF crColor // cor do texto

);

 

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

...

LOCAL mFonte:HFONT

LOCAL mFonteOriginal:HFONT

 

.ELSEIF uMsg == WM_PAINT

invoke BeginPaint, hWnd, ADDR ps

mov mCM, eax

invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,

OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE,

ADDR FontName

mov mFonte, eax

invoke SelectObject, mCM, mFonte

mov mFonteOriginal, eax

RGB 255, 0, 0

invoke SetTextColor, mCM, eax

invoke GetClientRect, hWnd, ADDR eRet

invoke DrawText, mCM, endTexto, -1, ADDR eRet,

DT_SINGLELINE or DT_CENTER or DT_VCENTER

invoke EndPaint, hWnd, ADDR ps

invoke SelectObject, mCM, mFonteOriginal

...

 

4. DESTRUINDO A FONTE LÓGICA

 

Todos objetos do contexto modelo, quando são criados, consomem recursos do sistema. Criamos uma fonte lógica para ser usada no nosso contexto modelo e, quando não precisamos mais dela, o correto é destruí-la para liberar os recursos do sistema. A função DeleteObjet elimina objetos do tipo pincel, fonte, bitmap, região, etc. É claro que, depois de destruídos, os manipuladores destes objetos deixam de ser válidos.

 

BOOL DeleteObject(

HGDIOBJ hObject // manipulador do objeto gráfico

);

 

Já que estamos fazendo faxina, não custa nada voltar a cor do texto para a original. Basta guardarmos a cor original numa variável local antes de trocar a cor do texto para, posteriormente, reverter as cores. A função que nos permite obter a cor do texto atual é a GetTextColor.

 

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

...

LOCAL mFonte:HFONT

LOCAL mFonteOriginal:HFONT

LOCAL CorTexto:DWORD

 

.ELSEIF uMsg == WM_PAINT

invoke BeginPaint, hWnd, ADDR ps

mov mCM, eax

invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,

OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE,

ADDR FontName

mov mFonte, eax

invoke SelectObject, mCM, mFonte

mov mFonteOriginal, eax

invoke GetTextColor, mCM

mov CorTexto, eax

RGB 255, 0, 0

invoke SetTextColor, mCM, eax

invoke GetClientRect, hWnd, ADDR eRet

invoke DrawText, mCM, endTexto, -1, ADDR eRet,

DT_SINGLELINE or DT_CENTER or DT_VCENTER

invoke EndPaint, hWnd, ADDR ps

invoke SelectObject, mCM, mFonteOriginal

invoke SetTextColor, CorTexto

invoke DeleteObject, mFonte

 

.ELSE ...

 

 

5. A NOVA APARÊNCIA DO TEXTO

 

Aqui terminamos a reforma do código fonte. Gere o executável e verifique o resultado.

 

 

6. O EXEMPLO FONTES II

No pacote para download (tutNB10.zip) existe um segundo exemplo cujo código fonte está em fontes2.asm. A direrença é a seguinte: para cada item de menu o texto é apresentado numa cor diferente. Para isto foi criada uma variável global corAtual, do tipo DWORD, não inicializada, que contém o valor da cor desejada. No macro RGB foi incluída uma instrução que inicializa corAtual:

RGB MACRO red, green, blue

xor eax, eax

mov ah, blue

shl eax, 8

mov ah, green

mov al, red

mov corAtual, eax

ENDM

 

O macro é utilizado apenas no processamento da mensagem WM_COMMAND:

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

...

.ELSEIF uMsg == WM_COMMAND

...

.ELSEIF ax == mnID_sopa

mov endTexto, OFFSET Texto_sopa

RGB 255,0,0

.ELSEIF ax == mnID_salada

mov endTexto, OFFSET Texto_salada

RGB 0,128,0

.ELSEIF ...

 

As instruções em WM_PAINT que trocavam a cor do texto:

RGB 255, 0, 0

invoke SetTextColor, mCM, eax

serão substituídas por:

invoke SetTextColor, mCM, corAtual

 

ATÉLOGO

 

As novidades neste tutorial são:

Para download:

 

O arquivo tutNB10.zip (21 Kb) contém os código fonte e os exemplos deste tutorial.

 


| AAAA | Página Inicial | Mapa do Site | Novidades | Busca | Indique esta página | Mestre da Teia | Voltar |
| Localizador || @ Info NumaBoa > oicìliS > Assembly > Fontes
Créditos: vovó Vicki

webdesign sobMedida by vickiSoft - /informatica/oiciliS/assembler/tutFontes/fontes.php (07.02.02) versão 1.0 de 10.02.02
Licença Creative Commons 1998-2006 Aldeia NumaBoa
Exceto onde especificamente declarado, todo material deste site é disponibilizado de acordo com a Licença Creative Commons.