implementation module StdPrint import StdArray, StdBool, StdEnum, StdInt, StdList, StdTuple import commondef, StdMaybe, StdPicture import osprint :: PageDimensions = { page :: !Size , margins :: !Rectangle , resolution :: !(!Int,!Int) } defaultPrintSetup :: !*env -> (!PrintSetup, !*env) | FileEnv env defaultPrintSetup env = os_defaultprintsetup env printSetupDialog :: !PrintSetup !*printEnv -> (!PrintSetup, !*printEnv) | PrintEnvironments printEnv printSetupDialog printSetup env = os_printsetupdialog printSetup env getPageDimensions :: !PrintSetup !Bool -> PageDimensions getPageDimensions printSetup emulateScreenRes # ((w,h),((x1,y1),(x2,y2)),resolution) = os_getpagedimensions printSetup emulateScreenRes = {page={w=w,h=h}, margins={corner1={x=x1,y=y1},corner2={x=x2,y=y2}}, resolution=resolution} instance == PageDimensions where (==) {page=page1,margins=margins1,resolution=resolution1} {page=page2,margins=margins2,resolution=resolution2} = page1==page2 && margins1==margins2 && resolution1==resolution2 fwritePrintSetup :: !PrintSetup !*File -> *File fwritePrintSetup printSetup file #! string = os_printsetuptostring printSetup hexChars = [ nibbleToChar (if low (lowNibble string.[i]) (highNibble string.[i])) \\ i<-[0..(size string)-1], low<-[True, False] ] = fwrites (toString hexChars+++" ") file where lowNibble ch = (toInt ch) bitand 0xF highNibble ch = ((toInt ch)>>4) bitand 0xF nibbleToChar nibble | 10<=nibble && nibble<=15 = toChar (nibble-10+(toInt 'A')) | 0<=nibble && nibble<=9 = toChar (nibble+(toInt '0')) freadPrintSetup :: !*File !*env -> (!Bool, !PrintSetup, !*File, !*env) | FileEnv env freadPrintSetup file env #! (hexChList, file) = readline [] file chList = map hexToChar (pair hexChList) printSetup = os_stringtoprintsetup (toString chList) (valid, env) = os_printsetupvalid printSetup env | not valid #! (defaultPS, env)= os_defaultprintsetup env = (False, defaultPS, file ,env) = (True, printSetup, file, env) where readline akku file #! (ok, ch, file) = freadc file | ok && isMember ch (['0'..'9']++['A'..'F']) = readline [ch:akku] file = (reverse akku, file) pair [] = [] pair [x] = [(x,'0')] pair [x,y:rest] = [(x,y): pair rest] hexToChar (lowNibble,highNibble) = (nibbleToInt lowNibble)+16*(nibbleToInt highNibble) nibbleToInt ch | 'A'<=ch && ch<='F' = (toInt ch) - (toInt 'A') + 10 | '0'<=ch && ch<='9' = digitToInt ch print :: !Bool !Bool .(PrintInfo *Picture -> ([IdFun *Picture],*Picture)) !PrintSetup !*printEnv -> (!PrintSetup, !*printEnv) | PrintEnvironments printEnv print doDialog emulateScreen prFun printSetup printEnv # (finalState,printEnv) = os_printpageperpage doDialog emulateScreen 0 initFun stateTransition printSetup printEnv = case finalState of Cancelled _ -> (printSetup,printEnv) StartedPrinting (_,printSetup2) -> (printSetup2,printEnv) where initFun _ printInfo=:{printSetup} picture # (drawFuns,picture) = prFun printInfo picture = ((isEmpty drawFuns,zero), ((drawFuns,printSetup),picture)) stateTransition (([drawFun:rest],printSetup),picture) =((isEmpty rest,zero), ((rest,printSetup), drawFun picture)) printUpdateFunction :: !Bool (UpdateState -> *Picture -> *Picture) [Rectangle] !PrintSetup !*printEnv -> (!PrintSetup, !*printEnv) | PrintEnvironments printEnv printUpdateFunction doDialog updateFunc rectangles printSetup printEnv # (result, printEnv) = os_printpageperpage doDialog True Nothing initState pageTrans printSetup printEnv outPrintSetup = case result of StartedPrinting (outPrintSetup,_) -> outPrintSetup Cancelled s -> printSetup = (outPrintSetup, printEnv) where initState s printInfo=:{ printSetup, jobInfo={range=(first,last), copies} } picture = ( ( isEmpty printedClips,(hd printedClips).corner1), ( (printSetup, printedClips), picture ) ) where {page={w=wP,h=hP}} = getPageDimensions printSetup True printedClips = flatten (repeatn copies (allClips % (first-1,last-1))) allClips = flatten (map clipsOfOneRectangle rectangles) clipsOfOneRectangle rectangle = clipRectangles where {rleft=x1,rtop=y1,rright=x2,rbottom=y2} = rectangleToRect rectangle wR = x2-x1+1 hR = y2-y1+1 columns = [0..(ceilOfRatio wR wP)-1] rows = [0..(ceilOfRatio hR hP)-1] clipRectangles = [ { corner1 = { x=c*wP+x1, y=r*hP+y1 }, corner2 = { x=min ((c+1)*wP+x1) x2, y=min ((r+1)*hP+y1) y2 }} \\ r<-rows,c<-columns] ceilOfRatio num denum // ceil (num/denom) | num rem denum == 0 = num/denum = num/denum + 1 min x y | x>y = y =x pageTrans ((printSetup, [clipRect:rest]), picture) # drawFunction = updateFunc (rectangleToUpdateState clipRect) = ( (isEmpty rest,if (isEmpty rest) zero (hd rest).corner1), ((printSetup,rest), appClipPicture (toRegion clipRect) drawFunction picture) ) printPagePerPage :: !Bool !Bool .x .(.x -> .(PrintInfo -> .(*Picture -> ((.Bool,Point2),(.state,*Picture))))) ((.state,*Picture) -> ((.Bool,Point2),(.state,*Picture))) !PrintSetup !*printEnv -> (Alternative .x .state,!*printEnv) | PrintEnvironments printEnv printPagePerPage doDialog emulateScreen x initFun transFun printSetup printEnv = os_printpageperpage doDialog emulateScreen x initFun transFun printSetup printEnv instance PrintEnvironments World where os_printpageperpage p1 p2 p3 p4 p5 p6 world = accFiles (os_printpageperpage p1 p2 p3 p4 p5 p6) world os_printsetupdialog p1 world = accFiles (os_printsetupdialog p1) world