IMG_3049.PNG

Estendere le capacitˆà di stampa di Cocoa

Avete realizzato l’interfaccia per cdlabelgen come descritto nel precedente post?

Beh, io si e ho affrontato anche il problema della stampa: voi?

La stampa in programmi Cocoa deriva dall’essenziale derivazione del motore grafico Quartz dal PDF. Quindi in Cocoa la stampa nasce dalla costruzione di un suo oggetto NSView da cui discendano come contenuto tutte le componenti grafiche necessarie a strutturare il layout finale.

Quello che otteniamo è dunque una relazione 1:1 tra widget Cocoa, testo e immagini e le componenti PDF che porteremo alla stampa.

Ma con cdlabelgen abbiamo a che fare con postscript: questo è ciò che viene generato dallo script. Che PDF e postscript siano parenti non aiuta affatto!

Cercando in Internet non ho trovato soluzioni, nemmeno lontanamente. Che la cosa non fosse mai stata affrontata o fosse stata risolta con librerie proprietarie dai software di grafica con tanto di blasone mi sembrava alquanto strana.

Poi (la disperazione a volte aiuta!) mi sono ricordato che nella cartella esempi di XCode qualcosa riguardo la stampa era presente: ho cominciato a cercare e studiare, tornando sull’indispensabile (e preziosa) documentazione ADC.

Ed ecco a voi la soluzione (Apple, non mia: io ho solo ritrovato e ora pubblicizzato tale soluzione).

Dicevamo che i frameworks che compongono l’universo Cocoa (in particolare AppKit) supportano una limitata visione del processo di stampa, segnatamente una versione NSView-centrica gestita attraverso le seguenti astrazioni:

  • NSPageLayout
  • NSPrintInfo
  • NSPrintOperation
  • NSPrintPanel
  • NSPrinter

Un supporto completo alla stampa deriva (da indicazione esplicita in documentazione) dall’utilizzo diretto del framework Core Printing, una API in C di cui AppKit crea una interfaccia limitata.

La soluzione da noi cercata per stampare dati postscript (file, in particolare) è la funzione PMPrinterPrintWithFile presente in questo framework; il suo prototipo è:

OSStatus PMPrinterPrintWithFile (

 PMPrinter printer,

 PMPrintSettings settings,

 PMPageFormat format,

 CFStringRef mimeType,

 CFURLRef fileURL

);

Come possiamo vedere mediante il parametro fileURL si fornisce un percorso al file da stampare, file di cui mediante parametro mimeType si indica anche il tipo. La specifica di tipo è importante in quanto deve coincidere con uno dei tipi supportati dal framework; i tipi supportati (ricavati dalla funzione per la validazione del tipo passato) sono:

  •     “application/octet-stream”
  •     “application/pc-eps”
  •     “application/pdf”
  •     “application/pictwps”
  •     “application/postscript”
  •     “application/vnd.apple-postscript”
  •     “application/vnd.cups-banner”
  •     “application/vnd.cups-command”
  •     “application/vnd.cups-postscript”
  •     “application/vnd.cups-raster”
  •     “application/vnd.cups-raw”
  •     “application/vnd.hp-hpgl”
  •     “application/x-cshell”
  •     “application/x-csource”
  •     “application/x-perl”
  •     “application/x-shell”
  •     “application/xhtml+xml”
  •     “image/fuji-raw”
  •     “image/gif”
  •     “image/imageio”
  •     “image/jp2”
  •     “image/jpeg”
  •     “image/minolta-raw”
  •     “image/openexr”
  •     “image/pict”
  •     “image/png”
  •     “image/rad”
  •     “image/tiff”
  •     “image/x-alias”
  •     “image/x-bitmap”
  •     “image/x-bmp”
  •     “image/x-ico”
  •     “image/x-icon”
  •     “image/x-photocd”
  •     “image/x-portable-anymap”
  •     “image/x-portable-bitmap”
  •     “image/x-portable-graymap”
  •     “image/x-portable-pixmap”
  •     “image/x-psd”
  •     “image/x-qtif”
  •     “image/x-sgi-rgb”
  •     “image/x-sun-raster”
  •     “image/x-tga”
  •     “image/x-xbitmap”
  •     “image/x-xpixmap”
  •     “text/html”
  •     “text/plain”
  •     “text/rtf”

Non male, vero?

È ovvio che per invocare questa funzione occorre completarne la lista argomenti: stampante, formato e settaggio per il processo di stampa.
Questi ultimi due parametri li ricaviamo fortunatamente direttamente in AppKit, in particolare da una istanza condivisa di NSPrintInfo 

 [NSPrintInfo sharedPrintInfo]

dopo averla popolata utilizzando NSPrintPanel e NSPageLayout (le componenti Cocoa che realizzano le finestre di dialogo utente per le rispettive finalitˆà utilizzando una istanza di NSPrintInfo). Per Il parametro stampante invocheremo PMSessionGetCurrentPrinter() passando la sessione ottenuta sempre da NSPrintInfo dopo averle collegato settaggio e formato mediante PMSessionDefaultPrintSettings() e PMSessionValidatePageFormat() (funzioni di Core Printing).

Mettendo assieme il tutto avrete la vostra stampa di file postscript.
Questo un rapido quadro della soluzione: per i dettagli c’e’ la documentazione: replicarla qui mi sembra troppo!

Alla prossima!