SIBO 'C' Software Development Kit FORM REFERENCE Version 2.20 March 1, 1999 (C) Copyright Psion PLC 1990-97 All rights reserved. This manual and the programs referred to herein are copyrighted works of Psion PLC, London, England. Reproduction in whole or in part, including utilization in machines capable of reproduction or retrieval, without express written permission of Psion PLC, is prohibited. Reverse engineering is also prohibited. The information in this document is subject to change without notice. Psion and the Psion logo are registered trademarks, and Psion, Psion MC, Psion HC, Psion Series 3, Psion Series 3a, Psion Series 3c, Psion Siena and Psion Workabout are trademarks of Psion PLC. TopSpeed is a registered trademark of Clarion Software Corporation. Intel 8086 and 80286 are registered trademarks of Intel Corporation. IBM, IBM XT and IBM AT are registered trademarks of International Business Machines Corp. Microsoft and MS-DOS are registered trademarks of Microsoft Corporation. Apple and Macintosh are registered trademarks of Apple Computer Inc. VAX and VMS are registered trademarks of Digital Equipment Corporation. Brief is a registered trademark of Underware Inc. Psion PLC acknowledges that some other names referred to are registered trademarks. 6102 0026 01 (v2.10 SIBO C SDK Bound) + sheets from 6102 0050 01 (v2.20 SIBO C SDK Update Pack) CONTENTS 1 Introduction.............ccsccsssssrsssssssrssersssreeseeeeseseesseesseesseesseesseesseesseesseessesssesscesscesscsesessseseseesseees 1-1 Using FORMsClasses: cscs, fect Seg. eed ede iasbedegecdannpbantstesiectoceeiantstett eeloeepbantseeiecbonpiactees 1-1 Measurement Units... cic. ccctessecaiestcaiseesuadevaeancasvesabacovduarcdsvdsetccsvdcancdevacebedevacancdevecsoceuvanes 1-2 IN ATI OM ade oat ceeded be eet ated alee dante chsh al ctedes thee Ah ab Madivte shan lhe aver atone cece 1-2 NAMM eS 5 scesveesdeecccda cise cesvaes betan res edes vaceiceneteavduancouacessseevdvasecst cesaduevdvancaatceseaeeviassiancteeens 1-2 Method function prototypes ...........ccccccceeeecccecesececeeeeeeeceesaeeeeseeeeeeseaeeeceeeaeeeseeneeeeeeeas 1-2 The. ‘no leave symbol-...:1:5.avesaegepdeet egustest ipiasbedes desedegdesd oder besdegiblesbeds eibdeydeeb diated 1-3 LONG: Parameters ose. vcs e5 Gansta sees eth vanes coe oUheoee (oratoaisotegestverseods ssangens deestouussavesst raed ats 1-3 Class: diagtams: sss:2.0hidseivncid eisai evil en eaves nee Rasa 1-3 Class Hier ar hiys fst. diessetedptatecegeted sii tentecesets dante nanterevedetodteaintecdedetoctpnieh esse etetoaeptanhats 1-3 Structured Error RECOVELy :..:s.5:c.yscsbeuiyiesdeseyseeneainbesteseyoivacaiyhs eshylesbegsyoeb beavaes gape dedaoeey 1-4 Use of the p_leave mechanism...........e ee eeeeceseecsseeceseeeesseecsaeesseecsseecesaeeesaeessaeeseeeeens 1-4 Panic NUMBERS oi si..cccvises cess scka cea cctecevs ccae cee edcaacenvecaa sua vdcda cuaucdaadeandesveeaeceanevandeaeevasceaetens 1-4 Gall-back: tmieth OdSvoiscacsaivedeassodesstavedeatcadeces deduce ve daeutevseedutashgniatecedolath ddsintecssatete Maacatetearts 1-5 MU xi ClasS@Sivicsceieescciedestedesdenuedeadescdevivatsdoedval cdovdsabecondssledovdshbedosdeatcdovdcabddevecdocdevcdeesenceds 1-5 2 The Formatted Document Content Classes..............cssssssssersssrsserscssscereserssssssssssssesssessessseees 2-1 The FORMDOC mixin class ...........ccecescccceeenceeeeenceeeeeeaceececesneeceseaeeeeesnaeeesseaeeecensaeeeeseanees 2-2 Class diagram «: $1; 2th is Sakic HE eee ed ie ee a ce ees 2-2 Class etinitiOnsccrei. detects deccdiaseestéiaess cabin scvugaieasessainsseutscvacnatbiaaceusscuacvasgianiadesdessetzanys 2-2 PLOPELY es5 sess2ehs cess ivesch lune cast cevstessonnssushctvons duie suv bauvedun Saves Cob bauvadan dees CaVtsuvseunldevs cubs Pex 2-2 FORMBDOC methods isis ucresdsecdercaiecdendan cdarcathelaadaiedaaaginecaadaniadaacathateadaniedeadescoudentoaneatcs 2-3 Scan to start of paragraph... eee eeeeeseecesneecsseeceseeceseecesaeeesaeecsseecseecsseeeesseesseeenes 2-3 Provide:characters:..i) Jc. ieniciitdn cin daadiaidtedetad acseeidad teas hasheacetenedh Ateoiacebvin ieee 2-3 Sense paragraph layout data ....... eee eeeeeessecesseecseessscecscecsseeessaeessaeecsaeessseeessaeessaes 2-4 Sense-paragraph labelesssiccesssusscssgsisceesasvetsasaassteehatues soe sasasnsagued susacasdeasacusonbecasooetagass 2-4 Returiiva:page number 25:4 fui Gokul ea iia eh ea ee 2-5 EPDOG so aviesi vais. bseiuscssetioel stespdenties) A avtesssanhoni | Socereuapiael Asuras abtaoes Anoneas Aerie Aaprass 2-5 Class dia Sr arin os. civs2.i5 28 cecys codsccvn pul secns cova ehbeseh savas eas csbaded Sanne pevtedes ded stubs nettesbsied sausea state 2-6 Pa Sit Ati Oni y.525.ssectsscacauedslaoestasiasantasbentaciasoendasstentactaguentattsstanswonendaseesieg asneadateasteniss 2-6 Document filter ise iiss science cheat becheactSs opeuck cuneach Secnavetceetones tens Mentevende ce eeerhonesea tenes 2-6 Class: definitiOt.t ssc: ae Bintnitto Bhd Rais dia dena atatie nie 2-7 PLOPOLly suces cvs dee ssuseteass es ussvbatevss sta teva feeedevss Uacees seadeossots See peietvoss 3 seeneeadeess Gatevae shee 2-8 EPDOG method sis. leutisiac coucsiveeasea ne cas aisocaiegng cata usteaieaancca saa eceaaaenestacansoannaaingsuacginaaeaaaies 2-8 Tittle’. cscs eo sat cess ctieeesencicacsecetoeseaneecsenaces orevenenasstacveeass teseonen eavannoetauonenersioresteuntiee ins 2-8 Sense:document len Sthyis.siss.ceet 8 Asta. cael Aatiesecetp ies dapteisushasedugheteoses podeenhass 2-8 Serise: characters forwards sz cscvesei ceeescusacuvetes sdiescudaavve teh sbuus cudasuwedessdnecedbsubedessankesesadne 2-8 Sense characters backwatds...........cccsscccessssceeeeeseceeeeeneeeceesneeeeseneeeeeseaeeeceenaeeeeeenneeeesees 2-9 TiVS]rt CHATACTERS 3565.5. ci55 Seeecd kos eadovbs dnsonts Seva coessanbened reve Guess deuesen ceeseuane dus eves Sovsgeunaccbe¥l Sous 2-10 Copy: charactersissssiswssh sot nsidoeindsehaieenB deinen ainsi bAdansi anatase 2-10 Delete: Characters’: ciiosc cts asestathorsctsdeebentetuvssetsahwaeadstees saves setenasselaauonsabsleessvladwerswyilaveds 2-11 Glear the doctimenit, 27333: .ci.scsvasesscatieanidaeiteucnesoenscaeaoounatavoracaas soategieoveneais nvtesueeseed ess 2-11 Compress'allocated: stora se... scis05 Succ sihctge dosed choco bests hub da shdcebostbesebbestaedesbetsiowsicee 2-11 Set (or clear) the page: list....::.5.asti6 Mohs aie Asis one Anite a Mente Mattei aes 2-11 REtuIma: Page NUMBER 4.2.5.2: 52. heck aces teshevee teh deve seitedbetalddeondeag ceesaehedenscuitcuvedea hdevedensPee 2-12 Get position at the start Of @ Page... ee eeseesseecsseecsseecsseeeesaeeesaeecsaeecsaeesseeessaeeesaee 2-12 Set (or clear) the filter list... ccccccscscccccccsssssseeceececesseesneeeeeeceesseesseeeeeeeeeesesssaeeeees 2-12 Getunfiltered position. s 355.chci Ahi Aah edted ss Mache siitessades nasetedessnostuanscs 2-12 FORM REFERENCE EPDOE call-back methods i0..::.:2.ssiss.2cecdenstens sshcdeesadeeeiensduvedeesdevesudedupeteusuevecta sdvectessivescea sy 2-13 Scan.to start.of parderaphis.s.ic:.scctaccssdauseasteaisceaadesdoastaniocsesdashovelgaieceoudaaseeenatestdaeieanass 2-13 Provide characters x: hssc.cidiistectaeisdhisies Seieeh isha dtieionhusiad Nboshicindl eaibebeiodensts 2-13 BPEDOG 7a stots aries ibis BA haiac hb Ashsenhsuhalen hs Asie Sasha amas 2-14 Class dia Sram. bors says eces2h osc Fash suestewses a bases tiwssiba tues cos tawss Daahie eavatsosechs Hees seisteeseds sede 2-15 Class:defnitiomissiscciiscicesseaiioesnasuspeasdaninestasespesngataceatasagesteauioeatanageeheatazeatsdoeone Motes 2-15 PLOPOrey. « soesieccveibsshcees Sevakosk sieheaess iuedovbadabdecbudutdowboduhtaesodca gostadghivstedeadestodesiesyolengevboegtees 2-15 EPFDOG-call= back Methods: ae :csi2, Sisssostiesscpeodoss osetieshceveossedussdeseiehs atdoe, peasdapiousedereceseds 2-15 Scan: to-start of para sraphy sic. css dosce cause seosehveteh shveesvdsdevetes ins tvibdevedeeseesaiaduvedebsadea se 2-15 Provade:characters:...:civoisctsiteestagiaceadaosstsssavesndaiaosatacisossntahecusanidosendaeeantancaosendais ens 2-15 3 The Document Layout Classes...............ccscccsssssssssscsscccsscssccsssccesssscsessssssesssscscesssscsesssssesessssees 3-1 PLECULSOLS secs seeserats tis soutsssetsehpoanteceessneeveystuscnnysiuberepstebeaspsdebeavestaCesedniutecveedutuseendassvecnde 3-1 Class. didertatn .t.c:5.cc:.gccthened asians etpissdgaebes te plant eth ds eeigdant ens edagibiten el atibee 3-1 SCRICA Yio. dcr ete eh ot eh ie tet nat eet ne Mit Aa eat eesti a oat ome sth Diet canvhitesh aed 3-2 Class: definition j:iessshehiitieinnd aren ean dn ieee aia 3-2 PLOPCEEYe cei. ccess iy evatoctpewetshgecatoreges ores satorbipstabedepainteruvetathdeyaiatedtestatedushatedesseseacvede 3-6 DatasStructures-siceccvascaive dtesivtieaigotitesitisechastebde tesa este arecee dare beardee eda pheseds 3-7 Special Character ssc. ie cees26asscecbus oes aM eveveacs ses cabctorevtuetettabeess hace sanedutenss Lact scnasuceemes leek es 3-7 Font-width ‘tables... 2:/scsgiini gi tavis het cilia aaiieeeiaeth bi ced aiadainy 3-8 SERA Yomethods yo. t..adaco gates ceewasesite gates saueadetezey oltneespaeet bees sdanevecaesthtes tdnavepbestedepeteae eee 3-8 Initialise: 3322.s532 she ieiyit anak eet aie la eee 3-8 Setslobal: layout Style cosy. At ses sites aves sesvasatows oust sa stite a ouas saviouateal ouaton tate sted 3-9 Sense global layout style... cee eeseesecceseeceseeesneecsseecscecsseeceseeessaeessaeecsaeesseeessaeeesaes 3-10 DESILOV oy ssessces ctessens easisee pstessvte sth ovepstviovegstubonepsanteaspsuunedepeluaeerpeuuiuevesSuceeesndunseepsdessesvent 3-10 Convert position to line number and pixel Offset... eeeeecesseeeeseeeeneeeeseeseseeeesaes 3-10 Convert line number and pixel offset to POSitiON ............eeeeeeeeeeseeeeseeceneeeeteeseseeeesaes 3-11 Get horizontal pixel offsets of start & end Of LINe..... ee eee eeeeeeneeeeneeeeseeesneeeeseeeesaes 3-11 Prépare:towtead line: datars so. sticscct cee, achpeseteecsegetennds int venpecesotepsins sespedesstepsceh vesgsustodeynant ss 3-11 Read: lin e:data's.es3.cyssiectoaned eeytekgeipaust (gach sed paaid ge ep UB Ge aise 3-12 Foriniat the next line... ise. bees cae shade shied cae totes east he eehad etait ant eat aie 3-12 Scroll the layout:.ccuss.vieieieinn tn invests herein ati eee 3-12 View position On given Line... eee eeeeceseecsseecesseeeseecscecseeecesseecseecseeseseeeesaeessaeers 3-12 Discard layout’.2:3. hc ntecpene chee eee eey aides eigenen einen Rye 3-13 Adjust screen/printer scaling ...........eesceescecsseecsseecesseeesseecsseecsaceceeeessaeeesaeessaeesseeeee 3-13 Set number6f littes.i:)syicsitiens hari Aires Ai een Miah aani ati 3-13 Discard lines from PoSitiOn..........eeeceeseeceeseecesseeeseecsseecsseecesaeeesaeecsaeecseeseseeeeseessaeers 3-13 WRAP cic cg uetcetegupigsieke Szi Deny dae dba Bei Dede pben Ganda DRL Ug Pa RE ep EIT 3-14 Class: definition». 2 svt an. se Beet eA eR het eA eR esl ie ae 3-14 PLOPCLly. Sdinc tase Bi Nee ea Se A EE MG a es 3-14 WRAP methods) o...2.55c:¢3 ssp edisets datey bank thd ete godess ateshg evetedepscetethy otatedeyacet ests etebedesbeetaceg etetedeber’ 3-14 Tri tal se wicca: cece teeiyacs bees beh Lec yoesedandesdecoyonee intel Teeoydevs iva Degavoese egal eaapoesk epheidemrte 3-14 Queue a line format request... eee eeesseeeeeeceeeseeseeeceeesesseeeceessesaeeaeeeseeeaes 3-15 Format a lin@ seis ssactelcn tas eevee alavin ina tas aivtere oar ain teen een eee 3-15 SS RII Gress fives aden aaeet oh atte vaca sotatag oft cacbeatbne ott eres Ot adeno eat te, eltne ee eet ats sana eal 3-15 Class. definition: 2: .cgiterireetgiedehetinaat give bettas aoe eigasd eave and eee 3-16 PHOPOUUY. Seas sou. stateas save egssseeesh Yo wet sus hbedeve cotet sau rsivesat Vouet sano alutscnsbuetomsnasuvec Ueustcteastusernests 3-17 SCRIMG methods s:) eset veel nein eh eh Behl eave ie Beh eda! 3-19 DEST OY si ees Seachde pote peacoat pe tet satis ee0s skp ede seduya Cobadey eds Sante aeehechy Pa tledde sdetedh p eSetoaepss@becegetecerny ost 3-19 Tri ta lise iiss 35.5 octet cccev teal bese coysivedbindes Deeovone i phustesaytows Qigaas Deeaehese Revdeibe seh eediyi beste 3-20 Seb Views and layout o o.5. cts fetes ons abcde tetoes Rist cats teat owe Sheba tiad ene hae tet en Reet 3-20 Sense Window information .......... ce eeeseessecsseecsseeceseeeesseecsaeecseeseneesesaeeesaeesseeseneeeees 3-22 Seb Emphasis OiOL: OFF. axes se geeec ite paven hc beat eee oven ety seat otep odes Bea adet Ar tees eeysio ay eee 3-22 Get select TES OM si52.s52:stescrehe edi beel ai eee ep a eee 3-22 Scroll the image horizontally... eeseeeseecsseecssceeesseecseecseeceseeeesaeessaeessneeesteeeesaes 3-22 Scroll the image vertically .............cesecesssecsesessseesessereneetonsnessonevensenensetensnessosertosenenens 3-23 Show position on Given line....... ee esse seseecsscecsseeeseecseecsseecsscesesaeecseessseeseseeeesaeeees 3-23 Set the Cursor: positiOn yvos3i552teceyeee gays ek egavaesk cdepeel buss deecdaplelbussreesvehepiasseneeeiyoabeety 3-23 Draw to: S1ven: TéCtam ol Oy. ooh sis sat oot eetbee ah ai eakttesl ae eeind oi tet ok ae ete AO 3-25 Discard screen layout, view and redraw..........eeeesceeseecsseecssceeeseecseecsseeessaeeesaeeesaeers 3-25 Discard layout and redraw.........eseesecescccsseecesseecseecseecsseecsscecesaeecsacecseecsseeeesaeeesaeers 3-25 Prepare for-a left delete. :.s::c:.cc2vait apcetigivis ded platen vesdehpoalin iia evinces 3-26 ii CONTENTS Draw paragraph to echo content Change .......... ec eeeeeeeeeseecceesseeeceeeeesesseeeeeeseeesensaeees 3-26 Redraw to echo a style Change ........e ee eeeseseeesseecsseeceeecescecseecsseeessaeecsaeesaeessaeesseeeees 3-26 Redraw for a change after the CUrSOF POSItION ......... cee eeeeeeeeseeseeeeeeeetsaeeceeeeeseeeeeeensaee 3-27 4 The Document Printing Classes...............csccccsssssscsssssssscssccssscseecssccsesssssesssscsssssscesessssccsessssseeees 4-1 PECULSOLS canadien tie hipi eats Mana haat arena tea 4-1 Class Cider arms: 2essesiet ok abst eae A PA BR Ae OL as a a tat on 4-2 Measurement units <.. 523) savauiichiiei aie aii ciel einai ane aeinovaiate 4-2 PRINTER 1 6 pect te cot Sad cst edasd tet dandatet dis tesbertd eset tue t coteanyedahctugaeetonvs ates step teeteandedetedeptentedes 4-2 Class:definition:. ssi: acsinsan een oias ile a aaron ein aa ie 4-3 PLOPORby foci Soci cae dai ese shis Sok va entiv sunt ius siesta s Mut ies oaltessta ul des al ttece saben den Gade eauvaust ows 4-5 ENVITONMENt VarIAbles ........... eee ceseecsseeeeseecesceecsseecseecsseecesaeeesseecsseecseecsseeeesaeeesaeers 4-5 PRINTER meth O85 et se 2 essciee coces soup since ves bces deg suns eve cecebete p tone deeavetbeagaletn paeetetes ateue es eeten ss 4-6 Destroy the print Manage ...........eeeeeeeccesseeesneecsseeceseeeesaeeessececssaeessaeecsaeersaeeesseeeesaes 4-6 Initialise printer & set default ValUeS 0.0... eee eeeeeeseeesseeceneecsnceceteeeesaeecsaeersaeesseeeees 4-6 Set serial port Characteristics .........eceesecsseecsscecsseeeesseecsseecseecsseeeesseessaeesseessneeeesaes 4-6 Set print file:spect Cat On w..e.c..ecssetsche vet ese usnhsvte svete depsentanhs edetedephceterds detedesbiebentsetetes 4-6 Setitype of printer Port: .ssi2.s.scc08s.peeidegayeeheaesiasdesbedesbgephasded end. masdenededceepoebianies 4-7 Set printer model no. & WDR file name... eee eeeeesseeeeneeceseeeesseecsseeeseessseeeesaes 4-7 Sense printer port information ........... cee eeseesseecsseeeeseeeesseesseeceseecesseecseesseessseeessaes 4-7 Sense current printer port device information ...........cceeseeeeseeceseeeeeeeseeerseeceteeeesaes 4-8 Sense printer model number & WDR file name... cee eeseeeeseeeeneeeeneeteneeseseeeesaes 4-9 Fetch address of printer parameters ............ccceesceesseecsseeceseeceseeeesneecsaeecseesseeesseeeesaes 4-9 Set top or bottom header text... eee eeseessecsseeceseeesseecseecsseecsseeeesaeessaeesseessneeeesaes 4-9 Get address of top or bottom header text... eeeeeseseeceseceseeseeecsseesseessseeeeseeeesaes 4-10 Create: WDR ‘Object is227..ecicc2.55: teeiaideeteain apie Teese ied pie evel. pie eeaedobd pa ees 4-10 Destroy WiIDR: Ob]eCt .ss6.222. Setect asics ccketeet cee cade coseteet ooh att ockt tant cas bth stet ce ai vente 4-10 Open printer port device s..2icseiee ates avast esi eeaistei es ineeince enone ieee. 4-10 PEIN E data SOULCE 0) ef ssns cevacec ite kote fees cesotey ate eter edatb tes alta te bles Lay otnnanh poet ate pldaeverranteaes 4-11 Paginate data SOUTCEcc.scc..c.cccicesseieseedundesbevandeseedandeveevendesed ior devvedendcavidandcousdendersacaadens 4-11 Initialise: Preview ...2 0:2. et ce atedseeversdce otietemsctectorechebumsace de distumeredtemeieeterdeeecteestt 4-12 PerfGrit preview #i.s5:38. eine thi eal ai ce Te si al a ie 4-13 P@LTMn Ate: PEC VIEW: Py encodes oct cedetebyspetedepstet slp aeutedesgadeer es idutedeetegstlpnsstaveseseesreph Sievert: 4-13 Return handle of preview data ............cccccecsesscceesenceeeesneeeeeeeeeeeessaeeecseseeeeeseneeeeesneeeees 4-14 AGES | tess nat Sects sak hele ect oat seed ceutical cet alt cata tiiet ooh aoa heel deh Cal acictat cat alone ces 4-14 Class -definition:.3:.sse cat essergestat an cargitel assae aisle iavainel ainda alleat 4-15 PLOPOLbyh it ccvecevoacitetovasivevacatete detauase aden ogee atausch codes etecstagncegbceteten aiacoweebees en gakace ch bees eis 4-17 Pape dimemSiOns?..3:.2.20;c5.2c2.e3esbegepeasd caey des bedigasd daavee bagi paael eeeyheibedepate) asdesdeepanebemaaaesy 4-20 PAGES iii eth od 8rses os cot Sse sth ies cen tte est saa ER het oes A Gt eee ER eat cesses Wee 4-21 Initialise and Queue... cscvcccecescccdivesecdiaecseccssecdecdscevas ccaeveas ccsescatecessete cenvadnecesveese couveaavens 4-21 Fetch text pritit Clement :.0-20:.22¢ ssh ede; test etegetapethe seshetes ade b sate seebedepedesoatp eset edepetetenteravbeded 4-23 Handléserror stig sa re tities Batihenr eerie nl arise eats tsb atareaede 4-24 Translate the print element and print data ...........ceeccceeeessceeeseeeceeeseeeeeeeeeeeeesneeeeeeees 4-24 WDR.eicsasesesteiteaiy hi wanes Si snes aa etenir baarseey duties tas saedhsiee vonssaedsieave nes 4-25 Glass de finrtronis rag fates Se adeeae toes ieee ote kt aca lat ch eet wena beet te otageveprentedg 4-26 Property sist matin ase eat ei ein aaah dha tdiadey 4-28 WD Rettieth ods sic fos sic cocthhe tock atin seus stat ech Vue oe aude ch vsned auth oetsah Vorut ct ath feeesoust anna tutes least oat 4-29 DEST Orisa ch seest i eR ioe ti eve CO hd St VR Pd UR a ot 4-29 Tmittalise WIDR os. ics fest eden acteg sceesnee seh ede pate tsatp esate dogadessnepidutedeyeten sulpnautadesesesuephStavevers 4-29 Return the number of models............eeceeesessseecsseeesseeceseeeesaeecsseecsseesesaeessaeeessseeeesaes 4-30 Get model name from model NUMDET..............eeeeeseeceseeseseeceseeeesaeecsaeerseessseeesseeeesaes 4-30 Set: the current model wisi: auceeseds nt ass havent savant sh mail Aiea wearin) 4-30 Sense:current MOdel datas, .cccce., 21s svocest dey ose set alec evepedeeschys iets aeede peiae eg eteeetegeatsty 4-30 Get typeface by index s..c:.t.c.ys.despeedeeeseibaaigtis deere badges deevieibeds pated dandesbeepane beta oes 4-30 Get typeface by typeface NUMDET........... ee eeeeessecsseecsseeesseeeesaeeesseecsaeecsseeceseeeesaeessaeers 4-31 Get font height by typeface & height indexes... eee eeseceesseeesneecsseecsneeseseeeeseeeesaes 4-31 Get font index given height 0.0.0.0... eeeeeeseecssneessseecsseecsseecesaeeesaeecsaeecseessseeeesaeessaeers 4-32 Get a requested font width table... ee eesecsseeceseecsseecesseessaeecsaeecsseeceseeeesaeessneers 4-32 Get printed: Width Of text,..0.655 02h ccketedt oak vad ees het seh aides taeh ah cides at ah aie et ees 4-33 Convert twips to primter UNItS 0.00... eee lee eeeeeeesneeeseecssceceseeeesaeessaeecsaeesseesseesesaeeesaes 4-33 Create a PDR for printer OUtPUE........ eee eeeeceneeceneeeeseecesaeeesaeeceaeecsseecstaeeesaeeseaeers 4-33 Load resource record's). Jsicses3 sh. bsedediate she aehbedigdasd ceseeelbadigdn esa epdeed eee apda ezine 4-34 iii FORM REFERENCE PIR sins ss s2uv5i0s Yai an abe suts dens dos Sevke devs 2evetbs sQube covetebsdts Raves favpeesdia stvie eladeoseuv Dues fubadeustonstebesd 4-34 Class: detnitiOn: sc etiatactiatatedescsticaradeteteacaieseadaisedaveainoeutastoatassnoontassosuug antaeoeetens 4-35 PLOPOUEY: 6s decks Hiis chewed ca eacbeis ondgweh Seoaeackb eedense ce sdgnchecsdewshceshousie evbuveacegoauetecedgnuh ocessouhe sevens 4-36 PDR methods’: pth cindncnidce Bhindi Biba ena nadis leaded aeheadaahe eae woesee ces 4-37 DGStOY 6. ck sas nseets chug peta tioes os hadeea tees svbs chu osvaateos svesdevassuadevs selaceoasevadvos sts Deeaeessbeesecdsdevaed 4-37 MnitialiSe: PIR sic. Messtes ssa tistassates ouatesenaates iozeatea ecules aaeateseeates aGcatesaecatesieeeatess 4-37 Translate print: command ..:. 2.0205 56: shag idisioces ecklgi Seed oegs ehh Posh ocestoekien Podesta ade 4-38 Add: command to butter: is. asises deseties oesacacssesatdassuseiassovsstcasovasdaandunsdbavsentvanssvancianses 4-41 Destroy method, subclassable by DYL.............c::cccessssceeeeeeeeeeenceeeeeeeeeeeseneeeeesneeeeesees 4-42 Start: Prim tim Os; :32.6c0stestas.sidseseeuneaiacestizskedsteasapageaveataanscaeabaissstaaieeerelavaeetasisaeudawdoestasy 4-42 FmaShs print Seine 235 casts cecveks doe eas ceeseuche den enck ceeesechecesetuncasheustegebetuicevneuet cession covsasel cbevene 4-42 Stata New pages: esis sinsieohAshsaaisl hina adohiasie haan As 4-43 Print text at CUFFENt POSITION... eee eeeeceseeesseeeesceeesneecsaeersseeceeecesseecsaeessaeessneeeesaes 4-43 Stara Mew lanes: wcasceessestesiiaesteaiaavatdeiiosetesiiorsweceateass teancaenesaneaeaeaaaaneeanaaaeoeusasenoannesy 4-43 Position to the right ............c:ceeesccccessseceeesseeeceeneeeeeeeeenneeeeseaeeeeeseaeeceesneeeeensneeeeeseeeeess 4-44 SeUthefont.. othe vecpeasnetiees Mecteasseetiees dadias vaeuis Arvadves Svasbues Araeheka veves ca deeebees uveaeaaes 4-44 Set-the font Style seccicegssiset stews sesesthe eetsceuscipbehe delsceuseuvscts ful sceescavssbead dewseuvtsieendeveuees 4-45 ‘Ehe;PAGELA Y-mixaniClass's..2:iiesstcsiaesadelines basing aseee teens at banteasteaeats aateausaaiaceutlanteartacs 4-46 Class: dias r aris of 5esig isch sedis seh eocd vated sotewud Moveved gekes th caus eek Seneend aubabebsdehge th esubebebelevrs 4-46 Class definition cic ahciiioBAhic ad hiainiaseh fhsanei Assn Asenatharti Rivka koetiaacteeds 4-46 PLOPOLUY.4 de ccvssapsavehietedeons ods dean seteteusscds cevaseeduvs cous dave seid dese rodsckvasvadustscdadevs snesduetscds Gevedn 4-46 PAGELAY call-back methods............cccscccecessceeeseeceeeesnneeeeesneeeeesneeeseeeeeeeeeseaeeessenneeeeeeas 4-46 Get next WDR_PRINT element.............c cece cccccessseecccccececaeseeecccesesaueeecccesssaaaeeeeeees 4-46 Handle stattis Messages ..........cseccccesssecceeeenceceeeesececeseececseeeeceeeaeeecsenneeeseeeeceeseeeeeeess 4-47 PRINLAY , eissscattebit ceed astinedst deus eet ehtevexg cavhsledel fave eos h¥eied piven cavbebbeded Sante eavtedneed Saetes 4-49 Class detinitiOnser-40cssschaccustavtcessaatacswstevieasicg eco eatantesnteatieawttiaveaieanooundinsoouageantateaateny 4-49 PLOPOLbY. 5 sos secictes de cigoui oa caceeisecaeses Seeacevie covewsh cosvguvaceuvensa coup aust eveaseiog goguete egsanes oessgeehedeeaee 4-50 PRNLAY methods ici so: nstdccie Mains Biaiiaen in dada hla a naonas. 4-52 Read text fOr primtin 8. foic$5 205 fesstiost ts bal eviedeeseds he deviiteess bes ntedonreigeerededeera desea te 4-52 Set'start:position: for Prints s.-..s25..255hsackcvesds laps iisehceptahasestasacesteasseahdispesteaateatsctase 4-52 SeTES 3 a/SETIES BS NOCES 5-66 och acek | Festes Mee vdoed ba sh ctahegvesaeioeseetesedeusechos seeten sovadeenoustetes Saewaenristess 4-53 5 The Print Preview Class ..............cccscccsssssssssscssccsscsecsscssesssscssesssscsesssscscesssscsessssccseessscssessssees 5-1 PLECULSOES 33.5353 ct Rae hyde ERE DER ea oats eve Gera ee eS ace 5-1 CASS AA STATI Fe sae Soe sah kN as Sak GR eae Se AUR cas ER Ea A cee See A ee Soc eset 5-1 PRV PDR bixaisiiteetes Givaraiinin etalon cai an Se a rain ian aTAL 5-2 Class: definiti Ottis... ee saycenteveceesdt. sedate coset deteneeadoensetecolucede Geintede deluth cides deletedieses 5-2 PrOPCrlycosies stses FeMee te eee piso Sis ai eee 5-3 PRVPDRotes st eh ee at et ee at te had Aa eA i heat el eh nee ae ha 5-5 Initialise .:33sh.cbsl svar dies avi aia aveil nie aad ted eae 5-5 Interpret print COMMANA.............eececeeeeeeeeeeenceeeeeeeeeeeseaeeeeeeneeeeceeeeeeeesaeeeceeneeeeeseneeeess 5-6 DESthOY i i2ite octdead cis tohitcaeyis teat edst eye Re a eda Roar ben eee ee 5-7 Start: printins (drawing) asc. seive ek inde ht es ail dst teve olathe et see elds latent ates 5-7 Slart AMCW Pale sisi ch stsont ai ea vent As isards irate venvaa moneda cyan eau aeetouan lesa 5-8 SOE ME TON tie. ccceavine canst d otegete doses ete s canna ve Cointedeselieees Point elioesssacs deintedeaateededadelededadiledseras 5-8 The PRNTPRYV mixin Class ...........cccccccessscceeesececeseneeecseeeeceesaeeecesneeeessaeeeeeesaeeceesessneeeensas 5-9 Cl aSS Gia Sram. sec is 8 Sets i cet abe sitoek Laeist sce g sues cake stones sbageeh Covetomes sited. Gustaseestatediats 5-9 Class definition j.cccccsactaecadiecccicsec tas cedevvanceatucevccsescarcevescanceds senecenvecndessscceucesvadauesaeeates 5-9 PLOPCUby voc sil seats euseet su cset stave cobs egede dea Uracobsnudegs Getty acosscts efetects eestechs esetedtgpestberegesstoaepess 5-9 PRNTPRV call-back methods.............cecccccceesecceeeesceeeeeeeeeceeneeeceseaeeeceseaeeeessaeeeeestaeeeeseanees 5-9 Han dle:status messages vc. civices cab abet ook cesta esitt ede ist oh altho dice oh Ah nee ae 5-9 6 The Calendar Image Class................ssccssssscssscsseccsscssecsssssescsscssesssscscessssescssssssesssscsssessscsssesscees 6-1 BLO CUTSOM Se: 335 2051 Lacie sxigseus cnchosetales oavbeucde souesuncyabenche seiebuncaoeanehs gueevenceueousteseeetuscostenetsaesere 6-1 CALIMG ei:8 sou ica ae Aiad oi win AAait aoe uiiaretphst siti ends Aaya etait 6-1 Class definition: 2.30032. esas teeth eteeen hs Mebalh tees nies Madevsdtexeribbeiabadeostata deed bas ceased 6-2 PLOPOrey a szisseecsss sass as lawss aadsiiaceassihe vandanssoabacascestastioassazaapestasassestaganaestesisoeenaaiaasatasevsene 6-4 CATEIM Gr imeth ods ie cies cack cde deck des danke Sendesdeceniucke denaned eduvanehedeedoheauvavenndeaguehonueenenedenaeescaveess 6-5 Destroy: the Calendars: :::./scs2ctc.aisbesarisesAsstusicsavdocecessdiasscasdossestuaseesebissseenbeascesedisbshe 6-5 Initialise: the:calen dat: si.c5ccckacecessseks cas vaihe cot sehen cTaebed oh cache res sdebs eck daebecetadebsitlcess a00ecebs 6-5 iv CONTENTS Set the: ttle ssc ses eis Ms saves cevsghbs Peektws favs tebstee steko cedibs fea dee sveadivsie Sivbesethtevsres toes wastes 6-7 Empliasise the: views sisisvcietcseaceandascasteslasesndathenstes sseandackea teatveandadeas tea aoensdsoaieatee 6-7 Move the Cursorisss sscasi hectic Shetaocks csdeoss Heeignsht culevssSasvouebessbenehoguoceuhe iuteses Sigtesvbecuteava cage 6-8 Move the: cursor by:date.cs(stssicaseAsphsr tb dsiisi eh idarhal tee sdaehai ate bans 6-9 Adjust the current date «a. :2c0:20.008 sis tevscdevsestachessctativcedesdivssasddvestolschvastbadvestdieteesevbatss 6-9 Redraw patt-of the viewss2..i2:.sssesisiicastcsiagcsidanieoatiaapcauatsgesteavgeahasusgesteasnpeasathnestaasss 6-10 Sense the current: dates ssciscsseei gh Sik aoa Seek nego see oak dunched Mee den esha eee 6-10 Dra with e: View. ecaisviess sted: sf cose hesssrsebiek avsphisssraioss heidissecasbond sattiassaeeisedaciesscnsibenb annus 6-10 Move the cursor by POSitiONn.......... ee eesecssecsseecsseeceseeeesseecsaeessseeseseeessaeeesaeesseeseeeenes 6-10 Update-today.s:datevis.tiscccstesiassandaihctssenianssadathensteaiaseandacseastea woeenaisea teaiaoeasioasedeteaise 6-11 7 The Polytext Classes.............ccsscccsscssscssscsccsssscccsscscesssscscesssssesssscscesssccssesssscsesssscssesssscssesssoesors 7-1 PLECULSOLS wes desssuc tess esecs eustatsvelesehtevvedes sieeodeseaevsteseveporet teuetebs tipedetswuedegusecebauteesesiaty 7-1 Class:diagtaim's:...yiscscyiast etal api nied oad nie ig sent en alain aed 7-2 PT ROOT stesso 5 tig seh ted oe a te Gl ea ete i a i te ae 7-2 Class definition i::3:3.vhsinivkis erie eee evi eave ae hie ay hier avei eee 7-2 PHOPOIEY. do fas sR saet ocedess Sects cute vids Setedupa swtece pete Gete'sssteceveStedust eters dade odds debedededeh tuvacetedes 7-3 PTROOT imethods..2.c:si.: arcitneak aise kp eeneei eis yae iyi lesyoee inten eehb eens 7-4 Add phtase-to:butfer sc). cciesc ok aces Auk oak aU ech intia auton Aue deh aM eta dead ode Ge eed 7-4 Wrap the text 2,.csstscctessiest as cavieievent aaecea sees oes eaatian dei ssuauceps tavdeave st ccuadeaveeisimteaaaces 7-4 Draw aime Ob texte, veins vecetls2egsioceveceees ote gaiete Mpstetotegssenevegeest cages etgutsbevesotes setpstatevsy se 7-5 Set font UD sissies cote hseaepsest gibi d osepaaad an bes eda dead een ged spas seb HA aaa eh aaa 7-5 Set font ID and style by phrase .0...... eee eeseeceseceseeeseecssceceeeceseesesaeeesaeessaeesseeenes 7-6 Set font ID and style by attribute... eee eceseeceseeesseeeeseeeesaeecsseecseeceseeeesaeessaeers 7-7 Find phrase by attribute ...........ececcceceesecceesencceeeeeneeecseceeeeseaeeeceseaeeeeeenaeeeeeeneeeeeeeeeeess 7-7 Find information about a phrase..........eeeeeseessecesseeceseeceseecesaeeesaeecsaeesseessseesssaeeesaes 7-8 PT ROOM deferred: Methods 35 e.oc¢ cas sct eels tact ote csvet cake beet ote shns aeksaast ote tulnds da taut devsbededds iets 7-8 Initialise:.ics.cedeasdishiecmbaitinl siete ai alinteihin ah erent nialineeai ati ate 7-8 RESO isi. feat suv erand esas ete gsdit vag suntbaepsdutenspstuceaypsluseavpsiateaey statues prtbedssdutee paces svessdehevsvadeseaey 7-8 Append @ record 53:5 caccestcgiggesdesepdest dey ashe digdend cdoydesbadagduel cdoydeibedepdssb dandesbedepdved eda heby 7-8 Store line-lensth table:.:.2. c.2ht.eet lee ie ea Aina 7-9 Get address of phrasés:) icainiihi reich arisen laa 7-9 DPT SAT coteahs snt ceeds casledas wea tedtes cet scedatat feet cobs ede tee coca date tes tote tedatetlsea ehededetet de Talend 7-9 Class definition. syisien silt nein iy ielienp eee aise epan ieee ema ep es 7-10 PHOPORby cess ek eek sek sah ovat ook valid ene s Sua iok vas ess Suh ek wahtows oBhut deh wal oe vate ee dabnt eoe unt eat 7-10 PTFUA Tmethods) ietscisscesiiettisnevanist Gitergiiat au cavaiisicsieauaieel aimee aie 7-10 Destroy them stance: sz. vocedzegeioer deus cos tegeianis coder hte alate iegecetedegadentve peeat ide dete teerestetey 7-10 Initialise ..ces.ecnieiapi si eet eisai opie i yi aa ape epibeeie 7-10 RESCE: gu. tues coca iets nt eat tithe Males cee acts aad can sate ae Pala dau nuk Baa sev alah eas Sev sete Vout sas 7-11 Append a phrases. iccesseeis cates cesecssvevacidacesdeceesevacadeuevaa deveevaadeveccda cess scatedevsctacenvecaedees 7-11 Store line-len sth table: yg. s ect cces szesy sue evavesesereesantevepetosenes tanhevsdedesoeustonteabeeverecussenteney 8 7-11 Get‘address of phrase: s.::..c.c..:s4 0ytesesipa edges tiieae ieee pdsedeydevbee pac lecteabbenepae beans 7-11 PY SEG ees aie atin an chet ti aoe att Me a ti a Arta ak Aleit ih alate ea 7-12 Class :definition.::.sstastvncaiiieienhatahapiiniincavai eles aie cumdaneieies 7-12 PLOPOreys. oiscs cee cat ete eleul ve gained pstaec ve peen sete geseue sh palette oalatn de vatutedvgscupade dade teesdagnveeacaseaey 7-13 PT SEG methods sis.25;50:3 gincestegigdeidedordestgis eidediptead eaves bedi paes deeb dipieel daebbetepd aay 7-13 Mind 1 ALT SO) toes Bes ot ween sa seh. Poaat ea tea aaah cde estates shed cau vatetesbtaesb ate saiete eusteeestieesantont wate 7-13 RESClaiaiienauietuBin vel ai oad eats Ph ene Sad eat ee a ed eae 7-13 Append a: phrases, sso: fee esleicctscedesnt ecupsceteceg ode pate acetetegsdh tesug teste dagedeseitpeeubededetetesterestecey 7-13 Store line-lensth ‘table w.2.: cc.cs.cscepseltesiptediyecibeshedesdaeyoesbactpdesd caeyoeibasnediel Goyhelbesiydnedets 7-13 Get-dddress: Of Phrase: fo de sase sk esiht cake has cee shag ah hak ae etek ae lnte ae ea es 7-14 CHAPTER 1 INTRODUCTION This manual is a reference document for Psion's FORM library. It provides a comprehensive guide to the library and documents the classes, methods, properties, inheritance hierarchies and other information essential for understanding and using the library. It assumes familiarity with the concepts of Object Oriented Programming. The Object Oriented Programming Guide is useful pre-requisite reading as it provides the necessary background to Object Oriented Programming as implemented at Psion. It can, of course, be read in conjunction with the FORM Reference manual. The FORM library is a collection of classes which provide a range of document formatting and printing services that are independent of the user interface used by an application. The object classes it contains can be used directly or can be subclassed by any application code. Many of the classes inherit methods and property from classes in the OLIB library; the OLIB Reference manual is, therefore, a useful pre-requisite. Use of the FORM library allows complex applications to be built quickly and reliably. Each chapter in this manual contains a description of a number of closely related classes. For example, the document layout chapter discusses all classes related to the laying out of text on the screen. The description of each class follows the same format. It includes the purpose of the class, the hierarchical relationship of the class to other classes, the actual class definition, a description of the property and a complete list and discussion of the methods. References to relevant manuals are included where necessary. The FORM library is supplied as the form.dyl dynamic link library in the ROM of all SIBO machines. All classes in the FORM library are ultimately derived from the Root class which is described in the OLIB Reference manual. It is, therefore, a required component of all object oriented programs. ! The content of this manual describes the version of FORM as it exists on the Series 3a and Workabout (it is identical on these two machines). In general, this is also applicable to the Series 3. However, where behaviour on the Series 3 differs or where certain features, methods or property are not available on the Series 3, then this will be noted at the appropriate points in the text. Using FORM classes An application (or DYL) that either subclasses or creates an instance of a FORM class must declare an external reference to the FORM library (and the OLIB library) in its category file. If, for example, an application's category file has the name myprog.cat, the content of this category file must start with the following lines: IMAGE myprog EXTERNAL olib EXTERNAL form This ensures that, amongst other things, the defined constants representing the external category numbers for the FORM and OLIB categories (in this case, cAT_MYAPP_FORM and CAT_MYAPP_OLIB, respectively) are available to application code. ! Tt is, however, permissible for a category that has no intrinsic dependence on other OLIB and FORM classes to define its own root class and thereby eliminate all dependency on OLIB and FORM. See, for example, the Building a Dynamic Library chapter of the Object Oriented Programming Guide. 1-1 FORM REFERENCE In the source code of the MYPROG application, an instance of an FORM class - say, of ptszc - would be created with p_new (or £_new) as follows: p_new (CAT_MYPROG_FORM, C_PTSEG) ; .If myprog.cat defines a subclass of a FORM class (say, the class susptsEc) this would exist in the local category. An instance is created using the local category number cat_mypRoG_MypPRoG, as follows: p_new (CAT_MYPROG_MYPROG, C_SUBPTSEG) ; Similar consideratons apply to instances created by means of £_newsend. Measurement units Measurements are generally presented to the user in inches, centimetres or points (there are 72 points per inch). Internally, these measurements are stored either in twips or printer units. A twip is a twentieth of a point, so that there are 1440 twips per inch. Printer units are defined to be the natural units associated with a particular printer. The size of the unit thus varies from printer to printer and is defined in the printer driver file (see WDR Printing in the Additional System Information manual). The unit may be one tenth of an inch for a printer that has a single monospaced font, whereas a typical value for a laser printer is one three hundredth of an inch (corresponding to a printer resolution of 300 dots per inch). The war_twips_to_xy method of the wor class, described later in this manual, converts a measurement in twips to the equivalent in printer units for a particular printer. Notation Throughout this manual, all references to the Series 3 should be taken to refer to the Series 3a, unless otherwise explicitly stated. Names Except in class diagrams a class name is always given in upper case, for example scriay. The method name in the title line of the description of each method is the defined symbol for the method number, without its leading o_. In the body of the text this name, in lower case letters, is used to refer to the method function (or more simply, the method) whereas the upper case name refers to the corresponding message. Thus, an object's dest roy method function is executed when the object receives a DESTROY Message. Method function prototypes The description of each method contains a function prototype that specifies the nature of any return value and the parameters with which the method is called. The parameters exclude the object handle and the method number. For example, a method for the class Eppoc with the title line: EP_ SENSE CHARS Sense characters forwards and prototyped as: UINT ep_sense_chars (TEXT **pbuf, UINT pos, UINT n); would be invoked by, for example: UINT n,pos; TEXT *buf; /* to take pointer to buffer */ n=40; pos=400; n=p_send4 (hand, O_EP_SENSE_CHARS, &buf,pos,n) ; 1 INTRODUCTION where hand is the handle of an instance of the Eppoc class. This corresponds to a method function declared in C source code as: METHOD UINT epdoc_ep_sense_chars(PR_EPDOC *self,TEXT **pbuf,UINT pos,UINT n) { } The & symbol The enter and leave mechanism (which uses p_enter and p_leave) is commonly used to implement structured error recovery. See the Error Handling and Error Recovery chapter of the Object Oriented Programming Guide and the Error Handling chapter of the PLIB Reference manual. Some methods (the vast majority of dest roy methods, for example) can never fail and will therefore never call p_leave. The title line of a number of the more significant methods of this type are marked with a leading © symbol. With the enter and leave mechanism, a call to p_leave should only occur within the protection of a p_enter harness. If p_leave is called outside a p_enter harness, the process will be panicked with panic number 47. The p_leave mechanism and its use in method functions is discussed briefly in the section on Structured Error Recovery later in this chapter. Long parameters A small number of FORM class methods require a Lone or a ULONG parameter. For the reasons explained in the Introduction chapter of the Object Oriented Programming Guide, the message-sending mechanism in TopSpeed C does not support such parameters and they should be passed as two tnt (or UINT) parameters, where the first is the least significant word and the second is the most significant word of the data. In such a case the actual method prototype is always followed by a conceptual form, illustrating the intent of the parameters. Class diagrams To illustrate the inheritance and using relationships between classes, most chapters will contain at least one class diagram. The notation is a subset of that used by Grady Booch and described in his book Object-oriented Analysis and Design with applications (2nd edition) with two minor changes; e classes which are referenced, but not described, within a chapter (i.e. classes whose full description lies in other chapters of this manual or in a different manual), are underlined, e the diagrams do not distinguish between ‘has' (aggregation) and ‘using’ (client/supplier) relationships. Also note that ultimate inheritance from the root class is assumed and is not shown. Class hierarchy In understanding the structure of a specific class, remember that methods and property are often inherited from a superclass (or superclasses). While a class may contain new methods and property, it may also re-define methods inherited from a superclass (or superclasses). Note that methods in a superclass can be what are known as deferred methods. To help illustrate these relationships, each class description in this manual is accompanied by a diagram which shows that class and its superclass(es) in hierarchical order. This diagram is placed at the beginning of the class description. The diagram consists of a series of adjacent columns. The rightmost column represents the class being described and will be marked by a double line border while the column to its left represents its immediate superclass (if any) marked by a single line border and so on up the hierarchy. Each column is headed by the class name followed by two boxes; the first lists that class's property and the second lists its methods. Deferred methods are separated from the preceding methods by a blank line and are printed in italics. If a class re-defines an inherited method, the method name in the appropriate superclass is written with a line through it. FORM REFERENCE For example, the following diagram would be included in a description of class cccc subclassed from BBBB which itself is subclasses aaaa. property_1 property_4 property_2 property_5 method_a method_b methed_—b method_c method_d method_x method_e method_y method_z method_u In this illustration, method_a is supplied by the superclass aaaa, while method_b is replaced in class BBBB and further replaced in class cccc. Another method, method_c, is introduced in class ppp but replaced in cccc, and so on. Note that method_u is a deferred method. The root class from which all classes are derived is assumed and will not be shown in the diagrams. Methods and property inherited from a superclass will be described in the appropriate class description. Structured Error Recovery As mentioned earlier, the enter and leave mechanism is commonly used to implement structured error recovery. Use of the p_leave mechanism In general, you should assume that all methods NOT marked with the & symbol (as discussed in the section on Notation) are capable of calling p_1eave, even if this is not explicitly mentioned in the method description. In some cases, such as where a method calls, directly or indirectly, a deferred method (which is supplied by a subclasser) it is not possible to specify whether the method may result in p_leave being called. In the event of an error (such as out of system memory) occurring a method may: e call p_leave, passing the (negative) error number, e return the error number, e either call p_1eave or return an error number, depending on the nature of the error. Some methods call p_leave (0), which has the effect of returning from the p_enter harness (with the return value zero) without signalling an error. This is used, for example, to provide a normal exit from a deeply nested function call, without the need for a zero return value to be passed back through the chain of calls. Intermediate functions in the chain may then be declared as voip. Some method functions that may call p_1leave are declared as vorp. One reason for this may be that the method forms part of a chain, as described in the preceding paragraph. If user code were to send such a message within a p_enter harness, the value returned from p_enter would be indeterminate if no error arose. The solution is to construct a shell function which sends the message and then returns zero, and call this shell within a p_enter harness. The call to p_enter will then return either zero (if the method calls p_leave (0) or it executes to completion) or a negative error number. Panic numbers See the Error Handling and Error Recovery chapter of the Object Oriented Programming Guide and the Error Handling chapter of the PLIB Reference manual for a discussion of panics and panic numbers. XADD does not have its own unique panic numbers, but panics a client that attempts an illegal operation using PLIB, OLIB and Window Server panic numbers, defined in the respective SDK manuals. 1 INTRODUCTION Call-back methods In general, an object passes a message to another object by calling the appropriate method using the relevant method number. Within the code, the method number is usually a symbolic constant generated at category translation time. However, an alternative is to define suitable property within the calling object and set the property to contain the method number. The code can then be constructed to use the value in the property, rather than use the symbolic constant. For example, in a class asc, a call to such a method would take the form: p_send(self-—>abc.handle, self—>abc.methnum,...); where the object's handle is assumed to have been written to self->abc. handle and self->abc.methnum has been previously set by, say: self->abc.methnum = O_METHOD_NUMBER; Clearly this is slightly less efficient, both in terms of memory usage and speed of execution, than the more usual: p_send(self-—>abc.handle, O_METHOD_NUMBER,...); It does, however, offer a number of advantages that, in certain circumstances, can prove to be of use: e it allows the message being sent to be changed dynamically during the lifetime of the calling object e the method number can be passed to the calling object, avoiding the need for the calling object to have any knowledge of the class to which the message is being sent - this can be of value in terms of design e it allows the service to be supplied by any class that supports a suitable method function e it effectively provides a multiple inheritance mechanism for the inheritance of class behaviour (but not of class property) Mixin classes A mixin class is a class that is defined for the sole purpose of being combined (or mixed in) with other classes to provide more sophisticated behaviour. Such a class encapsulates a single aspect of behaviour for the inheriting class and is not intended to be instantiated in its own right. The following figure illustrates a typical situation and shows that mixin classes are associated with multiple inheritance. ~ ~ - mixint =) mixin2 — < as ( \ \ \ pet ae ca ‘a ggreg / \ Ae —_ For further discussion of mixin classes see, for example, Object Oriented Analysis and Design with Applications by Grady Booch, published by The Benjamin/Cummings Publishing Company, Inc. Although Psion's object oriented programming system does not support multiple inheritance, a mixin class is an ideal way of formally specifying the required functionality of call-back methods. In application code terms the mixin class itself has no physical existence, but its method functions will be implemented as part of some other 'real' class. This manual contains formal descriptions of three mixin classes: e =the rFormpoc mixin class, described in the Formatted Document Content Classes chapter; e the pacELay mixin class, described in the Document Printing Classes chapter; e = the prnTPRv mixin class, described in the Print Preview Class chapter. Each of the chapters referred to above contain 'real' classes which implement the respective mixin class method functions. CHAPTER 2 THE FORMATTED DOCUMENT CONTENT CLASSES A window that is to display formatted editable text will own a class that contains the document text. The display of the text is managed by a further two classes - an imager class (for example, scrimc) and a layout class (for example, scrLay). These two additional classes (described in the Document Layout Classes chapter of this manual) are both formally owned by the window, but interact with each other and the document content class to provide displayable formatted text. l c Window / f scrimg - “s ) ™~ ) Ne X Document _ ) scrlay = / C content. ——__& x ) = ) ee C- During its initialisation, an instance of either the scrtay class (described in the Document Layout Classes chapter) or the prnuay class (used when preparing printable output, and described in the Document Printing Classes chapter) must be provided with the handle of an instance of a suitable document content class. The document content class must support up to five specific services (two of which are mandatory) by means of up to five call-back methods, whose method numbers are also passed to scRLAY Or PRNLAY. This chapter specifies the nature of the services that must be supported and describes the document content classes that are supplied in the FORM library. FORM REFERENCE The FORMDOC mixin class para_start sense_chars sense_plabel sense_pdata enq_page The rormpoc mixin class provides the formal specification for the call-back methods that must be supported by any class that provides access to the text content of a formatted document. These methods may be called by the scriay and prntay document layout classes. For a general discussion on call-back methods and mixin classes, see the Introduction chapter in this manual. The rormpoc class does not appear in the FORM library and an instance of rormpoc will never be created. The FORM library supplies the two classes EPppoc and EPFpoc to encapsulate document text and provide the behaviour to manipulate and query it. These two classes, described later in this chapter, supply the minimum set of rormpoc call-back methods required by scriay and pRNuay. Application programmers are, however, free to supply the methods in either a separate user-defined class, or by subclassing Eppoc or (more rarely) EPrpoc; any such methods must follow the general specification prescribed by this description of the rormpoc class. Class diagram The following class diagram formally illustrates the relationship between the rormpoc mixin class and the scRLay layout class (see the Document Layout Classes chapter in this manual). Exceptionally, this diagram shows the root class in order to emphasise the multiple inheritance aspect of mixin classes. ~~ or oa oe nec, f — C root / C formdoc / ~ es ) es Sa ee a a C scrlay / ~ ) Ser Class definition CLASS formdoc root { DEFER para_start scan to start of paragraph, mandatory DEFER sense_chars sense character content, mandatory DEFER sense_plabel sense paragraph 'label', optional DEFER sense_pdata sense layout data for paragraph optional DEFER enq_page sense a page number optional } Property None. 2 THE FORMATTED DOCUMENT CONTENT CLASSES FORMDOC methods FORMDOC_PARA_START Scan to start of paragraph VOID formdoc_para_start (UWORD *ppos) ; Find the position of the start of a paragraph. The parameter ppos should point to a uworp value which specifies a character position within the document text; the method should scan the text to find the position of the start of the paragraph containing the specified position. The position of the start of the paragraph should be written back to *ppos. A method that performs this function is mandatory; it must be supplied by the object designated to be the supplier of document text to an instance of scRLay or PRNLAY. Versions of this method are supplied by the EPpoc and Eprpoc classes. FORMDOC SENSE CHARS Provide characters INT formdoc_sense_chars (SCRLAY_SENSECHARS *sense, SCRLAY_FONT **pf, UBYTE **pfw); Sense a block of up to ws_MAx_PRINT_BOX_TEXT_LEN contiguous characters of data of the same style from the document text. The parameter sense must point to a data structure of type scnLAY_sENSECHARS. This structure, which is included as part of the scriay class definition, is as follows: typedef struct { UWORD pos; document position to sense WORD printer; TRUE for printer data, FALSE for screen data TEXT *buf; address of character block WORD blen; length of character block } SCRLAY_SENSECHARS; The value in sense->pos specifies the document position where sensing is to start. The address of a buffer containing the first character should be written to sense->buf and the number of contiguous characters available in this buffer should be written to sense->blen. The value written to sense->blen must be less than or equal to ws_Max_PRINT_BOX_TEXT_LEN, even if a greater number of contiguous characters are actually present in the buffer. There are two reasons why fewer than this number of characters may be available: e the characters terminate at a physical boundary within a segmented buffer, that is, at the edge of an individual buffer segment e the characters terminate at a logical boundary where, for example, there is a change of font or of text attributes If content-specific layout (i.e. line segments with individual font and style information) is not supported, the parameters pf and pfw may be ignored and the method should return rausz. This is the case with the document classes Eppoc and EPFDoc. If content-specific layout is supported, the parameters pf and pfw should not be ignored. If pf is not NuLL, the method should write into pt the address of a pointer to a scnLAy_Font data structure. This structure, which is included as part of the scruay class definition, is as follows: typedef struct { UWORD fid; font ID for screen or typeface no.for printer UWORD style; font style (e.g. bold) UWORD height; height of printer font } SCRLAY_FONT; This data structure contains information that describes the font to be applied to the sensed characters. The font descriptor should relate to either a printer font or the corresponding screen font, depending on whether sense->printer 1S TRUE Of FALSE. FORM REFERENCE If pfw is not NuLL, the method should write into pfw the address of a pointer to a font width table for the font that is to be applied to the sensed characters. The font width table should relate to either a printer font or the corresponding screen font, depending on whether sense->printer 1S TRUE Of FALSE. The method should return tTrRuz, if the characters terminate at a logical boundary, otherwise it should return FALSE. A method that performs this function is mandatory; it must be supplied by the object designated to be the supplier of document text to an instance of scRLAy or PRNLAY. Versions of this method (which do not support content-specific layout) are supplied by the Eppoc and Eprpoc classes. FORMDOC_SENSE_PDATA Sense paragraph layout data VOID formdoc_sense_pdata(UINT pos, INT printer, SCRLAY_PDATA *p); Sense layout data for a specific paragraph. The paragraph is that which contains the character position specified by the parameter pos. The parameter p should point to a data structure of type scrLay_ppata. The structure, which is included as part of the scriay class definition, is as follows: typedef struct { SCRLAY_MARGINS *margins; Paragraph margins SCRLAY_TABS *tabs; Paragraph tabs SCRLAY_SPACING *spacing; Paragraph spacing } SCRLAY_PDATA; If the parameter printer contains the value TrRuz, the method should write the address of three data structures of type SCRLAY_MARGINS, SCRLAY_TABS and SCRLAY_SPACING Into p->margins, p->tabs and p->spacing respectively. The information in the three data structures will describe the printer layout for the paragraph. If the parameter printer contains the value ratsez, the method should write the address of two data structures of type scRLAY_MARGINS and SCRLAY_TABS into p->margins and p->tabs respectively. The information in the two data structures will describe the screen layout for the paragraph. Since vertical spacing is not represented on the screen, p->spacing can be ignored. A method that performs this function is optional and need not be supplied if there is no paragraph-specific layout. If, however, it is supplied, it must be by the object designated to be the supplier of document text to an instance of SsCRLAY or PRNLAY. FORMDOC_SENSE_ PLABEL Sense paragraph label VOID formdoc_sense_plabel(UINT pos, INT printer, PRNLAY_PLABEL **p); Sense the label data for a specific paragraph. The paragraph is that which contains the character position specified by the parameter pos. The method should write into the parameter p, the address of a pointer to a PRNLAY_PLABEL data structure. This structure, which is included as part of the prnuay class definition, is as follows: typedef struct { SCRLAY_PLABEL s; as for the screen UBYTE *wid; the font width table UWORD margin; margin for paragraph labels in printer units UWORD gutter; gutter between label and para margin } PRNLAY_PLABEL; If the parameter printer contains the value TRuz, the method must specify all members of this data structure. If the parameter printer contains the value raussz, the method need only specify the first (i.e. the SCRLAY_PLABEL) member. A method that performs this function is optional and need not be supplied if paragraph labels are not supported. If, however, it is supplied, it must be by the object designated to be the supplier of document text to an instance of scRLAY or PRNLAY. 2-4 2 THE FORMATTED DOCUMENT CONTENT CLASSES FORMDOC_ENQ_ PAGE INT formdoc_enq_page(UINT pos, UINT len); Return a page number Return a page number. The method should expect the following two parameters: © pos, specifies a character position within the document text. ¢ en, specifies a character count, defining the number of contiguous characters starting at position pos. If 1en is zero, the method should return the page number of the page that contains character position pos. If 1en is non-zero and there is no page break between character position pos and the character position postlen, then the method should return a zero. If 1en is non-zero and there is at least one page break between character position pos and the character position pos+len, then the method should return the page number of the page that follows the first page break in the range pos tO pos+ien. In any event, the method should always return zero if no page information is currently available. It is worth noting that page numbers start from one; in other words, the first page is designated as page 1 and not as page 0. A method that performs this function is optional and need not be supplied if the display of page breaks is not supported. If, however, it is supplied, it must be by the object designated to be the supplier of document text to an instance of scRLAY or PRNLAY. EPDOC EPROOT maxlen ep_set_text ep_scan_word ep_word_count ep_scan_para ep_para_count ep_scan_block ep_add_para ep_copy_indent ep_copy_to_front ep_copy_to_back ep_paste ep_mod_chars ep_sense_text ep_capacity EPDOC pages filter ep_init ep_sense_len ep_sense_chars ep_back_chars ep_insert ep_extract ep_delete ep_clear ep_compress epdoc_para_start epdoc_sense_chars epdoc_set_pages epdoc_enq_page epdoc_goto_page epdoc_set_filter epdoc_pos_filter FORM REFERENCE The eppoc class encapsulates formatted document text. It provides the property for storing and the methods for manipulating the text and is referenced by instances of the scrLay and scrime classes. Further, it supplies the two mandatory call-back methods: the 'scan to start of paragraph' method and 'the sense character content’ method (also known as 'the provide characters’ method). The fundamental characteristics and behaviour of editable documents are described in the Editable Documents chapter of the OLIB Reference manual. The Eppoc class is designed for the efficient storage and manipulation of large quantities of dynamically changing text. The text itself is contained in an scBur segmented buffer component. For small quantities of text, the class Eprpoc, described later, is more efficient. Class diagram The following class diagram shows the relationship between the document content class zppoc and other classes. The underlined classes are imported from o118 and they are all discussed in the OLIB Reference manual. fo MALOOL: 7 ( eproot / Pes tee es acs y Nafix / ¢ epdec / my ) ~ ) wo le ee S22: C vaflat / y § buf / y sl N ae ee i oe Pagination Within its property, EPpoc contains pagination information on the document. This information is held in the form of a uworp array. The array itself is a varLat object whose handle is held in the property epdoc. pages. Each entry in the array represents a single page and contains a count of the number of characters fitting into that page. It is worth pointing out that the first entry in the array represents the first page and this is deemed to be page | (not page 0). The array itself is built by an instance of the paczs active object, not by EPpoc (the pagination process is relatively time consuming and is best done as a low priority background task). A number of Eppoc's methods change the content of the document text, for example ep_insert and ep_delete. To avoid the overhead of re-paginating the document every time text is inserted or deleted, EPpoc modifies the character count of the appropriate page (or pages) in such a way that the position of the page break relative to the existing text remains unchanged. Clearly, following any insertion or deletion, the calculated position of a page break may no longer be strictly accurate. This situation can only be corrected when the owning application schedules a re-pagination operation by sending a pR_PAGINATE message to the PRINTER Class. Document filter Very often, there is a need to work with a subset of the whole document text. The precise meaning of a subset varies from application to application. A situation that is very common occurs in word processor applications where, often, only outline text needs to be displayed and manipulated. For example, outline text may consist simply of the headings in the document. In other words, text which is not part of the outline must be logically deleted. To handle this kind of situation, zppoc embraces the concept of a document filter. In essence, a filter is a map of the document indicating which sections of text are included in the subset and which sections are excluded (or logically deleted). When the map exists, the document is said to be filtered. The document filter is implemented by means of a uworp array. The array itself is a varLat object whose handle is held in the property epdoc. filter. 2 THE FORMATTED DOCUMENT CONTENT CLASSES The entries in the array are logically grouped into consecutive pairs. Starting from the first position in the document, the first entry in the array contains a count of the number of characters which are to be excluded or logically deleted from the document; the second entry contains a count of the number of following characters which are to be included in the filtered document. This pattern is repeated for rest of the document. The idea is more easily understood by looking at the schematic diagram below. The horizontal bar represents document text where the shaded sections represent text which is to be excluded or logically deleted from the document while the non-shaded sections represent text which is to be included as part of the filtered document. Position zero is on the left hand side. The vertical column represents the filter array with the individual elements marked each containing the length of the corresponding section of text. Filter array | Document text Position 0 The sum of the values contained in each element of the array should be the same as the length of the unfiltered document. It should also be noted that both the first and the last entries in the array are often zero. Class definition The Eppoc class subclasses the OLIB class zproot and is defined in the sub-category file epdoc.cl (with generated header file epdoc.g). CLASS epdoc eproot { REPLACE ep_init REPLACE ep_sense_len REPLACE ep_sense_chars REPLACE ep_back_chars REPLACE ep_insert REPLACE ep_extract REPLACE ep_delete REPLACE ep_clear REPLACE ep_compress ADD epdoc_para_start Scan to start of paragraph ADD epdoc_sense_chars Provide characters ADD epdoc_set_pages Set the page list ADD epdoc_enq_page Enquire page break position ADD epdoc_goto_page Get pos at start of specified page ADD epdoc_set_filter Set (or clear) the filter list ADD epdoc_pos_filter Convert filtered pos to unfiltered pos PROPERTY 3 { PR_SGBUF *b; handle of buffers data PR_VAFLAT *pages; number of characters in each page PR_VAFLAT *filter; filter (e.g for outline mode) } FORM REFERENCE Property epdoc.b The handle of an instance of scpur containing the document text; this is a component of EPDoc. epdoc.pages The handle of an instance of varLat, containing a uworp array. Each consecutive entry in the array contains a value giving the number of characters in consecutive pages. The first entry in the array refers to page 1. See the Pagination section above. epdoc. filter The handle of an instance of varLat, containing a uworp array. The array contains the document filter information as described in the Document filter section above. EPDOC methods EP_INIT Initialise VOID ep_init (UINT maxlen) ; Initialise the instance of EPpoc. The maximum length of the document (the superclass property eproot .maxlen) is set to the value contained in the parameter maxien. Note that this length includes the terminating nNuLL. An instance of the segmented buffer scpur is created and its handle stored in the property epdoc.b. At the same time, the instance is initialised by sending a sn_1nrT message specifying a segment length of 128 bytes. The buffer itself is seeded with a single nuiu character. This is the delimiter which marks the end of the text and, in effect, creates an empty document. EP_ SENSE LEN Sense document length UINT ep_sense_len (VOID) ; Sense the current length of the document text. The method returns the number of bytes of text stored; note that this excludes the terminating NULL. If the document is filtered (i.e. epdoc. filter 1s not NULL), the reported length is that of the filtered document; again the length excludes the terminating nNuLL. EP_SENSE CHARS Sense characters forwards UINT ep_sense_chars (TEXT **pbuf, UINT pos, UINT n); Find the address of the character within the segmented buffer (containing the document) whose position within the document is given by the parameter pos. The method places the address of the character into an area whose address is passed in the parameter pbuf; i.e. the address of the character is set into *pbuf. In addition, it returns either the value in the parameter n or the number of characters stored contiguously at *pbuf, whichever is the smaller. As the document text is contained in a segmented buffer, the number of contiguous characters at the given position will never be greater than the maximum number of characters within a data segment. The number of contiguous characters will include the nu that terminates the document, if it happens to be in that particular segment. 2 THE FORMATTED DOCUMENT CONTENT CLASSES The following figure illustrates the situation for a non-filtered document. (previous) (next) buffer buffer buffer segment segment segment Character corresponding to to document position POS contiguous characters *PBUF If the document is filtered (i.e. epdoc. filter is not NULL), the character position, address and character count are all with respect to the filtered document. More information on segmented buffers can be found in The SGBUF Segmented Buffer Class chapter in the Olib Reference manual. EP _BACK_CHARS Sense characters backwards UINT ep_back_chars (TEXT **pbuf, UINT pos, UINT n); Find the address of a character within the segmented buffer (containing the document) which is a number of bytes in front of the character whose position is specified by the parameter pos. The method places the required address into an area whose address is passed in the parameter pbuf; i.e. the required address is set into *pbuf. In general, the required address is calculated by taking the address of the character whose position is given by pos and subtracting either the value in the parameter n or the number of contiguous characters stored in front of that character, whichever is the smaller. If the character specified by pos lies at the very beginning of a buffer, then the required address will lie in the previous buffer segment. In addition, the method returns either the value in the parameter n or the number of contiguous characters stored in front of that character, whichever is the smaller. As the document text is contained in a segmented buffer, the number of contiguous characters will never be greater than the maximum number of characters which can be fitted in a data segment. The following figure illustrates the situation for a non-filtered document where the character corresponding to document position pos lies wholly within the buffer segment. *pbuf is shown pointing to the lowest possible address in the buffer segment (a situation when n > number of contiguous characters). (previous) (next) buffer buffer buffer segment segment segment Character corresponding to document position POS t contiguous characters *PBUF (n >=no.contiguous characters) FORM REFERENCE The following figure illustrates the situation for a non-filtered document where the character corresponding to document position pos lies at the begining of the buffer segment. *pbuf is shown pointing to the lowest possible address in the previous buffer segment (a situation when n > number of contiguous characters). (previous) (next) buffer buffer buffer segment segment segment Character corresponding to document position POS contiguous characters *“PBUF (n >=no.contiguous characters) In both cases, if n < number of contiguous characters, then *pbuf will point to a position which is (number of contiguous characters - n) bytes higher than (to the right of) that shown. If the document is filtered (i.e. epdoc. filter is not NULL), the character position, address and character count are all with respect to the filtered document. More information on segmented buffers can be found in The SGBUF Segmented Buffer Class chapter in the Olib Reference manual. EP_INSERT Insert characters INT ep_insert (UINT pos, VOID *buf, UINT len); Insert characters into the (assumed unfiltered) document. The source for the characters is the buffer whose address is passed in the parameter but. The parameter len specifies the number of characters, while the parameter pos indicates the position within the document where the characters are to be inserted. If an attempt to insert the characters were to cause the size of the document to exceed its maximum permitted length (i.e. the value in the property eproot .maxlen), then no insertion would be attempted and p_leave would be called with an £_GEN_ovER error. If the document has been paginated, the character count for the page containing document position pos is incremented by 1en, so that page break positions, relative to the document text, do not move. This is achieved by incrementing the appropriate array entry in the component object epdoc. pages. Re-pagination may well be desirable after the insertion of text but is not done here. If there is insufficient memory to perform the insertion p_leave is called with an &_GEN_NOMEMoRY error. The method returns zero if the insertion is successful, and is thus suitable for being called under the protection of p_enter. EP_EXTRACT Copy characters VOID ep_extract (UINT pos, TEXT *buf, UINT len); Copy characters from the document into a buffer. The parameter pos specifies the position within the document from where copying is to start. The parameter buf points to a buffer supplied by the caller into which the characters are to be placed while the parameter 1en specifies how many characters are to be copied. The caller is responsible for supplying a buffer of sufficient length to contain the copied text. The document may be filtered or unfiltered. If it is filtered, the position and extracted characters are with respect to the filtered document. 2 THE FORMATTED DOCUMENT CONTENT CLASSES EP DELETE Delete characters VOID ep_delete(UINT posl, UINT pos2); Delete characters lying between two specified positions within the (assumed unfiltered) document. The parameter pos1 specifies the start document position while the parameter pos2 specifies the end document position. All characters starting at (and including) posi and ending at (but excluding) pos2, are to be deleted. The method deletes (pos2 - posi) characters beginning with the character at pos1 by sending a sB_DELETE message to the scpur object containing the document text. The following figure illustrates the situation; in this example, the characters in lower case are the ones which are deleted. XXxXxXxXxXxXXXXXXX pos1 pos2 Recall that the last addressable position lies immediately before the final paragraph delimiter (often referred to as the terminating nuLL); consequently, the final paragraph delimiter cannot be deleted. If the document is paginated (i.e. epdoc->pages is not NULL), the character count for the page containing position posi (and, if necessary, subsequent pages) is decremented by an amount equal to pos2-pos1. This may result in one or more pages containing zero characters. Page break positions for the remaining characters, from pos2 onwards, occur between the same characters as before. Re-pagination may well be desirable after the deletion of text but is not done here. EP CLEAR Clear the document VOID ep_clear (VOID) ; Delete the entire document content. The method deletes all of the text but leaves the terminating nuLL which marks the end of the document by sending a sB_DELETE message to the scBur object containing the text. Any existing document filter is destroyed by calling the epdoc_set_filter method, directly. EP_COMPRESS Compress allocated storage VOID ep_compress (VOID) ; Compress the allocated storage containing the document text. The text itself is held in the scpur (segmented buffer) component of zPppoc whose handle is held in the property epdoc.b. The segmented buffer is compressed by sending it a ss_comPRESS message. The buffer always contains at least one cell and guarantees sufficient space to contain, as a minimum, the document's terminating NULL. EPDOC SET PAGES Set (or clear) the page list VOID epdoc_set_pages(PR_VAFLAT *pages) ; Clear an exsiting page list and/or set a new one. The method destroys the current epdoc.pages component, if it exists, and resets the property epdoc. pages to NULL. The parameter pages is expected to be either nuLu or the handle of a variat object containing page information (as described in the section on EPpoc property) and is copied into epdoc. pages. FORM REFERENCE EPDOC_ENQ PAGE Return a page number INT epdoc_enq_page(UINT pos, UINT len); Return a page number. The parameter pos specifies a document position while the parameter 1en specifies the number of characters starting at pos. If the parameter 1en is zero, the method returns the page number of the page that contains the character at position pos; recall that page numbers start at one. If 1en is non-zero, the method returns: e the page number of the page that contains the character at pos, if there is a page break between positions pos and pos+len. e zero, if there is no page break between positions pos and pos+len. e = zero, if pos is zero The method always returns zero if there is no epdoc. pages component (i.e. the property epdoc. pages IS NULL). EPDOC_ GOTO PAGE Get position at the start of a page UINT epdoc_goto_page (UINT num); Return the document character position corresponding to the start of a given page. The parameter num specifies the page number. Page numbers always start at one. If num is zero, a value of one will be assumed. If num is greater than the maximum number of pages, the maximum value wil be assumed. The method always returns zero if there is no epdoc. pages component (i.e. the property epdoc. pages IS NULL). EPDOC SET FILTER Set (or clear) the filter list VOID epdoc_set_filter(PR_VAFLAT *filter); Clear an exsiting filter list and/or set a new one. The method destroys the current epdoc. filter component, if it exists, and sets the property to NULL. The parameter filter is expected to be either nuut or the handle of a varzat object containing filter information (as described in the Document filter section) and is copied into the property epdoc. filter. Because it is no longer valid, the current epdoc.pages component, if it exists, is also destroyed, setting its property to NULL. EPDOC POS FILTER Get unfiltered position UINT epdoc_pos_filter(UINT pos); Retrieve the unfiltered document position corresponding to a filtered document position. The parameter pos is assumed to contain the position within the filtered document. The method converts this position into the corresponding position in the unfiltered document. If no filter exists (1.e. the property epdoc. filter 1S NULL), the value in pos is returned. 2 THE FORMATTED DOCUMENT CONTENT CLASSES EPDOC call-back methods EPDoc supplies the two mandatory call-back methods required to implement the rormpoc mixin class. It does not supply the other three optional call-back methods. EPDOC_PARA_START Scan to start of paragraph VOID epdoc_para_start (UWORD *ppos) ; Find the position of the start of a paragraph. The parameter ppos points to a uworD value which specifies an (unfiltered) position within the document text; the method scans backwards to find the start of the paragraph which contains this position by sending an EP_SCAN_PaARA message (see the description of EPRoot in the Olib Reference manual). The position of the start of the paragraph is written back to *ppos. If *ppos is already at the start of a paragraph boundary, no scanning will be done. EPDOC SENSE CHARS Provide characters INT epdoc_sense_chars (SCRLAY_SENSECHARS *sense, SCRLAY_FONT **pf, UBYTE **pfw); Sense a block of up ws_MAx_PRINT_BOX_TEXT_LEN contiguous characters from the document text. The parameter sense must point to a data structure of type scRLAY_SENSECHARS. The structure, which is included as part of the scriay class definition, is as follows: typedef struct { UWORD pos; document position to sense WORD printer; TRUE for printer data, FALSE for screen data TEXT *buf; address of character block WORD blen; length of character block } SCRLAY_SENSECHARS; The value in sense->pos specifies the document position where sensing is to start. The address of the first character is written to sense->buf and the number of contiguous characters available is written to sense->blen. The content of sense->printer 1s not used by this method and its value is, therefore, irrelevant. The number of contiguous characters available will be less than or equal to ws_Max_PRINT_BOX_TEXT_LEN for reasons stated in the description of the ep_sense_chars method. The sensing is done by sending this instance of Eppoc (i.e. itself) an EP_SENSE_CHARS Message. The method always returns a value of FALSE. The parameters pf and pfw are not relevant here and can be ignored. They are included in the function prototype because this method is a special case of a more general design. In calling this method, the scriay object passes the parameters pf and pfw which, in general, the call- back method could modify in order to provide font and style information for a line segment. EPpDoc, however, does not support line segments with individual font and style information and, therefore, has no need to reference the parameters pf and pfw - which is why they can be safely ignored. For the same reason, the method always returns the value ratsz to indicate that there is no change of font or style in the characters sensed. FORM REFERENCE EPFDOC ep_set_text ep_scan_word ep_word_count ep_scan_para ep_para_count ep_scan_block ep_add_para ep_copy_indent ep_copy_to_front ep_copy_to_back ep_paste ep_mod_chars ep_sense_text EPFDOC destroy epfdoc_para_start ep_init epfdoc_sense_chars ep_sense_len ep_sense_chars ep_back_chars ep_insert ep_extract ep_delete ep_clear ep_compress ep_capacity ef_granularity ef_sense_buf The eprpoc class is, in many ways, similar to Eppoc. However, it is useful and indeed more efficient for very small documents such as those containing the text for edit boxes in dialogs. In contrast to the Eppoc class, the text is held contiguously in a single allocated cell. The methods and property provided by its superclass(es) EPpFLaAT and EpRoot are sufficient for the behaviour required of Eppoc, although the class makes use of EPpFDoc's epfdoc_para_start and epfdoc_sense_chars as the mandatory call-back methods (as required by instances of scruay). Because the class is designed for handling small amounts of text, no methods comparable to Eppoc's epdoc_set_pages method, for example, are needed. 2 THE FORMATTED DOCUMENT CONTENT CLASSES Class diagram The following class diagram shows the relationship between the document content class Eprpoc and other classes. The underlined classes are imported from o118 and they are all discussed in the OLIB Reference manual. l eproot = ) al Yk aes ¢ epflat / ) f M4 ‘. epfdoc ms a Wa Class definition The eprpoc class subclasses the OLIB class epriat and is defined in the sub-category file epdoc.cl (with generated header file epdoc.g). CLASS epfdoc epflat { ADD epfdoc_para_start=epdoc_epdoc_para_start ADD epfdoc_sense_chars=epdoc_epdoc_sense_chars } Property None. EPFDOC call-back methods EPFDOC supplies only the two mandatory call-back methods required to implement the rormpoc mixin class. It does not supply the other three optional call-back methods. EPFDOC_PARA_START Scan to start of paragraph VOID epfdoc_para_start (UWORD *ppos) ; This method is exactly the same as the epdoc_para_start call-back method discussed in the Eppoc class description. EPFDOC_SENSE CHARS Provide characters INT epfdoc_sense_chars (SCRLAY_SENSECHARS *sense, SCRLAY_FONT **pf, UBYTE **pfw); This method is exactly the same as the epdoc_sense_chars call-back method discussed in the Eppoc class CHAPTER 3 THE DOCUMENT LAYOUT CLASSES The document layout classes supply a flexible means to display formatted text. On the Series 3, the range of applications using or subclassing these classes varies from simple edit boxes to the Data, Agenda and Word applications. An application must supply an instance of a (machine-specific) window class that supplies the user interface for text editing and in which is to appear a view of the text. This edit window will create and initialise document layout class components. The Epwin edit windows class as described in the HWIM Reference manual is a good example and is included in the class diagram below. Precursors An understanding of the document layout classes will be helped by a knowledge of: e the p_enter and p_leave error handling services e =the OLIB editable document classes, EPROoT and EPFLAT e the OLIB active object class, AcTIVE Class diagram The following diagram shows the relationships between the classes involved in document layout and are discussed in detail in this chapter. The active class is imported from OLIB and is discussed in the OLIB Reference manual while Epw1n is the HWIM window class mentioned in the introduction. “~~ fo ~ Z lodger / ~ a) J /° edwin) S A art Ae y serimg / ae ) ( Settay oo / scrlay ae oe - Be ) ae a oe doe _ y wrap) ~ ) ~N _) _— FORM REFERENCE SCRLAY paras first nomemory adjust scan rd fmt doc slines spadjust l_sense 1_line_ends 1l_pos_to_xl 1_xl_to_pos 1_begin_read l_read 1_format_line I ien is the length of the document in characters, including the terminating zero byte. @ doc->content is the handle of the object that contains the text - typically an instance of (or a subclass of) EPDoc or EPFDOC. e the remaining fields specify the method numbers of call-back methods used to query the document content. Two of these methods - doc->sensechars and doc->toparst - are mandatory and are supplied by both eppoc and EPFpoc. The remaining three methods are optional. If they are not supplied, the corresponding fields of the scrLAY_Doc structure (i.e. doc->sensepdata, doc->senseplabel and doc->engpage) should be set to zero. The requirements of all five of these methods are specified in the rormpoc notional mixin class, described in The Formatted Document Classes chapter of this manual. The global layout style is specified by the parameter pstyle, a pointer to a structure of type SCRLAY_STYLE. The global layout style is the style applied to the whole document in the absence of any content-specific style supplied by the document content call-back methods. See the description of the s1_set method for a fuller discussion. Finally, the method sets the pena member of the scriay.fmt property to the highest possible value, i.e. the value Oxffff. SL_SET Set global layout style VOID sl_set (SCRLAY_STYLE *pstyle) ; Set the global layout style (i.e. the style that is applied to the whole document in the absence of any content-specific style supplied by the document content call-back methods) and reset the property scrlay.adjust to zero. The style is specified by the parameter psty1e, a pointer to a structure of type scRLAY_STYLE. The entire content of this data structure is copied into the object's scrlay.st property. The scRLAY_STYLE structure which is included as part of the scruay class definition, is as follows: typedef struct { UBYTE options; UBYTE printer; SCRLAY_PDATA pd; SCRLAY_FONT *font; UBYTE *fwtab; UWORD scrpwidth; SCRLAY_FONT *sfont; } SCRLAY_STYLE; pstyle->options contains a set of flags which control whether certain optional features are to be included. Amongst these are flags which control whether special symbols, such as paragraph ends, are to be displayed. The flags (which can be ored together) and their meaning are as follows: SCRLAY_SHOW_TABS if set, display tabs on screen SCRLAY_SHOW_SPACES if set, display spaces on screen SCRLAY_SHOW_CRS if set, show paragraph ends on screen SCRLAY_SHOW_HYPHENS if set, show all soft (potential) hyphens on screen SCRLAY_SHOW_LFS if set, show forced line breaks on screen SCRLAY_WIDOW_ORPHAN if set, enable widow and orphan suppression FORM REFERENCE The value of pstyle->printer is used to decide whether screen or printer layout is to be generated: ¢ TRUE generates printer layout ¢ FALSE generates screen layout The pstyle->pa structure specifies global values for paragraph margins, tab positions and spacing. The three pointers pstyle->pd.margins, pstyle->pd.tabs and pstyle->pd. spacing must point to data structures of type SCRLAY_MARGINS, SCRLAY_TABS and scRLAY_SPACING respectively. These data structures must remain in existence while being referenced by an instance of scruay. Typically, this is for the lifetime of the scriay object and it is common for the three data structures to form part of the property of the creator of the scriay object. The global settings can be overriden for any individual paragraph by content-specific paragraph layout specified by the optional call-back method whose method number can be found in the document content information, i.e scrlay.doc->sensepdata The three pointers may be set to nuut if all of the corresponding paragraph layout is content-specific. Each of pstyle->font and pstyle->sfont contain pointers to scRLAY_FonT data structures that respectively specify the global printer font and the corresponding global screen font. If pst yle->printer is FALSE, both pointers may indicate the global screen font. The global settings can be overriden for any individual line segment by means of the scrlay.doc->sensechars Call-back method. If pstyle->printer iS TRUE, pstyle->fwtab must contain a pointer to a global printer font width table. This only needs to be set in printer layout mode. The global setting can be overriden for any individual line segment by means of the scrlay.doc->sensechars Call-back method. The content of pst yle->scrpwidth is relevant only when generating printer layout, that is, when pstyle->printer is TRUE. In this case it defines the basis for the accurate on-screen representation of printer tab positions. SL_SENSE Sense global layout style VOID sl_sense(SCRLAY_STYLE *pstyle); Sense the global layout style, i.e. the style that is applied to the whole document in the absence of any content-specific style supplied by the document content call-back methods. The global layout style data is written to a data structure of type scRLAY_STYLE pointed to by the parameter pstyle and supplied by the caller. DESTROY Destroy VOID destroy (VOID) ; Destroy the instance. The method destroys the instance by sending an sit_p1scarp message to free all memory used by the layout model before supersending a DEsTRoy message. SL_POS_TO_XL Convert position to line number and pixel offset INT sl_pos_to_x1l(SCRLAY_PLX *p1x); Convert a character position within a document to the corresponding line number on the screen and the horizontal pixel offset of that character position within the line. A data structure of type scrLAy_pLx pointed to by the parameter p1x is supplied by the caller; p1x->pos contains the character position. The corresponding line number is written to p1x->1line and the corresponding horizontal pixel offset of that character within the line is written to p1x->x. If the character position is on the screen, the method returns 0. If the character position is above the screen, the method writes a value of -30000 to p1x->1ine and returns -1. 3 THE DOCUMENT LAYOUT CLASSES If the character position is below the screen or beyond the end of the document, the method writes a value of +30000 to p1x->1ine and returns +1. This method is used by the screen image class scrime, and is not normally accessed directly by users of FORM. SL_XL_TO_POS Convert line number and pixel offset to position VOID sl_xl_to_pos (SCRLAY_PLX *p1x); Convert a screen line number and the horizontal pixel offset within that line to the nearest matching character position within a document and then adjust the screen line number and the horizontal pixel offset to match the character position exactly. A data structure of type scRLAY_PLx pointed to by the parameter p1x is supplied by the caller; p1x->1ine contains the screen line number and p1x->x the horizontal pixel offset within that line. The nearest matching character position is written to p1x->pos while the updated line number and the horizontal pixel offset are written back to p1x->line and p1x->x respectively, overwriting the supplied values . This method is only intended to be called with a line number in the range 0 to nlines-1, where nlines is the number of lines of text that can be displayed on the screen. This method is used by the screen image class scrime, and is not normally accessed directly by users of FORM. SL_LINE_ENDS Get horizontal pixel offsets of start & end of line INT sl_line_ends(INT line,WORD *xb,WORD *xe); Determine the horizontal pixel offsets of the start and the end of a line whose number is passed in the parameter line. Provided xb is not Nutt, the horizontal pixel offset of the start of the line is written to the word pointed to by xb and, again, provided xe is not nut, the horizontal pixel offset of the end of the the line is written to the word pointed to by xe. Note, to be absolutely precise about definitions, the value for the end of the line gives the offset of the first pixel beyond the end of the line. In other words, the first pixel is inside the line while the last pixel is outside the line. The method returns true if successful. If the line is not within the currently generated layout, the method writes nothing to *xb and *xe and returns FALSE. This method is used by the screen image class scrime, and is not normally accessed directly by users of FORM. SL_BEGIN READ Prepare to read line data VOID sl_begin_read(INT line); Prepare for one or more following sit_READ messages, to read data from the line specified by the parameter line. The method prepares the read context information held in the property scriay.rd ready for subsequent SL_READ messages. Note, if the line lies outside the currently generated layout, the first subsequent s__REaD message will do nothing but return FALSE. This method is used by the screen image class scrime, and is not expected to be accessed directly by users of FORM. FORM REFERENCE SL_READ Read line data INT sl_read(SCRLAY_READ *pr, TEXT *buf); Read a line or part of a line from the currently generated layout and write information about it to a structure of type scRLAY_READ pointed by the parameter *pr. The first call to this method will have been preceded by a call to the s1_begin_read method to identify the line. If the parameter buf is not NULL, up to WS_MAX_PRINT_BOX_TEXT_LEN bytes of text are written to the buffer pointed to by buf. The actual number of bytes of text read by this method can be found in pr->blen. When the method reads the first tbox in the line, its sets pr->isfirst to TRUE and sets the appropriate value into pr->indent, otherwise pr->isfirst is set to FALSE and pr->indent is set to zero. Similarly, when the last text box in the line is read, pr->islast is set to TRUE. If there is more data to read, the method returns TRuE, otherwise it returns FALSE. This method is used by the screen image class scrimce, and is not expected to be accessed directly by users of FORM. SL_FORMAT_LINE Format the next line INT sl_format_line(UWORD *ppos) ; Format the next line using the document text belonging to the document object whose handle can be found in the property scrlay.doc. The status of the current format position is maintained in the property scrlay.fmt. Provided ppos is not nu, the character position at the start of this next line is written to the uworp pointed to by ppos. The method returns True if there are more lines to format, otherwise it returns FALSE. This method is used by the screen image class scrime, and is not expected to be accessed directly by users of FORM. SL_SCROLL Scroll the layout INT sl_scroll(INT dl); Scroll the screen layout by the number of lines specified by the parameter a1. If a1 > 0 then the data moves down the screen, possibly generating additional layout for previous paragraphs and deleting layout for complete paragraphs which are now "below" the screen. If a1 < 0 then the data moves up the screen, possibly generating additional layout for following paragraphs and deleting layout for complete paragraphs which are now "above" the screen. This method should only be called when the absolute value of a1 is Jess than the number of lines displayed on the screen. The method returns the actual number of lines by which the screen has scrolled (as limited by the bounds of the document). Note that the return value is signed; a value > 0 for the number of lines scrolled down the screen and a value < 0 for the number of lines scrolled up the screen. This method is used by the screen image class scrimce, and is not expected to be accessed directly by users of FORM. SL_VIEW View position on given line INT sl_view(UINT pos, INT line); Generate layout for sufficient paragraphs to enable document position pos to appear on the specified screen line. The screen layout may be scrolled if the position is already on the screen; new layout will be generated as required. Returns either the number of lines to scroll, or ox7££+4 if the screen should be completely redrawn. This method is used by the screen image class scrime, and is not expected to be accessed directly by users of FORM. 3 THE DOCUMENT LAYOUT CLASSES SL_DISCARD_LAYOUT Discard layout VOID sl_discard_layout (UINT doclen); Set new document length and discard the whole layout. If the parameter docien is non-zero, then this is the new document length to be recorded. This value is set into the property scrlay.doc.1en. If docien is zero, the existing document length is not to be changed and scrlay.doc.len remains unaltered. All currently generated layout is discarded by freeing all data items in the list anchored in the property scrlay.paras. This method is used by the screen image class scrime, and is not expected to be accessed directly by users of FORM. SL_RESCALE Adjust screen/printer scaling INT sl_rescale (VOID) ; Adjust the screen/printer scaling. If the property scrlay.adjust iS FALSE, indicating no change to the width of the screen/printer, then the method does nothing but returns raLse. If the property scrlay.adjust 1S TRUE, indicating a change to the width of the screen: e = The existing layout is discarded and the document length is left unchanged. e = The layout is re-built so that the document position defined by first .pos will appear on the line defined by first .1ine. e The method returns TRUE. This method is used to rescale the screen layout as necessary to ensure that printer tab positions are displayed accurately, despite differences between the screen and printer fonts. It is called by the screen image class scrim, and is not expected to be accessed directly by users of FORM. SL_SET_LINES Set number of lines VOID sl_set_lines (INT slines); Set the number of displayable lines in the layout to the value in the parameter slines. The method simply takes the value in the parameter s1ines and sets it into the property scriay.slines. This method is used by the screen image class scrime, and is not expected to be accessed directly by users of FORM. SL_PARA_CHANGED Discard lines from position INT sl_para_changed(INT code, SCRLAY_PLX *plx, WORD *lgood) ; Discard one or more lines of layout as a result of the change in the document content specified by the parameter code at document position p1x->pos. The change may be a left delete of one character (code is W_KEY_DELETE_LEFT) a right delete of one character (code 1S W_KEY_DELETE_RIGHT) or the insertion of a single content character, for which code is one of : e a printable character code e zero (paragraph end) @ W_KEY_TAB e ‘\n The value of code is used to infer the new document length. FORM REFERENCE In preparation for a following sequence of calls to scrlay_s1_format_line, the method updates plx->line to the line number of the first line that needs to be reformatted and sets p1x->pos to the character position at the start of this line. The line number of the first following line that does not need to be reformatted is written to the word pointed to by the parameter 1good. Returns True if a paragraph end was deleted, otherwise returns FaLsE. This method is used by the screen image class scrime, and is not expected to be accessed directly by users of FORM. WRAP scrimg priority isactive pcb stat destroy ao_init ao_init ao_queue ao_cancel ao_run ao_abrun ao_queue ao_run An instance of the wrap active object class is created and initialised by scrime, which uses it to reformat lines of text in background. Background formatting is restarted (from the scrIMG si_para_changed method) each time a key is pressed to insert or delete a character, but the reformatted text is only redrawn when such formatting runs to completion. This means that the response to keypresses is not degraded by the whole of the affected text being redrawn for each keypress. The expectation is that wrap will not be subclassed, and that it will only be used by scrime. Class definition wrap subclasses the OLIB class active and is defined in the sub-category file scrimg.cl (with generated header file scrimg.g). CLASS wrap active { REPLACE ao_init REPLACE ao_queue REPLACE ao_run PROPERTY { VOID *scrimg; } } Property wrap.scrimg The handle of the owning instance of the scrime class. 3 THE DOCUMENT LAYOUT CLASSES WRAP methods AO_INIT Initialise VOID ao_init (VOID *scrimg) ; Initialise this instance of wrap. The method takes one parameter; scrimg contains the handle of the instance of the scrime class which has created this wrap object. The method does the following: e Sets the handle of the creating instance of the scrime class into the property wrap.scrimg. e Adds the wrap object to the active object task queue with a priority of PRIORITY_ACTIVE_COMPUTE. This is a low priority so that the it will only run if there are no higher priority tasks ready to run. AO_QUEUE Queue a line format request VOID ao_queue (VOID) ; If the wrap object is not currently active, it supersends an ao_QuEUE message to queue a request to format a line. AO_RUN Format a line INT ao_run(VOID) ; Re-format a line. The method limits itself to re-formatting a single line. If there are more lines to be formatted, an ao_QuzUE message is sent to schedule the re-format of the next line. By doing this, the wrap object allows other (higher priority) active objects to run. Once formatting has finished, all reformatted lines are re-drawn and no further ao_QUEUE messages are sent. SCRIMG SCRIMG wrap select lay formatting win isredraw anc GCcreated crs emphasised oldcrs plabchange txwidth nopan mrwidth flags xleft lfmt xright lgood lcowidth xO lcline gc updownx destroy si_move_cursor si_init si_redraw si_set si_doc_changed si_sense si_doc_reset si_emphasize si_para_changed si_get_select si_style_changed si_pan si_delprep Si_isorol], si_fwd_change si_view FORM REFERENCE The scrime class provides the means of displaying formatted, editable text in a window. The class provides methods that manipulate the screen display including methods to perform scrolling and re-drawing. scRimcG works in close co-operation with an instance of the scriay class, which formats the text that SCRIMG Is to display. Although scrime relies on the presence of a document content object - generally an instance of (a subclass of) EPDoc or EPFDoc - it has no direct knowledge whatsoever about the nature or interpretation of the document content that is being displayed. In particular, scrrmc has no concept that the whole of the document may be already divided up into lines - lines for scrrmc mean nothing more than lines within the screen area that scrime draws to. In illustration of this point, it is worth noting that in the Word application, formatting information - including the locations of line breaks - only exists for the portion of the document that is displayed on the screen. Formatting information for other regions of the document is discarded as soon as it is no longer required for display purposes. The area drawn to by scrim is divided into three vertical regions: e an optional label margin e an optional line cursor region e an area for formatted text; this includes the text cursor This division of the drawing area is illustrated in the figure shown after the description of the property, below. The Series 3a built-in word processor provides a good illustration of this. Setting the "Show style bar" option in the "Set preferences" menu item of the "Special" menu to ves shows the word processor window divided into the three vertical regions. Class definition The scrime class subclasses root and is defined in the sub-category file scrimg.cl (with generated header file scrimg.g). CLASS scrimg root { REPLACE destroy Remove any text cursor ADD si_init Optional set then builds layout ADD si_set Set win and layout ADD si_sense Sense win setup data ADD si_emphasize Set emphasis on/off ADD si_get_select Return selection as pos,len ADD si_pan Horizontally scroll the image by pixels ADD si_scroll Scroll the image by lines ADD si_view Show pos on specified line ADD si_move_cursor Set the cursor position ADD si_redraw Draw to given rectangle ADD si_doc_changed Discard layout, cancel select and redraw ADD si_doc_reset Discard layout, cancel select, view and redraw ADD si_para_changed Background reformat of para from cursor pos ADD si_style_changed Re-evaluate layout ADD si_delprep Prepare for a left delete ADD si_fwd_change Like si_doc_changed except pivot from screen top CONSTANTS { ! si_move_cursor actions SCRIMG_LINEDN 0x00 SCRIMG_LINEUP Ox01 SCRIMG_PAGEDN 0x02 SCRIMG_PAGEUP 0x03 SCRIMG_LINBEG 0x04 SCRIMG_LINEND 0x05 SCRIMG_SETPOS 0x06 3 THE DOCUMENT LAYOUT CLASSES ! States for background formatting SCRI MG_FORMAT_DELETE_LEFT 1 SCRI MG_FORMAT_DELETE_RIGHT 2 SCRI ! si_pan horizontal scroll | SETNOPAN | DELTA | ABS SCRI SCRI SCRI MG_PAN MG_PAN MG_PAN MG_FORMAT_TYPING 3 (panning) modes 0 1 2 ! si_style_changed qualifiers SCRIMG_STCHNG_DOC 0 Reformat whole document SCRIMG_STCHNG_PARA nl Reformat from paragraph SCRIMG_STCHNG_LINE 2 Reformat from previous line SCRIMG_FLAGS_PAGEBREAK 0x01 SCRIMG_FLAGS_S3_COMPAT 0x02 } TYPES { typedef st { UWORD P_POIN WORD n UBYTE UBYTE WOR WORD m WORD 1 UBYTE UBYTE UBYTE UBYTE UBYTE UBYTE } SCRI D w PROPERTY 1 { PR_WRAP *w PR_SCRLAY SCRIMG_WIN SCRLAY_PLX SCRLAY_PLX SCRLAY_PLX WORD txwid WORD mrwid WORD xleft WORD xrigh UBYTE lcwi UBYTE lcli WORD updow UBYTE R R R R R R sele ruct wid; T tl; lines; lheight; lascent; idth; argin; cfont; cwidth; lestyle; 1lccode; hscrlx; hscrlm; drawplabs; MG_WIN; rap; *lay; win; anc; ens; oldcrs; th; th; , t; dth; ne; nx; (oh ee UBYTE UBYTE UBYTE UBYTE UBYTE UBYTE UBYTE WORD WORD WORD G_GC } formatting; isredraw; GCcreated; emphasised; plabchange; nopan; flags; lfmt; lgood; xO; gc; window ID top left corner of area being drawn to number of text lines to display line height in pixels distance from top of line to text base line total width in pixels (margin,line cursor,text) width of label margin in pixels line cursor font (or zero for no line cursor) text cursor width line cursor style line cursor character code horizontal scroll x jump horizontal scroll margin draw trailing para labels after formatting if set background word wrap active object the document screen layout describes the window to be drawn to select anchor position text cursor position old text cursor position width of text area in pixels width of margin plus line cursor left clip margin right clip margin width of line cursor area current line for line cursor latent x for cursor up/down movement TRUE if TRUE if TRUE if TRUE if TRUE if TRUE if don't pan to expose cursor if TRUE SCRIMG_FLAGS_PAGEBREAK, SCRIMG_FLAGS_S3_COMPAT Next line to be replaced by background format there is a selection backgound formatting performing a redraw a temp GC has been created emphasis is on para labels may have changed First line not requiring to be formatted x postion of left of layout for horiz scroll current graphics context FORM REFERENCE Property scrimg.wrap scrimg.lay scrimg.win scrimg.anc scrimg.crs scrimg.oldcrs scrimg.txwidth scrimg.mrwidth scrimg.xleft scrimg.xright scrimg.lcwidth scrimg.lcline scrimg.updownx scrimg.select scrimg.formatting scrimg.isredraw scrimg.GCcreated scrimg.emphasised scrimg.plabchange scrimg.nopan The handle of a background word-wrapping active object, expected to be an instance of wrap. This object is created and owned by scrime. The handle of an instance (or a subclass) of scruay. This instance is created by the creator of scrime and its handle passed as a parameter to the si_init or si_set methods. A data structure of type scrIMG_wINn containing information on the window within which the document content is displayed. The data structure is created by the creator of scrimc and its handle passed as a parameter to the si_init OF si_set methods. The anchor position for a select region, that is, a region of of highlighted text, stored as a character offset from the start of the document and as a screen line number and x-offset in that line. The current position of the text cursor, stored as a character offset from the start of the document and as a screen line number and screen x-offset in that line. A copy of a previous cursor position, described in terms of both a document and a screen position, as for scrimg.crs. This property is used by the si_move_cursor and si_scroll methods. The width, in pixels, of the text area. This is set by the si_set method and is calculated as the width of the drawing region minus the combined width of the label margin and the line cursor region. The sum of the widths, in pixels, of the label margin and the line cursor region. This is calculated and set by the si_set method. This defines the left hand horizontal pixel position for clipping. This defines the right hand horizontal pixel position for clipping. In general terms, those parts of a rectangle which extend outside a region bounded by scrimg.xleft and scrimg.xright, are clipped. The width, in pixels, of the line cursor region. This is set by the si_set method and is calculated as the sum of the width of the line cursor character plus two (pixels). The number of the line on the screen containing the line cursor The "latent" horizontal pixel offset of the text cursor. It records the default horizontal pixel position to which the cursor is moved during vertical scrolling and cursor movement operations. For example, when the text cursor is moved up one line, it defines where on that line the cursor should be placed. This property can be changed by a number of methods. Set to Truz if there is currently a select region. Set to TRuE if background formatting is in progress. Set to TRuE if redrawing is in progress. Set to TRuE if a temporary graphics context exists. Set to TRuE if the window containing the drawing area has the emphasis. This is set and unset by the si_emphasize method. Set to TRuE if paragraph labels have (or might have) changed. Set to rruE if horizontal scrolling is disabled; while this is set, horizontal scrolling is prevented - in particular, during attempts to make the cursor visible. 3 THE DOCUMENT LAYOUT CLASSES scrimg.flags This property contains a number of flags which can be a combination of the following: SCRIMG_FLAGS_PAGEBREAK _If set, at least one pagebreak line has been drawn on the screen during the lifetime of the SCRIMG Object. Once set, it is never unset. SCRIMG_FLAGS_S3_COMPAT If set, the Series 3a is running in Series 3 compatibility mode. scrimg.lfmt The number of the next line on the screen to be formatted when background formatting. scrimg.lgood After a character has been inserted or deleted, a number of lines may need reformatting; this is done in background. This property will contain the number of the first following line on the screen that does not require reformatting. scrimg.xo The horizontal pixel position of the left hand edge of the text relative to the window. This is set initially by the si_set method to be co-incident with the left hand edge of the text area. (i.e the horizontal pixel position of the drawing region plus the width of the label margin plus the width of the line cursor region). As the text is scrolled horizontally, the position of the left hand edge of the text moves; this property is changed accordingly to reflect the new position of the left hand edge of the text which may or may not be visible. This value can be negative. This is graphically illustrated in the figure below scrimg.ge The current graphics context. The following diagram illustrates the meaning of some of the property items discussed above. It shows a typical situation where the drawing area contains a label margin, a line cursor region and a text area. The dotted lines represent lines of text which are shown as having been scrolled. Text which is "outside" the text area is not visible. All the measurements depicted are in units of | pixel. SCREEN DRAWING AREA label line cursor| text area margin region scrimg.xo —_ 1cfont is non-zero), the method calculates the width of the line cursor region and sets the value into the property scrimg.1lcwidth. e The width of the line cursor region plus the label margin is calculated and set into the property scrimg.mrwidth. e =6The horizontal pixel position of the text area is calculated and set into the property scrimg.xo. e The width of the text area is calculated and set into the property scrimg.txwidth. 3 THE DOCUMENT LAYOUT CLASSES An SL_SET_LINES message is sent to the screen layout object, passing the value of win.nlines so that it knows the maximum number of text lines that are to be displayed on the screen. SCRIMG_wIn which is included as part of the scrime class definition, is as follows: typedef struct { UWORD wid; P_POINT tl; WORD nlines; UBYTE lheight; UBYTE lascent; WORD width; WORD margin; WORD lcfont; UBYTE cwidth; UBYTE lcstyle; UBYTE lccode; UBYTE hscrlx; UBYTE hscrlm; UBYTE drawplabs; } SCRIMG_WIN; The win->wid element specifies the window ID (as returned by a call to wcreat eWindow) of the window to which drawing is done. This will normally relate to the window object that creates and initialises the SCRIMG object. The area within this window within which scrime draws is defined by: e the coordinates of its top-left hand corner, given by win->t1.x and win->tl.y e the total width, in win->width e the total height, calculated from the number of lines, win->nlines, multiplied by the line height, win->lheight. These, and all other dimensions in the scrimc_wtn struct, are specified in pixels. The line height will normally be the height of the screen font in which the text is displayed, plus one or two pixels of additional space, known as leading. The base line for drawing characters within a line of text is defined by win->1ascent, which will normally be equal to the ascent of the screen font plus the leading. This is illustrated below. More information on fonts can be found in the section on Text output functions in the Window Server Reference manual. Line Of Text Vv (top leading) scrimg.win.lascent } neighrouions ascent of font t baseline descent of font y scrimg.win.lheight (bottom leading) In addition to the text region, the drawing area may contain a label margin and a line cursor margin, as described earlier in this chapter. The width of the label margin, used to display paragraph labels, is specified by win->margin. Labels will only be drawn if win->drawplabs 1S TRUE (in this case scriay will need to be supplied with a senseplabel call-back method). If win->drawplabs iS FALSE, win->margin may be zero and a senseplabel call-back method need not be specified. FORM REFERENCE A line cursor will be displayed in the line cursor margin if win->1cfont is non-zero. Its value should be the font ID of the screen font that contains the line cursor character. The character code of the line cursor character itself, is supplied in win->1ccode. The required line cursor style attribute, for example BOLD, is specified by win->1cstyle. A text cursor will be displayed in the text area if win->cwidth is non-zero. Its value should be the required width of the text cursor, normally one or two pixels. Automatic horizontal scrolling of text within the text area, provided lines of text are longer than the width of the text area, is controlled by win->hscrix and win->hscrim. The value of win->hscrix specifies the unit of horizontal scrolling motion (a unit being some number of pixels). The document will scroll, if necessary, when the text cursor reaches the right hand edge of the text area or when the text cursor moves to within win->hscr1m pixels of the left hand edge of that area. A call to si_set, other than one that precedes a call to si_init or the one that is made by si_init itself, should be followed by a call to si_doc_changed to force the layout to be rebuilt and the content to be redrawn. The method returns the width, in pixels, of the text area. Note that this method offers a simple way of waiting for the completion of background formatting, by calling it with both parameters set to NULL. SI_ SENSE Sense window information VOID si_sense(SCRIMG_WIN *win); Write a copy of scrime's window information data structure, as contained in the property scrimg.win, to the location pointed to by the parameter win; this is expected to point to a structure of type scRIMG_wIN supplied by the caller of the method. SI_EMPHASIZE Set emphasis on or off VOID si_emphasize(INT on); Turn emphasis on or off. The method takes a single parameter; on has the value TRUE or FALSE. When the window containing the drawing area has the emphasis, this is indicated by setting the property scrimg.emphasised tO TRUE. If the parameter on has the value TRuz, the method indicates that the emphasis is on by setting the property scrimg.emphasised to TRUE. If the parameter on has the value rasz, the method indicates that the emphasis is off by setting the property scrimg.emphasised to FALSE. Repeated calls with the same value of on do nothing. This method is often called from the wn_emphasis method of an instance of the wrn class (or more likely, a subclass of wr). Turning the emphasis off causes the text cursor to be removed and the highlight of any selected text to be removed. Turning the emphasis on causes the text cursor to be drawn and any selected text to be highlighted. SI_GET_ SELECT Get select region UINT si_get_select (UWORD *ppos) ; Write, to *ppos, the document position of the first character (the character nearest to the beginning of the document) of the select region. This will be either the anchor position or the cursor position, depending on the direction in which the selection was made. The method returns the length of the select region. If there is no select region, the current cursor position is written to *ppos and the method returns zero. 3 THE DOCUMENT LAYOUT CLASSES SI_PAN Scroll the image horizontally VOID si_pan(INT func, INT par); Scroll the image horizontally after any background formatting is completed. This method has three modes of operation depending on the value of the parameter func. The interpretation of the parameter par depends on the mode of operation. func can take one of the following values: SCRIMG_PAN_SETNOPAN The method either disables or enables horizontal scrolling depending on the value of par. If par has the value truz, horizontal scrolling is disabled; a value of ratsz enables horizontal scrolling. The value of par is set into the property scrimg.nopan SCRIMG_PAN_DELTA Scroll the image horizontally by par pixels. par may be negative or positive. If par is positive, the image is scrolled to the left by par pixels; if negative, the image is scrolled to the right by par pixels. SCRIMG_PAN_ABS Scroll the image such that the position par is at the left of the view. The scroll is limited to reasonable limits. Scrolling past the right hand end of the longest visible line is prevented. SI_SCROLL Scroll the image vertically INT si_scroll(INT dl); Scroll the image vertically by the number of lines specified by the parameter a1. The direction of scroll depends on the sign of a1. If positive (i.e. a1>0), the image moves down, bringing in new paragraphs from above; if negative (i.e. dl<0), the image moves up, bringing in new paragraphs from below. The method should only be called when the absolute value of ai is Jess than the number of lines displayed on the screen. After any background formatting is complete, a sL_scRoLL message is sent to the scrzay object to scroll the screen layout by a1 lines. The s1_scro11 method returns the number of lines actually scrolled and this value is used to update: e the number of the line on which the cursor is displayed (a component of scrimg.crs) e the line number for any previous text cursor (a component of scrimg.oldcrs) e the line number of the anchor position for any select region (a component of scrimg.anc) The screen display itself is scrolled by the number of lines returned by the s1_scro11 method, i.e. the number of lines by which the screen layout was scrolled. Note that the amount scrolled is limited by the bounds of the document. The method returns the actual number of lines scrolled, positive if scrolled down or negative if scrolled up. SIL VIEW Show position on given line VOID si_view(UINT pos, INT line); Draw a view of the document such that, subject to limitations imposed by the bounds of the document, document position pos is on screen line number line. Any background formatting is allowed to complete first. A st_v1iEw message to the scriay object to arrange the screen layout to satisfy this request. If the document position is already on the screen, the screen display is scrolled, otherwise it is completely re-built. FORM REFERENCE SI_MOVE_CURSOR Set the cursor position INT si_move_cursor(INT select, INT type, UWORD *ppos); Set the cursor position. Any background formatting is allowed to complete first. The movement of the cursor is controlled by the value of the parameter type which can take one of the following values: SCRIMG_SETPOS The cursor is moved to the document position specified by the value pointed to by the parameter ppos. If the position is already visible, no scrolling or re-building of the screen display is done. If the position is "above" the current display, the screen content is scrolled or re-built so that the line containing the specified position lies at the top of the screen. If the position is "below" the current display, the screen content is scrolled or re-built so that the line containing the specified position lies at the bottom of the screen. SCRIMG_LINEDN The cursor is moved down by one line. If the resulting line is "below" the current display, the screen content is scrolled or re-built so that this line lies at the bottom of the screen. The horizontal pixel position of the cursor is set to the latent value as recorded iN scrimg.updownx. However, if the cursor was already on the last displayable line, it will be positioned at the end of the line. SCRIMG_LINEUP The cursor is moved up by one line. If the resulting line is "above" the current display, the screen content is scrolled or re-built so that this line lies at the top of the screen. The horizontal pixel position of the cursor is set to the latent value as recorded iN scrimg.updownx. However, if the cursor was already on the first displayable line, it will be positioned at the beginning of the line. SCRIMG_PAGEDN The cursor is moved down by a number of lines equal to the number of lines displayed in the text area minus one. If the resulting line is "below" the current display, the screen content is scrolled or re-built so that this line lies at the bottom of the screen. The horizontal pixel position of the cursor is set to the latent value as recorded iN scrimg.updownx. However, if the cursor was already on the last displayable line, it will be positioned at the end of the line. SCRIMG_PAGEUP The cursor position is moved up by a number of lines equal to the number of lines displayed in the text area minus one. If the resulting line is "above" the current display, the screen content is scrolled or re-built so that this line lies at the top of the screen. The horizontal pixel position of the cursor is set to the latent value as recorded In scrimg.updownx. However, if the cursor was already on the first displayable line, it will be positioned at the beginning of the line. SCRIMG_LINBEG The cursor is moved to the beginning of the line on which it is currently positioned. The horizontal pixel offset of the text cursor is taken as the new "latent" value and is recorded in the property scrimg.updownx. SCRIMG_LINEND The cursor is moved to the end of the line on which it is currently positioned. The horizontal pixel offset of the text cursor is taken as the new "latent" value and is recorded in the property scrimg.updownx. 3 THE DOCUMENT LAYOUT CLASSES The new document position is written to *ppos. The select region is modified if the parameter select is TRUE, otherwise any selection is cancelled and the method returns Fase. If there is a selected region after the movement of the cursor, the method returns TRuE. S|_REDRAW Draw to given rectangle VOID si_redraw(P_RECT *prect) ; Redraw the region specified by the rectangle whose address is given by the parameter prect. The method assumes that a temporary or permanent graphics context has already been set up. The graphics context is frequently modified by calls to gsetec during drawing. The method may be called: e from within a redraw performed in response to a window server wM_REDRAW message. Such a message may be ignored by a window with a backup bitmap. e from code that draws directly to the view. If prect is nuuL the whole window is redrawn, otherwise those lines that intersect with the rectangle specified by prect are redrawn. If the specified rectangle does not intersect with the window, no re-drawing is done. Any background formatting is allowed to complete before any re-drawing is attempted. While re-drawing is in progress, the property scrimg.isredraw is set to TRUE; this is re-set to FALSE when re-drawing is complete. On the Series 3, and on other machines when running in Series 3 compatibility mode, prect is ignored, and the whole display area is always redrawn, but a value (uu if necessary) should always be supplied for prect. SI_DOC_RESET Discard screen layout, view and redraw VOID si_doc_reset (UINT doclen, UINT pos, INT line); Cancel any existing select region and discard any current layout. Rebuild the screen layout as necessary and redraw the view subject to the limitations imposed by the bounds of the document. The parameter docien should contain the new length of the document (which should include the terminating nuu1); this may be zero if the length is unchanged. The view is rebuilt such that document position pos is visible on the screen on line number 1ine. The value of 1ine may be -1, in which case document position pos should, if possible, be displayed on the screen line currently containing the cursor. This method is intended to be used to when a new document has replaced the original one; typically, it is used after the application has opened or created a new document. The method is also used if there has been a sufficiently large change to the document content to justify re-building the view from first principles. SI_DOC_ CHANGED Discard screen layout and redraw VOID si_doc_changed(UINT doclen) ; Cancel any existing select region and discard any current layout. Rebuild the screen layout as necessary and redraw the view subject to the limitations imposed by the bounds of the document. The parameter docien should contain the new length of the document (which should include the terminating nuL1); this may be zero if the length is unchanged. The view is rebuilt such that whatever character now occupies the current cursor position appears on the same screen line as the current cursor. FORM REFERENCE The method is intended to be used if there has been a sufficiently large change to the document content to justify re-building the view from first principles. This method is almost identical to si_doc_reset except that it does not allow the document position and line number to be changed. SI_DELPREP Prepare for a left delete VOID si_delprep(SCRLAY_PLX *old); Provide useful performance-enhancing information before performing a left delete. This method is ususally called prior to calling the si_para_changed method with a w_kEY_DELETE_LEFT character code (see later for a description of this method). The parameter o1d must point to a scRLAY_PLx type data structure. The method writes the document position of the character which is to the left of the current cursor to old->pos and writes the corresponding screen position to old->x and old->1ine. If this position is off-screen or not on same line as the cursor, a value of -1 is written to old->line. SI_PARA_CHANGED Draw paragraph to echo content change VOID si_para_changed(INT code, SCRLAY_PLX *old); Immediately echo the content change, indicated by the parameter code, to the screen display and then reformat and redraw in background. Any selected region is cancelled. The change indicated by code may be a left delete of one character (where code has the value W_KEY_DELETE_LEFT), a right delete of one character (where code has the value W_KEY_DELETE_RIGHT) or the insertion of a single content character, for which code is one of : e aprintable character code e zero (paragraph end) @ W_KEY_TAB e '\n' The parameter 01d is only relevant when code has the value w_KEY_DELETE_LEFT; it should point to a SCRLAY_PLx type data structure and should contain the document position and corresponding screen position of the character which is to the left of the current cursor (as returned by the method si_deiprep). If code has any value other than w_KEY_DELETE_LEFT, old can be set to NULL. This method supplies responsiveness to the most common keyboard operations used when editing a document. SI_STYLE_CHANGED Redraw to echo a style change VOID si_style_changed (INT type); Rebuild the screen layout and redraw one or more lines as appropriate, following a style change. The current cursor position and any select region are maintained and, in general, the cursor remains on the same line of the screen. The value of the parameter type specifies the nature of the change and can be one of the following values: SCRIMG_STCHNG_DOC A style change has occurred that potentially affects the whole document. The screen layout is rebuilt and the whole display redrawn. A typical use would be following a change in the base font used for the document SCRIMG_STCHNG_PARA __ A style change has occurred in the paragraph containing the cursor or the range of paragraphs that contain the select region, and affecting only that paragraph or paragraph range. The screen layout is rebuilt, from the start of the first paragraph in the range (excluding paragraphs that are entirely invisible) and the display is redrawn as appropriate. A typical use would be following a change in the margin positions of a single paragraph. 3 THE DOCUMENT LAYOUT CLASSES SCRIMG_STCHNG_LINE A style change has occurred in the line containing the cursor or the range of lines that contain a select region. The screen layout is rebuilt, from the beginning of the line before that in which the change starts, and the display is redrawn as appropriate. A typical use would be following a change in emphasis of one or more words. Note that on the Series 3 the whole view is redrawn in all cases, regardless of the value of type. S|I_FWD_CHANGE _ Redraw for changes beyond cursor position VOID si_fwd_change(UINT doclen) ; Redraw the screen forward of the current cursor position and record a new document length. The parameter docien should contain the new length of the document (which should include the terminating nuu1); this may be zero if the length is unchanged. Any existing select region is cancelled. The existing screen layout is discarded and re-built afresh such that the character originally on the first line of the screen and occupying the first position on that line, retains that position. All lines from:- the line above that which contains the cursor to:- the last line are redrawn; in effect, the top of the screen is frozen while those lines from the cursor downwards are redrawn. This method may be used following any change to the document content that does not affect the content before the current cursor position. CHAPTER 4 THE DOCUMENT PRINTING CLASSES The document printing classes are a set of classes which, co-operatively, permit documents to be printed, previewed and paginated. While this is true for the Series 3a, previewing is not available on the Series 3. The PRINTER class is the main interface to an application. It acts as a high level manager, being also a repository of useful information such as the printer model number, port characteristics and so on. The actual process of printing is delegated to the pacEs active class which, amongst other duties, handles pagination, builds the command sequences specific to individual printers and schedules the printing process. paces itself uses the services of other Form and o11B classes to achieve this behaviour. Information about specific printer models is held in a WDR printer resource file which can be access by an instance of the wor class. A PRINTER object always contains a woR component object. Precursors An understanding of the document printing classes will be helped by a knowledge of: e the description of WDR printing and .wdr files in the WDR Printing chapter of the Additional System Information manual e the Printing chapter of the Object Oriented Programming Guide e =the Document Layout Classes chapter of this manual e the Formatted Document Content Classes chapter of this manual e the OLIB active object class, AcTIVE e the OLIB variable array classes, vase and VAFLAT e the p_enter and p_leave error handling services FORM REFERENCE Class diagram The following diagram covers the relationships between the classes involved in document printing and are discussed in detail in this chapter. The underlined classes are either discussed in another chapter of this manual or they refer to OLIB classes in which case they are all discussed in the OLIB Reference manual. — se Pee scrlay » / active / 7, PEE? SS ) a — wdr c Pay NS ) see nn eo 2 / J y i 7 rscfile / AS ) UU oe oe Measurement units In addition to the standard inches and centimetres, this chapter will often refer to other measurement units which are in common use. These are as follows: point - defined as 1/72 of an inch; this gives 72 points per inch. twip - defined as 1/1440th of an inch; this gives 1440 twips per inch and, therefore, 20 twips per point. printer units - defined as the minimum distance of travel in both horizontal and vertical directions, normally defined in twips. The units are dependent on the printer model. See the description of the wor class for more detail. PRINTER PRINTER wdr defbottxt a Pp port_type deftoptxt destroy pr_init pr_store_srchar pr_store_file pr_set_port_type pr_set_model pr_port_data pr_sense_port pr_sense_model pr_get_params pr_set_hd pr_get_hd pr_open_wdr pr_close_wdr pr_open_port pr_print pr_paginate pr_preview_start pr_preview pr_preview_end pr_preview_data 4 THE DOCUMENT PRINTING CLASSES The print manager class provides an interface to an application for printing, paginating and print preview operations; it acts as a repository of information required to successfully execute an operation and provides the methods for setting and sensing this information. Note that print previewing is not available on the Series 3. All references to previewing apply to the Series 3a only. The class also supplies methods to launch a printing, paginating or previewing operation. An instance of the PRINTER class can be used for a single operation and then be destroyed, or it can be used for multiple operations. A second printing, paginating or previewing operation may be configured in a completely different fashion from the first. The printing, previewing or paginating process itself is delegated to an instance of the paczs active class; on completion of the process, the paczs class destroys itself. The PRINTER class also provides default values for page dimensions and the positioning of header and footer text which are set up at initialisation time. This information is required by the paczs class. PRINTER, however, provides no methods to change these values; if they are not suitable, then the PRINTER class must be subclassed to provide the required behaviour. The following configuration parameters can be set and sensed: e = The text of headers and footers. e The type of port to which printing is to be directed, (i.e. serial or parallel) or whether printing is to be directed to a file or to fax. On the Series 3, printing cannot be directed to fax. e The characteristics of the serial port. e The name of the file, if printing is directed to a file. e The printer resource filename (i.e. the WDR resource file name) and the model number of the printer to be used for the next printing operation. Class definition The PRINTER class subclasses root and is defined in the sub-category file printer.cl (with generated header file printer.g). CLASS printer root { REPLACE destroy Free alloc cells ADD pr_init Set default values ADD pr_store_srchar Store the serial characteristics ADD pr_store_file Store the spec of the print file ADD pr_set_port_type Set/store printer port type ADD pr_set_model Set/store wdr file & model number ADD pr_port_data Sense printer port data ADD pr_sense_port Sense printer port data of current port type ADD pr_sense_model Sense wdr file & model number ADD pr_get_params Get address of params struct for read/write ADD pr_set_hd Set top or bottom header text ADD pr_get_hd Return address of top or bottom header text ADD pr_open_wdr Create and init wdr object ADD pr_close_wdr Destroy wdr component (to save memory) ADD pr_open_port Open print port device ADD pr_print Print data source ADD pr_paginate Paginate data source ADD pr_preview_start Start preview (i.e. allocate resources) ADD pr_preview Preview data source ADD pr_preview_end End preview (i.e. destory any resources) ADD pr_preview_data Return pointer to preview data FORM REFERENCE CONSTANTS INTER_PORT_PARALLEL INTER_PORT_SERIAL INTER_PORT_FILE INTER_PORT_FAX INTER_PORT_NOT_SET INTER_HDR_TOP INTER_HDR_BOT INTER_PAGINATE INTER_PRINTING INTER_PREVIEW PRV_SEG_GRANULARITY } TYPES { typedef struct { TEXT *model; TEXT *hdtxt [2]; } PRINTER_ALLOC; typedef struct { SCRLAY_FONT f; awnr oOo Bb 16 paragraphs (256) (power of 2 is ideal) WDR filename and model number Header text Font data for body area text UBYTE size_choice; Paper size index (A4 is zero) UBYTE wo_control; TRUE to disable widows and orphans control UWORD spare[2]; Might be useful in future PRINTER_DATA; typedef struct PAGES_PARAMS p; PRINTER_DATA d; PRINTER_PARAMS,; typedef struct UBYTE *pSegName; PR_ROOT *pArray; UPOINT PrvSize; UWORD BitWidth; VOID *hPrvDone; WORD mPrvDone; } PREVIEW_INIT; typedef struct { HANDLE SegHandle; PR_ROOT *pArray; UPOINT Size; UWORD BitWidth; VOID *hPrvDone; WORD mPrvDone; } PREVIEW_DATA; PROPERTY 1 { PR_WDR *wdr; PRINTER_ALLOC a; WORD TEXT TEXT PRINTER_PARAMS p; PREVIEW_DATA prv; } Parameters for init of pages object Used externally used width of bitmap, use this for scaling Call-back handle for %done & completion Call-back method for %done & completion Handle of preview data segment Size of bitmap (pixels) used width of bitmap, use this for scaling Call-back handle for %done & completion Call-back method for %done & completion Printer driver Addresses of allocated cells port_type; Port type deftoptxt[3]; Default header text (top) defbottxt[3]; Default header text (bottom) Property printer printer printer printer printer printer. printer. .wdr 7a -port_type -deftoptxt -defbottxt pry 4 THE DOCUMENT PRINTING CLASSES The handle of the current printer resource object, i.e. the handle of an instance of wor. The wor object is created by the pr_open_wdr method. A data structure of type PRINTER_ALLOc containing three TExT pointers. Each pointer can contain the address of a single cell of allocated storage as follows: printer.a.model if not NULL, points to an allocated cell containing the model number and the filename of the printer resource (i.e. the wor name) as a zero terminated string. The first byte of the string holds the model number as a numeric character while subsequent bytes hold the zero terminated filename. printer.a.hdtxt[0] if not NULL, points to an allocated cell containing the top header text to be used. printer.a.hdtxt[1] if not NULL, points to an allocated cell containing the bottom header text to be used. This contains a value which indicates whether printer output is to be directed to the serial port, the parallel port, fax or to a file. It can take one of the values: PRINTER_PORT_PARALLEL PRINTER_PORT_SERIAL PRINTER_PORT_FAX PRINTER_PORT_FILE The default top header text. This property contains the zero terminated string "%F" and is the text used if top header text has not been explicitly set using the pr_set_hd method. The default bottom header text. This property contains the zero terminated string "%P" and is the text used if bottom header text has not been explicitly set using the pr_set_hd method. This is configuration information consisting of items which can be set and sensed and items such as page dimensions which cannot be altered. Preview parameters. These are set by the pR_PREVIEW_START method and are re-set by the pR_PREVIEW_END method. Note that the four methods pr_preview_start, pr_preview, pr_preview_end and pr_preview_data and the property printer.prv are not available on the Series 3 Environment variables The print manager makes use of a number of environment variables in which to store some of its information. When setting configuration information, the environment variables will be created if they do not already exist. If, when sensing configuration information, the appropriate variable does not exist, default values will be returned. The variable names and their meaning are as follows: P$D P$F P$S P$M - a zero terminated character string containing the type of port; the type is held as a numeric character. - a zero terminated character string containing the name of the file to which printing is to be directed. This file is referred to as the print file. the characteristics of the serial port held as a p_srcuar data structure. - a zero terminated character string containing the printer model number as a numeric character followed by the wor file name (i.e. the printer resource file name). FORM REFERENCE PRINTER methods DESTROY Destroy the print manager VOID destroy (VOID) ; Destroy the instance of the print manager. A copy of the address of the instance of the print manager is normally kept in a spare property of the application manager, appman. spare1; this method resets this property to NULL. The property printer.a 1S a PRINTER_ALLOoc data structure which contains three data members each of which may contain the handle of an allocated cell. If storage has been allocated, it is freed. The method supersends a pEstRoy message to complete the destruction process. PR_INIT Initialise printer & set default values VOID pr_init (VOID); Initialise the print manager and set default values for the page dimensions and the positioning of header and footer text. A copy of the address of this instance of the print manager is set into a spare property of the application manager, appman.spare1. This is done for convenience and gives other objects (such as instances of ppr) quick and easy access to this instance of PRINTER. Default values are also set for the printer port type and both the header and footer text. On the Series 3, there is a slight difference to the behaviour of this method. See the Series 3a/Series 3 notes section at the end of this chapter for detail. PR_STORE_SRCHAR Set serial port characteristics VOID pr_store_srchar(P_SRCHAR *psc) ; Set the characteristics of the serial port. The parameter psc points to a data structure of type p_sRcHar which defines the characteristics of the serial port. The method copies the entire content of the data structure pointed to by psc into the environment variable pss. The environment variable is created if it does not exist. The structure p_sRcuar is defined in p_serial.h but is shown below for completeness: typedef struct UBYTE tbaud; /* transmit Baud rate selector */ UBYTE rbaud; /* receive Baud rate selector */ UBYTE frame; /* number of data, parity and stop bits */ UBYTE parity; /* parity selector */ UBYTE hand; /* handshake flags */ UBYTE xon; /* XON character */ UBYTE xoff; /* XOFF character */ UBYTE flags; /* ignore parity errors/dont drive DTR changing chars */ ULONG tmask; /* terminator mask */ } P_SRCHAR; PR_STORE_FILE Set print file specification VOID pr_store_file(TEXT *file); Set the file specification of the file to which printing is to be directed. This file is often referred to as the print file. The parameter file points to a character string which contains the (zero terminated) specification of the file to which printing is to be directed. The method copies this string into the environment variable psr which is created if it does not already exist. If printing is directed to a file and the file specification is not set, then m:\p.L1s will be assumed as default. 4 THE DOCUMENT PRINTING CLASSES PR_SET PORT_TYPE Set type of printer port VOID pr_set_port_type(INT store, INT port_type); Set the type of the printer port. The value passed in the parameter port_type specifies the type of the printer port. This can be one of the following values: PRINTER_PORT_PARALLEL PRINTER_PORT_SERIAL PRINTER_PORT_FILE PRINTER_PORT_FAX The printer port type is set into either the property printer.port_type or the environment variable psp, not in both. If the parameter store contains the value Truz, the port type is set into the environment variable otherwise it is set into the property. Whichever location is chosen, the printer port type is held as a numeric character. PR_SET MODEL Set printer model no. & WDR file name VOID pr_set_model (INT store, TEXT *name, INT mnum); Set the printer resource file name (i.e. the WDR resource file name) and the printer model number. The parameter name should point to a zero terminated string containing the printer resource file name; the value in the parameter mnum should contain the printer model number. A character string is generated such that the first byte contains the model number as a numeric character; the zero terminated printer resource file name occupies the rest of the string. A cell of sufficient length is allocated to hold this string and its handle is stored in the property printer.a.model. If the value of the parameter store is TRUE, the string is also copied into the environment variable psm. PR_PORT_DATA Sense printer port information INT pr_port_data(TEXT *file, P_SRCHAR *ser, INT UseModel); Retrieve information about the printer port. The method returns the printer port type and retrieves the serial port characteristics and the name of the print file. The parameter ser should point to a data structure of type p_srcuar. If the environment variable pss can be read, the serial port characteristics are copied from that variable into this p_srcHar data structure; otherwise, default values are inserted. The default values are as follows: ser->tbaud P_BAUD_9600 ser->rbaud P_BAUD_9600 ser->frame P_DATA_8 ser->parity 0) ser—->hand P_OBEY_XOFF | P_OBEY_DSR | P_IGN_CTS ser->xoff 0x13 ser->xon Ox1l ser—>flags 0 ser->tmask 0 FORM REFERENCE For more information on the serial port, see the Serial Port chapter of the I/O Devices Reference manual. The parameter file should point to a text buffer. If the environment variable psr exists, the name of the print file is copied from that variable into the buffer; otherwise, the default print file name p..1s is copied instead. The printer port type returned depends on a number of factors and is determined as follows: e if the parameter useModel contains the value TRuE and the first three characters of the fully parsed printer resource file name (i.e. the WDR resource file name) are "FAX", the method returns the printer port type PRINTER_PORT_FAX. e if the property printer.port_type contains a valid printer port type, then this value is returned. e if the environment variable psp contains a value, this value is returned. e if the printer port type cannot be determined by any of the above, a value of PRINTER_PORT_PARALLEL is assumed by default. The effect of the useMode1 parameter can be neatly summarised: e if it has the value ratsz, the printer port information retrieved is that set by the user of the PRINTER Object (in an earlier call to the pr_set_port_type method). e if it has the value TRuz, it allows the method to return printer port information other than that set by the user. The best example of this is where the printer resource file name begins with the three characters F A X. In this case, regardless of the value set in the property printer.port_type or the environment variable psp, the printer port type returned is PRINTER_PORT_FAX. On the Series 3, there is a slight difference to the behaviour of this method. See the Series 3a/Series 3 notes section at the end of this chapter for detail. PR_SENSE PORT Sense current printer port device information INT pr_sense_port (TEXT *buf, P_SRCHAR *ser); Retrieve information about the current printer port device. The method returns the printer port type and retrieves the (zero terminated) name of the current printer port device; if the printer port type is PRINTER_PORT_SERIAL, the method retrieves the serial port characteristics. The parameter buf should point to a buffer into which the zero terminated name of the current printer port device will be placed. The name written to *buf depends on the port type as follows: PRINTER_PORT_FILE - the name of the file PRINTER_PORT_SERIAL - the serial device name PRINTER_PORT_PARALLEL - the parallel device name On the Series 3 and Series 3a, which only have one port, the serial and parallel device names will always be try:a and par:a respectively. On machines with more than one port, such as the Workabout, the port letter will be read from the relevant environment variable, if it exists: e = The serial port letter will be read from the first character of the environment variable pssp, if it exists. Thus, if the first character in this environment variable is 'B' the serial device name will be set to rry:s. If the environment variable doe not exist, the serial device name defaults to TTY:A. e The parallel port letter will be read from the first character of the environment variable pspp, if it exists. Thus, if the first character in this environment variable is 'C' the parallel device name will be set to par:c. If the environment variable doe not exist, the parallel device name defaults to PAR:A. These environment variables are not created by system code. It is an application's responsibility to create them if they are needed and do not already exist. The parameter ser should point to a data structure of type p_srcuar. If the printer port type is PRINTER_PORT_SERIAL, a copy of the serial port characteristics will be written to *ser. 4-8 4 THE DOCUMENT PRINTING CLASSES PR_SENSE MODEL Sense printer model no. & WDR file name INT pr_sense_model (TEXT *buf); Retrieve the fully parsed printer resource file name (i.e. the WDR resource file name) and return the model number. The parameter buf should point to a buffer into which the method can insert the zero terminated printer resource file name. The buffer itself must be capable of holding a fully parsed file name and, therefore, must be at least p_rNames1ze bytes long. The model number and the printer resource file name are held as a character string in an allocated cell pointed to by the property printer.a.modei and/or in the environment variable psm. The model number itself is held in the form of a numeric character and precedes the file name in the string. This information is retrieved from the property, if it exists, otherwise it is retrieved from the environment variable. By default, if the information exists in neither location, a value of 0 is returned for the model number and a printer resource file name of Rom: :BJ.wDR 1s written to *buf. A check is made to ensure that the printer resource file exists. If the file cannot be found, all of the Loc: : drives are searched. If this search is unsuccessful, the rom: : is searched. If, finally, the file has still not been found, then the printer resource file name of Rom: :BJ.wDR is assumed together with a model number of zero. On the Series 3, there is a slight difference to the behaviour of this method. See the Series 3a/Series 3 notes section at the end of this chapter for detail. PR_GET_PARAMS Fetch address of printer parameters PRINTER_PARAMS *pr_get_params (VOID); Return the address of the pRINTER object property printer.p. This property is a data structure of type PRINTER_PARams and contains information required by the pacEs object at its initialisation. As discussed earlier, this is printer configuration information, page dimension information and so on. See the class definition for more detailed information on pRINTER_PARaMs. It may also be useful to refer to the paces class definition. PR_SET_HD Set top or bottom header text VOID pr_set_hd(INT htype, TEXT *str); Set either the top or the bottom header text. The parameter str should be either nuut or point to a buffer containing the zero terminated text to be set. The value of the parameter ht ype indicates whether the text is to be set for the top or the bottom header. Both top and bottom header text are held in cells of allocated storage; the handles of both cells are held in printer.a.hdtxt[0] and printer.a.hdtxt [1] respectively. If ht ype contains the value PRINTER_HDR_TOP, any existing top header text is discarded by freeing the existing cell. If str is not NULL, a new cell is allocated large enough to contain the new text and its handle is stored in the property printer.a.hdtxt [0]; the text is copied into the new cell from *str. If str is NULL, any existing top header text is discarded and printer.a.hdtxt [0] is set to nuLL. The effect will be to cause the default top header text, as found in the property printer.deftoptxt, to be used. Similarly, if ntype contains the value PRINTER_HDR_BOT, any existing bottom header text is discarded by freeing the existing cell. If str is not NULL, a new cell is allocated large enough to contain the new text and its handle is stored in the property printer.a.hdtxt [1]; the text is copied into the new cell from *str. If str is NULL, any existing bottom header text is discarded and printer.a.hdtxt [1] 1S set to NULL. The effect will be to cause the default bottom header text, as found in the property printer.defbottxt, to be used. FORM REFERENCE PR_GET_HD Get address of top or bottom header text TEXT *pr_get_hd(INT htype) ; Return the current address of either the top or the bottom header text. The value of the parameter ht ype determines whether the address returned is that of the top or the bottom header text; a value of PRINTER_HDR_ToP causes the address of the top header text to be returned while a value of PRINTER_HDR_BOT Causes the address of the bottom header text to be returned. If the top header text has been set, the address of the cell containing this text is returned, otherwise the address of the default text is returned. This also applies to the bottom header text. A note of caution - if the method pr_set_ha 1s called after a call to pr_get_ha, the address of any header text may be invalid. PR_OPEN_WDR Create WDR object PR_WDR *pr_open_wdr (VOID) ; Create and initialise a new wor (printer resource) object and return its handle. Any existing wor object is destroyed by calling the pr_close_wdr method before attempting to create the new one. The new wor object is initialised by sending it a woR_INIT message and passing it both the current model number and the printer resource file name. The pr_sense_mode1 method is used to determine the current model number and the printer resource file name. The handle of the new wor object is set into the property printer.war. The model number set in the wor object may be changed at any time by sending the object a WDR_SET_MODEL message; however, if a different printer resource file name is needed, the existing wor object must be destroyed and a new one created, passing it the new file name. Note that this method is called by the pr_print and pr_paginate methods. PR_CLOSE_WDR Destroy WDR object VOID pr_close_wdr (VOID) ; Destroy the current printer resource (wor) object, if it exists. The wor object is destroyed by sending it a pestroy message. The property printer.wdr containing the handle of the object is re-set to NULL. PR_OPEN_PORT Open printer port device VOID *pr_open_port (VOID); Open the printer port device. The name of the printer port device, the printer port type and the serial characteristics (if the port type is PRINTER_PORT_SERIAL) are retrieved by calling the pr_sense_port method. The printer port device is opened by calling the Plib function £_open, passing it the retrieved device name. If the port type is PRINTER_PORT_SERIAL then p_iow Is called to set the serial port characteristics. The method returns the handle of the opened port (i.e. the address of the channel control block). 4 THE DOCUMENT PRINTING CLASSES PR_PRINT Print data source PR_PAGES *pr_print (PAGES_CALLS *pc)j; Launch the printing of the current data source and return the handle of the paczs object created to do the printing. The parameter pc must point to a data structure of type pacrs_catus. The caller of this method must set the call-back methods needed to handle read and done messages, into the pacEs_caLLs data structure. See the description of the pacgs class and the pacEzay notional mixin class in this chapter for more information. PAGES_CALLS can be found in the paczs class definition but is shown below for completeness: typedef struct { VOID *hread; Call-back handle for reading a line WORD mread; Call-back method for reading a line VOID *hdone; Call-back handle for %done & completion WORD mdone; Call-back method for %Sdone & completion } PAGES_CALLS; If the printer resource (wor) object does not exist, it is created by calling the pr_open_wdr method. The method creates a paces object to do the printing and initialises it by sending an ao_InIT message. The pacgs object requires information which consists of a copy of PRINTER'S property printer.p.p (a PAGES_PaRams data structure), a fully completed paczs_1ntrT data structure and an indication that it is to perform a printing operation. The information in the paces_1nit data structure includes a copy of the paczs_cauts data structure whose address is given in the parameter pc, the handle of the wor object, the addresses of both the top and bottom header text and the address of the buffer containing the name of the current data source. The pacers object destroys itself on completion of printing or if an error occurs. On the Series 3, there is a slight difference to the behaviour of this method. See the Series 3a/Series 3 notes section at the end of this chapter for detail. PR_PAGINATE Paginate data source PR_PAGES *pr_paginate(PAGES_ CALLS *pc)j; Launch the pagination of the current data source and return the handle of the paces object created to do the pagination. The parameter pc must point to a data structure of type pacrs_catts. The caller of this method must set the call-back methods needed to handle read and done messages, into the pacEs_caLus data structure. See the description of the pacgs class and the pacezay notional mixin class in this chapter for more information. PAGES_CALLs can be found in the paczs class definition (or see the description of pr_print earlier). If the printer resource (wor) object does not exist, it is created by calling the pr_open_wdr method. The method creates a paczs object to do the pagination and initialises it by sending an ao_INIT message. The paces object requires information which consists of a copy of PRINTER'S property printer.p.p (a PAGES_PaRAms data structure), a partially completed pacrs_intT data structure and an indication that it is to perform a pagination operation. The information required in the pacrs_1ntT data structure includes a copy of the paczs_cauts data structure and the handle of the wor object. The paces object destroys itself on completion of pagination or if an error occurs. FORM REFERENCE PR_PREVIEW_START Initialise preview HANDLE pr_preview_start (PREVIEW_INIT *pInit); Perform initialisation for previewing a data source. The parameter ptnit should point to a data structure of type PREVIEW_INIT containing the information required by preview. This structure, shown below, is defined in the class definition: typedef struct { UBYTE *pSegName; PR_ROOT *pArray; UPOINT PrvSize; UWORD BitWidth; used width of bitmap, use this for scaling VOID *hPrvDone; Call-back handle for %done & completion WORD mPrvDone; Call-back method for %Sdone & completion } PREVIEW_INIT; The members have the following meaning: pSegName The address of a buffer containing the name to be given to the external data segment. pArray The handle of a varnat array object which will be used to hold a series of values giving the position of consecutive compressed bitmaps within the preview data segment. It is designed to hold entries (records) which are the length of a tone 'C' data type and has a granularity of 16 entries (records). PrvSize The dimensions of the bitmap, in pixels, to which a page will be drawn. The x component is the value of Bitwidth rounded up so that it occupies an integral number of bytes. The y component is normally determined by the height of the application's window. BitWidth The number of horizontal bits needed to draw a single line so that it fits into the application's window and the ratio of this value to the height of the page measured in pixels will be the same as the ratio of the width to the height of the page measured in twips. Note that this value will not necessarily be exactly the same as that in PrvSize.x above. This item will be used by the prvppr class to calculate a rounding factor for its internal calculations hPrvDone The handle of the object which will provide the done callback method. mP rvDone The method number of the done callback method. For the general specification of this method, see the pagelay_mdone method in the description of the pacELay mixin class in this chapter. The exact method for calculating the values of prvsize and Bitwidth depends on the application. The following sequence shows how a typical application might proceed. However, it should only be used as a guideline: e Determine the space available to display a previewed page; in other words, determine the number of horizontal and vertical pixels available and set prvsize.y to the number of vertical pixels. e Ifin landscape mode, calculate Bitwidth to be the result of: page height (in twips) / page width (in twips) * vertical pixels available. e If in portait mode, calculate Bitwidth to be the result of: page width (in twips) / page height (in twips) * vertical pixels available. 4 THE DOCUMENT PRINTING CLASSES e Check that the resulting value of Bitwidth will fit into the number of horizontal pixels available. If it does not fit, re-set Bitwidth to the available number of horizontal pixels and adjust the value of PrvSize.y to maintain proportions: if in landscape mode, set prvsize.y to: page width (in twips) / page height (in twips) * horizontal pixels available. if in portrait mode, set prvsize.y to: page height (in twips) / page width (in twips) * horizontal pixels available. e =6Set prvsize.x to the value of Bitwidth rounded up to a multiple of eight, in other words, ensure that the number of bits represented will fit into an integral number of bytes. The method creates a dynamic external data segment; the name to be applied to the segment is supplied in a buffer pointed to by prnit->pSegName. Recall that an external data segment is one that is not constrained to the 64K limit but can extend to 512k, provided sufficient memory is available. Although the segment is initially created with a zero length, p_leave is called if the allocation fails. The handle of the successfully created external segment is set into the segdandie member of the property printer.prv. The size of the external segment is adjusted to pRv_SEG_GRANULARITY paragraphs. If the adjustment fails (e.g. E_GEN_NoMEMoRyY), the method pr_preview_end is called to free any acquired resources and is followed by a call to p_leave. All the remaining initialisation information supplied by *ptnit is copied into the property printer.prv. It is worth noting that an instance of prvppr (the print preview class) requests the address of the printer.prv property during its initialisation by sending a pR_PREVIEW_DATA message to this instance of PRINTER. The pr_preview_data method is described later. The method returns the handle of the dynamic external data segment. PR_PREVIEW Perform preview PR_PAGES *pr_preview (PAGES CALLS *pc)j; Launch the preview process of the current data source and return the handle of the paczs object created to do the previewing. The parameter pc must point to a data structure of type pacrs_catts. The caller of this method must set the call-back methods needed to handle read and done messages, into the pacEs_caLus data structure. See the description of the pacgs class and the pacEzay notional mixin class in this chapter for more information. PAGES_CALLS can be found in the paczs class definition (or see the description of pr_print earlier). If the printer driver (wor) object does not exist, it is created by calling the pr_open_wdr method. The method creates a paces object to perform the previewing and initialises it by sending an ao_INIT message. The paces object requires information which consists of a copy of PRINTER'S property printer.p.p (a PAGES_PaRams data structure), a fully completed paczs_1ntT data structure and an indication that it is to perform a previewing operation. The information in the paczs_1nit data structure includes a copy of the paczs_cauts data structure whose address is given in the parameter pc, the handle of the wor object, the addresses of both the top and bottom header text and the address of the buffer containing the name of the current data source. The pacers object destroys itself on completion of the previewing operation or if an error occurs. PR_PREVIEW_END Terminate preview VOID pr_preview_end (VOID); Terminate preview and free any acquired resources. The method frees the allocated external data segment using the Plib function p_sgclose and then indicates the end of preview by resetting the whole of property printer.prv to binary zero. FORM REFERENCE PR_PREVIEW_DATA Return handle of preview data PREVIEW_DATA *pr_preview_data (VOID); Return the handle of the preview data. This method returns the address of the PRINTER object's printer.prv property which contains information required by the preview operation. The content of printer.prv is set by the pr_preview_start method. PAGES q pagarr page priority todo reset_page isactive ephead newdoc pcb prhead started stat pdr newpage in region par holding last_pos pos flags pr pheight tabs brk_height spacing brk_above margins brk_pos time y date ioclen destroy ao_init ao_run aorinit ao_queue ao_abrun ao_cancel A paces object handles a request to print, paginate or preview one or more documents on behalf of an instance of the PRINTER class and is created when the application sends a PpR_PRINT, PR_PAGINATE OF PR_PREVIEW message to the PRINTER object. The pr_print, pr_paginate and pr_preview methods create a PAGES object as part of their implementation. PaGEs itself is a low priority active object; this allows the printing, previewing or pagination process to be done in discrete chunks, giving other active objects (and, therefore, other applications) the opportunity to run concurrently. In general, knowledge of the document to be printed, in terms of the text itself, the typefaces, fonts (i.e. height) and styles to be used, lies within other object(s) in the application. In order to print a document, the paczs object must ask the application for the next portion of text to be printed; this is normally represented by a data structure of type woR_PRINT, often referred to as a print element. The pacEs object must also keep the application informed of the current status of the printing operation. paces achieves this by means of callback methods. PAGES itself uses the services of an instance of the ppr (printer driver) class to translate a print element into a sequence of commands suitable for a specific printer. When performing a preview operation, the PpR object represents a specialised printer driver. When paginating, pacrs does no printing, instead it uses the print elements to build pagination information. Page breaks and the printing of headers and footers are done automatically by pacgs. Class definition 4 THE DOCUMENT PRINTING CLASSES The paczs class subclasses the OLIB class active and is defined in the sub-category file pages.cl (with generated header file pages.g). CLASS pages active { REPLACE ao_init REPLACE ao_run REPLACE ao_abrun REPLACE ao_queue CONSTANTS { PAGES_DONE_PAGE PAGES_DONE_DOC PAGES_DONE_END PAGES_DONE_ERROR WNrR O PAGES_DOC_NEW_PAGE PAGES_DOC_RESET_PAGE_NUM PAGES_FLAGS_PRINTING PAGES_FLAGS_NOTFIRST PAGES_FLAGS_ZERODOWN PAGES_REGION_BODY PAGES_REGION_TOP PAGES_REGION_BOTTOM PAGES_REGION_LAST_BOTTOM PAGES_REGION_END PAGES_REGION_VERY_END PAGES_REGION_DOC_END PAGES_PAGENUM_ARABIC PAGES_PAGENUM_ROMAN_U PAGES_PAGENUM_ROMAN_L PAGES_HEADER_2_COLUMNS PAGES_HEADER_3_COLUMNS } TYPES { typedef struct { UWORD x; UWORD y; } UPOINT; typedef struct { UPOINT t1; UWORD width; UWORD height; } UEXTENT; typedef struct { WORD event; UWORD page; PR_VAFLAT *pages; } PAGES_DONE; typedef struct { SCRLAY_FONT f; UBYTE align; UBYTE first_page; } PAGES_HEADER; A new doc resets the page number (on top of 1st page) 0x01 A new doc starts a new page 0x02 0x01 Printing (or previewing) 0x02 Discard down when FALSE 0x04 Discard lst down in todo list if TRUE 0 1 2 3 4 5 6 0 el 2 SCRLAY_ALIGN_JUSTIFY+1 SCRLAY_ALIGN_JUSTIFY+2 PAGES_DONE_PAGE, _DOC, END Page number of new page Page length array Font data Header alignment TRUE to emit on first page FORM REFERENCE typedef struct { UWORD width; Width of page UWORD height; Height of page UEXTENT body; Body area UWORD hdtop; body.tl.y-hdtop = Y of top of top header UWORD hdbot; body.tl.yt+tbody-.height+thdbot=height = Y of top of bottom header } PAGES_PAGE; typedef struct { WORD offset; Offset for page number WORD last; Last page number for %m WORD style; Style for page } PAGES_PAGENUM; typedef struct { PAGES_PAGE pg; Page dimensions with margins WORD pdrflags; WDR_PDR_LANDSCAPE, _DRAFT etc WORD docflags; PAGES_DOC_NEW_PAGE is set for new page per doc UWORD pgbeg; Page number to start printing (lst page is 1) UWORD pgend; Last page number to print (inclusive) PAGES_HEADER top; Top running header PAGES_HEADER bot; Bottom running header PAGES_PAGENUM pgnum; Page number for %p } PAGES_PARAMS; typedef struct { VOID *hread; Call-back handle for reading a line WORD mread; Call-back method for reading a line VOID *hdone; Call-back handle for %done & completion WORD mdone; Call-back method for %Sdone & completion } PAGES_CALLS; typedef struct { PR_WDR *wdr; Printer driver PAGES_CALLS oc; Call-backs TEXT *fname; File name for %f (ZTS) or NULL TEXT *toptxt; Top running header ZTS or NULL TEXT *bottxt; Bottom running header ZTS or NULL } PAGES_INIT; PROPERTY 5 } Property pages.pagarr pages.todo { PR_VAFLAT *pagarr; PR_VASEG *todo; PR_EPFDOC *ephead; PR_PRNLAY *prhead; PR_PDR *pdr; PAGES_INIT in; PAGES_PARAMS par; WORD last_pos; UWORD flags; WORD pheight; WORD brk_height; WORD brk_above; UWORD brk_pos; WORD y; WORD nrec; UWORD page; UBYTE reset_page; UBYTE newdoc; UBYTE started; UBYTE newpage; WORD region; WORD holding; UWORD pos; WDR_PRINT pr; SCRLAY_TABS tabs; SCRLAY_SPACING spacing; 4 THE DOCUMENT PRINTING CLASSES Page break array being built Pending print output Text for top/bottom header Layout for top/bottom header Output printer driver Init parameters User settable init parameters Pos of last page break Printing or paginating lst page etc Height of processed lines on current page Height of last line break At last line break Document pos at last page break Current page y Record number in todo list Page Number Reset page number on next footer if TRUE TRUE if there is another doc TRUE if printing has really started TRUE if pagination decided on a new page PAGES_REGION_TOP, BODY or_BOTTOM TRUE if holding data in todo list Document pos Being printed Header tab settings Header spacing SCRLAY_MARGINS margins; Header margins TEXT time [LN_TIME_DATE_STR]; TEXT date [LN_TIME_TIME_STR-2]; UWORD ioclen; } The handle of an instance of the variat class. The array of uworp elements contains pagination information where each entry contains a count of the number of characters fitting into a page. The entries are in page order. The handle of an instance of the vaszc class. The array of woR_pRiNtT data structures contains a queue of print elements to be dealt with. Queuing print elements is a convenient way of deferring printing. This is important when lines which must be kept together are being processed; in these circumstances it is not possible to know in advance whether a page pages.ephead pages.prhead pages.pdr break will occur after the lines are printed or whether a page break will need to be forced before the first line is printed (with the consequent need to print bottom and top header text first). N.B. This queue is also referred to as the todo list. The handle of an instance of the Eprpoc class, used to encapsulate the text of a top or bottom header. The handle of an instance of the prniay class, used to encapsulate the layout of a top or bottom header. The handle of the printer driver object. This is an instance of the ppr class and is created by the ao_init method. FORM REFERENCE pages.in pages.par pages.last_pos pages.flags pages.pheight pages.brk_height Initialisation information, derived from the application, and passed to the PAGES Object at initialisation time in a call to its ao_init method; this includes: e the handle of the printer resource (wor) object e the call-back information e when printing and previewing, the addresses of buffers containing the file name of the current data source, the top header text and the bottom header text. Initialisation information, set up internally by the pRInTER object, and passed to the paczs object at initialisation time in a call to its ac_init method. See the description of the ao_init method. The document position of the previous page break. This is used during pagination; in particular, during the process of generating entries for the pages array whose handle is contained in the property pages. pagarr. This is a general flag area; the following values can be ored into this property in combination: PAGES_FLAGS_PRINTING _ If set, paces has been created to perform a printing or previewing operation; if not set, paczs has been created to perform a paginating operation. PAGES_FLAGS_zERODOWN This flag is only set when a page break occurs. If set, any spacing above the first line of the next page is suppressed (by setting pages.pr.down to zero). At the top of a page, any spacing above a line is redundant. PAGES_FLAGS_NOTFIRST This flag is set after the first line on the first page of the first document has been processed. Once set, it remains set for the life of the pacEs object. Tf not set: e any page break before the first page of the first document is suppressed. e¢ any spacing above the first line of the first page of the first document is suppressed (by setting pages.pr.down to zero). At the top of a page, any spacing above a line is redundant. This is used during pagination. It is the cumulative height, in printer units, of the lines on the current page which have already been processed. In effect, it measures the current height of the current page (from the top of the page). This is used during pagination. It is a candidate page break position, measured in printer units. In effect, it measures the height of the candidate page (from the top of the page to the break point). The value in this property represents a potential (but legal) page break position. It is important when lines of text which must be kept together are being processed. Until all of the lines in such a group have been processed, it cannot be known in advance whether a page break can occur after the group or whether it must be forced before this group. In the latter case, this property will become the actual height of the page. pages. pages pages. pages pages pages. pages pages. pages. pages. brk_above -brk_pos -nrec -page reset_page -newdoc started newpage region 4 THE DOCUMENT PRINTING CLASSES This is used during pagination. It has a function which is closely related to that of the property pages.brk_height discussed above. It is the space above the first line element following the candidate page break position. The space above a line element is often referred to as the down value; this is used to define a gap between consecutive lines such as occurs between the last and first lines of consecutive paragraphs. Following on from the discussion of pages.brk_height above; where a group of lines must be kept together and are forced onto a new page, the down value of the first line will be set to zero, to avoid unnecessary blank space appearing at the top of the page, when printed. The cumulative page height for the new page is adjusted to take this change into account. The position within the document corresponding to the previous page break. The current vertical print position on the current page, measured in printer units. The position is measured relative to the top of the page. The current record number in the todo list; i.e. the current entry in the array of woR_PRINT records, anchored in the property pages.todo. The current page number. This property can take the value TRUE or FALSE. It is set to TRUE if the page number on the next footer is to be reset (to zero). This property can take the value TRUE or FALSE. It is set to TRUE if, on completion of processing a document, another document is to be processed. Set by the ao_run method but the decision is taken by the pacEs done callback method. This property can take the value TRUE or FALSE. It is set to TRUE if printing has started. This property can take the value TRUE or FALSE. It is set to TRUE if the pagination process has decided to begin a new page. This property contains a flag to record the current context; it is set to one of the following mutually exclusive values: PAGES_REGION_BODY if set, the main body of a document is currently being handled. PAGES_REGION_TOP if set, the top header text of a document is currently being handled. PAGES_REGION_BOTTOM if set, the bottom header text of a document is currently being handled. PAGES_REGION_LAST_BoTTom if set, the last bottom header text of the final document is currently being handled. PAGES_REGION_DOC_END if set, the current document is exhausted PAGES_REGION_END if set, the final document is exhausted PAGES_REGION_VERY_END if set, all documents are exhausted and the printing process has been terminated. It indicates that the paces object is ready to destroy itself. FORM REFERENCE pages. pages pages pages pages pages pages pages. pages. Page dimensions holding -pos .pr -tabs - Spacing -margins . time date ioclen This property can take the value TRUE Or FALSE. When set to TRuzg, the print element to be processed (in ao_run) is placed on the queue implemented by the vasze array object whose handle is in pages.todo. The property is set to TRUE if a print element must go onto a new line and, at the same time, must be kept on the same page as the following print element. The current position within the document being handled. The current print element. The information is contained in a data structure of type WDR_PRINT. Tab settings for the top and bottom headers, passed to the header prniay layout object when created. Spacing information for the top and bottom headers, passed to the header PRNLAY layout object when created. Margins for the top and bottom headers, passed to the header prnnay layout object when created. A character string containing the current time (set by ao_init). A character string containing the current date (set by ao_init). Length of the command buffer sent to the printer (set by ao_queue). The following diagram illustrates the meaning of the various members of a pAGES_PaGE structure in relation to the components of a typical document. The outer rectangle represents the page while the inner rectangles show the positions of the header text, the main body of the document and the footer text respectively. ’ hdbot «§————— body.width } ———— height body.height : \ =—_€§£—_- with ——_—__—________®® 4 THE DOCUMENT PRINTING CLASSES PAGES methods AO_INIT Initialise and queue INT ao_init (PAGES_INIT *in, INT printing, PAGES_PARAMS *par) ; Initialise the pacrs active object and begin the print/paginate/preview operation by sending an ao_QUEUE message. The method is called by an instance of the prinTER class as part of the implementation of that class's PR_PRINT, PR_PAGINATE and prR_PREVIEW methods. Three parameters, containing the information needed to build this instance of pacEs, are required. The parameter printing indicates whether the pacss active object represents a printing, pagination or preview operation. It can take one of three possible values: PRINTER_PRINTING perform a printing operation PRINTER_PAGINATE perform a pagination operation PRINTER_PREVIEW perform a preview operation The parameters in and par contain initialisation information and point to data structures of type PAGES_INIT and paGEs_PARams respectively. The two data structures reflect the different origins of the information contained within them. In general terms, some of the information contained within the pacrs_params data structure is set up internally by the pRinTER object itself as default values, whereas the information contained within the PAGES_INIT data structure is ultimately derived from the application. In some respects, this division is artificial. However, the design does minimise the effort required of an application if the defaults are adequate. A more sophisticated application would need to sub-class PRINTER and either replace the pr_init method or add new methods to modify these default values. The default values supplied by the prinTER object in the parameter par are as follows: pg.width PAGE_WIDTH_A4 pg-height PAGE_LENGTH_A4 pg.body.tl.x 1800 pg.body.tl.y 1800 pg.body.width PAGE_WIDTH_A4 - 3600 pg.body.height PAGE_LENGTH_A4 - 3600 pg.hdtop 720 pg.hdbot 720 top.f.height 240 bot.f.height 240 bot.align SCRLAY_ALIGN_CENTRE pgbeg 1 pgend OxFFFF where PAGE_WIDTH_A4 and paGE_LENGTH_aA4 are both defined in pagesize.h and scRALY_ALIGN_CENTRE can be found in the scriay class definition (see The Document Layout Classes chapter). All other members of this PAGES_PaRams structure and its sub-structures are uninitialised. The complete content of «par is copied into the property pages.par. FORM REFERENCE The information contained in the parameter in is as follows: wdr The handle of the printer resource (wor) object. c The callback method numbers and the handles of their "owning" objects. fname The address of a buffer containing the file name of the source. This member is only set if packs is to perform a printing or previewing operation. It is uninitialised for a pagination operation. toptxt The address of a buffer containing the top header text. This member is only set if pacEs is to perform a printing or previewing operation. It is uninitialised for a pagination operation. bottxt The address of a buffer containing the bottom header text. This member is only set if pacEs is to perform a printing or previewing operation. It is uninitialised for a pagination operation. The complete content of *in is copied into the property pages. in. The callback information referred to above, is itself contained within a data structure of type PAGES_CALLS and is set up by the application and passed to the PRINTER object before being handed on, in turn, to this instance of pacgs. This data structure, while defined in the paces class definition, is shown below: typedef struct { VOID *hread; WORD mread; VOID *hdone; WORD mdone; } PAGES_CALLS; As mentioned in the introductory text, packs must have a mechanism for requesting the next print element from the application and for keeping the application informed of the current status of the printing operation. This is achieved by means of callback methods. The creator of the pacrs object must supply the method numbers of two call-back methods together with the handles of their corresponding objects. The call-back methods are referred to as the read and the done call-back methods, expressions which will be used in this chapter. The read call-back method provides the means by which the paczs object can get the next print element from the application. The method number is supplied in pages. in.c.mread and the handle of the corresponding object is supplied in pages.in.c.hread. The done call-back method provides the mechanism by which the application can be told about the status of the printing operation; for example, the completion of a page or the completion of a document. This allows the application to take appropriate action. The method number is supplied in pages. in.c.mdone and the handle of the corresponding object is supplied in pages. in.c.hdone. Although the FORM class prniay supplies a read call-back method, in general, the design of the classes which supply these two methods is very much application dependent. However, the methods themselves must conform to the general specification described in the pacELay notional mixin class in this chapter. In practice, pRNLay is subclassed. The horizontal and vertical page dimensions held in the pages.par property are converted from twips to horizontal and vertical printer units respectively by calling the wdr_twips_to_xy method of the printer resource (WDR) object. If the paczs active object is intended to perform pagination, the method creates and prepares a vAFLAT object in which to build an array of uworp elements to contain the number of characters in each page. The handle of the variat object is set into the pages. pagarr property. If the pacEs active object is intended to perform either a printing or a preview operation, the method fetches the current time and date, using an instance of the OLIB class Trg, and stores their character representations in the properties pages.t ime and pages.date respectively. An instance of vaszc is created and initialised so that each record in the array will be large enough to contain a print element (i.e. a WDR_PRINT Structure); the handle of this object is set into the pages.todo property. Also, the PAGES_FLAGS_PRINTING flag is set in the property pages. flags. 4 THE DOCUMENT PRINTING CLASSES For a preview operation, a preview printer driver object (an instance of pRvppR) is created and initialised directly by sending it a ppR_1INIT message. It is important to note that the prvppr class is a subclass of ppR but does not reside in a separate dyl. The information in the ppR_in1t data structure required by the pdr_init method, is extracted from both paczs itself and the associated printer resource (wor) object. Note that the member dy1 is set to zero. For more information on previewing, see The Print Preview Class chapter in this manual. For a printing operation, a WOR_OPEN_PRINT message is sent to the associated printer resource (woR) object which, as part of its behaviour, creates a printer driver (ppR) object. In either case, the handle of the created printer driver object is set into the pages.pdr property. For a printing or a preview operation, a document object (an instance of EPprpoc) and a corresponding printer layout object (an instance of prNLay) are created for the top header and their handles stored in the properties pages.ephead and pages.prhead respectively. The priority of the pacgs active object is set to PRORITY_ACTIVE_comPUTE and the application manager is sent an AM_ADD_TASK message to add the active object to the application manager's active object task queue. The print/paginate/preview operation is started by sending an ao_quzEUE message and the method terminates by returning zero. On the Series 3, there is a slight difference to the behaviour of, and the interface to, this method. See the Series 3a/Series 3 notes section at the end of this chapter for detail. AO_RUN Fetch next print element INT ao_run(VOID); The method is called by the application manager when an I/O operation to the printer has completed or the paczs active object has been re-scheduled by a call to its superclass ac_queue method. In general terms, this method fetches the next print element to be processed as represented by a data structure of type woR_PRINT and further: e if printing or previewing, the ao_queue method is called to translate the information in this print element into a set of printer specific commands and to start the sequence of I/O operation(s) to the printer using the Plib function p_ioc. e if paginating, the information in the print element is used in the construction of the page array object anchored in pages. pagarr. This is followed by a call to the superclass ao_queue method to schedule the next call to this (i.e. the ao_run) method. When printing or previewing, there are circumstances where a print element cannot be processed immediately but must be placed in a queue, known as a fodo list - an instance of the vasze class. This is done to handle what are commonly known as widows and orphans. In a situation where a group of lines must be kept together, the position of page breaks cannot be determined until all such lines have been fetched in. Print elements are commonly fetched for processing by calling the read call-back method. However, in handling widows and orphans as mentioned above, a print element may, instead, be fetched from an existing todo list; alternatively, a print element may not be processed immediately but will be placed on the todo list - depending on the general context. When a page break occurs, the method will call the done call-back method with a completion status of PAGES_DONE_PAGE; Similarly, when the processing of a document is complete, the done call-back method will be called with a completion status of pacEs_DONE_Doc. If the pPAGES_REGION_VERY_END flag is set in the property pages. region, all documents will have been processed and the printing process itself will have been terminated. The done call-back method is called with a completion status of pacEs_DoNE_END. The paczs object destroys itself by sending itself a pzsTRoy message. FORM REFERENCE AO_ABRUN Handle error VOID ao_abrun (VOID); This method supports appman's architecture for handling p_1leave within the ao_run method. p_leave may be called if a write operation has not succeeded. The done call-back method is called with a completion status of PAcES_DONE_ERROR to notify the application that an error has occurred. This allows the application to take appropriate action. The method then destroys this instance of pacrs by sending a pDEsTRoy message. AO_ QUEUE Translate the print element and print data VOID ao_queue (VOID); If paces is performing a paginating operation, the method simply calls the superclass ao_queue method to re-schedule a call to ao_run. If pacgs is performing a printing or previewing operation, the method sends a ppR_PRINT message to the associated ppR object. For a printing operation, the pdr_print method translates the current print element into a sequence of printer commands. The printer commands are then sent to the printer device by doing a p_Fwritz I/O operation to the printer port. If the ppr object produces no printer commands, nothing is sent to the printer; instead, the method simply calls the superclass ao_queue method to re-schedule a call to ao_run. For a previewing operation, the pdr_print method translates the current print element into a sequence of drawing actions to a bitmap. As this does not require any I/O activity, this method (i.e. ao_queue) simply follows on by calling the superclass ao_queue method to re-schedule a call to ao_run. Before the ppR_PRINT message is sent, either for printing or previewing, some preliminary processing is done: e if the final document to be printed or previewed is exhausted, the woR_PRINT_END flag is ored into the flags field of the print element and the worR_pRiNT_pPacE flag is cleared. This will cause the printing/previewing process to terminate. e if the current page is not within the range of pages to be printed or previewed (as defined by pages.par.pgbeg and pages.par.pgend), the print element is ignored, the ppR_PRINT message is not sent and the method simply calls its superclass's ac_queue method to re-schedule a call to ao_run. e if printing or previewing has not yet started, the woR_PRINT_sTAaRT flag is ored into the flags field of the print element. This will cause the printer to be initialised and set up correctly or the preview bitmap to be cleared. e if page break is to be forced, the current vertical print position is adjusted appropriately. e if a line break is to be forced, the line element indent is adjusted appropriately. 4 THE DOCUMENT PRINTING CLASSES WDR file head model wid wdrname destroy wdr_init wdr_count_models wdr_sense_model_name wdr_set_model wdr_sense_model wdr_typeface wdr_search_typeface wdr_font_height wdr_search_height wdr_get_width_table wdr_sense_width wdr_twips_to_xy wdr_open_print wdr_load_record The wor printer resource class, encapsulates the handling of a WDR resource file. A WDR resource file contains printer specific information organised as a series of resources. For example, for each printer model supported, a resource file exists containing the various command sequences to control that printer. A wor object also provides methods to supply specific information from a WDR resource file. The WDR Printing chapter in the Additional System Information manual gives a full and comprehensive description of the structure of WDR resource files. Further useful information on printing can be found in the Printing chapter of the Object Oriented Programming Guide. A typical WDR file has resources containing the following information: e alist of printer models supported e the character command sequences to control printer operation ¢ amap used to translate the printer's character set onto that used by the SIBO computer (based on the IBM code page 850) e alist of typefaces supported by each model. e alist of fonts available in each typeface. e a width table for each font, where the widths in the WDR file are stored in difference form (see Widths of characters in fonts in the WDR Printing chapter of the Additional System Information manual). An instance of wor is normally created by a PRINTER object in its pr_open_wdr method. The wor class itself supports: e The accessing of the contents of a WDR resource file. The wor class may be used to read the contents of the WDR file. It does this by using an RScFILE class component. The wor class stores the current model and the list of available typefaces in memory. Other information is read from the file as and when required to minimise memory requirements. FORM REFERENCE The conversion of measurements from units of twips to horizontal and vertical printer units. The WDR resource file includes the minimum horizontal and vertical travel for each printer model. These distances are specified in units of twips. The wdr_twips_to_xy method is provided to convert horizontal and vertical distances from twips to printer units. The creation and initialisation of a suitable printer driver object - usually an instance of either the Por Class or a suitable subclass of ppr. A suitable printer driver object may be created and initialised using the wdr_open_print method; the method returns the handle of the object which is usually an instance of the ppr class or a suitable subclass. See the description of the wdr_open_print method for further details. An instance of wor can be created which is limited to reading the list of models supported. In this case the class does not store the details of the current model thus minimising memory requirements. In this mode only the wdr_count_models, wdr_sense_model_name, wdr_sense_width, wdr_set_model and wdr_destroy methods are available. A loaded font width table contains a sequence of unsigned bytes containing information about the width of each character in a font. Two kinds of width table are available: a monospace font width table - contains two bytes, the first of which contains zero, and the second of which specifies the width of a character. (By definition each character in a monospace font has the same width.) The zero in the first byte signifies a monospace font width table. a proportional font width table - contains 256 bytes, the first of which contains one; the remaining 255 bytes specify the width of the characters whose code ranges from 0x00 to OxFF. Thus the fiftieth byte specifies the width of the character whose code is 0x31. Note that, on being loaded from the WDR file, width tables are converted from differences to absolute character widths. Class definition The wor class subclasses root and is defined in the sub-category file prdrv.cl (with generated header file prdrv.g). CLASS wdr root { REPLACE destroy pPPppprprpprrprrep pp D D D D D D D D D D D D D D D wdr_init wdr_count_models wdr_sense_model_name wdr_set_model wdr_sense_model wdr_typeface wdr_search_typeface wdr_font_height wdr_search_height wdr_get_width_table wdr_sense_width wdr_twips_to_xy wdr_open_print wdr_load_record Init and optionally load model data Return the number of models Return model name by model number Set the current model number Sense struct of current model Get typeface struct by typeface index Get typeface struct and index given typeface Font height by typeface index, height index Get height index given height Width table given typeface, Get printed width of buf, Convert from twips to printer units height and style len Create a PDR for printer output Load specified resource record 4 THE DOCUMENT PRINTING CLASSES CONSTANTS { WDR_PRINT_PAGE 0x01 WDR_PRINT_LINE 0x02 WDR_PRINT_RIGHT 0x04 WDR_PRINT_FONT 0x08 WDR_PRINT_TEXT Ox10 WDR_PRINT_START 0x20 WDR_PRINT_END 0x40 WDR_PRINT_IDLE 0x4000 ! Used by pages WDR_PRINT_KEEP 0x8000 ! Used by pages WDR_PDR_LANDSCAPE 0x01 WDR_RSC_HEADER 1 Header resource ID WDR_RSC_COMMANDS 2 Commands resource ID WDR_DYL_LOAD 0x01 -WDR requires a DYL if set WDR_HP_PCL 0x02 printer driver is HP PCL compatible WDR_STYLE_NORMAL 0x0000 WDR_STYLE_UNDERLINE 0x0001 WDR_STYLE_BOLD 0x0002 WDR_STYLE_ITALIC 0x0004 WDR_STYLE_SUPER 0x0008 WDR_STYLE_SUB 0x0010 WDR_STYLE_MONOSPACE 0x8000 Reserved for external use WDR_STYLE_SANS_SERIF 0x4000 Reserved for external use WDR_TYPF_PROPORTIONAL 0x01 WDR_TYPF_SCALED 0x02 WDR_TYPF_SERIF 0x04 WDR_MODEL_LANDSCAPE_AVAILABLE 1 WDR_MODEL_MINX_IS_DOTS_PER_INCH 4 WDR_SCALE_DEFAULT_HEIGHT 1000 reference height = 1000 twips = 50 point WDR_FONT_NAME_LEN 20 significant characters from font name PRINTER_NAME_LEN 24 maximum length of printer name PRINT_TYPE_LEN 9 printer type length (filename+'\0') PDR_FILE_LEN 9 printer driver filename length } TYPES { typedef struct UWOR 5 i a, oe Se, Me D height; height_max; height_delta; width_scale; width_normal; width_italic; width_bold; width_bold_italic; command; } WDR_FONT; typedef struct { Height (or min height for scalable fonts) Max height (only relevant for scalable fonts) Delta height (only relevant for scalable fonts) Multiplier for font width table Width for mono, rid for proportional Set font command number TEXT name [WDR_FONT_NAME_LEN] ; Typeface name UWORD typeface; UWORD type; WORD trans_rid; UWORD num_heights; WDR_FONT font[1]; } WDR_TYPEFACE; RTF/Word compatible typeface WDR_TYPF_PROPORTIONAL WDR_TYPF_SCALED rid of translates record Number of different typeface heights List of different heights FORM REFERENCE typedef struct { UWORD minx; minimum delta x (in twips, unless MINX_IS_DPI flag set) UWORD miny; minimum delta y in twips UWORD skipx; amount printer auto indents UWORD skipy; amount printer auto feeds UWORD flags; WDR_MODEL_LANDSCAPE_AVAILABLE WDR_MODEL_MINX_IS_DOTS_PER_INCH UWORD num_typefaces; number of typefaces supported by model WDR_TYPEFACE *typeface[1]; list of typeface rids/pointers to typeface data WDR_MODEL; typedef struct UWORD rid; rid of model block TEXT name [PRINTER_NAME_ LEN]; model name WDR_MODEL_INDEX; typedef struct TEXT id[6]; file identifier UWORD flags; flags (WDR_DYL_LOAD) UWORD num_model; number of models described in file WDR_MODEL_INDEX model[1]; list of model names/rid's } WDR_HEADER; typedef struct width_table { struct width_table *next; UWORD rid; Resource ID width table (used as a key) UWORD height; Needed if font is scaled UBYTE *table; Address of width table } WDR_WIDTH_TABLE; typedef struct { WORD flags; WDR_PRINT_XXX WORD typf; Typeface number for WDR_PRINT_FONT WORD fheight; Font height for WDR_PRINT_FONT WORD style; Font style for WDR_PRINT_FONT WORD down; Line down for WDR_PRINT_LINE WORD indent; Line indent for WDR_PRINT_LINE WORD height; Line height for WDR_PRINT_LINE WORD right; Right movement for WDR_PRINT_RIGHT TEXT *buf; Text to print for WDR_PRINT_TEXT UWORD blen; Length of data at buf for WDR_PRINT_TEXT } WDR_PRINT; PROPERTY 1 { PR_RSCFILE *file; Resource file containing driver data WDR_HEADER *head; Header and model index WDR_MODEL *model; The current model WDR_WIDTH_TABLE *wid; List of font widths TEXT wdrname[P_FNAMESIZE]; -WDR File name } } Property wdr.file The handle of an instance of the rscriue class which is used to read resources from the WDR resource file. wdr.head The address of the WDR header resource, a data structure of type woR_HEADER. The header resource is fetched from the resource file by the wdr_init method; it achieves this by sending an rs_READ message to the RscFILE component object. 4 THE DOCUMENT PRINTING CLASSES wdr.model Information about the current printer model. Amongst other things, it includes the number of typefaces available for the current printer model and the resource ID for each typeface. wdr.wid This is a linked list of woR_wIpDTH_TABLE data structures each of which contains: e the resource ID of the font width table. e the height of the font (in the case of a scalable font). ¢ apointer to the loaded font width table itself. wdr .wdrname The full file specification of the WDR resource file. It is useful to note that the wor_pRinT structure defines the fields of a print element as used by the paces and ppr classes and its use is discussed in these classes. The structure is not used by the wor class. WDR methods DESTROY Destroy VOID destroy (VOID); Destroy the wor instance. The method frees the linked list of woR_w1pTH_TABLE data structures anchored in the property war.wia and frees the memory occupied by the font width tables. The memory used to contain the header resource whose address is held in the property wdr. head, is freed; wdr.head 1S reset to NULL. All memory cells containing printer model information as anchored in the property wdr.model, are freed; wdr.model itself is reset to NULL. The method concludes by supersending a pEstRoy message. WDR_INIT Initialise WDR VOID wdr_init (TEXT *filename, INT model); Initialise the wor instance. This method takes two parameters: @ filename points to a buffer containing the filename of the WDR resource file. © model contains the printer model. See the WDR Printing chapter in the Additional System Information manual for more information on the concept of model numbers. The method builds a full file specification using the name pointed to by filename; the default path is used to supply any missing components. The resulting name is written to the property wdr.wdrname. The method creates an instance of the rscrILE class and writes the handle to the property war. file. The resulting rscr1Le object is initialised by sending it an Rs_inrT message and passing the full file specification of the WDR resource file as an argument. The header resource is loaded by sending the rscr1iLe object an Rs_READ message and passing it the resource ID of the header. The address of the loaded resource is written to the property wdr.head. The header resource contains a list of models supported. A check is made to ensure that the header is valid. It contains a five character identification field which should always be "WDROS5". If this is not so, the method calls p_1eave with an argument of &_FILE_INVALID. The resource for the specific printer model specified by the parameter mode is loaded by sending a WDR_SET_MODEL message specifying an argument of mode1. The address of the loaded model resource is written to the property wdr.model. If the wor instance is only to be used to sense the models supported then mode1 should have the value -1; this avoids needless memory allocation by the wdr_set_mode1 method. FORM REFERENCE WDR_COUNT_MODELS Return the number of models INT wdr_count_models (VOID) ; Return the number of printer models supported. The method simply returns the value of war. head->num_model. WDR_SENSE MODEL_NAME Get model name from model no. TEXT *wdr_sense_model_name (INT model); Returns the address of the area containing the name of the printer model corresponding to a specified model number. This method takes a single parameter; mode1 contains the number of the printer model whose name is required. The method uses the value of mode1 as an index to address the appropriate woR_MODEL_INDEx data structure within the header resource; it then simply returns the address of the string containing the model name (i.e. &self->wdr.head->model [model] .name[0]). Note that the name will contain no more than pRINTER_NAME_LEN characters (defined in prdrv.g). WDR_SET MODEL Set the current model VOID wdr_set_model (INT model); Free allocated memory, load the resource for the printer model specified by the parameter mode1 and load the resource for each typeface supported by the specified printer model. The method frees the linked list of woR_wIDTH_TABLE data structures anchored in the property war.wia and frees the memory occupied by the font width tables. All memory cells containing printer model information as anchored in the property wdr.model, are freed; war.mode1 itself is reset to NULL. If the parameter mode1 contains the value -1, no model resource information is to be read in and the method simply returns. If the value of the parameter mode1 1s greater than the number of models supported, the method resets model to Zero. The method reads the resource for the specified printer model from the WDR resource file by sending a RS_READ message to the component rscFILE object, and writes the address of the loaded resource to wdr.model For each typeface, it loads the corresponding resource and writes the address of the loaded resource to the corresponding element of the war .model->typeface array. WDR_SENSE MODEL Sense current model data WDR_MODEL *wdr_sense_model (VOID) ; Sense the data for the current printer model. The method simply returns the content of wdr.model, i.e. the address of the wor_mopet data structure containing the current printer model information. WDR_TYPEFACE Get typeface by index WDR_TYPEFACE *wdr_typeface (INT typfix); Return the address of a woR_TYPEFACE data structure. The method takes a single parameter; t ypfix contains the index of an entry within the array of pointers to WDR_TYPEFACE data structures for the current printer model. Each worR_typerace data structure contains typface information for the current printer model. The method simply uses the index to return the address of the corresponding typeface entry. Formally, it returns: self—>wdr.model->typeface [typfix] 4 THE DOCUMENT PRINTING CLASSES WDR_SEARCH_TYPEFACE Get typeface by typeface number INT wdr_search_typeface (INT typf, WORD *ptypfix,WDR_TYPEFACE **ppdata) ; Search for the typeface, in the printer model information, whose typeface number matches the supplied value. This method takes three parameters: e typf contains the typeface number corresponding to the typeface being sought. A typeface number uniquely identifies a typeface (Courier, for example) and is compatible with DOS/WORD font numbers. Each typeface resource contains a typeface number as part of its identity; see the WDR_TYPEFACE Structure. @ ptypfix is the address of an area into which this method will write the index of the entry within the array of pointers to woR_TYPEFACE data structures containing the typeface with number typrf. This parameter can be nux in which case no attempt is made to write the index. @ ppdata is the address of an area into which this method will write the address of the WDR_TYPEFACE data structure containing the typeface with number typrf. This parameter can be nuu in which case no attempt is made to write the address. If the specified typeface is not present, the method will attempt to search for a substitute typeface. The following table shows how the substitution is done. The left-hand column shows the specified typeface (implied by the typeface number) while the right-hand column shows the corresponding base font that is substituted. Proportional Serif -> Times Proportional Sans Serif -> Helvetica Mono = Courier (default mono) Times, Helvetica —> Courier (default mono) Note that if the specified typeface is Times or Helvetica, implying that either (or both) of these base fonts is not present, no matching substitute is available and the default monospaced font is used.. For further details, see the Printer driver font mapping section od the Word Processor File Format chapter of the Additional System Information manual. The method returns e tRuE if the specified typeface was located or a suitable substitution was made. e ra.se if neither the specified typface nor the substitution was found - in this case, the typeface index is set to zero which corresponds to the default typeface. WDR_FONT_HEIGHT Get font height by typeface & font indexes INT wdr_font_height (INT typfix,INT fhix); Return the height in twips of the font with a given font (i.e. height) index in a typeface with a given typeface index. This method takes two parameters: @ typfix contains the index of an entry within the array of pointers to woR_TYPEFACE Structures. @ £hix contains the index of an entry within the array of woR_ront structures in the typeface determined by typfix above. For a non-scalable font, the method simply returns the height of the font. Formally this is the value: self—>wdr.model.typeface[typfix]->font [fhix] .height 4-31 FORM REFERENCE For a scalable font, the height is explicitly calculated. fhix is used as a scaling factor. The value returned is the result of: self—>wdr.model.typeface [typfix]->font[0].-height plus self—>wdr.model.typeface[typfix]-—>font [0] .height_delta*fhix WDR_SEARCH_HEIGHT Get font index given height INT wdr_search_height (INT typfix,UWORD *pheight); Return the font (i.e. height) index of the font with a specified height (in twips) in a given typeface. This method takes two parameters: @ typfix contains the index of an entry within the array of pointers to woR_TYPEFACE Structures. @ pheight is the address of an area which contains the height of the font (in twips). The value returned is the index of an entry within the array of woR_ronT structures in the typeface determined by typfix above. If a font with the exact desired height is not located, the method returns the index of the tallest of all those fonts whose heights are lower than the value in *pheight. In this case, *pheight is overwritten with the new height. WDR_GET_WIDTH_TABLE Get a requested font width table UBYTE *wdr_get_width_table(INT typf,INT height,INT style); Return the address of the font width table for the font with a given height in a given typeface in a given style. The method takes three parameters: ¢ typf contains the typeface number of the typeface being sought. ® height specifies the height of the font in twips e style specifies the style. The only combination of styles which are used by this method are: WDR_STYLE_NORMAL WDR_STYLE_ITALIC WDR_STYLE_BOLD WDR_STYLE_ITALIC | WDR_STYLE_BOLD All other styles are ignored. If style contains neither wOR_STYLE_ITALIC nor WDR_STYLE_BOLD in any combination, then woR_STYLE_NORMAL is assumed by default. The method starts by sending a woR_SEARCH_TYPEFACE message to find the index and the address of the WDR_TYPEFACE data structure of the typeface with number typf. For monospace fonts, the method simply returns a pointer to the font width table. For proportional fonts, the font width table to be selected depends on the style combinations in the parameter style. If the selected table has previously been loaded, the method simply returns the required address; otherwise, a new (uninitialised) woR_wIDTH_TABLE Structure is allocated and inserted into the existing queue so that war .wid points to the new entry and the new entry points to the existing entries. The required font width table resource is loaded into the new entry by sending an rs_READ message to the RSCFILE component object. The remaining fields of a new woR_WIDTH_TABLE entry are filled in as follows:- e rid is set to the associated resource ID ¢ height is set to the font height e the first byte of the table itself is set to 1 to distinguish it from a monospace table 4-32 4 THE DOCUMENT PRINTING CLASSES Notes:- If the requested typeface is unavailable, a substitute typeface will be used. If a font of the desired height is unavailable, the tallest possible font which is less than the desired font will be substituted. The method supports scalable proportional fonts but does not support scalable monospace fonts. WDR_SENSE WIDTH Get printed width of text INT wdr_sense_width(UBYTE *pwid, TEXT *buf,INT len); Return the printed width of text, in printer units. The method takes three parameters: e pwid contains the address of the font width table to be used. ¢ uf contains the address of a buffer holding the text whose width is to be found. ¢ en contains the length of the text. The method simply adds up the width of each character in the buffer pointed to by buf, using the width values defined in the font width table. WDR_TWIPS TO XY Convert twips to printer units VOID wdr_twips_to_xy(WORD **ppx,WORD **ppy) ; Convert twips to printer units. The method takes two parameters; © px points to a list of addresses, each of which points to a word containing a twips value to be converted into horizontal printer units. The list of addresses is terminated by a nuLL. ¢ ppy points to a list of addresses, each of which points to a word containing a twips value to be converted into vertical printer units. The list of addresses is terminated by a nuLL. Resulting values are rounded up to the nearest integer which avoids small measurements coming out as zero. To get zero, the caller must explicitly enter zero. WDR_OPEN_PRINT Create a PDR for printer output VOID *wdr_open_print (INT flags,INT page_length,VOID **ppcb) ; Create and initialise an instance of the ppr (printer driver) class or a suitable subclass of ppr, returning the handle of the instance. The method takes three parameters; ¢ flags specifies the orientation of a page. If woR_ppR_LANDScapPE is set, then landscape orientation is required, otherwise portrait orientation is implied. @ page_length specifies the height of a page in printer units. ¢ ppcb is the address of an area into which the handle of a channel to the opened printer port will be inserted. If the flag woR_DyL_Loap is set in wdr.head->flags, then it is assumed that an instance of a subclass of Ppp is to be created and that this subclass is to be found in a separate DYL. A DYL with the same filename as the WDR resource file but with an extension of .dy/ is assumed to exist and an attempt is made to load and link to it. If this DYL does not exist or cannot be found, the method will terminate with a p_leave. An instance of the first class in the DYL is created. If the flag woR_DyL_Loap is not set in wdr.head->flags, then an instance of the basic ppr class as defined in FORM is created. The created object is initialised and printing is started by sending it a ppR_InrT message. See the ppr class for a description of the par_init method and the information passed to it. FORM REFERENCE WDR_LOAD_RECORD Load resource record VOID wdr_load_record(INT rid,VOID **pcell); Load a resource from the WDR resource file. The method takes two parameters; ¢ rid specifies the resource ID of the resource to be loaded. e pceili is the address of an area into which the address of a memory cell containing the loaded resource is placed; i.e. the address of the loaded resource is written to *pcell. The resource is loaded by sending an rs_READ message to the RScFILE component of wor. PDR par mode typfix fhix style lheight a trans_rid outlen skipy destroy pdr_init pdr_print pdr_add_command pdr_destroy pdr_start pdr_end pdr_page pdr_text pdr_line pdr_right pdr_font pdr_style Por is the printer driver class and is that part of document printing that encapsulates the conversion of print elements (as defined by the content of a woR_pRinT data structure) into a sequence of printer commands. The printer commands generated are specific to a particular printer; information about the printer model is passed to the ppr object at initialisation time. An instance of ppr is normally created by an instance of the printer resource (wor) class but is made a component of a pacEs object; in general, there is a degree of dependence on the wor object which is asked to provide further information from time to time. ppr can, under some circumstances, be created directly by other suitable classes (e.g. PAGES). Once created, active objects such as pacers use a PpR object to build a sequence of printer specific commands on its behalf ; the pacEs active object then schedules the transmission of the commands to the printer. Note that if the ppr class is subclassed, the normal usage is to load the subclass from a DYL: see the description of the pdr_init method for more detail. 4-34 4 THE DOCUMENT PRINTING CLASSES A description of the contents of WDR resource files can be found in the WDR Printing and Resource Files chapters of the Additional System Information manual. Further useful information on printing can be found in the Printing chapter of the Object Oriented Programming Guide. Class definition The ppr class subclasses root and is defined in the sub-category file prdrv.cl (with generated header file prdrv.g). CLASS pdr root { REPLACE destroy D pPpppprppprpppr ep ep pdr_init Ca pdr_print pdr_add_command pdr_destroy=p_dummy Fo pdr_start st pdr_end Fi pdr_page st pdr_text Pr pdr_line st pdr_right Po pdr_font Se pdr_style Se CONSTANTS { Se i> LAS LAS AY © IL © A © ©» © a kw © Dw 6 a av © a DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM DR_CM D_RESET 0 D_FORM_LENGTH 1 D_PREAMBLE 2 D_POSTAMBLE 3 D_UNDERLINE_ON 4 D_UNDERLINE_OFF 5 D_BOLD_ON 6 D_BOLD_OFF 7 D_ITALIC_ON 8 D_ITALIC_OFF 9 D_SUPERSCRIPT_ON 10 D_SUPERSCRIPT_OFF 11 D_SUBSCRIPT_ON 12 D_SUBSCRIPT_OFF 13 D_NEW_PAGE 14 D_CARRIAGE_RETURN 15 D_MOVE_DOWN 16 D_MOVE_RIGHT_PREFIX DR_CM DR_CM D_MOVE_RIGHT 18 D_MOVE_RIGHT_SUFFIX DR_CM D_LANDSCAPE 20 typedef struct { PR_WDR *wdr; WORD flags; WORD page_length; HANDLE dyl; WDR_HEADER *head; WDR_MODEL *model; } PDR_INIT; typedef struct { UBYTE *commands; UBYTE *outbuf; UBYTE *trans_res; TEXT **tix; } PDR_ALLOC; lled from WDR Called externally by the print active object Add command to printer buffer r a DYL subclass destroy art printing nish printing art a new page int text at current pos art a new line sition to the right t the font t the font style 17 19 Ref back to creating wdr WDR_PDR_LANDSCAPE Page length for setting form size Handle of loaded DYL Header Model Command strings Print output buffer Character set translates resource Translates lookup table 4-35 FORM REFERENCE PROPERTY } Property pdr. pdr. pdr. pdr. pdr. pdr. pdr. par mode typfix fhix style lheight a { PDR_INIT par; UWORD mode; Mode (landscape) WORD typfix; Current typeface index WORD fhix; Current font height index WORD style; Current font style WORD lheight; Height of current line PDR_ALLOC a; Various allocated cells UWORD trans_rid; Resource ID of loaded translates WORD outlen; Length of data in output buffer UWORD skipy; Initialisation data set by the pdr_init method and defined as a data structure of type PDR_INIT. This includes items such as pointers to the associated WDR object and the current printer model information. This property is used to indicate whether printing is to be done in landscape or porttrait mode. If the woR_ppR_LANDscapE flag is set, printing is to be done in landscape mode; if the property contains nuut then printing is to be done in portrait mode. The index of an entry within the array of pointers to woR_TYPEFACE structures. The WDR_TYPEFACE Structure identified contains information on the current typeface . The array is part of the woR_mopEt data structure representing the current printer model. The index into the array of woR_FonT structures which corresponds to the current font height. The array is part of the woR_TyPEFace data structure representing the current typeface. The current font style. This can be a combination of a number of individual styles represented by an ored combination of the following flags: WDR_STYLE_NORMAL WDR_STYLE_UNDERLINE WDR_STYLE_BOLD WDR_STYLE_ITALIC WDR_STYLE_SUPER See the description of the pdr_style method for more detail. The height of the current line in printer units. This property is set whenever a print element is handled which has woR_PRINT_LINE set in its flags member and is copied from the print element's height member. In other words, it is set when a new line is forced. This is a data structure of type ppR_ALLoc which contains a number of pointers to allocated memory cells. They are grouped together in this structure for convenience. The individual members of this structure are important and are discussed below: commands This is a pointer to a table of commands supported by the current printer model(s). The table starts with a byte count giving the number of commands followed by the commands themselves. Each command starts with a byte count giving the total length of the command. The remaining bytes contain a format string consisting of the printer command itself and formatting characters as used by the Plib function p_atob. See the Plib Reference manual and the WDR Printing chapter of the Additional System Information manual for more detail. The table itself is loaded from the WDR resource file during execution of the pdr_init method. 4 THE DOCUMENT PRINTING CLASSES outbuf The address of the output buffer in which the sequences of printer commands are built. trans_res A pointer to a translate table as loaded in from the resource file. Translate tables are described in the WDR Printing chapter of the Additional System Information manual for more detail. tix A pointer to a lookup table for the translate table referenced by trans_res. The lookup table is a table of addresses. The ASCII value of any character gives the offset into the lookup table for that character's entry which, in turn, gives the address of the translate table entry for that character. In other words : * (pdr.a.tix+ (ASCII value of a char')) points to the translate table entry for that character. pdr.trans_rid The resource ID of the current translate table. pdr.outlen The length of data currently held in the output (i.e. the commands) buffer which is in allocated memory pointed by pdr.a.outbuf. pdr.skipy This property is set to the printer vertical auto-feed value whenever a page break occurs (pdr_page) and the printer is started (pdr_start). It is reset to zero after every new line (pdr_line). The printer vertical auto-feed value itself is copied from the printer model information supplied when this instance of ppr is created (see the ppR_rnitT and the woR_MoDEL data structures.) This property is used to calculate the amount by which the print head must actually move down when a new line is requested and is of particular importance when a page break occurs. PDR methods DESTROY Destroy VOID destroy (VOID) ; Destroy the ppr instance. The destroy method begins by sending ppR_DEsTRoy message. The pdr_dest roy method, as supplied in PpR, is a dummy method which can be replaced by a subclass. The intention is that any subclass specific destroy tasks are done, and indeed must only be done, within the pdr_destroy method. (Do not be confused between the destroy method and the pdr_dest roy method.) All memory whose pointers are held in the ppR_anioc data structure in property pdr.a are freed. If an external DYL was loaded (indicated by a positive value in pdr.par.dy1), as is often the case when ppR 1s subclassed, the DYL whose handle is contained in pdr. par.dy1, is unloaded. The method finally supersends a pestroy message. This method must not be replaced by subclassers - an attempt to return into the DYL after it has been freed will fail. PDR_INIT Initialise PDR VOID pdr_init (PDR_INIT *par,VOID **ppcb) ; Initialise the instance of ppr. The parameter par points to a data structure of type ppR_1nrT which contains the information required to initialise the instance. The entire content of *par is copied into the property pdr.par. 4-37 FORM REFERENCE The ppr_1niT structure, shown below, is defined in prdrv.cl: typedef struct { PR_WDR *wdr; WORD flags; WORD page_length; HANDLE dyl; WDR_HEADER *head; WDR_MODEL *model; } PDR_INIT The significance of the members of the ppR_in1T struct is as follows: wdr The handle of an instance of an associated wor class. Although the ppr object is created by this instance of wor, it does require the services of this wor object. flags An ored combination of flags as follows: WDR_PDR_LANDSCAPE - if Set, it indicates that landscape orientation is required. This is the only flag to be set in this property; subclassers may wish to add additional flags. page_length The page height in printer units. dyl If the ppr class is used directly, this member is nuuu. If the ppr class is subclassed and the subclass has been loaded from a DYL, then this member will contain the category handle of that DYL. head The address of the WDR file header resource. model The address of the wor_mopet data structure containing the information on the current printer model. The method opens a channel to the printer port and writes the handle of the opened channel to *ppcb by sending a PR_OPEN_PORT message to the object whose handle is contained in w_am->appman. spare1. This is a property of the application manager and is assumed to contain the handle of an instance of the PRINTER Class or its equivalent. A FORM printer object always inserts a copy of its own handle into w_am-—>appman.sparel during initialisation. A WDR_LOAD_RECORD message is sent to the associated wor object requesting it to load the commands resource for the current printer from the wor resource file; the address of the loaded resource is written to pdr.a.commands The method allocates a cell of length 256 bytes and writes its address to pdr.a.outbuf. This area will be used to build the sequence of printer commands. The cell will be re-allocated if it eventually proves to be too short. On the Series 3, there is a slight difference to the behaviour of this method. See the Series 3a/Series 3 notes section at the end of this chapter for detail. PDR_PRINT Translate print command INT pdr_print (WDR_PRINT *pr,UBYTE **pbuf) ; Translate a print element into a sequence of printer specific commands and return the length of the generated commands. The print element is a data structure of type woR_PRINT pointed to by the parameter pr. The method takes the print element and translates the contents into a sequence of printer specific commands; the commands themselves are written to a buffer whose address is contained in the property pdr.a.outbuf and the start address of the sequence is written to *pbuf. Before starting the translation process, the property pdr. outien (the current length of the data in the output buffer) is reset to zero. 4 THE DOCUMENT PRINTING CLASSES The command sequences generated depend on the setting of the f£1ags member of the print element. Separate methods exist to handle each possible setting of f1ags. The detailed work is delegated to other Ppr methods, each of which builds and adds commands to existing command sequences in the output buffer and updates the current length of the buffer as held in the property pdr. outlen. The method finally writes the address of the output buffer to *pbur and returns the length of the generated command sequences, i.e. the current value of pdr. outlen. This return value is used by the calling instance of pacEs to determine how much data to transmit to the printer. A subclass of ppr that wishes to direct output to a device other than the printer may replace this method to perform the output and return zero. In such a case, the output must have completed before the pdr_print method returns. As mentioned earlier, a print element is a data structure of type woR_pRiInt defined in prdrv.cl; this is shown below together with an explanation of the individual fields: typedef struct WORD flags; WORD typf; WORD fheight; WORD style; WORD down; WORD indent; WORD height; WORD right; TEXT *buf; UWORD blen; } WDR_PRINT; flags This member gives meaning to the print element. It is an oned combination of flags. The command sequences generated by pdr.print depend on the combinations set. However, they are added to the output buffer in the same order as the flags are described below. WDR_PRINT_sTaRT This flag indicates that the printer is to be started. The command sequence to do this is generated by sending a ppR_sTarT message. The method requires no arguments. WDR_PRINT_PAGE This flag indicates that the print element is to go onto a new page; in other words, a page break is required. The command sequence to do this is generated by sending a ppR_pacE message. The method requires no arguments. WDR_PRINT_LINE This flag indicates that the print element is to go onto a new line. A copy of the line height as found in pr->height is copied into the property pdr.1height, as this could prove useful to subclasses. The command sequence to force a new line is generated by sending a PDR_LINE message. The method requires two arguments which govern the initial position of the printhead on the new line - the vertical distance through which the print head is to move down and the horizontal distance the print head is to move to the right from the left-hand margin. The first argument is the value of pr->down plus pr->height. The second argument is the value of pr->indent. WDR_PRINT_FONT This flag indicates that a new font is to be set. The command sequence to do this is generated by sending a ppR_FONT message. The method requires three arguments - the typeface index, the height of the font and the required style. The arguments are the values pr->typf, pr->fheight and pr->style respectively. 4-39 FORM REFERENCE typft fheight style WDR_PRINT_RIGHT This flag indicates that the print head must be moved to the right. The command sequence to do this is generated by sending a ppR_RIGHT message. The method requires a single argument which specifies the amount by which the print head is to be moved. The argument is the value of pr->right. Note:- if woR_PRINT_TEXT is also set, then the print head is moved to the right before attempting to print any text. WDR_PRINT_TEXT This flag indicates that there is text to be printed. The command sequence to do this is generated by sending a ppR_TEXT message. The method requires two arguments which define the text to be printed - the address of a buffer containing the text and the length of the text to be printed. The first argument is pr->buf. The second argument is the value of pr->blen. Note:- if woR_PRINT_RIGHT is also set, then the print head is moved to the right before starting to print any text. WDR_PRINT_END This flag indicates that this print element terminates the print process. The command sequence to do this is generated by sending a ppR_END message. The method requires no arguments. The typeface number. It is a number that uniquely identifies the typeface, (Courier, for example) and is compatible with DOS/WORD font numbers. Each typeface resource contains a typeface number as part of its identity; see the woR_TYPEFACE structure in the wor class definition. This member is important when the woR_pRINT_FonT flag is set and is used as an argument to the pdr_font method. The height of the font in twips. This member is important when the woR_PRINT_FontT flag is set and is used as an argument to the pdr_font method. The style to be applied to the font. The style is represented by an ored combination of flags each of which represents an individual style as shown below. This member is important when the woR_PRINT_FonT flag is set and is used as an argument to the pdr_font method. WDR_STYLE_NORMAL Plain text. WDR_STYLE_UNDERLINE Text is underlined. WDR_STYLE_BOLD Text is boldened. WDR_STYLE_ITALIC Text is italicised. WDR_STYLE_SUPER Text is superscripted. WDR_STYLE_SUB Text is subscripted. down indent height right buf blen 4 THE DOCUMENT PRINTING CLASSES The downwards displacement of the print head in printer units. When a print element is to go onto a new line, the print head is moved down by this value plus the value given in height. This member gives a mechanism for defining the extra spacing which is often needed before a line of text is printed (as occurs, for example, before the first line of a new paragraph.) This member is important when the woR_PRINT_LINE flag is set and is used in the construction of an argument to the pdr_line method. The right indentation of the print head in printer units. This member is important when the wor_PRINT_LINE flag is set and is used as an argument to the pdr_line method. The height of the line in printer units. When a print element is to go onto a new line, the print head is moved down by this value plus the value given in down. This member is important when the woR_PRINT_LINE flag is set and is used in the construction of an argument to the pdr_line method. The rightwards displacement of the print head, in printer units, from its current position. It defines how far to the right the print head is to move. If the print element also contains text to be printed, the print head is moved right before text is printed. This member is important when the woR_PRINT_RIGHT flag is set and is used as an argument to the pdr_right method. The address of a buffer containing text to print. This member is important when the woR_PRINT_TExT flag is set and is used as an argument to the pdr_text method. The length of the text to print. This member is important when the wor_PRINT_TExT flag is set and is used as an argument to the pdr_text method. PDR_ADD_COMMAND Add command to buffer VOID pdr_add_command (INT num,WORD *args) ; Add a printer command to the output buffer. This method takes two parameters: num represents the number of the command format string within the commands table. It can take one of the ppR_cmp_... values as defined in the sub-category file prdrv.cl. The address of the commands table is in pdr.a.commands. Recall that, in general, a command format string consists of the command itself (one or more characters) followed by formatting control characters which are discussed in the description of the Plib function p_atob in the Plib Reference manual. args points to a contiguous list of arguments; this parameter will be nu if the printer command requires no arguments. If no arguments are supplied, the command sequence added to the output buffer is simply the printer command as found in the commands table. If arguments are supplied, the way the method proceeds depends on the content of the command format string as follows: If the first character of the command format string is an asterisk ('*'), the first argument pointed to by args is assumed to be an integer value containing a repeat count. Any other arguments follow the repeat count. If the first character is not an asterisk, the method assumes a repeat count of one. FORM REFERENCE e A single command sequence is constructed, consisting of the printer command and the values in the argument list converted according to the formatting control characters. e A number of copies of the constructed single command sequence are added to the output buffer as defined by the repeat count calculated above. A special case occurs where the first character of the command string is an asterisk and the next character is NULL (i.e. the character '\o'); again, args will point to an integer value containing a repeat count. In this situation, a number of '\o' characters are added to the output buffer as defined by the repeat count. The method automatically re-allocates the output buffer if it is not big enough. PDR_DESTROY Destroy method, subclassable by DYL VOID pdr_destroy (VOID); This is a dummy method and does nothing. The method is intended for use by subclasses; its use is more fully discussed in the description of the destroy method. PDR_START Start printing VOID pdr_start (VOID); Generate the command sequences to initialise and set up the printer and add them to the output buffer. The following commands are added to the output buffer by sending a ppR_ADD_comMAND message: @ PDR_CMD_RESET instructing the printer to reset itself. @ PDR_CMD_FORM_LENGTH to set the form length. This requires a single argument specifying the length of the form. The length is specified in units of Jines and the assumption is made that there are 6 lines per inch; thus the value passed is the result of the calculation: (pdr.par.page_length * pdr.par.model->miny) / 240 e PDR_CMD_PREAMBLE. @ PDR_CMD_LANDSCAPE instructing the printer to operate in landscape mode if and only if, on initialisation of this instance of ppr, landscape orientation was requested and the current printer model supports landscape orientation (i.e. woR_PDR_LANDSCAPE Is set IN pdr.par.flags and WDR_MODEL_LANDSCAPE_AVILABLE iS Set iN pdr.par.model->flags). If this command is generated, then the woR_ppR_LANDscapE flag is set into the property pdr. mode. The property pdr.typfix containing the index into the array of pointers to woR_TYPEFACE structures, corresponding to the current typeface, is initialised to -1. As any sensible index is always non-negative, this guarantees that any subsequent call to the par_font method will cause the relevant translate table resource to be loaded. To complete the start up command sequence, the par_font method is called to ensure that a default font is set. The default font has a typeface number of zero, a font height of 240 twips and normal style. It is worth noting that 240 twips is the height of a single line based on the assumption that there are 6 lines per inch. Finally, the method writes the printer auto-feed value (as found in the printer model information pdr.par.model->skipy) into the property pdr.skipy. This ensures that the downward displacement of the print head for the first new line is calculated correctly. PDR_END Finish printing VOID pdr_end(VOID) ; Generate the command sequences to terminate printing and add them to the output buffer. This method calls the pdr_page method to add a ppR_cmp_NEW_PAGE command to the output buffer and then adds a ppR_cMD_POSTAMBLE command directly by calling the pdr_add_command method. 4 THE DOCUMENT PRINTING CLASSES PDR_PAGE Start a new page VOID pdr_page (VOID) ; Generate the command sequences to start a new page and add them to the output buffer. This method adds a ppR_cmp_NEW_PAGE command to the output buffer and then writes the printer auto-feed value (as found in the printer model information pdr.par.model->skipy) into the property pdr.skipy. This ensures that the downward displacement of the print head for the first new line on the new page, is calculated correctly. PDR_TEXT Print text at current position VOID pdr_text (TEXT *buf, INT len); Generate the command sequences to print text at the current position and add them to the output buffer. This method takes two parameters; buf points to a buffer containing the text to be printed and 1en contains the length of the buffer. The method substitutes the following characters into the buffer: e all scRLAY_syM_SOFT_HYPHEN and scRLAY_SYM_HARD_HYPHEN Characters are replaced with a '-' character. e all scrLAY_syM_HARD_sSPACcE characters are replaced with a'' character. If a translate table exists, the method translates any characters that need to be translated using both the translate table and its associated lookup table (see the description of the property pdr.a.tix and pdr.a. trans_res). Finally, the method adds the text, including all of the substitutions and translations, to the output buffer. PDR_LINE Start a new line VOID pdr_line(INT down, INT indent) ; Generate the command sequences to start a new line and add them to the output buffer. The method takes two parameters; down specifies the vertical distance through which the print head is to move; indent specifies the initial position of the print head relative to the left-hand edge of the page. Both indent and down are given in printer units. The following commands are added to the output buffer by sending a ppR_ADD_CoMMAND message: @ PDR_CMD_CARRIAGE_RETURN. @ PDR_CMD_MOVE_DowN to move the print head down. This requires a single argument specifying the amount of vertical travel. If the parameter down is non-zero and this is the first new line on the page, then the argument passed is the value of down Jess the vertical printer auto-feed value. (A negative result is reset to zero) In the context of this method, the first line on a new page is implied by the value of the property pdr.skipy. This is set to the printer auto-feed value at the start of printing and on page breaks; it is reset to zero by this method after the PpR_cmD_movE_Dbown command has been added to the output buffer. If the parameter indent is non-zero, the print head is to be moved horizontally. However, before this is done, the printer style is reset to normal, if it is other than normal. The pre-existing style is re-applied after the print head has moved. Thus, if the parameter indent is non-zero, the following occurs: e If the existing printer style is other than normal, a ppR_sTyLE message is sent with an argument of woR_STYLE_NoRMAL to add a command sequence to the output buffer to reset the style to normal. The existing style, as defined by the content of the property pdr. style is temporarily saved. FORM REFERENCE e A PDR_RIGHT message is sent to add a command sequence to move the print head right. The pdr_right method itself requires an argument specifying the amount of horizontal travel. The value of the argument passed is the value of indent Jess the horizontal printer auto-feed value (A negative result is reset to zero). e If necessary, a PDR_STYLE message is sent to add a command sequence to the output buffer in order to re-set the style to its pre-existing value. PDR_RIGHT Position to the right VOID pdr_right (INT right); Generate the command sequences to move the print head right from its current position and add them to the output buffer. The method takes a single parameter; right specifies the horizontal distance through which the print head is to move from its current postition and is given in printer units. The following commands are added to the output buffer by sending a ppR_aDD_CoMMAND message: e PDR_CMD_MOVE_RIGHT_PREFIX. e PDR_CMD_MOVE_RIGHT. e PDR_CMD_MOVE_RIGHT_SUFFIX. ALL three commands require a single argument specifying the amount of horizontal travel; the argument passed to all commands is the value of the parameter right. The method generates three command sequences to allow for the fact that some printers require a mode switch before and after the actual move right command. However, for many printers, this is not necessary and both the prefix and suffix commands are effectively null. PDR_FONT Set the font VOID pdr_font (INT typf,INT height, INT style); Generate the command sequences to set the font and add them to the output buffer. The method takes three parameters: @ typ specifies the typeface number which identifies the typeface, (Courier, for example) and is compatible with DOS/WORD font numbers ¢ height specifies the height of the font in twips @ style specifies the style to be applied and is represented by an ored combination of flags (see the description of the pdr_style method for the flags and their meanings) The method sends a woR_SEARCH_TYPEFACE message to the associated wor object to retrieve the index of the entry within the array of pointers to woR_TYPEFACE structures which represents the typeface with number typ¢é. This index is referred to as the typeface index. The method then sends a woR_SEARCH_HEIGHT message to retrieve the index of the entry within the array of woR_FonT structures which most closely represents the font with height height. This index is referred to as the font index. See the section on wor in this chapter for a full description of the data structures and for more detail on the wdr_search_typeface and wdr_search_height methods. If both the typeface index and the font index are the same as the current values held in the properties pdr.typfix and pdr. fhix respectively, then the method only needs to send a ppR_sTYLE message with an argument of style, to add the command sequence to set the style. 4 THE DOCUMENT PRINTING CLASSES If, however, either the typeface index or the font index are different from the current values held in pdr.typfix and pdr.fhix: e = Either one or both parameters height and style are set into the properties pdr.typfix and pdr. fhix, respectively to reflect the changes. These new values are now regarded as the current values. e If the resource ID of the translate table for the specified typeface is different from the current translate table resource ID as defined by the property pdr.trans_ria, then the new translate table is loaded by sending a woR_LOAD_RECORD message to the associated wor object and the pdr.trans_rid is updated with the new resource ID. The translate lookup table is also re-built. e A PpR_STYLE message is sent, with an argument of zero, to add a command sequence to the output buffer to set the style to normal. e For a non-scalable font, a PpR_ADD_COMMAND message is sent to add the 'set font' command as found in the command member of the current woR_Font data structure; formally:- self—>pdr.par.model.typeface[pdr.typfix]->font [pdr.fhix] .command e For a scalable font, a ppR_ADD_CoMMAND message is sent to add the 'set font’ command as found in the command member of the first woR_ront data structure; formally:- self—>pdr.par.model.typeface[pdr.typfix]->font [0] .command This command requires an argument specifying the font height in points. e = Finally, a ppR_styLE message with an argument of style, is sent to add the command sequence to set the style. PDR_STYLE Set the font style VOID pdr_style(INT style); Generate the command sequences to set the style and add them to the output buffer. The method takes a single parameter; style specifies the style to be applied. In practice, style is a combination of individual styles each of which is represented by a flag. The flags, which can be ored together, are as follows : WDR_STYLE_NORMAL specifies that the style is set to normal - i.e. no underline, no italic etc. WDR_STYLE_UNDERLINE specifies that underlining is to be set. WDR_STYLE_BOLD specifies that bold is to be set. WDR_STYLE_ITALIC specifies that italic is to be set. WDR_STYLE_SUPER specifies that superscript is to be set. WDR_STYLE_SUB specifies that subscript is to be set. The property pdr. style contains the current setting of the style flags. By comparing the current style with the required new style, as defined by the content of the parameter style, the method generates a sequence of commands to turn individual styles on or off as appropriate. The method uses the services of the pdr_add_command method to add the commands to the output buffer. For example, to turn underlining off and bold emphasis on, the commands ppR_cMD_UNDERLINE_oON and PDR_CMD_BOLD_OFF are generated and added to the output buffer. The method concludes by setting the property par. style to the value in the parameter style. FORM REFERENCE The PAGELAY mixin class PAGELAY The paceLay mixin class provides the formal specification for the call-back methods that must be supported by any class that provides access to the text content of a formatted document. These methods may be called by the paczs class. The call-back methods mread and mdone are also referred to as the read and the done methods in other parts of this manual. For a general discussion on call-back methods and mixin classes, see the Introduction chapter in this manual. The pacexay class does not appear in the FORM library and an instance of pacrLay will never be created. The FORM library supplies the prniay class to build and manipulate the layout of printer text. This class, described later in this chapter, provides the s1_print_reada method as the required mreaa or the read callback method. However, the FORM library does not supply a class which can provide the necessary mdone or done call-back method; this is normally supplied by the application. Class diagram The following class diagram formally illustrates the relationship between the paczLay mixin class and the pacEs Class. This diagram shows both the active class and the pacExay class in order to emphasise the multiple inheritance aspect of mixin classes. ~~ — ts a sad, re pa active / / pagelay / Ne se ) ) es Les y fs — A pages / i ) cae Class definition CLASS pagelay root { DEFER mread fetch print element DEFER mdone report status } Property None. PAGELAY call-back methods PAGELAY MREAD Get next WDR_PRINT element UINT pagelay_mread(INT flag,WDR_PRINT *pr) This method is also referred to as the read method in this chapter. The printing/previewing/pagination process is normally broken down into a sequence of operations such as moving the printing position down, changing the typeface, printing a number of characters and so on. Each of these operations can be described by what is known as a print element. 4 THE DOCUMENT PRINTING CLASSES Once created, the pacrs object drives this process by requesting print elements from the application. It is the application's responsibility to "know" what it wants to do next. For print and preview operations, the pacrs object is responsible for taking a print element and translating it into an appropriate sequence of commands suitable for the chosen printer and scheduling any resulting I/O operations. For pagination operations, the paczs object uses the print elements to build pagination information. This method provides the mechanism by which a paces object obtains a print element from an application. A print element is represented by the information contained in a data structure of type woR_pRInT. While this structure is used by the application, the pacrs object and by the printing (epR) object, it is in fact defined in the printer resource (wor) class definition. PAGES supplies two parameters when calling this method: ¢ pr isa pointer to a data structure of type woR_PRINT. @ £1ag indicates the type of operation for which the instance of paczs has been constructed; if set to TRUE, the pacEs object is performing a print or preview operation; if set to raLsE, the PAGES object is performing a pagination operation. The method must insert the information which describes the next element to be printed, into this data structure. While the Printing chapter in the Object Oriented Programming Guide discusses woR_PRINT in greater detail, an overview is given below. The pr->flags field describes the type of the print element and affects how the element is to be used. A number of flags may be set into this field; they are not mutually exclusive and are summarised below. WDR_PRINT_START If set, this print element will start the printing process. In effect it causes the printer to be reset and appropriately initialised. WDR_PRINT_END If set, this print element will terminate the printing process. It tells the pacgs object that there is no more data available. WDR_PRINT_LINE If set, the current print position is to be moved back to the beginning of the line, then down by pr->down printer units, then down again by pr->height printer units and finally moved right by pr->indent printer units. WDR_PRINT_FONT If set, the font (i.e. the typeface) is to be changed to that specified in pr->typf, the height changed to that specified in pr->fheight and the style changed to that specified in pr->style. WDR_PRINT_TEXT If set, pr->blen bytes of text from the buffer pointed to by pr->buf are to be printed. WDR_PRINT_KEEP If set, the line containing this print element is to be kept, if possible, on the same page as the following print element. WDR_PRINT_PAGE If set, this print element is to go onto a new page. In other words, a page break will be forced. WDR_PRINT_IDLE If set, the pacEs object is to ignore this print element and then suspend itself. To resume, the application must send the paces object an explicit ao_QUEUE message. PAGELAY_MDONE Handle status messages INT pagelay_mdone (PAGES_DONE *pdone, PAGES_PARAMS *par); This method is also referred to as the done method in this chapter. This call-back method, supplied by the application, provides the mechanism by which a paces object can keep an application informed of the current status of the printing, previewing or paginating operation. The content of the method is application dependent; however, it must take note of the information pacEs passes to it. In return, packs may require "feedback" from the method depending on the precise circumstances in which it is called. FORM REFERENCE PAGES passes two parameters to the method: e par is a pointer to a data structure of type pAcEs_PARAMs, containing such information as page dimensions. See the paces class for more detail on the contents of this structure. ¢ pdone is a pointer to a data structure of type PAGES_DONE. par will contain the handle of the pages.par property of pacEs. pdone will contain information relating to the current status; in particular pdone.event indicates the status of the printing, previewing or paginating operation and can take one of the following values: PAGES_DONE_END Set when printing, previewing or paginating is complete and no further documents are to be printed. Whether printing or paginating, the pacrs object destroys itself after this call-back method returns. If pacEs is paginating, the page array will have been built and its handle placed in pdone->pages. Responsibility for the page array passes to the application which must ensure that it is destroyed before the application itself terminates. Any value returned by this method is ignored. PAGES_DONE_PAGE Set when a page break occurs. paces puts the new page number into pdone->page. Any value returned by this method is ignored. PAGES_DONE_ERROR Set when an error occurs. If an error occurs, the PAGES ao_abrun method is called which: e does a notify by supersending an ao_aBRUN message e calls this call-back method to inform the application e sends itself a pesTRoy message Any value returned by this method is ignored. PAGES_DONE_DOC Set when the printing, previewing or paginating of a document is complete. If more copies of the same document or new documents are to be printed then the method should return TRug; if no more documents are to be printed then the method should return Fratse. 4 THE DOCUMENT PRINTING CLASSES PRNLAY paras tbxlen first senselen nomemory sensebuf adjust pos scan line rd nlines fmt below doc excess slines ngaps spadjust ngap st used ptab plabel destroy sl_print_read l_ init sl_print_pos |_set |_sense | line_ends 1l_pos_to_xl 1_xl_to_pos |_ begin_read l_read 1 _ format_line LsseroLl |_ view |_discard_layout 1 _set_lines 1_para_changed An DH HHA HHA AHA HAR ARR HA A l_rescale The prntay class, in conjunction with its superclass scrLay, provides services to lay out lines and line segments for a printer, from a document that is composed of a sequence of paragraphs. In effect, pRNLay provides property and structures which model the layout of a document on the printer. The methods supplied by this class allow the layout model to be manipulated. It is important to note that the behaviour of prntay is, in essence, the same as the document layout class scruay. All of scriay's property and behaviour is re-usable by prnnay. Only two extra methods are provided by prniay in order to provide the full behaviour. An instance of prniay is normally referenced by two other objects: its creator (normally a window class) and a pacgs class. paces needs a class to provide it with a read call-back method, a method which can supply pacEs with a sequence of print elements; many applications, such as the word-processor, use the PRNLAY sl_print_read method as the call-back method; the specification for the pacEs read call-back method can be found in the description of the paczLay mixin class in this chapter. pacEs, itself, creates an instance of prniay to handle layout for header text. This section makes references to data structures (e.g. Tboxes) which are described in the section on the scruay Class in The Document Layout Classes chapter of this manual. It is strongly recommended that PRNLAY be read in conjunction with scruay. Class definition The prniay class subclasses the FORM class scruay and is defined in the sub-category file scriay.cl (with generated header scrlay.g). The scruay class is documented in The Document Layout Classes chapter in this manual. FORM REFERENCE CLASS prnlay { scrlay ADD sl_print_read ADD sl_print_pos TYPES { typedef struct { Read text for printing Set the start position for printing SCRLAY_PLABEL s; as for the screen UBYTE *wid; the font width table UWORD margin; margin for paragraph labels in printer units UWORD gutter; gutter between label and para margin } PRNLAY_PLABEL; PROPERTY { WORD tbxlen; Number of bytes to still to read from TBOX WORD senselen; Number of bytes to still to read from sensebuf TEXT *sensebuf; Address of text being read (justified only) UWORD pos; Document position to read WORD line; Current line in paragraph WORD nlines; Number of lines in paragraph WORD below; Carried over from previous paragraph WORD excess; Excess width for justified alignment WORD ngaps; Number of gaps for justified alignment WORD ngap; Number of gaps so far WORD used; Excess width used so far SCRLAY_TBOX *ptab; Last tab in line or NULL if no tabs WORD plabel; Line has a para label if TRUE } } Property prnlay.tbxlen prnlay.senselen prnlay.sensebuf prnlay.pos prnlay.line prnlay.nlines This contains the number of characters remaining to be read from the current Tbox. See scruay for a definition of scrLay_TBox. This property is re-set to zero by the s1_print_pos method. This property is only relevant for paragraphs with justified alignment. It is used in conjunction with the prniay.sensebuf property and records the number of characters remaining to be processed within a block of contiguous characters sensed from the document using the sensechars call-back method. This property is re-set to zero by the si1_print_pos method This property is only relevant for paragraphs with justified alignment. The handling of a block of contiguous characters, sensed from the document using the sensechars call-back method, is slightly different when justified alignment is used. Each contiguous section of non-blank characters in the block must be printed separately. This allows the gaps to be adjusted (by moving the print head) to ensure correct alignment. This property records the current position within a block of contiguous characters. The position within the document where text is to be read from next. The current line in the current paragraph. Note that the first line is line zero. The total number of lines in the current paragraph prnlay. prnlay. prnlay. prnlay. prnlay. prnlay. prnlay. below excess ngaps ngap used ptab plabel 4 THE DOCUMENT PRINTING CLASSES This is the space required below the previous paragraph, measured in printer units. The value is added to the value of the space above the current paragraph to calculate the total downward movement of the print head before printing the first line of the current paragraph. This property is re-set to zero by the s1_print_pos method. This property is only relevant for paragraphs with justified alignment. It is a measure of the number of pixels by which the characters on a line (excluding any trailing whitespace) fall short of the right hand margin. This value is used in the calculation of the adjustment to the gaps between contiguous non-blank characters, necessary to achieve justified alignment. This property is only relevant for paragraphs with justified alignment. This is the number of gaps in a line; generally speaking, a gap corresponds with a blank character. If there are any left hand used tabs in the line, it is the number of gaps after the ast used left hand tab. This property is re-set in the sL_PRINT_READ method whenever the first Tbox in a line is being handled. This property is only relevant for paragraphs with justified alignment. It is used in the st_pRINT_READ method to keep a record of how many of the gaps in a line have been adjusted, when printing that line. This information is used to ensure that the line is aligned correctly. This property is re-set in the sL_PRINT_READ method whenever the first Tbox in a line is being handled. This property is only relevant for paragraphs with justified alignment. It is used in the st_PpRINT_READ method to keep a record of how much of the excess width in a line has been "used up" by the adjustment of gaps between words. The address of the final used tab on a line or nutt if the line has no used tabs. The tab is represented by a Tbox (a scRLAY_TBox structure). This property is only relevant if a senseplabel call-back method is supplied by the document content object. In this event, paragraph labels are to be printed. It records the number of printer units the printhead must move after the label has been printed, to reach the start of the paragraph margin. This property is only relevant to the first line of a paragraph. FORM REFERENCE PRNLAY methods SL_PRINT_READ Read text for printing UINT sl_print_read(INT WantData,WDR_PRINT *pr); Read a portion of text for printing and build a print element containing information which describes the text, the typeface, the font height etc. The method takes two parameters: @ WantData indicates the type of operation for which this portion of text is being read. If set to TRUE, a print or preview operation is in progress; if set to FALSE, a pagination operation is in progress. ¢ pr points to a data structure of type woR_pRINT. This structure represents what is known as a print element. The method writes all the necessary information about the portion of text into this data structure. Although this structure is defined in the wor class definition, it is used by paces methods and ppr methods. See the description of the ppr class and the Printing chapter of the Object Oriented Programming Guide. It returns the position within the document corresponding to the start of the portion of text represented by the print element. The method constructs layout for one paragraph at a time and uses this information to construct a series of WDR_PRINT print element for successive sections of text. The method only builds one print element at a time but is expected to be called repeatedly until all of the document has been processed. Much of the property of prnuay (and its superclass scriay) is used to record the "current position" within the document and the layout data structures. The method will correctly calculate items such as right indentations and the address/length of text to be printed; it will also flag line breaks and font changes as required by setting the appropriate WDR_PRINT_... flags. The method will also flag a new page when a paragraph is required to start on a new page. If the senseplabel call-back method has been supplied, worR_pRintT elements will be created to cause a label to be printed in the left hand margin of the first line. When the end of the document is reached, a woR_PRINT_END flag will be set; this will, ultimately, cause printing to terminate. SL_PRINT_POS Set start position for printing VOID sl_print_pos(UINT pos,UINT doclen); Set the start position and the document length for the next call to sL_PRINT_READ. The method takes two parameters: © pos indicates the start position within the document to be printed. This position should correspond to the beginning of a paragraph. @ docien contains the length of the document The method discards any existing layout by sending an si_p1scarp_LayouT message. If the value passed in the parameter doclen is non-zero, this value is recorded as the new document length. If the value is zero, the recorded document length remains unchanged. 4 THE DOCUMENT PRINTING CLASSES A number of items of property are re-set. The following list shows which items are re-set and the corresponding new values: scri scr scr prnl prnl prnl ay.rd.pos the value in pos lay.fmt.pos the value in pos ay.rd.pp NULL ay.tbxlen 0 lay.senselen 0) ay.below 0 Series 3a/Series 3 notes The version of the FORM classes described in this chapter are those which exist on the Series 3a and Workabout. On the Series 3, the classes and the relationships between them are essentially the same. However, there are some differences which need to be discussed. 1. On the Series 3, the pr_print method opens the printer port device itself (by sending a PR_OPEN_PORT message) rather then allowing it to be done by the pdr_init method as occurs on the Series 3a. The handle to the opened port is passed to the paces object as the second parameter in the call to the PAGES ao_init method. Further, the parameter is also used as a flag to indicate whether the PAGES Object is to perform a printing or paginating operation (previewing does not exist on the Series 3). A nuu value is used to indicate that the pacrs object is to perform a pagination rather than a printing operation. The paces ao_init method is prototyped as: VOID ao_init (PAGES_INIT *in,VOID *port,PAGES_PARAMS *par); On the Series 3a, the handle of the prinTER object is set into the spare1 property of the application manager by the pr_init method. On the Series 3, this is not done. Instead, the handle can be found in the printer property of HWIM's wseErv active object. On the Series 3a, the pRINTER class method pr_port_data takes three parameters, the last of which can take the value TRUE or FALSE. On the Series 3, however, this final parameter does not exist and has the effect that the method can only return printer port information as set by the user of the PRINTER object (by an earlier call to the pr_set_port_type). On the Series 3a, the pr_sense_mode1 method searches for a .wdr file of the same name as that held in property or the environment variable psm. If the file cannot be found, all the Loc:: drives are searched. If the file still cannot be found, the rom is searched and, only if it cannot be found here, is the default file Rom: :Bg.woR and model number zero used. The search behaviour on the Series 3 differs slightly. Here, if the file cannot be found, drives a:, B:, and m: are searched before using the default file Rom: :Bg.woR and model number zero. CHAPTER 5 THE PRINT PREVIEW CLASS The Print Preview class, or the prvppR class, to give its correct name, is a subclass of ppr that provides the necessary behaviour to build a preview of a document. Previewing allows us to see up to four pages (up to two in landscape mode) of a document at time, in "miniature", to get an overall view of the layout of the text and to see how it would look when printed. The pages are displayed on the screen. A great deal of the property and behaviour of prvppr is provided by the base class ppr. However, a number of methods are replaced by prvepr, in particular, those dealing with the initialisation and "printing" of a document. The class does not perform I/O to a real physical printer; instead, requests such as printing text, starting a new line and moving the print head are converted into drawing actions on a bitmap and manipulating the position within the bitmap where drawing is to be done. In effect, each page is drawn to a bitmap and each bitmap is compressed and placed into a data segment. This class does not contain behaviour to display the previewed document. The application user interface is normally responsible for decompressing the bitmaps and displaying the previewed pages. It should be noted that although prvppr is a subclass of por, it is not loaded from a separate DYL. This class is not available on the on the Series 3. Precursors An understanding of the print preview class will be helped by a knowledge of: e the p_enter and p_leave error handling services e =the Graphics Output chapter of the Window Server Reference e = =The Document Printing Classes chapter of this manual e the OLIB variable array class, vAFLAT Class diagram The following diagram covers the relationship between the prvppr class and other classes and is discussed in detail in this chapter. The underlined classes are either discussed in another chapter of this manual or they refer to OLIB classes in which case they are all discussed in the OLIB Reference manual. fine Ne a / pdr) y varoot / ~ > ) eres SEES Ye aS / prvpdr_ Z vafix / ~ ) ~ Zod) A eae Z vaflat / = ) oes FORM REFERENCE PRVPDR par pChWidths mode SpaceWidth typfix FontYy fhix TwipsRound style PageHeight lheight Scale a Round trans_rid Pos outlen hPrvDone skipy mPrvDone Bmp SegHandle SegPos SegHeight SegSize pArray pBitRow pLastRow pRowRec destroy pdr_init pdr_print pdr_destroy pdr_start pdr_page pdr_font pdr_end parcpage pdr_text pdr_line pdr_right pde—feont pdr_style Class definition The prvepr class subclasses the ppr class and is defined in the sub-category file prvpdr.cl (with generated header file prvpdr.g). CLASS prvpdr pdr { REPLACE pdr_init Allocate larger buffer REPLACE pdr_print REPLACE pdr_destroy To get around bug in pdr class REPLACE pdr_start Start printing REPLACE pdr_page REPLACE pdr_font TYPES { typedef struct { INT Id; ID of bitmap HANDLE SegHandle; handle of bitmap segment UPOINT Size; UWORD ByteWidth; UWORD BitWidth; width of used bitmap, use this for scaling } PRV_BITMAP; typedef { struct UWORD typeface; UWORD height; UWORD style; typedef typedef BMP_RASTER_TL tl; FONT_DESC; struct UBYTE Type; UBYTE Length; BMP_RASTER_TL; struct UBYTE Data[2]; } BMP_RASTER_ROW_REC; PROPERTY { UBYTE UWORD UWORD UWORD UWORD UPOINT UPOINT UPOINT VOID WORD 5 THE PRINT PREVIEW CLASS *pChWidths; character widths for current font SpaceWidth; width of space in current font FontyY; pixel height of current font TwipsRound; used for rounding in twips conversion PageHeight; Scale; x and y scales (printer units to bitmap units) Round; used to round unit conversions Pos; x and y position in current page bitmap *hPrvDone; Callback handle for %done & completion mPrvDone; Callback method for %Sdone & completion PRV_BITMAP Bmp; HANDLE LONG INT INT PR_ROOT UBYTE UBYTE BMP_RASTER_ROW_REC } } Property prvpdr.pChWidths prvpdr.SpaceWidth prvpdr.Fonty prvpdr.TwipsRound prvpdr.PageHeight SegHandle; segment to save drawing to SegPos; current position in segment SegHeight; height of bitmap segment (lines) SegSize; size of segment (in paragraphs) *pArray; varray of page positions in segment *pBitRow; current row from bitmap *pLastRow; previous row from bitmap *pRowRec; compressed data from preview segment The address of the font width table for the current typeface, font height and style. The width of the space character in the current font, in printer units The height of the current font, in pixels. This is a horizontal and vertical correction factor used in the conversion of twips to pixels in the vertical direction. prvpdr.TwipsRound is the ratio of the number of vertical bits in the bitmap (the number of 'lines' in the bitmap) to the height of the page to be displayed in twips. 1.€. prvpdr.Bmp.Size.y / prvpdr.PageHeight. The height of a page to be displayed in twips. The actual value contained in this property depends on the display mode. In landscape mode, this value is set to the width of the page; in portrait mode, this value is set to the height of the page. FORM REFERENCE prvpdr. prvpdr. prvpdr. prvpdr. prvpdr. prvpdr. prvpdr.SegHandle prvpdr. prvpdr.SegHeight Scale Round Pos hPrvDone mPrvDone Bmp SegPos This is a horizontal and vertical scaling factor used in the conversion of printer units to pixels. prvpdr.Scale.x gives the number of horizontal print head movements needed to print the full width of the page; prvpdr.scale.y gives the number of vertical print head movements needed to print the full height of the page. This is a horizontal and vertical correction factor used in the conversion of printer units to pixels. prvpdr.Round.x is the ratio of the horizontal scaling factor to the number of horizontal bits needed to draw a line (prvpdr.Bmp.BitWidth); prvpdr.Round.y is the ratio of the vertical scaling factor to the number of vertical bits available in the bitmap (prvpdr.Bmp.Size.y). The x and y position in the current page bitmap measured in printer units The handle of the object providing the done callback method. The method number of the done callback method. For the general specification of this method, see the prntprv_mdone method in the description of the PRNTPRV mixin class in this chapter. N.B. The done call-back method here is quite distinct from the paczs done call-back method referred to in The Document Printing Classes chapter. This is a data structure of type prv_BiTmap and contains information relating to the bitmap used for drawing a representation of the page. The individual members of this structure are shown below. N.B. the size, Bytewidth and Bitwidth are shown in a different order to that in the structure. Id The ID of the bitmap as returned by a call to the Window Server function gcreateBit SegHandle The handle of the bitmap segment as returned by the Plib function p_sgopen BitWidth The number of horizontal bits needed to draw a single line so that it fits into the application's window and the ratio of this value to the height of the page measured in pixels is the same as the ratio of the width to the height of the page measured in twips. This value is used to calculate the value of prvpdr. round. x, described above. ByteWidth | The number of bytes needed to accommodate a single line of the bitmap. It is the value of (size.x/s) and assumes that size.x is an exact multiple of eight. Size The dimensions of the bitmap in pixels. The x component is the value of Bitwidth rounded up to an exact multiple of 8. The y component is normally determined by the height of the application's window. The handle of an external data segment into which are copied the compressed bitmaps containing the drawn representation of each document page. This is also referred to as the preview data segment. The segment is created by an instance of the prinTER class and the handle is passed to this instance of prvppr in a call to the pdr_init initialisation method. The current position within the preview data segment measured in bytes. The height of the bitmap segment. Effectively, this represents the number of lines of bits available for drawing. 5 THE PRINT PREVIEW CLASS prvpdr.SegSize The current size of the preview data segment, in paragraphs (i.e. units of sixteen bytes). prvpdr.pArray The handle of a varLat object. The array is used to hold a series of values which give the position of consecutive compressed bitmaps within the preview data segment. It is designed to hold entries (records) which are the length of a Lone 'C' data type and has a granularity of 16 entries (records). The instance of var.at is initialised by the application before the creation of this instance of prvpr and contains a single entry (record) holding a zero value. prvpdr.pBitRow The address of a buffer to contain a copy of the current row from the bitmap. The buffer itself is prvpdr.Bmp.ByteWidth bytes long. This buffer is used by the pdr_page method during bitmap compression. prvpdr.pLastRow The address of a buffer to contain a copy of the previous row from the bitmap. The buffer itself is prvpdr.Bmp.ByteWidth bytes long. This buffer is used by the pdr_page method during bitmap compression. prvpdr.pRowRec The address of a buffer to contain compressed data from the bitmap. The buffer itself is (prvpdr.Bmp.ByteWidth plus the length of structure BMP_RASTER_ROW_REC) bytes long. This buffer is used by the pdr_page method during bitmap compression. PRVPDR methods PDR_INIT Initialise VOID pdr_init (PDR_INIT *pPar) Initialise the instance of prvppr. This method replaces the subclass pdr_init method. The method takes a single parameter: ppar points to a data structure of type ppR_iniT which contains information required to initialise the instance. The method starts by copying the entire content of *ppar into the property pdr. par. A PR_PREVIEW_DATA message is then sent to the PRINTER object to fetch the address of the pRINTER property printer.prv. This is a data structure of type PREVIEW_DaTA and contains information required for the preview operation. For more detail on the content of this structure, see the PRINTER class pr_preview_start method in The Document Printing Classes. Note that the assumption is made that a copy of the handle of the pRInTER object is contained in the application manager's spare1 property. A FORM printer object, as part of its initialisation process, always inserts a copy of its own handle into the application manager's spare1 property for the convenience of a large number of methods within a variety of classes. A number of items of property are set by copying corresponding members from the PpREVIEW_DATA structure: prvpdr.SegHandle, prvpdr.pArray, prvpdr.hPrvDone, prvpdr.mPrvDone plus the size and Bitwidth members of prvpdr.Bmp. The sytewidth member of prvpdr.Bmp is set to the value of prvpdr.Bmp.Size.x divided by eight. A memory cell, large enough to contain three buffers, is allocated and added to the cleanup list. The memory cell is partitioned as follows: e the address of the first prvpdr.Bmp.Bytewidth bytes is set into the property prvpdr.pBitRow; this buffer is prvpdr.Bmp.Bytewidth bytes long and will contain the current bitmap row. e the address of the second prvpdr.Bmp.Bytewidth bytes is set into the property prvpdr.pLastRow; this buffer is prvpdr.Bmp.Bytewidth bytes long and will contain the previous bitmap row. e the address of the third prvpdr.Bmp.Bytewidth bytes is set into the property prvpdr.pRowRec} this buffer is (prvpdr.Bmp.Bytewidth + length of a BMP_RASTER_ROW_REC structure) bytes long and will contain the bitmap raster row record. FORM REFERENCE A bitmap is created in its own memory segment, using the gcreateBit Window Server function, and the returned bitmap ID is set into prvpdr.Bmp.1d; the size of the bitmap is determined by the value of prvpdr.Bmp.Size. The bitmap memory segment is then opened, using the p_sgopen Plib function, and the returned handle to the opened memory segment is set into prvpdr.Bmp.SegHandle. Note that if p_sgopen returns an error condition, the bitmap is explicitly freed (using wrree) and p_leave called, passing it the error code returned by p_sgopen. A PR_GET_PARAMS message Is sent to the PRINTER object to get the address of the printer parameters. The printer parameters are held in a pRINTER_PARaMs data structure in PRINTER'S property printer.p. The horizontal and vertical scaling factors and rounding values are calculated and set into the properties: prvpdr.Scale, prvpdr.Round and prvpdr.TwipsRound. These values will be used to calculate the number of bits required to represent items of text in the bitmap representation of the document. Specifically, they are used to convert twips and printer units into numbers of pixels. Note that, in calculating these values, account is taken of whether the document is in landscape or portrait mode. Finally, the memory cell containing the three buffers is removed from the cleanup list. PDR_PRINT Interpret print command INT pdr_print (WDR_PRINT *pr,UBYTE **ppbuf) Interpret a print element and manipulate, or draw, to the bitmap. The method takes two parameters: ¢ pr contains the address of a print element; this is a data structure of type woR_PRINT. See the description of the ppr superclass pdr_print method in The Document Printing Classes chapter in this manual for more information on the woR_PRINT structure. The Printing chapter of the Object Oriented Programming Guide also contains some useful background information. ¢ ppbuf is not used by this method but is included in the method prototype for compatibility with the superclass pdr_print method. When calling this method, the parameter can be nut. In general, the method uses the information in the print element to print (1.e. to draw) to the bitmap and to manipulate the position within the bitmap where drawing is to be done. A print element will also indicate where page breaks occur and the start and end of the printing process. The detailed working of this method is driven by the settings of the f£1ags member of the print element. flags can contain an ored combination of values. Depending on the individual flags set, the method proceeds as follows: WDR_PRINT_START The method sends a ppR_sTarT message to this instance of pRvppR to prepare the printing process. WDR_PRINT_PaGE This flag indicates a page break request and causes the method to send a PDR_PAGE message to this instance of pRvppR to copy (and compress) the bitmap of the current page to the preview data segment. The code is constructed such that if the pdr_page method returns with an error, the done callback method is called to inform the application of the error and is followed by a call to p_leave specifying the returned error code. WDR_PRINT_LINE This flag indicates a line break. The sum of the down and height members of the print element indicates the amount by which the print position must be moved downwards. The value of the indent member of the print element indicates the initial print position relative to the left hand edge of the page. With this flag set, the vertical print position within the bitmap, as defined by the value of prvpdr.Pos.y, is adjusted by the sum of the down and height members of the print element; the horizontal print position within the bitmap, as defined by the value of prvpdr.Pos.x, is set to the value of the indent member of the print element provided that this is greater than zero. A zero or negative value of indent causes prvpdr.Pos.x to be set to zero. 5 THE PRINT PREVIEW CLASS WDR_PRINT_FonT This flag indicates a request to set a font and causes the method to send a PDR_FONT message to this instance of prvppr to set the typeface, font height and style as defined by the typf, fheight and style members of the print element respectively. The code is constructed such that if the pdr_font method returns with an error, the done callback method is called to inform the application of the error and is followed by a call to p_leave specifying the returned error code. WDR_PRINT_RIGHT This flag indicates a request to move the print position to the right. The horizontal print position within the bitmap, as defined by the value of prvpdr.Pos.x, is incremented by the value of the right member of the print element provided that its value is greater than zero. If the value of right is zero or negative, no adjustment is made. WDR_PRINT_TExT This flag indicates that there is text to be printed. The address of a buffer containing the text to be printed (i.e. drawn ) to the bitmap is contained in the buf member of the print element. The length of the text to be printed is contained in the 1en member. No attempt is made to draw actual scaled characters because the resolution of the screen is not sufficiently fine. Instead, filled rectangles are drawn for every word of text, scaled according to the size of the word and the font height. A temporary graphics context is used for the drawing. WDR_PRINT_END The method terminates the printing (i.e. drawing) process by sending a PDR_PAGE message to this instance of prvppr to ensure that the bitmap of the final page is copied (and compressed) to the preview data segment. If the called pdr_page method completes successfully, it (pdr_print) calls the done call-back method, passing a value of pacEs_DONE_Doc, to inform the application of the event. If the called pdr_page method fails with an un-recoverable error, it (pdr_page) calls the done call-back method, passing a value of PAGES_DONE_ERROR before calling p_leave to propagate the error. The method always returns a zero value. PDR_DESTROY Destroy VOID pdr_destroy (VOID) Destroy the instance of pRvppR. The memory cell from which the three buffers, allocated in pdr_init, and anchored in the properties prvpdr.pBitRow, prvpdr.pLastRow and prvpdr.pRowRec, is freed. The bitmap is freed using the window server function wrree and the bitmap memory segment is freed using the Plib function p_sgclose. PDR_START Start printing (drawing) VOID pdr_start (VOID) Prepare to start the printing (i.e. drawing) process. The method clears the bitmap ready for drawing by doing the following: ¢ Create a temporary graphics context, specifying the bitmap as the drawable entity. e Clear the pixels in the whole bitmap by calling the window server function gcirRect. e Free the temporary graphics context. The property pdr.typfix is set to -1; this guarantees that a font width table will be loaded in. See the pdr_font method. FORM REFERENCE An internal call is made to code which implements the pdr_font method to set the default typeface, a font height of 120 twips and the normal style. This code runs under the protection of p_enter. If an un-recoverable error occurs within this code, the done call-back method will be called, passing a value of PAGES_DONE_ERROR before calling p_leave to propagate the error. PDR_PAGE Start a new page INT pdr_page (VOID) Copy (and compress) the bitmap of the current page to the preview data segment. The preview data segment is the external data segment allocated by the prInTER object and whose address is passed to pRvppR during initialisation (see the pdr_init) method. The method calls the window server function wF1ush to ensure that all drawing to the bitmap is complete. The method then takes the bitmap representing the current page and compresses the data using raster graphics compression techniques and copies the compressed data to the preview data segment. The bitmap itself is then cleared in exactly the same way as described in the pdr_start method, ready for another page to be drawn. If a full page is successfully drawn to the bitmap, the method informs the application by calling the done call-back method, passing a value of PAGES_DONE_PAGE. Note that the code implementing this method runs under the protection of p_enter. If an un-recoverable error occurs within this code, the done call-back method will be called, passing a value of PAGES_DONE_ERROR before calling p_leave to propagate the error. PDR_FONT Set the font INT pdr_font (INT typeface, INT height,INT style) Set the typeface, font height and style. The method takes three parameters: e typeface specifies the number of the required typeface. e height specifies the height, in twips, of the required font. e style specifies the required style and can be an ored combination of: woR_STYLE_NORMAL, WDR_STYLE_UNDERLINE, WOR_STYLE_BOLD, WDR_STYLE_ITALIC, WDR_STYLE_SUPER and WDR_STYLE_suB. See the description of the pdr_style method of the ppr class in The Document Printing Classes chapter of this manual. The method sends a woR_SEARCH_TYPEFACE message to the associated wor object to retrieve the typeface index. The typeface index is the index of the entry within the array of pointers to woR_TYPEFACE structures which represents the typeface with number typf. In effect, it identifies the location of the information on the required typeface. The method then sends a woR_SEARCH_HEIGHT message to retrieve the font height index. This is the index of the entry within the array of woR_ronT structures which most closely represents the font with height height. In effect, it identifies the location of the information on the required font. See the description of the wor class in The Document Printing Classes chapter of this manual for more information on typefaces and fonts and the data structures representing them. The font height is converted from twips to pixels and the resulting value set into the property prvpdr.Fonty. If the required typeface or the required font height or the required style differs from the existing ones (as recorded in the subclass property: pdr.typfix, pdr.fhix and pdr.style respectively), then a WDR_GET_WIDTH_TABLE Message is sent to get the address of the new font width table. This address is set into the property prvpdr.pchWidths; the width of the blank character is set into the property prvpdr.SpaceWidth. Note that the code implementing this method runs under the protection of p_enter. If an un-recoverable error occurs within this code, the done call-back method will be called, passing a value of PAGES_DONE_ERROR before calling p_leave to propagate the error. 5 THE PRINT PREVIEW CLASS The PRNTPRV mixin class PRNTPRV The prntprv mixin class provides the general specification for the call-back method(s) that may be called by the prvppr class. The call-back method mdone is also referred to as the done method. For a general discussion on call-back methods and mixin classes, see the Introduction chapter in this manual. The prntprv class does not appear in the FORM library and an instance of prntprv will never be created. The FORM library does not supply a class which can provide the required done call-back method; this is normally supplied by the application. Class diagram The following class diagram formally illustrates the relationship between the prntprv mixin class and the PRVPpDR Class. This diagram shows both the ppr class and the prntprv class in order to emphasise the multiple inheritance aspect of mixin classes. OLE i ES os if pdr / C prniprv / N“N ) Sy ) a 7 Lo f — yb dr / ~ ) ees Class definition CLASS prntprv root { DEFER mdone report status } Property None. PRNTPRV call-back methods PRNTPRV_MDONE Handle status messages INT prntprv_mdone (INT event); This method is also referred to as the done method in this chapter. This call-back method, supplied by the application, provides the mechanism by which a prvepr object can keep an application informed of the current status of the previewing operation. It is very similar, in some respects, to the pacELay done call-back method. However, unlike the paceLay done call-back method, this method is only passed the status of the pRvppR object. The content of the method is application dependent; however, it should take note of the information PRVPDR passes to it. PRVPDR passes a single parameter: ¢ event indicates the status of the previewing operation and can take one of the following values: FORM REFERENCE PAGES_DONE_PAGE PAGES_DONE_ERROR PAGES_DONE_DOC This is set when a full page has been successfully drawn to the bitmap, the bitmap has been compressed and copied to the data segment and the bitmap itself has been cleared and other property reset ready to build the next page. Any value returned by this method is ignored by prvppr. This is set when an un-recoverable error occurs. Any value returned by this method is ignored by prvepr. This is set when the previewing operation is complete. The last page will have been successfully drawn to the bitmap and the bitmap itself copied to the data segment. Any value returned by this method is ignored by prvepr. Although this method is prototyped to return an int value, a pRvPDR object makes no use of it. As a useful convention, it is suggested that this method return a TrRuE value. CHAPTER 6 THE CALENDAR IMAGE CLASS Precursors An understanding of the canine class will be helped by a knowledge of: e the graphical calendar display in the Series 3a Agenda application. Note that on the Series 3a it is more convenient to use the cALWwIN class rather than the caine class. See the Calendar Classes chapter of the HWIM Reference manual. The canine class simply subclasses Root and uses no other classes as components. CALIMG rect bwidth title_rect filler dayNameAbbrev deftitle startOfWeek title thisyear emphasised thismth img thisday bmid ystart destroy ci_adjust_date ci_init ci_redraw ci_set_title ci_sense ci_emphasise ci_view ci_move_cursor ci_pos_mxy ci_goto_date ci_today_changed The canine class supports a graphical calendar display as used by the Series 3a Agenda application. The calendar display provides a convenient method for the user to either select a date or determine the day of the week for a given date. Note that the user is responsible for passing the ID of a suitable window for the calendar image. The various titles in the calendar are indicated in the following picture: month title calendar title days of the week title FORM REFERENCE Note that the borders are not drawn by the cani1mc object and thus must be explicitly drawn by the application. The calendar supports multiple rows and columns of months as illustrated in the following picture: 1994 February March April MTWT‘FSS NTWTFSS MNMTWTFSS 123456 123456 123 7 8 918111213 7 8 99]111213 45 6 7 8 916 14151617181926 14151617181926 11121314151617 21 222324252627? 2122232425262? 18192621 22 2324 28 28 29 36 31 25 26 27 28 29 36 On the Series 3a the practical limit to the maximum number of rows is two whilst the limit on the number of columns is six. Note that the edges of the calendar are notionally mapped onto the preceding and following months. Thus in the above example moving the cursor upwards eventually scrolls the display to the preceding month. Class definition The canine class subclasses root and is defined in the sub-category file calimg.cl (with generated header file calimg.g). CLASS { REPLACE destroy calimg root ADD ci_init ADD ci_set_title ADD ci_emphasise ADD ci_move_cursor ADD ci_goto_date ADD ci_adjust_date ADD ci_redraw ADD ci_sense ADD ci_view ADD ci_pos_mxy ADD ci_today_changed CONSTANTS { CI_MAX_MONTH 12 CI_GRIDY TRUE /* get month row */ CI_GRIDX FALSE /* get month col */ CALIMG_CURSOR_NO_FLASH 0x01 CALIMG_DOW_EVERY_ROW 0x02 CALIMG_FONT_DATA_KNOWN 0x04 CALIMG_LEFT 0x00 /* physically go to day on the left */ CALIMG_HOME 0x01 /* goto leftmost day & month of row */ CALIMG_PREV_DAY 0x02 /* decrement by day */ CALIMG_PREV_MONTH 0x03 /* decrement by month */ CALIMG_RIGHT 0x04 /* physically go to day on the right */ CALIMG_END 0x05 /* goto most right day & month of row */ CALIMG_NEXT_DAY 0x06 /* increment by day */ CALIMG_NEXT_MONTH 0x07 /* increment by month */ CALIMG_UP 0x08 /* physically go to day above */ CALIMG_PAGEUP 0x09 /* goto previous page maintain x,y in month */ CALIMG_PREV_WEEK OxOA /* decrement by week */ CALIMG_PREV_YEAR 0x0OB /* decrement by year */ CALIMG_DOWN 0x0C /* physically go to day below */ CALIMG_PAGEDN 0x0D /* goto next page,maintain x,y in month */ CALIMG_NEXT_WEEK OxOE /* increment by week */ CALIMG_NEXT_YEAR OxOF /* increment by year */ 6 THE CALENDAR IMAGE CLASS CALIMG_GOTO_TODAY 0x10 CALIMG_WEST 0x01 CALIMG_EAST 0x02 CALIMG_NORTH 0x03 CALIMG_SOUTH 0x04 CALIMG_ADJ_DAY 0x01 CALIMG_ADJ_MONTH 0x02 CALIMG_ADJ_YEAR 0x04 } TYPES { typedef struct { UBYTE title_ascent; ascent for title UBYTE title_lht; line height for title UBYTE dow_ascent; ascent for day of week UBYTE dow_lht; line height for day of week UBYTE mth_ascent; ascent for month UBYTE mth_lht; line height for month UBYTE day_ascent; ascent for day/date UBYTE day_lht; line height for day/date UBYTE daygapx; gap between 2 dates UBYTE daywidth; 2 numeric width characters ie width for 1 day } CI_EXT_FONT; Extended font information typedef struct { WORD fid; font ID UWORD style; font style whether bold,italics,etc UWORD leading; leading below text } CI_FONT_DATA; typedef struct { UWORD wid; window ID UWORD width; calimg window width P_POINT tl; tl.x=left & right gutters; tl.y=top & bottom gutters UBYTE mrow; number of rows of months to display UBYTE mcol; number of cols of months to display UWORD flags; CI_FONT_DATA title; font info for main top line title CI_FONT_DATA month; font info for month title CI_FONT_DATA dow; font info for day of week CI_FONT_DATA day; font info for the days itself UWORD daygap; CHAR NUMBER to use as horizontal gap between 2 days UBYTE mthgapx; no of pixels of horizontal gap between 2 months UBYTE hscrlm; granularity for scrolling horizontally by month UWORD startm; month number to display as first month, ie tl month ULONG days; days field of daysec struct ie days since 1/1/1900 CI_EXT_FONT font; extended font info, defaults filled in by ci_init() } IN_CALIMG; typedef struct { UBYTE year; Year number since 1900 UBYTE month; month number 0 to 11 P_POINT pos; x,y position within a month } CI_CURSOR; typedef struct { WORD year; WORD month; WORD day; }CI_DATE; FORM REFERENCE PROPERTY { P_REC P_REC CI_CU BYTE UBYTE UBYTE UBYTE UBYTE UBYTE UBYTE UBYTE TEXT TEXT TEXT WORD T rect [12]; T title_rect; RSOR crs; day; startOfWeek; thisyear; thismth; thisday; ystart; bwidth; filler; dayNameAbbrev [7]; deftitle[3]; *title; emphasised; region to draw for each month, tl==tl of month title line use to print title current cursor pos x,y & month & year day number in month, 0 to 30, negative days are possible as opposed to last year & next year as opposed to last month & next month TODAY year of the tl month on display 2*char width of bold font for today ist letters of days of week, default title starting at startOfWeek keeping track of whether it is already emphasised IN_CALIMG img; INT bmid; } } Property cal cal cal cal cal cal cal cal cal cal cal cal cal cal img. img. img. img. img. img img. img img. img. img. img. img. img. rect title_rect crs day startOfWeek -thisyear thismth .-thisday ystart bwidth filler dayNameAbbrev deftitle title calimg.emphasised calimg.img calimg.bmid 6-4 bitmap ID for all days in a month defines the drawing region for each month in the calendar view - used internally. defines the drawing region for the calendar title - used internally. the cursor coordinates in the current month - (0,2) for example defines a cursor at the intersection of column one and row three. the day number of the current day in the range 0 to 30 where 0 is the first of the month. the day number (in the range 0 to 6 where 0 is Monday) of the first day of the week. This is usually 0 on UK machines. the year number for today - where today is determined by a call to p_date - in the range 0 to 254 inclusive where 0 is 1900. the month number for today in the range 0 to 11 inclusive where 0 is January. the day number for today in the range 0 to 30 inclusive where 0 is the first of the month. the year number of the first month in the calendar view - the first month is in the top left corner. two times the width of a bold numeric character in the day font - this is the width of the day symbol when the day is ‘today’. used internally. contains the first letter of each day with the first element corresponding to the day in calimg.startofWeek. On UK machines the first element usually contains 'M’. the default format string for the calendar title - i.e. "%Y". the format string for the calendar title - nun1 indicates that the format string is to be read from calimg.deftitle. All occurrences of %Y and %y are replaced with the appropriate year(s). All occurrences of %% are replaced with %. All other occurrences of % are ignored. Thus "A& silly %% example %Y title" generates "A silly % example 1994 title" in 1994 and "A silly % example 1994-1995 title" in 1994-1995. TRUE if the calendar is emphasised, and rause otherwise. data passed to the ci_init method: see the description of the ci_init method for details of the fields. ID of a bitmap - the bitmap is for internal use only. 6 THE CALENDAR IMAGE CLASS CALIMG methods DESTROY Destroy the calendar VOID destroy (VOID) Destroy the caLime instance. If calimg.emphasised is TRUE, the method erases the text cursor. If calimg.title is non-zero, the method frees the cell with address calimg.title. The method then frees the bitmap with ID calimg.bmid and supersends a DESTROY message. Cl_INIT Initialise the calendar VOID ci_init (IN_CALIMG *init) Initialise the instance of caLimc according to the content of the 1n_cauime structure pointed to by init. The tn_catince structure is defined as follows: typedef struct { UWORD wid; UWORD width; P_POINT tl; UBYTE mrow; UBYTE mcol; UWORD flags; CI_FONT_DATA title; CI_FONT_DATA month; CI_FONT_DATA dow; CI_FONT_DATA day; UWORD daygap; UBYTE mthgapx; UBYTE hscrilm; UWORD startm; ULONG days; CI_EXT_FONT font; } IN_CALIMG; The significance of the members of the 1n_cauine structure is as follows: wid specifies the ID of the window which provides the drawing region. width specifies the width in pixels of the drawing region. ED specifies the gutter dimensions. the x member specifies the width in pixels of the left and right gutters and must not be less than 3. the y member specifies the height in pixels of the top and bottom gutters and must not be less than 3. mrow specifies the number of rows in the calendar view. mcol specifies the number of columns in the calendar view. flags an ored combination of flags: see below for the available flags. title specifies the font characteristics of the main title. A description of the c1_FonT_INFo structure may be found below. month specifies the font characteristics of the month title. A description of the c1_FonT_INFo structure may be found below. dow specifies the font characteristics of the days of the week title. A description of the CI_FONT_INFo structure may be found below. FORM REFERENCE day specifies the font characteristics of the day of the month numbers. A description of the CI_FONT_INFo structure may be found below. daygap specifies a character, the width of which in the day number font and style, defines the spacing between day numbers. mthgapx _ specifies the horizontal pixel separation between adjacent months. hserlm specifies the default granularity for scrolling horizontally by month: should be divisible by the total number of months in the calendar view. startm specifies the month number of the first month that appears in the top left corner of the calendar. days specifies the current date expressed as the number of days elapsed since 1/1/1900. font specifies additional font information for the main title, month title, days of the week title and the day of the month numbers. This information includes the line heights and line ascents as described below. The flags member of the c1_1n1T structure may contain an ored combination of the following flags: CALIMG_CURSOR_NO_FLASH draw a non-flashing cursor indicating the current day. The default is a flashing cursor. CALIMG_DOW_EVERY_ROW specifies that the days of the week title is to be included only in the first row of months. This flag must be set on the Series 3a when two rows of months are required otherwise the calendar view will be too large for the screen. FONT_DATA_KNOWN indicates that the line heights and ascents are specified in init->font. Otherwise the method overwrites font with default values. The c1_ExtT_ront structure specifies the line heights and line ascents in the calendar view. It is defined as follows: typedef UBYT } Cl struct title_ascent; title_lht; dow_ascent; dow_lht; mth_ascent; mth_lht; day_ascent; day_lht; daygapx; daywidth; _EXT_FONT; The significance of the members of the c1_zxT_FonT structure is as follows: title_ascent specifies the ascent in pixels of the calendar title. title_lht dow_ascent dow_lht mth_ascent mth_lht day_ascent day_lht daygapx daywidth specifies the height in pixels of the calendar title. specifies the ascent in pixels of the days of the week title. specifies the height in pixels of the days of the week title. specifies the ascent in pixels of the month title. specifies the height in pixels of the month title. specifies the ascent in pixels of a day of the month number. specifies the height in pixels of a day of the month number. specifies the gap between adjacent days of the month. specifies the width of a day of the month number i.e. two times the width of a numeric character. 6 THE CALENDAR IMAGE CLASS The c1_Font_inro structure which is used to specify the appearance of all text displayed in the calendar is defined as follows: typedef struct { WORD fid; UWORD style; UWORD leading; } CI_FONT_DATA; The significance of the members of the c1_FonT_inFo structure is as follows: fid specifies the font ID of the text. style specifies the style of the text. leading specifies the leading - i.e. vertical spacing - below the text. If the total number of months in the calendar as specified by init->mcol*init—>mrow exceeds CI_MAx_montH the method calls p_leave with an argument of &_cGEN_ToomaNY. The method initialises the property according to the content of the c1_1nrT structure with address init as described above. If init->hscr1m is greater than the total number of months in the calendar as specified by init- >mcol*init->mrow then the method resets init->hscrim to the total number of months in the calendar. If init->startm is outside the allowed range of 0 to 11 inclusive, the method resets init->startm to 0. If the current month as specified by init->days is not included in the calendar view, the method adjusts init->startm appropriately. Write *init tO calimg.img. Cl_SET_TITLE Set the title VOID ci_set_title(TEXT *zts) Replace the calendar title with the zero terminated string pointed to by zts. The method frees the cell pointed to by calimg.title. If zts is NuLL the method writes zero to calimg.title. Otherwise the method allocates an appropriately sized cell and copies into the cell the title string pointed to by zts. The address of the cell is written to calimg.title. Cl_EMPHASISE Emphasise the view VOID ci_emphasise(UINT flag) Emphasise the calendar if f1ag is TRUE, otherwise de-emphasise the calendar. If f1ag is equal to calimg.emphasised the method simply returns as no change is required. Otherwise the method records the emphasis state by writing flag to calimg. emphasised. If calimg.img.flags does not contain cALIMG_CURSOR_NO_FLASH, and flag iS TRUE the method draws the cursor by calling wrextcursor. If calimg.img.flags does not contain cALIMG_CURSOR_NO_FLASH, and flag is raLsE the method erases the cursor by calling weraseTextCursor. FORM REFERENCE Cl_MOVE_CURSOR Move the cursor VOID ci_move_cursor(INT flag) Move the cursor to the position specified by f1ag and redraw the calendar view ensuring that the current date is visible. The allowed values of £1ag are as follows: CALIMG_GOTO_TODAY move the cursor to the date today - as stored by the machine - by sending seif a CI_GOTO_DATE message with appropriate arguments. CALIMG_LEFT move the cursor to the left one day by sending se1f a cI_Pos_mxy message specifying calimg.img.hscrim as the scroll increment. If the resulting cursor position is not valid, move the cursor to the last day of the month. CALIMG_RIGHT move the cursor to the right one day by sending se1f a cI_Pos_mxy message specifying calimg.img.hscrim as the scroll increment. If the cursor is either on the last day of the month or in the last column of the month the method moves the cursor rightwards into the first column of the next month. If this is not a valid day, the method then moves the cursor upwards until a valid day is found. CALIMG_UP move the cursor up one day by directly calling the ci_pos_mxy member function specifying mco1 as the scroll increment. CALIMG_DOWN move the cursor down one day by directly calling the ci_pos_mxy member function specifying mco1 as the scroll increment. CALIMG_HOME move the cursor horizontally to the left most day in the calendar view by directly calling the ci_pos_mxy member function. CALIMG_END move the cursor horizontally to the right most day in the calendar view by directly calling the ci_pos_mxy member function. CALIMG_PAGEUP move the calendar view and the cursor backwards in time by calimg.img.mrow*calimg.img.mcol months by directly calling the ci_pos_mxy member function. CALIMG_PAGEDN move the calendar view and the cursor forwards in time by calimg.img.mrow*calimg.img.mcol months by directly calling the ci_pos_mxy member function. CALIMG_PREV_DAY move the cursor backwards in time one day by sending self a CI_ADJUST_DATE message specifying a scroll increment of calimg.img.hscrim. CALIMG_NEXT_DAY move the cursor forwards in time one day by sending self a CI_ADJUST_DATE message specifying a scroll increment of calimg.img.hscrim. CALIMG_PREV_MONTH move the cursor backwards in time by one month by sending self a CI_ADJUST_DATE message specifying a scroll increment of calimg.img.hscrim. CALIMG_PREV_YEAR move the cursor backwards in time by one year by sending self a CI_ADJUST_DATE message specifying calimg.img.mrow*calimg.img.mcol as the scroll increment. CALIMG_NEXT_MONTH move the cursor forwards in time by one month by sending self a CI_ADJUST_DATE message specifying a scroll increment of calimg.img.hscrim. CALIMG_NEXT_YEAR move the cursor forwards in time by one year by sending self a CI_ADJUST_DATE message specifying calimg.img.mrow*calimg.img.mcol as the scroll increment. 6 THE CALENDAR IMAGE CLASS CALIMG_PREV_WEEK move the cursor backwards in time one week by sending self a CI_ADJUST_DATE message specifying a scroll increment of calimg.img.hscrim. CALIMG_NEXT_WEEK move the cursor forwards in time one week by sending self a CI_ADJUST_DATE message specifying a scroll increment of calimg.img.hscrim. Note that both the ci_adjust_date and the ci_pos_mxy methods redraw the calendar view once the cursor has been repositioned. Cl_GOTO DATE Move the cursor by date VOID ci_goto_date(CI_DATE *pdate) Move the cursor to the date specified by the c1_pate structure pointed to by pdate and redraw the calendar view ensuring that the current date is visible. The c1_pate structure is defined as follows: typedef struct { WORD year; WORD month; WORD day; }CI_DATE; The significance of the members of the c1_pate structure is as follows: year The candidate year number in the range 0 to 254 inclusive where 0 is the year 1900 - set to zero if a negative value is specified. month The candidate month number in the range 0 to 11 inclusive where 0 is January - set to the nearest limit if the specified value is outside of the allowed range. day The candidate day number in the range 0 to 30 inclusive where 0 is the first of the month - set to the nearest valid day in the month if the specified value is not a valid day. Note of course that the last valid day number may be less than 30. The method updates calimg.crs according to the values specified in pdate and then updates the view by sending self a CI_vIEW message specifying a scroll increment of calimg.img.hscr1m. Cl_ADJUST_DATE Adjust the current date VOID ci_adjust_date(CI_DATE *pinc, INT flag, INT hscrl1m) Move the cursor forwards or backwards in time as specified by pinc and flag and redraw the calendar view ensuring that the current date is visible specifying a scroll increment of hscrim. The action is controlled by writing one of the following values to £f1ag: CALIMG_ADJ_YEAR adjust the year, the month and the day. CALIMG_ADJ_MONTH adjust the month and the day. CALIMG_ADJ_DAY adjust the day. The year is adjusted by moving the cursor forwards or backwards in time by pinc->year years. The month is adjusted by moving the cursor forwards or backwards in time by pinc->month months and if the cursor is not on a valid day moving the cursor to the last day of the month. The day is adjusted by moving the cursor forwards or backwards in time by pinc->day days. Note that if the cursor moves to a year that is out of range the method beeps and then returns without modifying the property. The method call thus has no effect. The method draws the view by sending self a cI_viEw message specifying a scroll increment of hscrim. FORM REFERENCE Cl_REDRAW Redraw part of the view VOID ci_redraw(P_RECT *prect) Redraw calendar months that overlap the rectangle defined by prect. If calimg.img. flags contains CALIMG_CURSOR_NO_FLASH, and the current cursor position is visible, draw an appropriately sized inverted obloid at the current cursor position. (Otherwise the system takes care of drawing the flashing cursor.) Cl_SENSE Sense the current date VOID ci_sense(ULONG *psense) Write the current date to the uLonc pointed to by psense. The current date is expressed as the number of days elapsed since 1/1/1900. Cl_VIEW Draw the view VOID ci_view(INT hscrlm) Draw the calendar view ensuring that the current date is visible specifying a scroll increment of hscrim. The method sets the first month in the calendar view as specified by calimg.img.startm and calimg.ystart and then scrolls the calendar view forwards or backwards in time an integral multiple of hscrim months until the current date is included in the calendar view. On occasion this will lead to months outside the allowed date range being included. In such cases the method sets the first month in the calendar view as specified by calimg.img.startm and calimg.crs.year and then repeats the above algorithm. The method then draws the calendar view, using the wscrol1Rect routine whenever possible. Cl_POS MXY Move the cursor by position VOID ci_pos_mxy(CI_CURSOR *pcrs,INT gravity,INT scrl) Move the cursor to the year, month and coordinates specified by the c1_cursor structure with address pers Specifying a scroll increment of scr1. Note that if the coordinates within the month do not correspond to a valid day the method moves the cursor according to the value of gravity until a valid day is located. The c1r_cursor structure is defined as follows: typedef struct { UBYTE year; UBYTE month; P_POINT pos; } CI_CURSOR; The significance of the members of the c1_cursor structure is as follows: year the year number in the range 0 to 254 inclusive where 0 is the year 1900. month — the month number in the range 0 to 11 inclusive where 0 is January. pos an x,y position within a month: the third day on the second row for example has position (2,1). If pcrs->pos.x is less than zero, the method resets pcrs->pos.x to 6, and moves the cursor backwards in time one month. If pcrs—->pos.x 1s greater than 6, the method resets pcrs->pos.x to 0, and moves the cursor forwards in time one month. If pcrs->pos.y is less than zero, the method resets pcrs->pos.y to 6, and moves the cursor backwards in time calimg.img.mcol months. 6 THE CALENDAR IMAGE CLASS If pcrs->pos.y is greater than 5, the method resets pcrs->pos.y to 0, and moves the cursor forwards in time calimg.img.mcol months. If as a result of one of the above tests the year exceeds 2154, the method beeps and then returns. If the coordinates specified by pcrs->pos do not correspond to a valid day in the current month, the method moves the cursor in the manner indicated by gravity until a valid day is located. The allowed values for gravity are as follows: CALIMG_NORTH move the cursor upwards in the calendar until a valid day is located. CALIMG_WEST if the cursor is in the bottom row of the current month, the bottom row contains no valid days and the cursor lies to the right of the last day of the month, move the cursor to the last day of the current month. otherwise if the cursor is in the bottom row of the current month and the bottom row contains no valid days move the cursor to the first day in the last valid row of the current month i.e. to coordinates (0,4), or (0,3) if (0,4) is not valid. otherwise move the cursor leftwards in the calendar view until a valid day is located. CALIMG_SOUTH move the cursor downwards in the calendar view until a valid day is located. CALIMG_EAST if the current position is in a bottom row of a month which contains no valid days, move the cursor to the last valid day of the month. otherwise move the cursor rightwards in the calendar view until a valid day is located. The method draws the view by sending self a cI_vIEw message specifying a scroll increment of scri. Cl_TODAY_CHANGED Update today's date VOID ci_today_changed (VOID) Update today's date and redraw the calendar as required. The method obtains the actual date by calling the p_date PLIB routine and then writes the year number to calimg.thisyear, writes the month number to calimg.thismth and writes the day number to calimg.thisday. The method redraws the calendar view as required to ensure that today's date is correctly highlighted. CHAPTER 7 THE POLYTEXT CLASSES The Polytext classes are a set of classes for displaying text in a variety of window server fonts and styles. In addition, the classes also implement their own styles; for example, text can be displayed with an overstrike, a horizontal line through the text to implement "crossing out". Text may be wrapped into a number of lines where the line boundaries are defined by the application. FORM supplies three classes. The ptroot class is an abstract class which must be subclassed to provide a usable Polytext class. pTRooT contains a number of deferred methods which must be supplied by a subclass. PTSEG and PTFLAT subclass pTRooT and supply the required deferred methods. ptRoot itself can be seen as supplying the basic or common methods and properties needed to implement a fully functioning Polytext class. A number of terms and concepts are used in the description of these classes and it will be useful to give them here. A phrase describes a segment of text. It is a combination of the text itself and information which qualifies it, such as the length of text, the window server font to be applied; it is represented by a data structure of type PT_pHRASE. Note that a phrase can contain a maximum of PT_MAX_PHRASE_LEN characters. This and other symbols and structures can be found in the Polytext class definition in polytext.cl. Phrases are collected into a buffer in the order in which they would be displayed. pTRoot makes no assumptions about the way a buffer is implemented; this decision is left to a subclass. pTsEG implements a buffer as an instance of a vaxvar array while ptFrLat simply allocates a single cell and adds phrases in sequence into this cell. A line-table is built when text is wrapped into a number of lines with each line having a definite length. The table is a list of byte values containing the number of text characters within each line. The number of bytes in the table is, therefore, the same as the number of lines. The line-table, itself, is normally placed at the beginning of the buffer. The mechanism by which the line-table is inserted depends on the way the buffer is implemented. In ptszc, the first entry in the vaxvaR array is reserved for the table while in ptrat, the table together with a preceding byte containing the number of bytes in the table, is inserted directly at the start of the buffer causing any existing records to be shifted and the buffer to be re-allocated, if necessary. The Polytext classes are used as part of implementation of the Series 3a Agenda built-in application. Note that the classes themselves are only defined and implemented in the version of FORM as exists on the Series 3a. Precursors An understanding of the Polytext classes will be helped by a knowledge of: e =the p_enter and p_leave error handling services e the OLIB variable array class vaxvaR e the Window Server functions: gSetGc, gPrintBoxText, gClrRect and gFontInfo FORM REFERENCE Class diagram The following diagram covers the relationships between the Polytext classes which are discussed in detail in this chapter. The underlined classes are either discussed in another chapter of this manual or they refer to OLIB classes in which case they are all described in the OLIB Reference manual. “— — f — y Ptroot / * =3 ia fee. Oe ae ee d piseg / C ptflat / es a ay Ne Ni “~~ — y vaxvar / ~ ) Le — PTROOT PTROOT nphrases wwidth nchars imargin nlines ascent pt_add_phrase pt_init pt_wrap pt_reset pt_display_line pt_append pt_set_fonts pt_put_lintab pt_mod_by_num pt_pbuf pt_mod_by_attrib pt_find pt_inquire Class definition The prroot class subclasses root and is defined in the sub-category file polytext.cl (with generated header file polytext.g). CLASS polytext root { DEFER pt_init DEFER pt_reset Reset entire polytext as just initialized DEFER pt_append for "internal" use — by ptroot only DEFER pt_put_lintab for "internal" use - by ptroot only DEFER pt_pbuf for "internal" use - by ptroot only ADD pt_add_phrase Add a phrase to end of polytext ADD pt_wrap re-wrap text based on changed conditions ADD pt_display_line Draw single line of polytext ADD pt_set_fonts set/reset all fonts per PT_FONT_SPEC array ADD pt_mod_by_num i.e. modify phrase descriptor by phrasenum ADD pt_mod_by_attrib i.e. modify descriptor if attribute matches ADD pt_find Return phrase number of next matching phrase ADD pt_inquire Return screen position of phrase CONSTANT { PEF PIF PIF Ss ND_DEFAULT ND_BACKWARDS ND_CAN_STAY PT_STY_DEFAULT PT_s1 PT_s1 PT_S PT_S PT_S [TY_BREAK_AT_START [TY_BREAK_AT_END TY_OSTRIKE_ TY_OSTRIKE_ [TY_OVERSTRI XLEFT XRIGHT KE PT_MAX_PHRASE_LEN PT_DESCR_MOD_FONT PT_DESCR_MOD_WS_STYLE PT_DESCR_MOD_PT_STYLE PT_DESCR_MOD_ATTRIB PT_DESCR_MOD_TLEN } TYPES { typedef struct type UWORD UBYTE def NT NT NT font_id; attrib; PT_FONT_SPEC; struct line; offset; width; PT_PHRASE_INFO; typedef struct UWORD UBYTE UBYTE UBYTE UBYTE font_id; ws_style; pt_style; attrib; tlen; } PT_PHRASE_DESCR; typedef struct PROPERTY { UINT UINT UINT UINT UINT UINT } { 7 THE POLYTEXT CLASSES 0x0000 Exec O_PT_FIND method in default mode 0x0001 Execute O_PT_FIND method "descending" 0x0002 Exec O_PT_FIND including start phrase 0x00 Default polytext phrase style 0x01 Start of phrase is acceptable wrap pt 0x02 End of phrase is acceptable wrap point 0x20 Extend overstrike to left 0x40 Extend overstrike to right 0x80 Overstrike displayed text 236 Max text bytes in one phrase 0x0001 Modify font in phrase descriptor 0x0002 Modify style in phrase descriptor 0x0004 Modify style in phrase descriptor 0x0008 Modify attrib (by phrase number only) 0x0010 Modify text length (not implemented) font ID for corresponding ptxt phrase polytext phrase attribute polytext font specifier. Line number in which phrase starts Pixel offset to start of phrase Pixel width of the phrase Information returned by O_PT_INQUIRE method Font for this segment Window server style Polytext display style To be specified by caller Length of text in segment Phrase descriptor PT_PHRASE_DESCR descr; TEXT txt[1]; } PT_PHRASE; nphrases; nchars; nlines; wwidth; lmargin; ascent; Start of formatted text string. Phrase (descriptor plus text) Number of phrases in polytext Total number of chars in entire polytext (bytes) in line-length table Width used for last wrap Left margin for text display Ascent for text display Number of lines FORM REFERENCE Property pt root .nphrases The total number of phrases represented by this instance. ptroot .nchars The total number of characters represented by this instance. ptroot.nlines This property is of interest when the text represented by this instance has been wrapped; it is the number of lines into which the text has been wrapped. ptroot .wwidth The maximum width of a line, in pixels, available for displaying text. This property is important when text is being wrapped. This value excludes the width of the left-hand margin, if any. ptroot.lmargin The width of the left-hand margin, in pixels. Text is wrapped so that it fits between the left-hand margin and the right-hand margin. The right-hand margin is ptroot .wwdith pixels from the left-hand margin. ptroot.ascent Ascent for text display. This is the distance between the base line of the text and the top of the rectangle or "box" within which the segment of text is drawn and is specified by the application. For more information on this concept, see the description of the gprintBoxText function in the Graphics Output chapter of the Window Server Reference. PTROOT methods PT ADD PHRASE Add phrase to buffer INT pt_add_phrase (PT_PHRASE_DESCR *pd, TEXT *txt); Add a phrase to the buffer. The method takes two parameters: ¢ pd points to a data structure of type pT_PHRASE_DESCR which contains information describing this phrase, for example, the length of the text and the ID of the font to be applied. e txt holds the address of a buffer containing the text of the phrase to be added. The method takes the text and the phrase description supplied in the parameters and builds a Rc_vaxvar type data structure representing the data to be added to the buffer. The rc_vaxvar structure is defined in the ors class vaxvar but is shown below: typedef struct { UWORD len; UBYTE *buf; } RC_VAXVAR The method constructs a pT_pHRasE record, fully describing the phrase, and sets the address of this record into the member buf. The member 1en contains the length of the data represented by this pt_pHrRass record. The length of text in a single phrase is limited to pt_max_PHRASE_LEN characters. Thus, if more than PT_MAX_PHRASE_LEN characters are passed to this method, then a number of pt_purasz records will be created. In practice, no more than two records can ever be created. New ptT_PuRASE records are added to the buffer by sending one pt_puT_APPEND message per record. The pt_put_append method is a deferred method and must be supplied by a subclass. The implementation of this method depends on the way the buffer itself is implemented, as discussed in the introduction to this chapter. The ptriat and ptszc sub-classes supply a suitable method. As new phrases are added to the buffer, the method updates the properties ptroot .nchars and ptroot .nphrases, the total number of characters and the total number of phrases respectively. The method always returns zero. 7 THE POLYTEXT CLASSES PT_WRAP Wrap the text INT pt_wrap(INT maxwidth, INT margin, UWORD wrapflag); Wrap the text represented by this instance and return the number of lines generated. The method takes three parameters: @ maxwidth is a value which gives the maximum length of each line in pixels. This value includes the length of the left hand margin (if any). @ margin is a value which gives the width of the left hand margin in pixels. @ wrapflag is a value which can take the value TRUE Or FALSE. The method wraps the text represented by this instance by reading through all phrases held in the buffer (by sending a series of ptT_pBuF messages) and fitting the text into lines whose pixel width is given by the value of maxwidth - margin. The result of the wrapping process is a line-table as described in the introduction to this chapter. The method returns the number of lines generated. Note that pt_pburf is a deferred method and must be supplied by a subclass. The implementation of this method depends on the way the buffer itself is implemented as discussed in the introduction to this chapter. The ptriat and prsec sub-classes supply a suitable method. If wrapflag 1s TRUE, the method will wrap the text into as many lines as necessary. If, however, wrapflag 1S FALSE, an attempt is made to fit the text into a single line; if necessary the text is clipped to fit into the available width. In this case, the method always returns a value of one. As new lines are added to the line-table, the method updates the property pt root .nlines, the number of lines into which the text has been wrapped. Once the line-table is complete, a pT_puT_LINTAB message is sent to add the line-table to the buffer. pt_put_lintab is a deferred method and must be supplied by a subclass. The implementation of this method depends on the way the buffer itself is implemented, as discussed in the introduction to this chapter. The ptriat and ptszc sub-classes supply a suitable method. PT DISPLAY LINE Draw a line of text VOID pt_display_line(P_RECT *prect,INT ascent,UINT displine) ; Draw a single line of text to the screen The method takes three parameters: ¢ prect points to data structure of type p_REct and describes a rectangle within which the line of text is to be drawn. @ ascent is as used by the window server function gPrintBoxText. It measures the required distance between the base line of the text and the top of the rectangle within which the text is to be drawn. @ displine is the number of the line to be drawn and is used as an index into the line-table. This assumes that the text has previously been wrapped. If no phrases exist or the number of the line to be displayed is invalid, the pixels within the specified rectangle are cleared and the method returns. The phrases corresponding to the line to be displayed are fetched in turn from the buffer using the pt_pbuf deferred method. For each phrase fetched, the window server function gsetcc is called to switch the graphics context font and style to that specified by the phrase. The method assumes that a temporary graphics context has already been created by the application. The window server function gPrintBoxText is used to display the text within each phrase. If a phrase has the Polytext style pT_sty_OVERSTRIKE Set, a horizontal "line", two pixels deep, is drawn through the text. The "line" itself is drawn by clearing the top line of pixels and by setting the bottom line of pixels. FORM REFERENCE PT SET FONTS Set font ID VOID pt_set_fonts(UINT count, PT_FONT_SPEC *pfspec0O); Set the font ID for phrases in the buffer. The method takes two parameters: ® pfspecd iS a pointer to an array of ptT_FonT_spec data structures. ¢ count contains the number of entries in the array of pT_ronT_sprc data structures whose address is passed in the parameter pfspeco. As can be seen in the prroot class definition, each element in the array of pt_ront_spec data structures consists of a member (attrib) containing a set of Polytext attributes and a member (font_id) containing a font ID. The method scans through all the phrases in the buffer; for each phrase, all elements in the pT_ronT_sPEC array are examined. Where the Polytext attributes of the phrase match an element's attributes, the font ID in the phrase is replaced by that in the pt_rontT_sPzEc element and scanning then continues with the next phrase in the buffer. Note that the attributes of the phrase will match the pt_ront_spec element's attributes, if a logical AND of the two sets results in a TRUE value. As a result of this method, some or all of the phrases in the buffer will have new font IDs. It is also possible that none of the phrases will be changed. PT_MOD_BY_NUM Set font ID and style by phrase VOID pt_mod_by_num(UINT phrasenum, PT_PHRASE_DESCR *pdescr,UWORD flags); Set the font ID and graphic styles for a specific phrase. The method takes three parameters: @ phrasenum is an index which identifies the exact phrase within the buffer. A value of one refers to the first phrase while a value of two refers to the second and so on. @ pdescr points to a data structure of type pT_PHRASE_DEScR and contains the font-id, window server style, polytext style and attribute to be set into the phrase. lags contains a set of bit values which can be ored together; it indicates which item(s) in the phrase descriptor is(are) to be set. The possible values are as follows: e im) PT_DESCR_MOD_FONT PT_DESCR_MOD_WS_STYLE PT_DESCR_MOD_PT_STYLE PT_DESCR_MOD_ATTRIB If phrasenum contains an invalid value (i.e. zero or a value greater than the total number of phrases in the buffer), the method does nothing and simply returns. The address of the specific phrase within the buffer is found by sending a pt_pBur message and passing phrasenum as an argument. Recall that pt_pbur is a deferred method and must be supplied by a subclass. The implementation of this method depends on the way the buffer itself is implemented as discussed in the introduction to this chapter. The ptriat and prssc sub-classes supply a suitable method. 7 THE POLYTEXT CLASSES Depending on the setting of the f1ags parameter, corresponding members referenced by the pdescr parameter replace the equivalent members in the phrase descriptor as follows: PT_DESCR_MOD_FONT causes the phrase’s font_ia member to be replaced by pdescr->font_id. PT_DESCR_MOD_WS_STYLE causes the phrase's ws_style member to be replaced by pdescr-—>ws_style. PT_DESCR_MOD_PT_STYLE causes the phrase's pt_style member to be replaced by pdescr->pt_style. PT_DESCR_MOD_ATTRIB causes the the phrase's attrib member to be replaced by pdescr->attrib. PT MOD BY_ ATTRIB Set font ID and style by attribute VOID pt_mod_by_attrib( PT_PHRASE_DESCR *pdescr,UWORD flags) ; Set the font ID and graphic styles for phrases within the buffer. The method takes two parameters: @ pdescr points to a data structure of type pT_PHRASE_DESCR and contains the font-id, window server style and polytext style to be set into the phrase(s). It also contains the attributes to be used to find matching phrases. e mu) lags contains a set of bit values which can be ored together; it indicates which item(s) in the phrase descriptor is(are) to be set. The possible values are as follows: PT_DESCR_MOD_FONT PT_DESCR_MOD_WS_STYLE PT_DESCR_MOD_PT_STYLE The method scans through all the phrases in the buffer by sending successive pt_pBur messages. Where the Polytext attributes of the phrase match the attributes referenced by the pdescr parameter, corresponding members referenced by the pdescr parameter replace the equivalent members in the phrase descriptor, depending on the setting of the f1ags parameter as follows: PT_DESCR_MOD_FONT causes the phrase's font_ia member to be replaced by pdescr->font_id. PT_DESCR_MOD_WS_STYLE causes the phrase's ws_style member to be replaced by pdescr-—>ws_style. PT_DESCR_MOD_PT_STYLE causes the phrase's pt_style member to be replaced by pdescr->pt_style. Note that the attributes of the phrase will match the attributes referenced by pdescr, if a logical AND of the two sets results in a TRUE value. PT_FIND Find phrase by attribute INT pt_find(UINT phrase0,UWORD flags,UWORD attrib); Find the next phrase whose attributes match a given set and return its index. The method takes three parameters: ¢ phraseo Is the index of the phrase within the buffer where the search is to begin. @ flags contains indicators which determine: 1. whether or not the search process is to include the phrase represented by phraseo. 2. the direction of search, i.e. forwards or backwards. ¢ attrib contains the attributes to be matched with the phrase attributes. FORM REFERENCE The method scans each phrase in the buffer, beginning with the phrase whose index (or relative position within the buffer) is given by phraseo, until the Polytext attributes of the phrase match the attributes given by the attrib parameter. The index of the resulting phrase is returned. If no matching phrase can be found, a value of -1 is returned instead. Note that if pT_rIND_BACKWARDS is set in the flags parameter, the search is done backwards from the phrase indicated by phraseo. Further, if pt_r1np_can_stay is set, the search includes the phrase indicated by phraseo; otherwise, it is excluded. PT_INQUIRE Find information about a phrase INT pt_inguire(INT phrasenum, PT_PHRASE_INFO *pinfo); Fetch information about a given phrase. The method takes two parameters: @ phrasenum is the index of the phrase, i.e. the relative position of the phrase within the buffer. ¢ pinfo points to a PT_PHRASE_INFo data structure to be filled in by the method. If no phrases exist or the parameter phrasenum contains an invalid value (i.e. zero or a value greater than the total number of phrases in the buffer), then a value of -1 is returned. The method sends pt_ppur messages to fetch the line-table and the given phrase and, using this information, fills in the pr_pHRASE_1NFo data structure. The pt_PHRASE_INFo data structure has three members described as follows: line The number of the line within which the given phrase will be displayed. offset The offset, in pixels, of the start of the given phrase from the beginning of the line. width | The width, in pixels, of the given phrase. On successful completion, the method returns zero. PTROOT deferred methods PT_INIT Initialise INT pt_init (UINT granularity) A deferred method for initialising the instance. The method should handle a single parameter specifying the granularity of the buffer. The way this value is used will depend on the way the buffer is implemented. In very general terms, the size of a buffer should always be some multiple of the granularity. The method is not used in this class PT_RESET Reset VOID pt_reset (VOID) A deferred method for resetting the instance back to its initialised state. The method is not used in this class. 7 THE POLYTEXT CLASSES PT_APPEND Append a record VOID pt_append(RC_VAXVAR *pdescr) A deferred method for adding phrases to the buffer The method should handle a single parameter. This is a pointer to a data structure of type Rc_vAXvAR containing the address of the phrase to be added to the buffer and the total length of this phrase (a PT_PHRASE data structure). The way this parameter is used will depend on the way the buffer is implemented. The method is used in this class by the pt_add_phrase method. PT_PUT_LINTAB Store line-length table VOID pt_put_lintab(UBYTE *plinetable) A deferred method for inserting the line-table into the buffer. The method should handle a single parameter which is a pointer to the line-table itself. The ptroot methods assume that the line-table is always located at the beginning of the buffer and regards it as being phrase zero; in other words, the address of the line-table can be found by sending a pt_pBuF message with an argument of zero. The method is used by the pt_wrap method. PT_PBUF Get address of phrase PT_PHRASE *pt_pbuf (UINT recnum) A deferred method for obtaining the address of a phrase in the buffer. The method should handle a single parameter. This is the index of the phrase; in other words, it is the relative position of the phrase within the buffer. A value of one refers to the first phrase while a value of two refers to the second phrase and so on. Note, however, that a value of zero refers to the line-table. The method is used by the following methods: pt_wrap, pt_display_line, pt_set_fonts, pt_mod_by_num, pt_mod_by attrib, pt_find, and pt_inquire. PTFLAT PTROOT nphrases buffer nchars bufsize nlines granularity wwidth nextoff imargin ascent pt_add_phrase destroy pt_wrap pt_init pt_display_line pt_reset pt_set_fonts pt_append pt_mod_by_num pt_put_lintab pt_mod_by_attrib pt_pbuf pt_find pt_inquire FORM REFERENCE PTFLAT 1s a subclass of pTRoot. It implements the buffer as a single memory cell. Phrases are simply appended to the end of the cell as they are received. The line-table is inserted at the beginning of the cell. If the cell proves too small to contain extra phrases, it is simply re-allocated. Extra property is provided by this subclass to control access to this cell and is detailed in the property section below. All methods deferred by ptroot are supplied here. Class definition The ptriat class subclasses prroot and is defined in the sub-category file polytext.cl (with generated header file polytext.g). CLASS ptflat ptroot { REPLACE destroy REPLACE pt_init REPLACE pt_reset REPLACE pt_append for "internal" use — by ptroot only REPLACE pt_put_lintab for "internal" use - by ptroot only REPLACE pt_pbuf for "internal" use - by ptroot only PROPERTY { UBYTE *buffer; UWORD bufsize; UWORD granularity; UWORD nextoff; } } Property ptflat.buffer The address of the allocated cell containing the buffer. ptflat.bufsize The size, in bytes, of the allocated cell containing the buffer. ptflat.granularity The granularity of the buffer in bytes. The cell in which the buffer resides is always allocated in exact multiples of the granularity. If necessary, the size of the buffer is always rounded up to the next multiple of the granularity. ptflat.nextoff The offset, from the beginning of the cell, to the next available position within the buffer. PTFLAT methods DESTROY Destroy the instance VOID destroy (VOID) Destroy this instance of pTFLaT. The method frees the allocated cell which contains the buffer and then supersends a pEsTRoy message. PT_INIT Initialise INT pt_init(UINT granularity) Initialise this instance of PTFLAT. The method takes a single parameter; granularity specifies the granularity of the buffer. The buffer is contained within a cell which is always allocated in multiples of this value. The method takes the value of this parameter and sets it into the property pt flat.granularity. 7 THE POLYTEXT CLASSES A minimum buffer is constructed by allocating a cell of size pt flat .granularity; its address is set into the property pt flat .buffer and its current size set into the property pt flat .bufsize. The buffer will be expanded (i.e. re-allocated), as necessary by other ptrLat methods. In this subclass, the first byte of the buffer is used to contain the number of bytes allocated to the line-table; the line-table itself, will always follow this single byte and will precede the sequence of phrases. As part of the initialisation process, the first byte is set to zero, indicating that there is no line-table. The property pt flat .nextoff, containing the offset of the next free byte in the buffer, is initialised to one. p_leave Is called if there is insufficient memory to allocate the minimal buffer, otherwise the method returns zero. N.B. the property ptroot.nlines will always contain the current number of lines into which the text is wrapped and will, therefore, give the current number of entries used in the line-table. This will not necessarily be the same as the value in the first byte of the buffer. In general, the value of ptroot .nlines will always be less than or equal to the value in the first byte of the buffer. PT RESET Reset VOID pt_reset (VOID) Reset the instance back to its initialised state. The method effectively resets a number of pt root properties, re-allocates the buffer to its minimal size and initialises it in the same way as described in the pt_init method. In effect, the method "empties" the PTFLAT Object of all text and deletes any existing line-table. The properties which are reset to zero are: ptroot .nphrases, ptroot.nchars, ptroot.nlines and ptroot.wwidth. PT_APPEND Append a phrase VOID pt_append(RC_VAXVAR *pdescr) Append a phrase to the buffer. The method takes a single parameter; pdescr points to a data structure of type Rc_vaxvar. The members of this structure, 1en and buf, contain the length of the phrase and a pointer to the phrase content (a PT_PHRASE data structure) respectively. The Rc_vaxvar structure can be found in the OLIB vaxvar class definition. The phrase data is appended to the end of the buffer. If necessary, the buffer is re-allocated to accommodate the new data and the pt flat .nextoff property is updated to point to the next free byte. PT_PUT_LINTAB Store line-length table VOID pt_put_lintab(UBYTE *plinetable) Store the line-table in the buffer. The method takes a single parameter; plinetable contains the address of the line-table to be stored. The method inserts the line-table into the buffer so that it starts at the second byte; any existing line-table will be overwritten. If necessary, the buffer is re-allocated and any existing phrases moved to make room for the new table. If the space reserved for the line-table is increased, the first byte in the buffer will be updated to reflect the new size. FORM REFERENCE PT_PBUF Get address of phrase PT_PHRASE *pt_pbuf (UINT recnum) Fetch the address of the specified phrase within the buffer. The method takes a single parameter; recnum contains the index of the phrase whose address is required. In other words, it is the relative position within the buffer of the required phrase. If recnum is zero, the address of the line-table is returned; otherwise, the method returns the address of the required phrase. A recnum value of one causes the address of the first phrase to be returned, a value of two causes the address of the second phrase to be returned, and so on. Note, this method does not check that the value of recnum lies within sensible limits. If the value is greater than the number of phrases currently held in the buffer, an invalid address will be returned with unpredictable consequences. PTSEG PTROOT nphrases nchars nlines wwidth imargin ascent pt_add_phrase pt_init pt_wrap pt_reset pt_display_line pt_append pt_set_fonts pt_put_lintab pt_mod_by_num pt_pbuf pt_mod_by_attrib pt_find pt_inquire PTSEG is a subclass of pTRooT. It implements the buffer as an indexed array of variable length records, where each record is stored in its own heap cell. This is achieved by using an instance of the OLIB class vaxvar, where each entry in the array contains data relating to a single phrase. The use of a vaxvar object allows efficient random access to phrases and is suitable for a "medium" number of phrases or for a large number of phrases where the maximum number is known. The first entry (i.e. entry number 0) in the vaxvar array is always reserved for the line-table, while subsequent entries are used for the phrases themselves. All methods deferred by ptroot are supplied here. 7 THE POLYTEXT CLASSES Class definition The prtssc class subclasses pTRoot and is defined in the sub-category file polytext.cl (with generated header file polytext.g). CLASS ptseg ptroot { REPLACE pt_init REPLACE pt_reset REPLACE pt_append for "internal" use — by ptroot only REPLACE pt_put_lintab for "internal" use - by ptroot only REPLACE pt_pbuf for "internal" use —- by ptroot only PROPERTY 1 { PR_VAXVAR *phrases; } } Property ptseg.phrases The handle of an instance of a vaxvar class. The array is used to store phrase data. The first entry in the array is always reserved for the line-table. PTSEG methods PT_INIT Initialise INT pt_init (UINT granularity) Initialise this instance of ptszEc. The method takes a single parameter; granularity specifies the granularity of the vaxvar object which implements the buffer. The method creates an instance of vaxvar and sets the handle into the property ptseg. phrases. The vaxvar buffer object is initialised (with a granularity as specified in the parameter) by sending it a VA_INIT Message. A VA_APPEND message is then sent to the vaxvar buffer object to add a minimum sized entry (a single zero filled byte) to the array; this will be the first entry in the array and is reserved for the line-table. The method always returns zero. PT RESET Reset VOID pt_reset (VOID) Reset the instance back to its initialised state. The method effectively resets a number of ptroot properties and sends a va_RESET message to the vAxvaR buffer object to delete all entries from the array. A VA_APPEND message is then sent to add a minimum sized entry (a single zero filled byte) to the array; this will be the first entry in the array and is reserved for the line-table. In effect, the method "empties" the ptszc object of all text and deletes any existing line-table. The properties which are reset to zero are: ptroot .nphrases, ptroot.nchars, ptroot.nlines and ptroot.wwidth. FORM REFERENCE PT_APPEND Append a phrase VOID pt_append(RC_VAXVAR *pdescr) Append a phrase to the buffer. The method takes a single parameter; pdescr points to a data structure of type rc_vaxvar. The members of this structure, 1en and buf, contain the length of the phrase and a pointer to the phrase content (a PT_PHRASE data structure) respectively. The Rc_vaxvar structure can be found in the OLIB vaxvar class definition. The method simply sends a va_apPEND message to the vaxvar buffer object, passing pdescr as a parameter, to add a new entry containing the phrase data. PT PUT_LINTAB Store line-length table VOID pt_put_lintab(UBYTE *plinetable) Store the line-table in the buffer. The method takes a single parameter; plinetable contains the address of the line-table to be stored. The line-table is always inserted as the first entry in the vaxvar array which will have been reserved at initialisation time (by the pt_init method). The method builds a rc_vaxvar record descriptor; the buf member is set to point to the line-table while the 1en member is set to the length of the line-table (the value of pt root .nlines). The first entry in the array is replaced by the new line-table by sending a va_REPLACE message to the vaxvar buffer object, specifying record number zero and passing it the address of the record descriptor. PT_PBUF Get address of phrase PT_PHRASE *pt_pbuf (UINT recno) Fetch the address of the specified phrase within the buffer. The method takes a single parameter; recno contains the index of the phrase whose address is required. In other words, it is the relative position within the buffer of the required phrase. The method sends a va_pBur message to the vaxvar buffer object, specifying the record number recno; if recno is zero, the address of the line-table is returned - otherwise, the method returns the address of the required phrase. A recno value of one causes the address of the first phrase to be returned, a value of two causes the address of the second phrase to be returned, and so on. Note, this method will panic if the value of recno is greater than the number of phrases currently held in the buffer INDEX AO_ABRUN PAGES class method, 4-24 AO_INIT PAGES class method, 4-21 WRAP class method, 3-14 AO_QUEUE PAGES class method, 4-24 WRAP class method, 3-15 AO_RUN PAGES class method, 4-23 WRAP class method, 3-15 buffer polytext classes, 7-1 calendar image classes, 6-1 CALIMG class CI_ADJUST_DATE method, 6-9 CI_EMPHASISE method, 6-7 CI_GOTO_DATE method, 6-9 CI_LMOVE_CURSOR method, 6-8 CI_POS_MXY method, 6-10 CI_LREDRAW method, 6-10 CI_SENSE method, 6-10 CI_SET_TITLE method, 6-7 CI_TODAY_CHANGED method, 6-11 CI_VIEW method, 6-10 CL_INIT method, 6-5 DESTROY method, 6-5 methods, 6-5 oop, 6-1 call back methods FORM library, 1-5 CI_ADJUST_DATE CALIMG class method, 6-9 CI_EMPHASISE CALIMG class method, 6-7 CI_GOTO_DATE CALIMG class method, 6-9 CI_LMOVE_CURSOR CALIMG class method, 6-8 CI_POS_MXY CALIMG class method, 6-10 CI_LREDRAW CALIMG class method, 6-10 CI_SENSE CALIMG class method, 6-10 CI_SET_TITLE CALIMG class method, 6-7 CI_TODAY_CHANGED CALIMG class method, 6-11 CI_VIEW CALIMG class method, 6-10 CL_INIT CALIMG class method, 6-5 class CALIMG, 6-1 EPDOC document filter, 2-6 EPDOC, 2-5 EPDOC pagination property, 2-6 EPFDOC, 2-14 FORMDOC, 2-2 mixin, 1-5 PAGELAY, 4-46 PAGES, 4-14 PDR, 4-34 PRINTER environment variables, 4-5 printer layout SCRLAY, 3-2 PRINTER, 4-2 PRNLAY, 4-49 PRNTPRV, 5-9 PRVPDR, 5-2 PTFLAT, 7-9 PTROOT, 7-2 PTSEG, 7-12 screen layout SCRLAY, 3-2 SCRIMG, 3-15 SCRLAY data structure, 3-7 SCRLAY font width tables, 3-8 SCRLAY, 3-2 SCRLAY screen diagram, 3-19 SCRLAY special characters, 3-7 SCRLAY text line diagram, 3-21 WDR, 4-25 WRAP, 3-14 class diagrams FORM hierarchy, 1-3 FORM library, 1-3 classes FORM library overview, 1-1 FORM using, 1-1 mixin, 1-5 DESTROY CALIMG class method, 6-5 PDR class method, 4-37 PRINTER class method, 4-6 PTFLAT class method, 7-10 SCRIMG class method, 3-19 SCRLAY class method, 3-10 WDR class method, 4-29 document filter EPDOC class, 2-6 document formating FORM library, 1-1 document layout classes, 3-1 ADDITIONAL SYSTEM INFORMATION document printing classes, 4-1 DYL FORM library introduction, 1-1 environment variables print manager, 4-5 EP_BACK_ CHARS EPDOC class method, 2-9 EP_CLEAR EPDOC class method, 2-11 EP_COMPRESS EPDOC class method, 2-11 EP_DELETE EPDOC class method, 2-11 EP_EXTRACT EPDOC class method, 2-10 EP_INIT EPDOC class method, 2-8 EP_INSERT EPDOC class method, 2-10 EP_SENSE_CHARS EPDOC class method, 2-8 EP_SENSE_LEN EPDOC class method, 2-8 EPDOC class document filter, 2-6 EP_BACK_CHARS method, 2-9 EP_CLEAR method, 2-11 EP_COMPRESS method, 2-11 EP_DELETE method, 2-11 EP_EXTRACT method, 2-10 EP_INIT method, 2-8 EP_INSERT method, 2-10 EP_SENSE_CHARS method, 2-8 EP_SENSE_LEN method, 2-8 EPDOC_ENQ_PAGE method, 2-12 EPDOC_GOTO_PAGE method, 2-12 EPDOC_PARA_START call back method, 2-13 EPDOC_POS_FILTER method, 2-12 EPDOC_SENSE_CHARS call back method, 2-13 EPDOC_SET_FILTER method, 2-12 EPDOC_SET_PAGES method, 2-11 methods call-back, 2-13 methods, 2-8 oop, 2-5 pagination property, 2-6 EPDOC_ENQ_ PAGE EPDOC class method, 2-12 EPDOC_GOTO_PAGE EPDOC class method, 2-12 EPDOC_PARA_START EPDOC class method call back, 2-13 EPDOC_POS_FILTER EPDOC class method, 2-12 EPDOC_SENSE_CHARS EPDOC class method call back, 2-13 EPDOC_SET_FILTER EPDOC class method, 2-12 ii EPDOC_SET_PAGES EPDOC class method, 2-11 EPFDOC class EPFDOC_PARA_START call back method, 2-15 EPFDOC_SENSE_CHARS call back method, 2-15 methods call-back, 2-15 oop, 2-14 EPFDOC_PARA_START EPFDOC class method call back, 2-15 EPFDOC_SENSE_CHARS EPFDOC class method call back, 2-15 error handling FORM library, 1-4 FORM library panics, 1-4 FORM call back methods, 1-5 class diagrams, 1-3 class hierarchy, 1-3 error handling, 1-4 error numbers panics, 1-4 library introduction, 1-1 long function parameters, 1-3 FORM class methods Series 3 notes, 4-53 FORM classes using, 1-1 FORM library function prototypes, 1-2 form.dyl ROM, 1-1 formatted document content classes, 2-1 formatted text classes, 3-1 formatting document FORM library, 1-1 printing FORM library, 1-1 FORMDOC class FORMDOC_ENQ_PAGE method, 2-5 FORMDOC_PARA_START method, 2-3 FORMDOC_SENSE_CHARS method, 2-3 FORMDOC_SENSE_PDATA method, 2-4 FORMDOC_SENSE_PLABEL method, 2-4 methods, 2-3 oop, 2-2 FORMDOC_ENQ_PAGE FORMDOC class method, 2-5 FORMDOC_PARA_START FORMDOC class method, 2-3 FORMDOC_SENSE_CHARS FORMDOC class method, 2-3 FORMDOC_SENSE_PDATA FORMDOC class method, 2-4 FORMDOC_SENSE_PLABEL FORMDOC class method, 2-4 library FORM DYL introduction, 1-1 form.dyl ROM, 1-1 line-table polytext classes, 7-1 long parameters FORM functions, 1-3 FORM library functions, 1-3 measurement units points, 1-2 printer units, 1-2 twips, 1-2 method function FORM long parameters, 1-3 FORM prototypes, 1-2 methods CALIMG class, 6-5 call back FORM library, 1-5 EPDOC class call-back, 2-13 EPDOC class, 2-8 EPFDOC class call-back, 2-15 FORM class Series 3 notes, 4-53 FORMDOC class, 2-3 PAGELAY class call back, 4-46 PAGES class, 4-21 PDR class, 4-37 PRINTER class, 4-6 PRNLAY class, 4-52 PRVPDR class, 5-5 PTFLAT class, 7-10 PTROOT class deferred, 7-8 PTROOT class, 7-4 PTSEG class, 7-13 SCRIMG class, 3-19 SCRLAY class, 3-8 WDR class, 4-29 WRAP class, 3-14 mixin classes oop, 1-5 oop calendar classes, 6-1 CALIMG class, 6-1 CALIMG class methods, 6-5 document layout classes, 3-1 document printing classes, 4-1 EPDOC class, 2-5 EPDOC class call-back methods, 2-13 EPDOC class methods, 2-8 EPDOC document filter class, 2-6 EPDOC pagination property class, 2-6 EPFDOC class, 2-14 EPFDOC class call-back methods, 2-15 FORM class methods Series 3 notes, 4-53 formatted document content classes, 2-1 formatted text classes, 3-1 FORMDOC class, 2-2 FORMDOC class methods, 2-3 PAGELAY class, 4-46 PAGELAY class call back methods, 4-46 PAGES class, 4-14 PAGES class methods, 4-21 PDR class, 4-34 PDR class methods, 4-37 INDEX polytext classes, 7-1 print preview classes, 5-1 PRINT PREVIEW classes, 5-1 PRINTER class, 4-2 PRINTER class diagram, 4-2 PRINTER class methods, 4-6 PRINTER environment variables, 4-5 printer layout SCRLAY class, 3-2 PRINTER measurement units, 4-2 PRNLAY class, 4-49 PRNLAY class methods, 4-52 PRNTPRYV class, 5-9 PRVPDR class, 5-2 PRVPDR class methods, 5-5 PTFLAT class, 7-9 PTFLAT class methods, 7-10 PTROOT class, 7-2 PTROOT class deferred methods, 7-8 PTROOT class methods, 7-4 PTSEG class, 7-12 PTSEG class methods, 7-13 screen layout SCRLAY class, 3-2 SCRIMG class, 3-15 SCRIMG class methods, 3-19 SCRLAY class, 3-2 SCRLAY class methods, 3-8 SCRLAY data structures class, 3-7 SCRLAY font width tables class, 3-8 SCRLAY screen diagram, 3-19 SCRLAY special characters class, 3-7 SCRLAY text line diagram, 3-21 text formatting classes, 3-1 WDR class, 4-25 WDR class methods, 4-29 WRAP class, 3-14 WRAP class methods, 3-14 page dimensions diagram, 4-20 PAGELAY class methods call back, 4-46 oop, 4-46 PAGELAY_MDONE method, 4-47 PAGELAY_MREAD method, 4-46 PAGELA Y_MDONE PAGELAY class method, 4-47 PAGELAY_MREAD PAGELAY class method, 4-46 PAGES class AO_ABRUN method, 4-24 AO_INIT method, 4-21 AO_QUEUE method, 4-24 AO_RUN method, 4-23 methods, 4-21 oop, 4-14 pagination EPDOC class property, 2-6 panics FORM error numbers, 1-4 parallel port letter types, 4-8 iii ADDITIONAL SYSTEM INFORMATION PDR class DESTROY method, 4-37 methods, 4-37 oop, 4-34 PDR_ADD_COMMAND method, 4-41 PDR_DESTROY method, 4-42 PDR_END method, 4-42 PDR_FONT method, 4-44 PDR_INIT method, 4-37 PDR_LINE method, 4-43 PDR_PAGE method, 4-43 PDR_PRINT method, 4-38 PDR_RIGHT method, 4-44 PDR_START method, 4-42 PDR_STYLE method, 4-45 PDR_TEXT method, 4-43 PDR_ADD_COMMAND PDR class method, 4-41 PDR_DESTROY PDR class method, 4-42 PRVPDR class method, 5-7 PDR_END PDR class method, 4-42 PDR_FONT PDR class method, 4-44 PRVPDR class method, 5-8 PDR_INIT PDR class method, 4-37 PRVPDR class method, 5-5 PDR_LINE PDR class method, 4-43 PDR_PAGE PDR class method, 4-43 PRVPDR class method, 5-8 PDR_PRINT PDR class method, 4-38 PRVPDR class method, 5-6 PDR_RIGHT PDR class method, 4-44 PDR_START PDR class method, 4-42 PRVPDR class method, 5-7 PDR_STYLE PDR class method, 4-45 PDR_TEXT PDR class method, 4-43 phrase polytext classes, 7-1 points printer measurement units, 1-2 polytext class buffer, 7-1 line-table, 7-1 phrase, 7-1 polytext classes oop, 7-1 port parallel letter types, 4-8 port serial letter types, 4-8 iv port type printer, 4-8 PR_CLOSE_WDR PRINTER class method, 4-10 PR_GET_HD PRINTER class method, 4-10 PR_GET_PARAMS PRINTER class method, 4-9 PR_INIT PRINTER class method, 4-6 PR_OPEN_PORT PRINTER class method, 4-10 PR_OPEN_WDR PRINTER class method, 4-10 PR_PAGINATE PRINTER class method, 4-11 PR_PORT_DATA PRINTER class method, 4-7 PR_PREVIEW PRINTER class method, 4-13 PR_PREVIEW_DATA PRINTER class method, 4-14 PR_PREVIEW_END PRINTER class method, 4-13 PR_PREVIEW_START PRINTER class method, 4-12 PR_PRINT PRINTER class method, 4-11 PR_SENSE_MODEL PRINTER class method, 4-9 PR_SENSE_PORT PRINTER class method, 4-8 PR_SET_HD PRINTER class method, 4-9 PR_SET_ MODEL PRINTER class method, 4-7 PR_SET_PORT_TYPE PRINTER class method, 4-7 PR_STORE_FILE PRINTER class method, 4-6 PR_STORE_SRCHAR PRINTER class method, 4-6 print manager environment variables, 4-5 print preview classes, 5-1 PRINT PREVIEW class oop, 5-1 PRINTER class DESTROY method, 4-6 diagram, 4-2 document printing, 4-1 environmet variables, 4-5 measurement units, 4-2 methods, 4-6 oop, 4-2 PR_CLOSE_WDR method, 4-10 PR_GET_HD method, 4-10 PR_GET_PARAMS method, 4-9 PR_INIT method, 4-6 PR_OPEN_PORT method, 4-10 PR_OPEN_WDR method, 4-10 PR_PAGINATE method, 4-11 PR_PORT_DATA method, 4-7 PR_PREVIEW method, 4-13 PR_PREVIEW_DATA method, 4-14 PR_PREVIEW_END method, 4-13 PR_PREVIEW_START method, 4-12 PR_PRINT method, 4-11 PR_SENSE_MODEL method, 4-9 PR_SENSE_PORT method, 4-8 PR_SET_HD method, 4-9 PR_SET_MODEL method, 4-7 PR_SET_PORT_TYPE method, 4-7 PR_STORE_FILE method, 4-6 PR_STORE_SRCHAR method, 4-6 text printing, 4-1 printer layout SCRLAY class, 3-2 printer model get type, 4-9 printer port device types, 4-8 printing formating FORM library, 1-1 page dimensions diagram, 4-20 PRINTING PREVIEW class, 5-1 PRNLAY class methods, 4-52 oop, 4-49 SL_PRINT_POS method, 4-52 SL_PRINT_READ method, 4-52 PRNTPRYV class oop, 5-9 PRNTPRV_MDONE method, 5-9 PRNTPRV_MDONE PRNTPRV class method, 5-9 PRVPDR class methods, 5-5 oop, 5-2 PDR_DESTROY method, 5-7 PDR_FONT method, 5-8 PDR_INIT method, 5-5 PDR_PAGE method, 5-8 PDR_PRINT method, 5-6 PDR_START method, 5-7 PT_ADD_PHRASE PTROOT class method, 7-4 PT_APPEND PTFLAT class method, 7-11 PTROOT class method deferred, 7-8 PTSEG class method, 7-13 PT_DISPLAY_LINE PTROOT class method, 7-5 PT_FIND PTROOT class method, 7-7 PT_INIT PTFLAT class method, 7-10 PTROOT class method deferred, 7-8 INDEX PTSEG class method, 7-13 PT_INQUIRE PTROOT class method, 7-8 PT_MOD_BY_ATTRIB PTROOT class method, 7-7 PT_MOD_BY_NUM PTROOT class method, 7-6 PT_PBUF PTFLAT class method, 7-11 PTROOT class method deferred, 7-9 PTSEG class method, 7-14 PT_PUT_LINTAB PTFLAT class method, 7-11 PTROOT class method deferred, 7-9 PTSEG class method, 7-13 PT_RESET PTFLAT class method, 7-11 PTROOT class method deferred, 7-8 PTSEG class method, 7-13 PT_SET_FONTS PTROOT class method, 7-5 PT_WRAP PTROOT class method, 7-4 PTFLAT class DESTROY method, 7-10 methods, 7-10 oop, 7-9 PT_APPEND method, 7-11 PT_INIT method, 7-10 PT_PBUF method, 7-11 PT_PUT_LINTAB method, 7-11 PT_RESET method, 7-11 PTROOT class methods deferred, 7-8 methods, 7-4 oop, 7-2 PT_ADD_PHRASE method, 7-4 PT_APPEND deferred method, 7-8 PT_DISPLAY_LINE method, 7-5 PT_FIND method, 7-7 PT_INIT deferred method, 7-8 PT_INQUIRE method, 7-8 PT_MOD_BY_ATTRIB method, 7-7 PT_MOD_BY_NUM method, 7-6 PT_PBUF deferred method, 7-9 PT_PUT_LINTAB deferred method, 7-9 PT_RESET deferred method, 7-8 PT_SET_FONTS method, 7-5 PT_WRAP method, 7-4 PTSEG class methods, 7-13 oop, 7-12 PT_APPEND method, 7-13 PT_INIT method, 7-13 PT_PBUF method, 7-14 PT_PUT_LINTAB method, 7-13 PT_RESET method, 7-13 resource files WDR printing, 4-25 ADDITIONAL SYSTEM INFORMATION ROM form.dyl, 1-1 screen layout SCRLAY class, 3-2 SCRIMG class DESTROY method, 3-19 methods, 3-19 oop, 3-15 SI_LDELPREP method, 3-26 SI_DOC_CHANGED method, 3-25 SI_DOC_RESET method, 3-25 SI_LEMPHASIZE method, 3-22 SI_LFWD_CHANGE method, 3-27 SI_GET_SELECT method, 3-22 SLINIT method, 3-20 SI_MOVE_CURSOR method, 3-23 SI_PAN method, 3-22 SI_LPARA_CHANGED method, 3-26 SI_LREDRAW method, 3-25 SI_SCROLL method, 3-23 SI_SENSE method, 3-22 SI_SET method, 3-20 SI_STYLE_CHANGED method, 3-26 SI_VIEW method, 3-23 SCRLAY class data structures, 3-7 DESTROY method, 3-10 document layout, 3-1 font width tables, 3-8 methods, 3-8 oop, 3-2 screen diagram, 3-19 SL_BEGIN_READ method, 3-11 SL_DISCARD_LAYOUT method, 3-13 SL_FORMAT_LINE method, 3-12 SL_INIT method, 3-8 SL_LINE_ENDS method, 3-11 SL_PARA_CHANGED method, 3-13 SL_POS_TO_XL method, 3-10 SL_READ method, 3-12 SL_RESCALE method, 3-13 SL_SCROLL method, 3-12 SL_SENSE method, 3-10 SL_SET method, 3-9 SL_SET_LINES method, 3-13 SL_VIEW method, 3-12 SL_XL_TO_POS method, 3-11 special characters, 3-7 text layout, 3-1 text line diagram, 3-21 serial port letter types, 4-8 Series 3 FORM class notes, 4-53 SI_DELPREP SCRIMG class method, 3-26 SI_DOC_CHANGED SCRIMG class method, 3-25 SI_DOC_RESET SCRIMG class method, 3-25 SI_LEMPHASIZE SCRIMG class method, 3-22 SILFWD_CHANGE SCRIMG class method, 3-27 SI_GET_SELECT SCRIMG class method, 3-22 SLINIT SCRIMG class method, 3-20 SI_MOVE_CURSOR SCRIMG class method, 3-23 SI_PAN SCRIMG class method, 3-22 SIPARA_CHANGED SCRIMG class method, 3-26 SIREDRAW SCRIMG class method, 3-25 SILSCROLL SCRIMG class method, 3-23 SI_SENSE SCRIMG class method, 3-22 SLSET SCRIMG class method, 3-20 SILSTYLE_CHANGED SCRIMG class method, 3-26 SIL VIEW SCRIMG class method, 3-23 SL_BEGIN_READ SCRLAY class method, 3-11 SL_DISCARD_LAYOUT SCRLAY class method, 3-13 SL_FORMAT_LINE SCRLAY class method, 3-12 SL_INIT SCRLAY class method, 3-8 SL_LINE_ENDS SCRLAY class method, 3-11 SL_PARA_CHANGED SCRLAY class method, 3-13 SL_POS_TO_XL SCRLAY class method, 3-10 SL_PRINT_POS PRNLAY class method, 4-52 SL_PRINT_READ PRNLAY class method, 4-52 SL_READ SCRLAY class method, 3-12 SL_RESCALE SCRLAY class method, 3-13 SL_SCROLL SCRLAY class method, 3-12 SL_SENSE SCRLAY class method, 3-10 SL_SET SCRLAY class method, 3-9 SL_SET_LINES SCRLAY class method, 3-13 SL_VIEW SCRLAY class method, 3-12 SL_XL_TO_POS SCRLAY class method, 3-11 text display polytext classes, 7-1 text formatting classes, 3-1 twips printer measurement units, 1-2 WDR resource files printing, 4-25 WDR class DESTROY method, 4-29 methods, 4-29 oop, 4-25 WDR_COUNT_MODELS method, 4-30 WDR_FONT_HEIGHT method, 4-31 WDR_GET_WIDTH_TABLE method, 4-32 WDR_INIT method, 4-29 WDR_LOAD_RECORD method, 4-34 WDR_OPEN_PRINT method, 4-33 WDR_SEARCH_HEIGHT method, 4-32 WDR_SEARCH_TYPEFACE method, 4-31 WDR_SENSE_MODEL method, 4-30 WDR_SENSE_MODEL_NAME method, 4-30 WDR_SENSE_WIDTH method, 4-33 WDR_SET_MODEL method, 4-30 WDR_TWIPS_TO_XY method, 4-33 WDR_TYPEFACE method, 4-30 WDR_COUNT_MODELS WDR class method, 4-30 WDR_FONT_HEIGHT WDR class method, 4-31 INDEX WDR_GET_WIDTH_TABLE WDR class method, 4-32 WDR_INIT WDR class method, 4-29 WDR_LOAD_RECORD WDR class method, 4-34 WDR_OPEN_ PRINT WDR class method, 4-33 WDR_SEARCH_HEIGHT WDR class method, 4-32 WDR_SEARCH_TYPEFACE WDR class method, 4-31 WDR_SENSE_MODEL WDR class method, 4-30 WDR_SENSE_MODEL_NAME WDR class method, 4-30 WDR_SENSE_WIDTH WDR class method, 4-33 WDR_SET_MODEL WDR class method, 4-30 WDR_TWIPS_TO_XY WDR class method, 4-33 WDR_TYPEFACE WDR class method, 4-30 WRAP class AO_INIT method, 3-14 AO_QUEUE method, 3-15 AO_RUN method, 3-15 methods, 3-14 oop, 3-14