Compartilhar via


Line Drawing

Windows Mobile Not SupportedWindows Embedded CE Supported

9/8/2008

O processo de desenho em uma ou mais linhas é dividido em três fases distintas: a fase de preparação, a fase de desenho e a fase de conclusão.

Etapa 1: Desenho de linha preparar fase

Desenho de linha começa quando um aplicativo chama Polilinha. GDI manipula a chamar para Polilinha. GDI valida que há pelo menos dois vértices e que a estilo de linha não é NULL. GDI, em seguida, chama o GPE DrvStrokePath função ou, para uma caneta ampla, DrvFillPath.

Quando GDI chama a função membro GPE, ele passa a seguinte informações de contexto de dispositivo:

  • Objeto de superfície
  • Objeto caminho
  • CLIP retângulo
  • Pincel
  • Valor ROP2
  • Sólido ou atributos linha tracejada

Esses parâmetros foram definidos por um aplicativo ou são realizados atributos.

GPE usa alguns entrada parâmetros para definir os membros do seu GPELineParms estrutura. GPE, em seguida, chama do o driver exibir GPE::Line função, passando o GPELineParms e passar o valor gpePrepare.

O driver examinará as propriedades da linha a ser desenhado. O driver, em seguida, decidir se ela deve usar o GPE EmulatedLine função ou identificador de linha com sua própria acelerado função.

Antes de selecionar uma função aceleradora, o driver deve determinar se o hardware pode identificador a estilo de linha e ROP.

O driver exibir ATI exemplo, disponível em Diretório o %_WINCEROOT%\Public\Common\OAK\Drivers\Display\ATI, o driver define o ponteiro de função para EmulatedLine Por padrão, mas escolhe a aceleração hardware para linhas que estão em vídeo memória e uso de ROP 0x0D0D.

O seguinte mostra amostra de código como a aceleração hardware escolher para linhas que estão em vídeo memória.

if (phase == gpeSingle || phase == gpePrepare){
  pLineParms->pLine = EmulatedLine;
  if (((ATISurf*)(pLineParms->pDst))->InVideoMemory() && pLineParms->mix == 0x0d0d){
    pLineParms->pLine = (SCODE (GPE::*)(struct GPELineParms*)) AcceleratedSolidLine;
  }
}

Além disso, na fase de preparação, o driver pode executar processamento adicional, such as ao inicializar o hardware registra com a cor selecionada. Após a fase de preparação, controle retorna para o GPE DrvStrokePath função.

Step 2: Fase desenhar line Drawing

Após determinar o apropriado função line-Drawing, o DrvStrokePath função executa os loops aninhados dois. O seguinte exemplo mostra os retângulos recorte enquadra um caminho.

for( each clip rectangle in clip list )
{
    for( each line segment in stroke path )
    {
       calculate line segment clipped to current cliprect
       call pParms->pLine(pParms);
    }
}

O GPE::Line função do driver não é necessário juntar a linha segmentos para o retângulo de recorte porque DrvStrokePath realiza essa ação.

Na verdade, o driver será impedido de recorte porque nenhum válido informações recorte está disponível durante a fase de preparação. Talvez não haja um retângulo de recorte ou pode haver uma seqüência inteira do recorte retângulos para um único preparar chamar.

EmulatedLine é a função line-Drawing usar como padrão GPE. O seguinte exemplo de código mostra o algoritmo EmulatedLine Usa.

long accum = (long)(pParms->dN) + pParms->llGamma;
long axstp = (long)(pParms->dN);
long dgstp = (long)(pParms->dN) - (long)(pParms->dM);
for( remainingPels = pParms->cPels; remainingPels; remainingPels-- )
{
   if( accum < 0)
   {
      accum += axstp;
   }
   else
   {
       increment_in_minor_direction;
       accum += dgstp;
   }
}
increment_in_major_direction;
draw_current_pixel;
}

Uso EmulatedLine Para linhas diagonais identificador, que são relativamente raros e, portanto, geralmente não precisam ser acelerado. Da mesma forma, ele é muito raro para estilos de linha a ser usado. EmulatedLine Deve ser usado como o processador usar como padrão para este maiúsculas e minúsculas as well.

Para dispositivos que suporte hardware linha-desenho aceleração, o driver pode implementar suas próprias acelerado função de linha para substituir a usar como padrão EmulatedLine implementação.

Como alternativa, o driver pode chamar uma função de emulação existente ou criar uma nova função de emulação software para identificador de line Drawing.

Mesmo se suficiente aceleração line-Drawing estiver disponível, se sólida-preencher aceleração blit de cores é implementada no hardware, isso deve ser usado para acelerar linhas horizontais e verticais, como operações blit cores acelerado por hardware quase sempre são mais rápidas do que hardware acelerado operações de linha.

A abordagem recomendada para a maioria das situações é para emular todas as linhas diagonais e styled e usar hardware line-Drawing ou Fill-blit hardware para acelerar linhas horizontais e verticais. Linhas horizontais e verticais constituem a maioria das linhas desenhadas, portanto, essa abordagem pode levar a resultados melhores.

Para linhas horizontais e verticais, dN Será 0 e não conta precisa ser tomadas das informações subpixel in dM e termo de erro llgamma, conforme o seguinte exemplo de código.

if( pLineParms->dN == 0 )
{
     //Line is vertical or horizontal
     //Use fill-BLGT or h/w line to draw a line starting at
     //pLineParms->xStart, pLineParms->yStart
     //in the direction specified by pLineParms->iDir
     //for a total of pLineParms->cPels pixels
}
else   // use software implementation for diagonal lines
{
     return EmulatedLine( pLineParms );
}

Para linhas diagonais, os valores de dM, dNe termo de erro llgamma Campos de GPELineParms contêm informações subpixel.

Este informações devem ser usadas quando inicializar o hardware linha-desenho registra; caso contrário, as linhas diagonais que são cortadas irão ser desenhadas incorretamente. Este efeito pode ser bastante perceptível quando mover uma janela em outra janela que contém uma linha diagonal.

Na fase de preparação, o driver realiza uma inspeção geral dos parâmetros de linha para determinar se ele pode acelerar a linha. Quando a função de aceleração é chamado, o driver talvez precise executar validação adicional. Isso ocorre porque quando o driver do acelerado função é chamado, a função é para um segmento específico caminho cortado para um região de recorte específico. O driver deve garantir que a linha de segmento comprimento será não causar registra seu hardware para estouro.

O seguinte amostra de código mostra como fazer essas verificações adicionais.

Porque o dM e dN Os valores são expressos originalmente em uma-sixteenths de um pixel, as hardware inclinação iterações do dispositivo devem reter esses comprimentos de qualquer segmento de linha está sendo desenhado.

A maioria dos hardware foi projetado para desenhar uma linha diagonal através de Tela inteira, mas este hardware espera a dM e dN Valores ou equivalentes a ser expressa em pixels. Como GPE usa precisão subpixel, esses contadores precisam quatro bits mais. Para linhas curtas, isso não é um problema. No entanto, para linhas longas, esses valores pode estouro os registradores e causar o hardware para desenhar linhas incorreto.

Embora linhas diagonais são incomuns, as linhas diagonais longos são extremamente raras, portanto, a quantidade de tempo para linhas diagonais longo processar usando o EmulatedLine função não é importante.

O seguinte amostra de código mostra um método para verificar os parâmetros de linha não serão estouro registra a hardware.

Int errTerm = (in)pLineParms->dN + 
              (in)pLineParms->llGamma – 
              ( ( command & PLUS_X ) ? 0 " 1 );
   if(
     ( pLineParms->dN > 4090 ||   //Remember dM >= dN
     ( errTerm > 4090 ) ||
     ( errTerm < -4090 ) )
   {
      RetVal = EmulatedLine(pLineParms); //The hardware DDA would
                                         //overflow; use emulation.
   }
   else
   {
     WaitForFIFO(7);     //seven parameters required
     reg_ALT_CURXY = ((pLineParms->xStart + ((IGS2010Surf*)
                      (pLineParms->pDst))->Left()) << 16 |
                      (pLineParms->yStart + ((IGS2010Surf*)
                      (pLineParms->pDst))->Top());
     reg_MAJ_AXIS_PCNT = (pLineParms->cPels-1);
     reg_ALT_STEP = (((pLineParms->dN-pLineParms->dN)/*&0x3FFF*/)<<16) |
                    (pLineParms->dN /*&0x3FFF*/);
     reg_err_Term = errTerm /*&0x3FFF*/;
     reg_CMD = command;
     RetVal = S_OK;
   }

Step 3: Fase de conclusão line Drawing

Uma seqüência line Drawing termina com um chamar para do o driver GPE::Line função com o gpeComplete valor como o fase parâmetro.

O driver pode usar a fase de conclusão como uma oportunidade para redefinir qualquer hardware registra ou executar outras ações configuração para o hardware exibir conforme necessário.

See Also

Concepts

Display Driver Development Concepts
Display Driver Extensions
Display Driver Samples

Other Resources

Display Drivers