Pergunta

Eu tenho uma função de desenho que só tem um HDC. Mas eu preciso mostrar uma versão exata escalado do que será impresso.

Assim, atualmente, eu uso CreateCompatibleDC () com uma impressora HDC e CreateCompatibleBitmap () com HDC da impressora.

Eu acho que desta forma o DC terá largura exata da impressora e altura. E quando eu selecionar fontes para este HDC, o texto será dimensionado exatamente como a impressora faria.

Infelizmente, eu não posso para a StretchBlt () para copiar pixels deste HDC a HDC do controle desde que eles são de diferentes tipos HDC eu acho.

Se eu criar a "tela de memória" de uma janela HDC com o mesmo w, h como a página da impressora, as fontes sair WAY pequenino, uma vez que está escalado para a tela, não a página ...

Devo CreateCompatibleDC () de DC da janela e CreateCompatibleBitmap () de DC ou algo da impressora ??

Se alguém poderia explicar o caminho certo para fazer isso. (E ainda tem algo que parece exatamente como ele faria em impressoras) ...

Bem, eu aprecio isso !!

... Steve

Foi útil?

Solução

Dependendo de quão preciso você quer ser, isso pode ficar difícil.

Existem muitas abordagens. Parece que você está tentando atrair para um mapa de bits de tamanho de impressão e, em seguida, reduzi-lo para baixo. As etapas para fazer isso são:

  1. Criar um DC (ou melhor ainda, um IC - Contexto da Informação). Para a impressora
  2. Consulta a impressora DC para descobrir a resolução, tamanho da página, deslocamentos físicos, etc.
  3. Criar um DC para a janela / tela do.
  4. Criar um DC compatível (a memória DC).
  5. Criar um mapa de bits compatível para janela / tela de, mas o tamanho deve ser o tamanho do pixel da página da impressora. (O problema com esta abordagem é que este é um bitmap enorme e pode falhar.)
  6. Selecione o bitmap compatível para a memória DC.
  7. Desenhar para a memória DC, usando as mesmas coordenadas que você usaria se estivesse desenhando para a impressora actual. (Quando você seleciona fontes, certifique-se de escalá-los para polegada lógica da impressora, não polegada lógica da tela.)
  8. StretchBlt a memória DC para a janela, o que irá diminuir a imagem inteira. Você pode querer experimentar com o modo de alongamento para ver o que funciona melhor para o tipo de imagem que você está indo para mostrar.
  9. Solte todos os recursos.

Mas antes de ir nessa direção, considerar as alternativas. Esta abordagem envolve a alocação de um bitmap fora da tela enorme. Isso pode falhar em computadores com poucos recursos. Mesmo se isso não acontecer, você pode estar morrendo de fome outros aplicativos.

A abordagem metarquivo dada em outra resposta é uma boa escolha para muitas aplicações. Eu ia começar com isso.

Outra abordagem é descobrir todos os tamanhos em alguma unidade de alta resolução ficcional. Por exemplo, suponha que tudo está em 1000ths de uma polegada. Em seguida, suas rotinas de desenho iria escalar essa unidade imaginária ao dpi real usado pelo dispositivo de destino.

O problema com esta última abordagem (e possivelmente o Metafile) é que as fontes GDI não escala perfeitamente linearmente. As larguras de caracteres individuais são alterados, dependendo da resolução de destino. Em um dispositivo de alta resolução (como uma impressora a laser mais de 300 dpi), este ajuste é mínimo. Mas em uma tela de 96 dpi, os ajustes podem adicionar até um erro significativo ao longo do comprimento de uma linha. Então texto em sua janela de visualização pode parecer fora de proporção (tipicamente mais amplo) do que na página impressa.

Assim, a abordagem incondicional é medir texto no contexto da impressora, e medir novamente no contexto da tela e ajuste para a discrepância. Por exemplo (usando números confeccionados), você pode medir a largura de algum texto no contexto da impressora, e ele sai para 900 pixels de impressora. Suponhamos que o rácio de pixels para pixels do ecrã de impressão é de 3: 1. Você esperaria o mesmo texto na tela para ser de 300 pixels da tela de largura. Mas você mede no contexto da tela e você terá um valor como 325 pixels de tela. Quando você desenha para a tela, você vai ter de alguma forma fazer o texto 25 pixels mais estreita. Você pode ram os personagens mais próximas, ou escolher uma fonte ligeiramente menor e, em seguida, esticá-los.

A abordagem incondicional envolve mais complexidade. Você pode, por exemplo, tentar detectar substituições de fontes feitas pelo driver de impressora e combiná-los, tanto quanto você pode com as fontes de tela disponível.

Eu tive sorte com um híbrido do big-bitmap e o hardcore se aproxima. Em vez de fazer um bitmap gigante para a página inteira, faço um grande o suficiente para uma linha de texto. Então eu desenhar no tamanho da impressora para o bitmap fora da tela e StretchBlt lo para baixo para o tamanho da tela. Isso elimina lidar com a discrepância de tamanho com uma ligeira degradação da qualidade da fonte. É apropriado para visualização de impressão real, mas você não gostaria de construir um editor WYSIWYG assim. O bitmap de uma linha é pequeno o suficiente para fazer esta prática.

A boa notícia é apenas texto é difícil. Todos os outros desenho é uma escala simples de coornates e tamanhos.

Eu não usei GDI + muito, mas acho que acabou com escala fonte não-linear. Então, se você estiver usando GDI +, você deve apenas tem que escalar suas coordenadas. A desvantagem é que eu não acho que a qualidade da fonte em GDI + é tão bom.

E finalmente, se você é um aplicativo nativo no Vista ou posterior, certifique-se que você marcou o seu processo como " DPI-aware". Caso contrário, se o usuário estiver em uma tela de alta DPI, o Windows irá mentir para você e alegação de que a resolução é de apenas 96 dpi e depois fazer um difusa up-scaling de tudo o que você desenhar. Isto degrada a qualidade visual e pode fazer a depuração do visualização de impressão ainda mais complicado. Uma vez que muitos programas não se adaptam bem a telas maiores DPI, a Microsoft adicionou "alta escala DPI" por padrão a partir de Vista.

editado para adicionar

Outra ressalva: Se você selecionar um HFONT na memória DC com o bitmap tamanho impressora de, é possível que você começa uma fonte diferente do que o que iria ficar ao selecionar essa mesma HFONT na impressora real DC. Isso porque alguns drivers de impressora irá substituir fontes comuns com aqueles em memória. Por exemplo, algumas impressoras PostScript irá substituir uma fonte interna PostScript para determinadas fontes comum TrueType.

Você pode selecionar primeiro o HFONT na impressora IC, em seguida, usar funções GDI como GetTextFace, GetTextMetrics, e talvez GetOutlineTextMetrics para saber mais sobre a fonte real selecionado. Em seguida, você pode criar um novo LOGFONT para tentar mais de perto corresponder ao que a impressora usaria, transformar isso em um HFONT, e selecione que em sua memória DC. Esta é a marca de uma realmente boa implementação.

Outras dicas

Uma coisa que pode valer a pena tentar é criar um metarquivo avançado DC, desenhar a ele como normal e, em seguida, escalar essa metarquivo usando a métrica da impressora. Esta é a abordagem usada pelo WTL amostra BmpView - Eu não sei o quão preciso este será mas pode valer a pena olhar (que deve ser fácil para a porta das classes relevantes para Win32 mas WTL é um ótimo substituto para o Win32 programação assim pode valer a pena utilizar.)

Bem, não vai ter a mesma aparência, porque você tem uma resolução maior na impressora DC, então você vai ter que escrever uma função de conversão de tipos. Eu iria com o método que você tem para trabalhar, mas o texto era muito pequena e basta multiplicar cada posição tamanho / font pela largura da janela da impressora e dividir pela largura da janela fonte.

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