Según la precisión que desee, puede ser difícil.
Hay muchos enfoques. Parece que está intentando dibujar en un mapa de bits del tamaño de una impresora y luego reducirlo. Los pasos para hacerlo son:
- Cree un DC (o mejor aún, un contexto de información de IC) para la impresora.
- Consultar la impresora DC para conocer la resolución, el tamaño de página, los desplazamientos físicos, etc.
- Cree un DC para la ventana/pantalla.
- Cree un DC compatible (la memoria DC).
- Cree un mapa de bits compatible para la ventana/pantalla, pero el tamaño debe ser el tamaño de píxel de la página de la impresora. (El problema con este enfoque es que este es un mapa de bits ENORME y puede fallar.)
- Seleccione el mapa de bits compatible en la memoria DC.
- Dibuje en la memoria DC, usando las mismas coordenadas que usaría si dibujara en la impresora real.(Cuando selecciona fuentes, asegúrese de escalarlas a la pulgada lógica de la impresora, no a la pulgada lógica de la pantalla)
StretchBlt
la memoria DC a la ventana, lo que reducirá la escala de toda la imagen. Es posible que desee experimentar con el modo de estiramiento para ver qué funciona mejor para el tipo de imagen que va a mostrar.
- Libere todos los recursos.
Pero antes de ir en esa dirección, considere las alternativas. Este enfoque implica la asignación de un ENORME mapa de bits fuera de la pantalla. Esto puede fallar en computadoras con pocos recursos. Incluso si no es así, es posible que esté muriendo de hambre otras aplicaciones.
El enfoque del metarchivo dado en otra respuesta es una buena opción para muchas aplicaciones. Comenzaría con esto.
Otro enfoque es averiguar todos los tamaños en alguna unidad ficticia de alta resolución. Por ejemplo, suponga que todo está en milésimas de pulgada. Luego, las rutinas de dibujo escalarían esta unidad imaginaria a los ppp reales utilizados por el dispositivo de destino.
El problema con este último enfoque (y posiblemente el metarchivo) es que las fuentes GDI no se escalan perfectamente linealmente. El ancho de los caracteres individuales se ajusta según la resolución del objetivo. En un dispositivo de alta resolución (como una impresora láser de 300+ dpi), este ajuste es mínimo. Pero en una pantalla de 96 ppp, los ajustes pueden sumar un error significativo sobre la longitud de una línea. Por lo tanto, el texto en la ventana de vista previa puede parecer desproporcionado (generalmente más ancho) que en la página impresa.
Por lo tanto, el enfoque hardcore es medir el texto en el contexto de la impresora, y medir de nuevo en el contexto de la pantalla, y ajustar la discrepancia. Por ejemplo (usando números inventados), puede medir el ancho de algunos textos en el contexto de la impresora, y sale en 900 píxeles de impresora. Supongamos que la relación de píxeles de la impresora a píxeles de la pantalla es de 3: 1. Es de esperar que el mismo texto en la pantalla tenga 300 píxeles de pantalla de ancho. Pero mides en el contexto de la pantalla y obtienes un valor como 325 píxeles de pantalla. Cuando dibuja en la pantalla, de alguna manera debe hacer que el texto sea 25 píxeles más estrecho. Puede ramificar los caracteres más cerca, o elegir una fuente un poco más pequeña y luego estirarlos.
El enfoque hardcore implica más complejidad. Podría, por ejemplo, intentar detectar las sustituciones de fuentes realizadas por el controlador de la impresora y hacerlas coincidir lo más posible con las fuentes de pantalla disponibles.
He tenido buena suerte con un híbrido de los enfoques de big-bitmap y hardcore. En lugar de hacer un mapa de bits gigante para toda la página, creo uno lo suficientemente grande para una línea de texto. Luego dibujo el tamaño de la impresora al mapa de bits fuera de pantalla y StretchBlt
al tamaño de la pantalla. Esto elimina lidiar con la discrepancia de tamaño con una ligera degradación de la calidad de fuente. Es adecuado para la vista previa de impresión real, pero no le gustaría construir un editor WYSIWYG como ese. El mapa de bits de una línea es lo suficientemente pequeño como para hacer esto práctico.
La buena noticia es que solo el texto es difícil. El resto del dibujo es una escala simple de coordenadas y tamaños.
No he usado mucho GDI, pero creo que se eliminó con el escalado de fuente no lineal. Entonces, si estás usando GDI +, solo deberías escalar tus coordenadas. El inconveniente es que no creo que la calidad de fuente en GDI + sea tan buena.
Y, por último, si usted es una aplicación nativa en Vista o posterior, asegúrese de que ha marcado su proceso como "DPI-aware". De lo contrario, si el usuario está en una pantalla de PPP alto, Windows le mentirá y alegará que la resolución es de solo 96 ppp y luego realizará una escala ascendente difusa de lo que dibuje.Esto degrada la calidad visual y puede hacer que la depuración de su vista previa de impresión sea aún más complicada. Debido a que muchos programas no se adaptan bien a pantallas DPI más altas, Microsoft agregó "escalamiento de PPP alto" de forma predeterminada comenzando en Vista.
editar para agregar
Otra advertencia: Si se selecciona un HFONT en la memoria de CC con el mapa de bits-impresora de tamaño, es posible que se obtiene un tipo de letra diferente a lo que llegaría la hora de seleccionar el mismo HFONT en la impresora real DC. Esto se debe a que algunos controladores de impresora sustituirán las fuentes comunes por las de memoria. Por ejemplo, algunas impresoras PostScript sustituirán una fuente PostScript interna por ciertas fuentes TrueType comunes.
primera Puede seleccionar el HFONT en la impresora IC, a continuación, utilizar funciones GDI como GetTextFace
, GetTextMetrics
, y tal vez GetOutlineTextMetrics
para averiguar acerca de la fuente real seleccionado. A continuación, puede crear un nuevo LOGFONT para intentar hacer corresponder mejor lo que usaría la impresora, convertirlo en un HFONT y seleccionarlo en la memoria DC. Esta es la marca de una implementación realmente buena.
No estoy demasiado orgulloso de la ruta que decidí ...:/Obtenga la información de DC de la impresora: ancho, alto y logpixelsy. CreateCompatibleDC, Bitmap desde la ventana de vista previa de impresión pero con ancho, altura de la impresora (memoria de tamaño mondo que mata el mapa de bits) Y cuando CreateFont, uso - :: MulDiv (point, logPxlY, 72) para la altura (usando logPxlY desde la impresora dc). Soooooo, espero volver a visitar esta solución no muy óptima, pero tengo otras funcionalidades para agregar primero ...:/http://pianocheater.com fyi :) –
Argh !! Esta no es una buena solución (la que no me enorgullece). En mi máquina Vista con 4 Gigs RAM, no puedo CreateCompatibleBitmap de un mapa de bits compatible con pantalla con w/h de impresora - sin memoria - probablemente la cantidad de memoria de la tarjeta gráfica, estoy seguro, que encajaría en 4 gigas de la memoria regular. De vuelta al tablero de dibujo ... –
Sé que esto fue hace un tiempo, pero ¿alguna vez trataste de crear el mapa de bits a partir de un DC compatible con la impresora, desmarcarlo y seleccionarlo en una nueva pantalla compatible con DC para StretchBlt? Además, puede dividir las dimensiones y las coordenadas del mapa de bits entre 2 para que quepa sin riesgo de demasiada distorsión. –