Las otras respuestas ya cubrió el "¿Cuáles son los diccionarios?" parte de su pregunta. Ahora veamos el "¿Cómo puede Ghostscript acceder a ellos?"
Quizás la pregunta debería ser más bien: "¿Cómo puedo (un usuario avanzado, un desarrollador, un geek ...) acceder a ellos?"
Puede imprimir el contenido de cualquier diccionario accesible que sea conocido para su intérprete PostScript (que puede ser Ghostscript) escribiendo un programa simple PostScript one-liner o simplemente llamando al intérprete (Ghostscript) con el programa código entregado en la línea de comandos (-c ...
).
Solo necesita saber el nombre del diccionario respectivo para esto.
Veamos uno de esos diccionario Ghostscript interna interesante, llamado .distillersettings
:
gs \
-dNODISPLAY \
-c ".distillersettings {exch ==only () print ==} forall quit"
Resultado:
/default -dict-
/prepress -dict-
/PSL2Printer -dict-
/ebook -dict-
/screen -dict-
/printer -dict-
Esto no se puede decir mucho a primera vista. Pero puede reconocer algunos de los nombres clave en ese diccionario: /prepress
, /printer
, /screen
, /ebook
...
Todos estos se pueden utilizar en una línea de comandos de Ghostscript para solicitar un conjunto predefinido de configuraciones cuando se desea un resultado creado por -sDEVICE=pdfwrite
(la funcionalidad Ghostscript 'Distiller'-similar). Para solicitar dicho conjunto de configuraciones, simplemente agregue -dPDFSETTINGS=/printer
a la línea de comandos.
En la segunda mirada ahora verá que el contenido del diccionario .distillersettings
es esencialmente un conjunto de 6 diccionarios más. Es un 'diccionario de diccionarios'.
Los contenidos del diccionario no se imprimen por defecto (no con el código PostScript anterior). Pero si los quiere, puede usar un procedimiento específico de Ghostscript llamado ===
en lugar del operador estándar de lenguaje PostScript ==
en el comando anterior. Este procedimiento se comporta de la misma manera que ==
execpt que también expande los diccionarios e imprime todos los pares clave: valor contenidos en ellos.
tener cuidado con ese procedimiento ===
: la -dict-
que está tratando de ampliar puede ser veeeeeery largo y podría hacer que se pierda la vista. :-)
En nuestro caso actual sin embargo, todavía es manejable:
gs \
-dNODISPLAY \
-c ".distillersettings {exch ==only () print ===} forall quit"
salida actual es:
/default << /Optimize false /DoThumbnails false /PreserveEPSInfo true /ColorConversionStrategy /LeaveColorUnchanged /DownsampleMonoImages false /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments true /GrayACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >> /DownsampleColorImages false /PreserveOverprintSettings true /CreateJobTicket false /AutoRotatePages /PageByPage /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >> /DownsampleGrayImages false /UCRandBGInfo /Preserve >>
/prepress << /DoThumbnails true /MonoImageResolution 1200 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo true /ColorConversionStrategy /LeaveColorUnchanged /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Error /PreserveOPIComments true /GrayImageResolution 300 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 300 /PreserveOverprintSettings true /CreateJobTicket true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /NeverEmbed [] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Preserve >>
/PSL2Printer << /DoThumbnails false /CompatibilityLevel 1.2 /TransferFunctionInfo /Preserve /MonoImageResolution 1200 /PreserveEPSInfo true /CompressFonts true /ColorImageDownsampleType /Bicubic /GrayImageDownsampleType /Bicubic /ColorConversionStrategy /LeaveColorUnchanged /EmbedAllFonts true /ColorACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CannotEmbedFontPolicy /Error /PreserveOPIComments true /CompressPages true /GrayImageResolution 600 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 600 /PreserveOverprintSettings true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /ASCII85EncodePages true /MaxViewerMemorySize 8000000 /NeverEmbed [] /PreserveHalftoneInfo true /UCRandBGInfo /Preserve >>
/ebook << /DoThumbnails false /MonoImageResolution 300 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo false /ColorConversionStrategy /sRGB /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments false /GrayImageResolution 150 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /ColorImageResolution 150 /PreserveOverprintSettings false /CreateJobTicket false /AutoRotatePages /All /MonoImageDownsampleType /Bicubic /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Remove >>
/screen << /DoThumbnails false /MonoImageResolution 300 /ColorImageDownsampleType /Average /PreserveEPSInfo false /ColorConversionStrategy /sRGB /GrayImageDownsampleType /Average /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments false /GrayImageResolution 72 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /ColorImageResolution 72 /PreserveOverprintSettings false /CreateJobTicket false /AutoRotatePages /PageByPage /MonoImageDownsampleType /Average /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /CompatibilityLevel 1.3 /UCRandBGInfo /Remove >>
/printer << /DoThumbnails false /MonoImageResolution 1200 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo true /ColorConversionStrategy /UseDeviceIndependentColor /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments true /GrayImageResolution 300 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.4 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 300 /PreserveOverprintSettings true /CreateJobTicket true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /NeverEmbed [] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.4 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Preserve >>
Aún no tan agradable. Así que intentemos mejorarlo. La forma en que podemos hacerlo es modificar nuestro código PostScript: ahora le decimos que acceda al diccionario .distillersettings
y obtenga el valor de una de las claves (use /screen
). Como sabemos que el valor es otro diccionario, sabemos que vamos a llegar otro conjunto de pares clave: valor que vamos a ser capaces de formatear la misma manera que hicimos antes:
gs \
-q \
-dNODISPLAY \
-c ".distillersettings /screen get {exch ==only () print ===} forall quit"
Ahora bien, esto se ve mejor, DOESN no es así? Véase a sí mismo:
/DoThumbnails false
/MonoImageResolution 300
/ColorImageDownsampleType /Average
/PreserveEPSInfo false
/ColorConversionStrategy /sRGB
/GrayImageDownsampleType /Average
/EmbedAllFonts true
/CannotEmbedFontPolicy /Warning
/PreserveOPIComments false
/GrayImageResolution 72
/GrayACSImageDict -dict-
/ColorImageResolution 72
/PreserveOverprintSettings false
/CreateJobTicket false
/AutoRotatePages /PageByPage
/MonoImageDownsampleType /Average
/NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats]
/ColorACSImageDict -dict-
/CompatibilityLevel 1.3
/UCRandBGInfo /Remove
medida que su ojo agudo puede haber visto ya: algunos de los valores clave son de nuevo los diccionarios . Usted es libre de utilizar el comando de arriba de nuevo, esta vez con un ===
en lugar de la segunda ==
para resolver los misterios que /GrayACSImageDict -dict-
y similares se pueden mantener escondite ...
En cualquier caso, ahora que sabes lo que ahorra en tecleando simplemente usando -dPDFSETTINGS=/screen
en lugar de enumerar todos los parámetros individuales integrados en este diccionario /screen
...
Y también se sabe qué valor único que necesita para anular el caso de que desee de salida general de la calidad de 'pantalla', pero con la diferencia de que todas las fuentes se incrustan:
gs \
-o out.pdf \
-sDEVICE=pdfwrite \
-dPDFSETTINGS=/screen \
-c "<</NeverEmbed [ ] /AlwaysEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats]>> setdistillerparams" \
-f input.pdf
Puedes explorar un montón de cosas interesantes de esta manera sobre las partes internas de Ghostscript, si solo conoces el nombre de los diccionarios que utiliza.:-)
Muchas gracias por la respuesta detallada, @pipitas! Si/cuando tienes tiempo, también podrías agregar un breve ejemplo de terminal 'ghostscript', de" _ el intérprete [] buscando un nombre_ "(que también puede mostrar que '_'userdict' se busca antes de' systemdict'_, y posiblemente sobrescribir a un operador)? Muchas gracias de nuevo, ¡salud! – sdaau
@sdaau: mi otra respuesta muestra cómo buscar el nombre/tecla '/ pantalla' en el diccionario' .distillersettings': es tan simple como '.distillersettings/screen get'. El operador 'get' pone el valor de la clave (si se encuentra) en la pila del operando (si no se encuentra, se imprimirá un error' undefined'). Ahora que el valor de la clave está en la pila, el resto del fragmento de código simplemente lo trae allí, lo formatea un poco para que se vea mejor e imprime su contenido ... –
Muchas gracias, @pipitas: ¡muy apreciado! – sdaau