1 - Establecer una fuente monoespaciada.
Es necesario para simplificar los cálculos, porque así cualquiera que sea el carácter ocupa el mismo espacio al ser impreso, si cada carácter tiene su medida individual hay que calcular uno a uno, mientras que siendo todos iguales, es una multiplicación.
(al final de imprimir la lista debe ser restablecida la fuente a la que tenía, por eso hay que salvaguardar la fuente previamente usada).
2 - Repartir el ancho del papel entre las columnas a usar y posicionar el cursor en cada comienzo de columna e imprimir ahí el ítem. Damos por hecho que ningún ítem supera el ancho de una columna, de ser así debe invocarse una función que calcule y corte el exceso de caracteres, o reducir el número de columnas, etc... por eso digo asumiendo 'todo lo más simple posible').
Dadas x columnas, se recurre a dividir el ancho disponible del papel entre el número de columnas. Para esto los datos necesarios son: saber los márgenes izquierdo, derecho y ancho del papel.
Entonces en un bucle se recorre de x columnas en x columnas, (es deicr las que caben en una línea son un ciclo de este bucle) y en un bucle interno se recorre desde 0 a x columnas -1 (es decir en el bucle interno se recorre cada columna de la línea y es en éste donde se imprime. el bucle exterior simplemente sirve para preparar la línea.
Ahora imprimes el siguiente ítem del texto en la posición con la que empieza la columna (dando por hecho una alineación izquierda).
Supongamos que el papel mide 10.000 puntos de ancho, que son 5 columnas, que el margen izquierdo son 400 y el derecho 300.... y pongamos que la lista son los meses del año:
el pseudocódigo sería:
Código:
set tempfuente = impresora.fuente
impresora.fuente.nombre = "Courier New"
anchoCol = (((anchoPapel - (margenderecho + margenIzquierdo)) / numColumnas)
anchoCol = (((10.000 - (400 + 300)) / 5) = ((10.000-700)/5) = 1.860
bucle Y desde 0 hasta lista.count -1 en pasos de NumColumnas ' desde 0 hasta 11 (pués hay 12 meses)
impresora.PosicionY = (impresora.PosicionY + impresora.altofuente)
Bucle x desde 0 hasta numColumnas -1 ' desde 0 hasta 4 (5 columnas en total)
impresora.PosicionX = (margenizquierdo + (x * anchoCol))
impresora.Imprimir meses(y+x)
siguiente en bucle
siguiente en bucle
' como 5+5 son 10 y hay 12 meses, sobran 2 meses que caben en la última línea:
resto = (lista.Count modulo numCols)
Si (resto > 0) luego
impresora.PosicionY = (impresora.PosicionY + impresora.altofuente)
Bucle x desde 0 hasta resto -1 ' desde 0 hasta ? (? columnas restantes)
impresora.PosicionX = (margenizquierdo + (x * anchoCol))
impresora.Imprimir meses(y+x)
siguiente en bucle
Fin si
set impresora.fuente = tempFuente ' restablecemos la fuente a la que había previamente...
Supongamos que la posición Y actual de la impresora fuera 1.250 y que el alto de la fuente fuera 230 puntos. Estos serían pués los valores que irían arrojando los bucles;
LineaActual = posicionY
PosicionY = (LineaActual + altoFuente) = (1.250 +230) = 1.480
PosicionX para columna 0 = 400 + (0 * 1.860) = 400
imprimir lista(0+0) = "Enero"
PosicionX para columna 1 = 400 + (1 * 1.860) = 2.260
imprimir lista(0+1) = "Febrero"
PosicionX para columna 2 = 400 + (2 * 1.860) = 4.120
imprimir lista(0+2) = "Marzo"
PosicionX para columna 3 = 400 + (3 * 1.860) = 5.980
imprimir lista(0+3) = "Abril"
PosicionX para columna 4 = 400 + (4 * 1.860) = 7.840
imprimir lista(0+4) = "Mayo"
LineaActual = posicionY
PosicionY = (LineaActual + altoFuente) = (1.480 +230) = 1.710
PosicionX para columna 0 = 400 + (0 * 1.860) = 400
imprimir lista(5+0) = "Junio"
PosicionX para columna 1 = 400 + (1 * 1.860) = 2.260
imprimir lista(5+1) = "Julio"
PosicionX para columna 2 = 400 + (2 * 1.860) = 4.120
imprimir lista(5+2) = "Agosto"
PosicionX para columna 3 = 400 + (3 * 1.860) = 5.980
imprimir lista(5+3) = "Septiembre"
PosicionX para columna 4 = 400 + (4 * 1.860) = 7.840
imprimir lista(5+4) = "Octubre"
LineaActual = posicionY
PosicionY = (LineaActual + altoFuente) = (1.480 +230) = 1.710
PosicionX para columna 0 = 400 + (0 * 1.860) = 400
imprimir lista(10+0) = "Noviembre"
PosicionX para columna 1 = 400 + (1 * 1.860) = 2.260
imprimir lista(10+1) = "Diciembre"
Los puntos 1 y 2 remarcados en negrita son el resumen general (si cambian detalles hay que hacer más o menos funcionalidad para que cumplan todas las expectativas de los detalles).
En el código primero, concatenaba los valores de los items que forman una línea a base añadir los espacios necesarios tras un ítem hasta llegar a la posición de inicio de la siguiente columna, lo cual exigía calcular la cantidad de espacios a añadir o caracteres a cortar (si excedía el ancho de la columna). Y así imprimia toda una línea d euna sola vez... es un código más simple (de hacer y entender) imprimir el dato de cada columna, pero menos eficiente y solo sirve si no hay detalles adicionales que lo compliquen (como otra alineación que no sea izquierda y valores que superen el ancho de la columna).