| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381 |
- //
- // "$Id: Fl_Help_View.cxx 9325 2012-04-05 05:12:30Z fabien $"
- //
- // Fl_Help_View widget routines.
- //
- // Copyright 1997-2010 by Easy Software Products.
- // Image support by Matthias Melcher, Copyright 2000-2009.
- //
- // This library is free software. Distribution and use rights are outlined in
- // the file "COPYING" which should have been included with this file. If this
- // file is missing or damaged, see the license at:
- //
- // http://www.fltk.org/COPYING.php
- //
- // Please report all bugs and problems on the following page:
- //
- // http://www.fltk.org/str.php
- //
- // Contents:
- //
- // Fl_Help_View::Fl_Help_View() - Build a Fl_Help_View widget.
- // Fl_Help_View::add_block() - Add a text block to the list.
- // Fl_Help_View::add_link() - Add a new link to the list.
- // Fl_Help_View::add_target() - Add a new target to the list.
- // Fl_Help_View::begin_selection() - Begin text selection.
- // Fl_Help_View::build_faces() - build font face look-up tables.
- // Fl_Help_View::clear_global_selection() - Clear text selection.
- // Fl_Help_View::clear_selection() - Clear current text selection.
- // Fl_Help_View::cmp_targets() - Compare two targets.
- // Fl_Help_View::do_align() - Compute alignment for a line in a block.
- // Fl_Help_View::draw() - Draw the Fl_Help_View widget.
- // Fl_Help_View::end_selection() - End text selection.
- // Fl_Help_View::extend_selection()- Extend current text selection.
- // Fl_Help_View::fileislink() - Was link clicked or nav button?
- // Fl_Help_View::filepath() - Set value file path string.
- // Fl_Help_View::filepath() - Get value file path string.
- // Fl_Help_View::find() - Find the specified string.
- // Fl_Help_View::find_link() - Find the link at the given position.
- // Fl_Help_View::follow_link() - Follow the specified link.
- // Fl_Help_View::font_face() - Get a font face from a list of names.
- // Fl_Help_View::font_style() - Get a font style from a font list index.
- // Fl_Help_View::format() - Format the help text.
- // Fl_Help_View::format_table() - Format a table.
- // Fl_Help_View::free_data() - Free memory used for the document.
- // Fl_Help_View::get_align() - Get an alignment attribute.
- // Fl_Help_View::get_attr() - Get an attribute value from the string.
- // Fl_Help_View::get_color() - Get an alignment attribute.
- // Fl_Help_View::get_css_value() - Outputs the value of a given css property to buffer.
- // Fl_Help_View::get_font_size() - Get a height value for font-size.
- // Fl_Help_View::get_image() - Get an inline image.
- // Fl_Help_View::get_length() - Get a length value either absolute or %.
- // Fl_Help_View::get_length() - Get a length value of a given width.
- // Fl_Help_View::gettopline() - Get current topline in document.
- // Fl_Help_View::handle() - Handle events in the widget.
- // Fl_Help_View::hv_draw() - Draws text.
- // Fl_Help_View::initfont() - Initialize font stack.
- // Fl_Help_View::leftline() - Set the left line position.
- // Fl_Help_View::load() - Load the specified file.
- // Fl_Help_View::load_css() - Loads a css file.
- // Fl_Help_View::parse_css() - Parses all supported css properties.
- // Fl_Help_View::popfont() - Pop from font stack.
- // Fl_Help_View::pushfont() - Push to font stack.
- // Fl_Help_View::resize() - Resize the help widget.
- // Fl_Help_View::select_all() - Select all text.
- // Fl_Help_View::setstyle() - - Set the html style flag.
- // Fl_Help_View::topline() - Set the top line to the named target.
- // Fl_Help_View::topline() - Set the top line by number.
- // Fl_Help_View::value() - Set the help text directly.
- // Fl_Help_View::~Fl_Help_View() - Destroy a Fl_Help_View widget.
- //
- // Local:
- //
- // command() - Convert a command with up to four letters into an uint.
- // quote_char() - Return the character code associated with a quoted char.
- // hscrollbar_callback() - Callback for the horizontal scrollbar.
- // scrollbar_callback() - Callback for the scrollbar.
- //
- /*
- markcw: since July 2008 I have heavily modified this file and it's
- header. To make it a little easier for me to follow I made original
- code comments start in uppercase and my code comments start in lowercase.
- List of currently supported HTML tags/elements with attributes:
- <a href name target></a>
- <b></b> <strong></strong>
- <blockquote type></blockquote>
- <dl compact></dl> <dd> <dt>
- <ol type></ol> <li type></li>
- <ul type></ul> <li type></li>
- <body background bgcolor text link vlink alink></body>
- <br clear>
- <center></center>
- <code></code> <tt></tt>
- <div align id></div>
- <font face size color></font>
- <h1 align></h1>
- <head></head>
- <hr width size align clear>
- <html></html>
- <i></i> <em></em>
- <img src lowsrc alt align width height hspace vspace border usemap name>
- <kbd></kbd>
- <noscript></noscript>
- <p align></p>
- <pre></pre>
- <script language src></script>
- <table bgcolor background border cellpadding cellspacing width height></tab>
- <tr valign align bgcolor background></tr>
- <td valign align width height colspan rowspan bgcolor background></td>
- <th as td></th>
- <title></title>
- <u></u>
- <var></var>
- */
- //
- // Include necessary header files
- //
- #include <FL/Fl_Help_View.H>
- #include <FL/Fl_Window.H>
- #include <FL/Fl_Pixmap.H>
- #include <FL/x.H>
- #include <stdio.h>
- #include <stdlib.h>
- #include "flstring.h"
- #include <ctype.h>
- #include <errno.h>
- #include <math.h>
- #include "forms_timer.cxx" // for fl_gettime in resize()
- #if defined(WIN32) && ! defined(__CYGWIN__)
- # include <io.h>
- # include <direct.h>
- // Visual C++ 2005 incorrectly displays a warning about the use of
- // POSIX APIs on Windows, which is supposed to be POSIX compliant...
- # define getcwd _getcwd
- #else
- # include <unistd.h>
- #endif // WIN32
- //
- // Define preprocessor constants and macros
- //
- #define HV_64 64 // Columns, was 200 but practically 64 is enough
- #define HV_32 32 // medium array size
- #define HV_16 16 // small array size
- #define HV_DEFAULT 0 // html style flag
- #define HV_NOCONTEXTMENU 1 // no right-click menu
- #define HV_NONAVIGATE 2 // no user navigation
- // 'ENC(ANSI/Unicode, Mac Roman)' - OS character encoding macro
- #ifdef ENC
- # undef ENC
- #endif
- #ifdef __APPLE__
- # define ENC(a, b) b
- #else
- # define ENC(a, b) a
- #endif
- // 'CTRL(char)' - Shortcut key macro, get bits 0..4 of char
- #define CTRL(x) ((x) & 0x1f)
- // 'CMD(char[0], char[1], char[2], char[3])' - Fourcc macro, chars to int
- #define CMD(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d)
- // 'CHR(int, charindex)' - char from int macro, used like a 4-char array
- #define CHR(a, b) ((a & (255 << ((3-(b & 3)) << 3))) >> ((3-(b & 3)) << 3))
- // 'MIL(sec, mil, sec2, mil2)' - difference in mil macro, using fl_gettime
- #define MIL(a, b, c, d) ((c > a || (c == a && d > b)) ? \
- (1000000 * (c - a)) - b + d : \
- (1000000 * (a - c)) - d + b)
- //
- // Typedef the C API sort function type the only way I know how...
- //
- extern "C" // Compile qsort() in C style to avoid any compiler errors
- {
- typedef int (*compare_func_t)(const void *, const void *);
- }
- //
- // Declare local functions
- //
- static unsigned int command(const char *cmdp); // Used in end_selection
- static int quote_char(const char *qp, int fc = 0); // added fc
- static void hscrollbar_callback(Fl_Widget *s, void *);
- static void scrollbar_callback(Fl_Widget *s, void *);
- //
- // Broken image
- //
- static const char *broken_xpm[] =
- {
- "16 24 4 1",
- "@ c #000000", // Black
- " c #ffffff", // White
- "+ c none", // Transparent
- "x c #ff0000", // Red
- // Pixels
- "@@@@@@@+++++++++",
- "@ @++++++++++",
- "@ @+++++++++++",
- "@ @++@++++++++",
- "@ @@+++++++++",
- "@ @+++@+++++",
- "@ @++@@++++@",
- "@ xxx @@ @++@@",
- "@ xxx xx@@ @",
- "@ xxx xxx @",
- "@ xxxxxx @",
- "@ xxxx @",
- "@ xxxxxx @",
- "@ xxx xxx @",
- "@ xxx xxx @",
- "@ xxx xxx @",
- "@ @",
- "@ @",
- "@ @",
- "@ @",
- "@ @",
- "@ @",
- "@ @",
- "@@@@@@@@@@@@@@@@",
- 0 // nul-terminate - rem'd NULL
- };
- static Fl_Pixmap broken_image(broken_xpm);
- //
- // Simple margin stack for Fl_Help_View::format()
- //
- struct fl_margins
- {
- int depth_; // Array index
- int default_margin_;
- int margins_[100]; // Margins stack
- fl_margins(int default_margin=10) {
- default_margin_ = default_margin;
- clear();
- }
- int clear() { // Init margins
- // puts("fl_margins::clear()");
- depth_ = 0;
- return margins_[0] = default_margin_; // Default indent
- }
- int current() { // Get current margin
- return margins_[depth_];
- }
- int pop() { // Get last margin
- //printf("fl_margins::pop(): depth_=%d, xx=%d\n", depth_,
- // (depth_ > 0) ? margins_[depth_ - 1] : 4);
- if (depth_ > 0) {
- depth_ --;
- return margins_[depth_];
- }
- else
- return default_margin_; // Default indent
- }
- int push(int indent) { // Set next margin
- int xx;
- xx = margins_[depth_] + indent; // New indent
- //printf("fl_margins::push(indent=%d): depth_=%d, xx=%d\n", indent,
- // depth_ + 1, xx);
- if (depth_ < 99) {
- depth_ ++;
- margins_[depth_] = xx;
- }
- return xx;
- }
- };
- //
- // All the stuff needed to implement text selection in Fl_Help_View
- //
- /* matt:
- We are trying to keep binary compatibility with previous versions
- of FLTK. This means that we are limited to adding static data members
- only to not enlarge the Fl_Help_View class. Lucky for us, only one
- text can be selected system wide, so we can remember the selection
- in a single set of values.
- Still to do:
- - &word; style characters mess up our count inside a word boundary
- - we can only select words, no individual characters
- - no dragging of the selection into another widget
- - selection must be cleared if another widget get focus!
- - write a comment for every new function
- markcw: Static data members don't change the binary size or layout
- of a class because they are defined externally.
- For more info on binary compatibility (BC) see:
- http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
- */
- /*
- matt: The following functions are also used to draw stuff and should be
- replaced with local copies that are much faster when merely counting.
- fl_color(Fl_Color);
- fl_rectf(int, int, int, int);
- fl_push_clip(int, int, int, int);
- fl_xyline(int, int, int);
- fl_rect()
- fl_line()
- img->draw()
- markcw: local functions more-so static are faster than class functions.
- */
- //
- // Fl_Help_View::Fl_Help_View() - Build a Fl_Help_View widget.
- //
- Fl_Help_View::Fl_Help_View(int xx, // I - Left position
- int yy, // I - Top position
- int ww, // I - Width in pixels
- int hh, // I - Height in pixels
- const char *lp) // I - Label pointer, opt
- : Fl_Group(xx, yy, ww, hh, lp),
- scrollbar_(xx + ww - Fl::scrollbar_size(), yy,
- Fl::scrollbar_size(), hh - Fl::scrollbar_size()),
- hscrollbar_(xx, yy + hh - Fl::scrollbar_size(),
- ww - Fl::scrollbar_size(), Fl::scrollbar_size())
- {
- color(FL_WHITE, FL_SELECTION_COLOR); // Set bgcolor and selcolor of widget - rem'd FL_BACKGROUND2_COLOR
- title_[0] = '\0'; // Title string
- defcolor_ = FL_BLACK; // Default text color - rem'd FL_FOREGROUND_COLOR
- bgcolor_ = FL_WHITE; // Background color - rem'd FL_BACKGROUND_COLOR
- textcolor_ = defcolor_; // Text color
- linkcolor_ = FL_BLUE; // Link color - rem'd FL_SELECTION_COLOR
- serifont_ = FL_TIMES; // Default font, was textfont_
- fontsize_ = 12; // Default font size, was textsize_
- value_ = 0; // HTML text value - rem'd NULL
- ablocks_ = 0; // Allocated blocks
- nblocks_ = 0; // Number of blocks
- blocks_ = (Fl_Help_Block *)0; // Blocks
- link_ = (Fl_Help_Func *)0; // Link transform function
- alinks_ = 0; // Allocated links
- nlinks_ = 0; // Number of links
- links_ = (Fl_Help_Link *)0; // Links
- //targets_ = (Fl_Help_Target *)0; // rem'd
- atargets_ = 0; // Allocated targets
- ntargets_ = 0; // Number of targets
- directory_[0] = '\0'; // Directory for current file
- filename_[0] = '\0'; // Current filename
- topline_ = 0; // Top line in document
- leftline_ = 0; // Lefthand position
- size_ = 0; // Total document length
- hsize_ = 0; // Maximum document width
- scrollbar_size_ = 0;
- scrollbar_.value(0, hh, 0, 1);
- scrollbar_.step(8.0);
- scrollbar_.show();
- scrollbar_.callback(scrollbar_callback);
- scrollbar_.linesize(32); // vertical scroll size, default is 16
- hscrollbar_.value(0, ww, 0, 1); // Set line position, window, top, total
- hscrollbar_.step(8.0); // Set mouse step rounding value
- hscrollbar_.show(); // Show widget
- hscrollbar_.callback(hscrollbar_callback); // Set callback func for widget
- hscrollbar_.type(FL_HORIZONTAL); // Set slider type, default is vertical
- end(); // End current Fl_Group widgets
- selection_first = 0;
- selection_last = 0;
- selection_push_first = 0;
- selection_push_last = 0;
- selection_drag_first = 0;
- selection_drag_last = 0;
- selected = 0;
- draw_mode = 0;
- mouse_x = 0;
- mouse_y = 0;
- current_pos = 0;
- current_view = 0; // rem'd NULL
- hv_selection_color = 0;
- hv_selection_text_color = 0;
- default_margin_ = 10; //internall padding
- tr_td_adjust_ = 0; //when printint with pdfs
- d = (Fl_Help_Target *)malloc(sizeof(Fl_Help_Target)); // d-pointer
- d->targets = (Fl_Help_Link *)0; // Targets
- d->linkp = (Fl_Help_Link *)0; // Currently clicked link
- d->ispush = 0; // link is pushed
- d->islink = 0; // link clicked
- d->resized = 0; // window resized
- d->ispath = 0; // is path used
- d->nstyle = 0; // navigation style flag
- d->isnew = 0; // is new page
- d->top = 0; // current topline
- d->ltop = 0; // last topline
- d->isnav = 0; // is nav link
- d->rwidth = w(); // resize width
- d->cssurllen = 0; // css url length
- d->csswordlen = 0; // css word length
- d->cssword = 0; // css word value
- d->rtime = 0; // resize time
- d->rsec = 0; // resize seconds
- d->rmil = 0; // resize millisecs
- d->csstextlen = 0; // css text length
- d->csstext = 0; // css text value
- d->cssurl = 0; // css url value
- d->path[0] = '\0'; // current file path
- d->lpath[0] = '\0'; // last file path
- d->fonts[0][0] = 0; // font stack
- d->nfonts = 0; // number of fonts in stack
- build_faces();
- // load new default fonts
- serifont_ = FL_TIMES; // default/serif font
- sansfont_ = FL_HELVETICA; // sans font
- monofont_ = FL_COURIER; // monospace font
- resize(xx, yy, ww, hh); // Resize widget
- } // Fl_Help_View::Fl_Help_View()
- //
- // Fl_Help_View::add_block() - replaced, code moved
- //
- Fl_Help_Block * // O - Pointer to new block
- Fl_Help_View::add_block(const char *sp, // I - Pointer to start
- int xx, // I - X position
- int yy, // I - Y position
- int ww, // I - Right margin
- int hh, // I - Height
- unsigned char bc) // I - Draw border, opt
- {
- return 0;
- } // Fl_Help_View::add_block()
- //
- // Fl_Help_View::add_block() - Add a text block to the list.
- //
- Fl_Help_Block * // O - Pointer to new block
- Fl_Help_View::add_block(const Fl_Help_Block &b, // I - block object
- const char *sp, // I - Pointer to start
- int ww) // I - Right margin
- {
- Fl_Help_Block *block; // New block
- if (nblocks_ >= ablocks_) {
- ablocks_ += 16; // Allocated blocks, 16 blocks per allocation
- int size = sizeof(Fl_Help_Block) * ablocks_; // block size
- if (ablocks_ == 16) // Memory was freed
- blocks_ = (Fl_Help_Block *)malloc(size);
- else // First pass or resize resulted in a few new blocks
- blocks_ = (Fl_Help_Block *)realloc(blocks_, size);
- }
- block = blocks_ + nblocks_;
- memset(block, 0, sizeof(Fl_Help_Block));
- block->start = sp; // Start of text, varies so set by sp
- block->end = sp; // End of text, varies so set by sp
- block->x = b.x; // Starting X coordinate
- block->y = b.y; // Starting Y coordinate
- block->w = ww; // Width, varies so set by ww
- block->h = 0; // Height, always zero
- block->maxh = 0; // max image height
- block->imgy = 0; // image y position
- block->pre = b.pre; // pre text flag
- block->tag = b.tag; // tag/element fourcc int
- block->border = b.border; // Draw border?
- block->border_color = b.border_color; // Border color
- block->font = b.font; // current font
- block->fsize = b.fsize; // current font size
- block->bgcolor = b.bgcolor; // Background color
- block->cbi = nblocks_; // current block index
- nblocks_ ++; // Number of blocks
- return block;
- } // Fl_Help_View::add_block()
- //
- // Fl_Help_View::add_link() - Add a new link to the list.
- //
- void Fl_Help_View::add_link(const char *np, // I - Name of link
- int xx, // I - X position of link
- int yy, // I - Y position of link
- int ww, // I - Width of link text
- int hh) // I - Height of link text
- {
- Fl_Help_Link *link; // New link
- char *target; // Pointer to target name
- if (nlinks_ >= alinks_) {
- alinks_ += 16; // Allocated links, 16 blocks per allocation
- int size = sizeof(Fl_Help_Link) * alinks_; // block size
- if (alinks_ == 16)
- links_ = (Fl_Help_Link *)malloc(size);
- else
- links_ = (Fl_Help_Link *)realloc(links_, size);
- }
- link = links_ + nlinks_;
- link->x = xx; // X offset of link text
- link->y = yy; // Y offset of link text
- link->w = xx + ww; // Width of link text
- link->h = yy + hh; // Height of link text
- strlcpy(link->filename, np, sizeof(link->filename)); // nul-terminated
- if ((target = strrchr(link->filename, '#'))) { // Last '#' - rem'd != 0
- *(target ++) = '\0'; // Remove target from link->filename
- strlcpy(link->name, target, sizeof(link->name)); // Link target
- }
- else
- link->name[0] = '\0'; // Blank link target
- nlinks_ ++; // Number of links
- } // Fl_Help_View::add_link()
- //
- // Fl_Help_View::add_target() - Add a new target to the list.
- //
- void Fl_Help_View::add_target(const char *np, // I - Name of target
- int yy) // I - Y position of target
- {
- Fl_Help_Link *target; // New target
- if (ntargets_ >= atargets_) {
- atargets_ += 16; // Allocated targets, 16 blocks per allocation
- int size = sizeof(Fl_Help_Link) * atargets_; // block size
- if (atargets_ == 16)
- d->targets = (Fl_Help_Link *)malloc(size);
- else
- d->targets = (Fl_Help_Link *)realloc(d->targets, size);
- }
- target = d->targets + ntargets_;
- target->y = yy; // Y offset
- strlcpy(target->name, np, sizeof(target->name)); // Target name
- ntargets_ ++; // Number of targets
- } // Fl_Help_View::add_target()
- //
- // Fl_Help_View::begin_selection() - Begin text selection.
- //
- char // O - True if text selected
- Fl_Help_View::begin_selection()
- {
- clear_global_selection();
- if (!Fl_Help_View_buffer)
- Fl_Help_View_buffer = fl_create_offscreen(1, 1);
- mouse_x = Fl::event_x();
- mouse_y = Fl::event_y();
- draw_mode = 1; // Begin selection mode
- current_view = this;
- fl_begin_offscreen(Fl_Help_View_buffer);
- draw();
- fl_end_offscreen();
- draw_mode = 0;
- if (selection_push_last)
- return 1;
- else
- return 0;
- } // Fl_Help_View::begin_selection()
- //
- // Fl_Help_View::build_faces() - build font face look-up tables.
- //
- unsigned char // O - number of font faces
- Fl_Help_View::build_faces()
- {
- char buf[100],
- namebuf[100],
- tbufs[100][100]; // buffers
- const char *namep; // pointer
- char *bufp,
- *namebufp; // r+w pointer
- int ti = 0,
- tj = 0,
- tk = 0, // temp loop vars
- tnum = 0,
- lnum = 0,
- fnum = 0, // temp/last/font counters
- tfi[100],
- tf[10],
- cbit = 0,
- fbit = 0,
- tbit = 0, // bits
- nfonts = 0,
- nfaces = 0, // number of fonts and faces
- temp = 0; // lengths
- strlcpy(buf, " ", sizeof(buf)); // init buffer
- memset(face_, 0, sizeof(face_)); // zero tables
- memset(flet_, 0, sizeof(flet_));
- memset(fref_, 0, sizeof(fref_));
- nfonts = Fl::set_fonts(0); // number of ISO8859-1 fonts in list
- for (ti = 0, nfaces = 0; ti < nfonts; ti ++) { // find base fonts
- namep = Fl::get_font_name((Fl_Font)ti, &temp); // fltk font name
- for (tk = 0; namep[tk] != '\0'; tk ++)
- namebuf[tk] = tolower(namep[tk]); // copy chars to lowercase
- namebuf[tk] = '\0'; // nul-terminate
- if (strstr(namebuf+1, "black") || strstr(namebuf+1, "bold") ||
- strstr(namebuf+1, "extra") || strstr(namebuf+1, "heavy") ||
- strstr(namebuf+1, "inclined") || strstr(namebuf+1, "italic") ||
- strstr(namebuf+1, "light") || strstr(namebuf+1, "oblique") ||
- strstr(namebuf+1, "slanted") || strstr(namebuf+1, "wide") ||
- strstr(namebuf+1, "ultra"))
- continue; // skip font styles
- if ((bufp = strstr(namebuf, "-"))) { // full font name
- if (strstr(bufp+1, "bd") || strstr(bufp+1, "cond") ||
- strstr(bufp+1, "cn") || strstr(bufp+1, "it") ||
- strstr(bufp+1, "obl") || strstr(bufp+1, "smbd"))
- continue; // skip font styles
- }
- temp = strlen(namebuf);
- if (temp < (int)strlen(buf)) temp = strlen(buf); // use bigger length
- if (!strncmp(namebuf, buf, temp)) continue; // same name as last
- if (nfaces < (int)sizeof(face_)/8) { // store next face
- face_[nfaces][2] = ti; // first font for face
- face_[nfaces][3] = (uchar)*namebuf; // first letter for face, a..z
- if (face_[nfaces][3] < 97 || face_[nfaces][3] > 123)
- face_[nfaces][3] = 123; // illegal char, z
- nfaces ++; // next face
- }
- strlcpy(buf, namebuf, sizeof(buf)); // last name in buffer
- }
- for (ti = 0, fnum = 0; ti < 27; ti ++) { // sort faces alphabetically
- for (tj = 0; tj < nfaces; tj ++) {
- tnum = face_[tj][3] - 97; // first letter, a = 0
- if (ti == tnum) { // current letter match
- face_[fnum][0] = face_[tj][2]; // first font index
- face_[fnum][1] = face_[tj][3]; // first letter
- fnum ++; // next face
- }
- }
- }
- for (ti = 0; ti < nfaces; ti ++) { // store all fonts in face table
- fnum = face_[ti][0]; // face index
- namep = Fl::get_font_name((Fl_Font)fnum, &temp);
- for (tk = 0; namep[tk] != '\0'; tk ++)
- buf[tk] = tolower(namep[tk]);
- buf[tk] = '\0'; // nul-terminate
- if (!(bufp = strstr(buf, "-"))) bufp = buf + tk;
- *bufp = '\0'; // shorten full name
- strlcpy(tbufs[0], buf, sizeof(tbufs[0]));
- face_[ti][1] = face_[ti][2] = face_[ti][3] = 0; // reset
- memset(tf, 0, sizeof(tf));
- for (tj = 0, tfi[0] = fnum, lnum = 1; tj < nfonts; tj ++) { // get all fonts of face
- namep = Fl::get_font_name((Fl_Font)tj, &temp); // fltk font name
- for (tk = 0; namep[tk] != '\0'; tk ++)
- namebuf[tk] = tolower(namep[tk]); // copy to lowercase
- namebuf[tk] = '\0'; // nul-terminate
- if (!isalpha(namebuf[0])) continue; // skip foreign chars
- if (!(namebufp = strstr(namebuf, "-"))) namebufp = namebuf; // full font name
- if (strstr(namebuf, " ") && namebufp == namebuf) { // basic font name
- namebufp = strstr(namebuf, " bold");
- if (!namebufp) namebufp = strstr(namebuf, " italic");
- if (!namebufp) namebufp = strstr(namebuf, " oblique");
- }
- if (!strncmp(buf, namebuf, bufp-buf) && (namebufp-namebuf == bufp-buf)) { // face name match
- strlcpy(tbufs[lnum], namebuf, sizeof(tbufs[lnum]));
- tfi[lnum] = tj; // font indexes
- lnum ++; // count fonts
- if (strstr(namebuf, "-")) { // abbreviations if full name
- if (strstr(namebufp+1, "bd")) tf[1] = 1;
- if (strstr(namebufp+1, "it")) tf[2] = 1;
- }
- if (strstr(namebufp+1, "bold")) tf[1] = 1; // set flags of current face
- if (strstr(namebufp+1, "italic")) tf[2] = 1;
- if (strstr(namebufp+1, "medium")) tf[3] = 1;
- if (strstr(namebufp+1, "plain")) tf[4] = 1;
- if (strstr(namebufp+1, "regular")) tf[5] = 1;
- }
- }
- for (tj = 0; tj < lnum; tj ++, tk = 0) { // sort fonts styles in face
- if (!(namebufp = strstr(tbufs[tj], "-"))) namebufp = tbufs[tj];
- if (tf[1] && strstr(namebufp+1, "black")) tk = 1; // favour bold, italic, etc
- else if (strstr(namebufp+1, "condensed")) tk = 1;
- else if (strstr(namebufp+1, "cond") && namebufp > tbufs[tj]) tk = 1;
- else if (strstr(namebufp+1, "cn") && namebufp > tbufs[tj]) tk = 1;
- else if (strstr(namebufp+1, "extra")) tk = 1;
- else if (tf[1] && strstr(namebufp+1, "heavy")) tk = 1;
- else if ((tf[3] || tf[4] || tf[5]) && strstr(namebufp+1, "light")) tk = 1;
- else if (tf[2] && strstr(namebufp+1, "light")) tk = 1;
- else if (tf[2] && strstr(namebufp+1, "oblique")) tk = 1;
- else if (tf[2] && strstr(namebufp+1, "obl") && namebufp > tbufs[tj]) tk = 1;
- else if (tf[2] && strstr(namebufp+1, "inclined")) tk = 1;
- else if (tf[1] && strstr(namebufp+1, "semibold")) tk = 1;
- else if (tf[1] && strstr(namebufp+1, "smbd") && namebufp > tbufs[tj]) tk = 1;
- else if (tf[2] && strstr(namebufp+1, "slanted")) tk = 1;
- else if (strstr(namebufp+1, "ultra")) tk = 1;
- if (lnum > 8 && tf[1] && tf[2]) { // simplify if too many variations
- tk = 1;
- if (!strncmp(namebufp+1, "bold", 4) && namebufp[5] == '\0') tk = 0;
- if (!strncmp(namebufp+1, "italic", 6) && namebufp[7] == '\0') tk = 0;
- if (!strncmp(namebufp+1, "bolditalic", 10) && namebufp[11] == '\0') tk = 0;
- if (!strncmp(namebufp+1, "medium", 6) && namebufp[7] == '\0') tk = 0;
- if (!strncmp(namebufp+1, "regular", 7) && namebufp[8] == '\0') tk = 0;
- }
- if (tk == 1) continue; // skip font
- cbit = fbit = tbit = 0; // set font styles
- if (strstr(namebufp+1, "medium") || strstr(namebufp+1, "plain") ||
- strstr(namebufp+1, "regular")) cbit = 1;
- if (strstr(namebufp+1, "roman") && namebufp > tbufs[tj]) cbit = 1;
- if (strstr(namebufp+1, "bold") || strstr(namebufp+1, "italic")) cbit = 0;
- if (strstr(namebufp+1, "black") || strstr(namebufp+1, "bold") ||
- strstr(namebufp+1, "heavy") || strstr(namebufp+1, "semibold") ||
- strstr(namebufp+1, "wide")) fbit = 1;
- else if ((strstr(namebufp+1, "bd") || strstr(namebufp+1, "smbd")) &&
- namebufp > tbufs[tj]) fbit = 1;
- if (strstr(namebufp+1, "oblique") || strstr(namebufp+1, "inclined") ||
- strstr(namebufp+1, "italic") || strstr(namebufp+1, "slanted")) tbit = 1;
- else if ((strstr(namebufp+1, "it") || strstr(namebufp+1, "obl")) &&
- namebufp > tbufs[tj]) tbit = 1;
- if (cbit) face_[ti][0] = tfi[tj];
- if (fbit && !tbit && !face_[ti][1]) face_[ti][1] = tfi[tj]; // bold
- if (!fbit && tbit && !face_[ti][2]) face_[ti][2] = tfi[tj]; // italic
- if (fbit && tbit && !face_[ti][3]) face_[ti][3] = tfi[tj]; // plus
- }
- }
- for (ti = 0; ti < nfaces; ti ++) { // remove duplicate fonts
- for (tj = ti+1; tj < nfaces; tj ++)
- if (face_[ti][1] == face_[tj][1]) face_[tj][1] = 0; // sort face loop does the rest
- }
- for (ti = 0; ti < nfaces; ti ++) { // sort face table
- if (!face_[ti][2]) face_[ti][2] = face_[ti][0]; // no italic
- if (!face_[ti][3]) face_[ti][3] = face_[ti][1]; // no plus
- if (face_[ti][1]) { // move face
- for (tk = 0; tk < ti; tk ++) {
- if (!face_[tk][1]) { // first empty face
- for (tj = 0; tj <= 3; tj ++) {
- face_[tk][tj] = face_[ti][tj];
- face_[ti][tj] = 0;
- }
- break;
- }
- }
- }
- }
- for (nfaces = 1; nfaces < (int)sizeof(face_)/8; nfaces ++)
- if (!face_[nfaces][1]) break; // recount faces
- for (ti = 0, lnum = 0; ti < nfaces; ti ++) { // sort letter lut
- fnum = face_[ti][0];
- namep = Fl::get_font_name((Fl_Font)fnum, &temp);
- tnum = (uchar)tolower(*namep) - 97; // current letter, a = 0
- if (tnum != lnum && tnum < 27) // first instance of letter a..z
- flet_[tnum] = ti; // store face index
- lnum = tnum; // last letter
- }
- flet_[27] = nfaces; // last face index
- for (ti = 0; ti < nfaces; ti ++) { // face reference table
- for (tj = 0; tj <= 3; tj ++) { // fonts in face
- fnum = face_[ti][tj]; // font index
- if (fnum < (int)sizeof(fref_)) fref_[fnum] = ti; // store face index
- }
- }
- return nfaces; // we're done
- } // Fl_Help_View::build_faces()
- //
- // Fl_Help_View::clear_global_selection() - Clear text selection.
- //
- void Fl_Help_View::clear_global_selection()
- {
- if (selected) redraw(); // Set widget to draw
- selection_push_first = selection_push_last = 0;
- selection_drag_first = selection_drag_last = 0;
- selection_first = selection_last = 0;
- selected = 0;
- } // Fl_Help_View::clear_global_selection()
- //
- // Fl_Help_View::clear_selection() - Clear current text selection.
- //
- void Fl_Help_View::clear_selection()
- {
- if (current_view == this) clear_global_selection();
- } // Fl_Help_View::clear_selection()
- //
- // Fl_Help_View::cmp_targets() - Compare two targets.
- //
- int // O - Result of comparison
- Fl_Help_View::cmp_targets(const Fl_Help_Link *t0, // I - First target
- const Fl_Help_Link *t1) // I - Second target
- {
- return strcasecmp(t0->name, t1->name); // Target names
- } // Fl_Help_View::cmp_targets()
- //
- // Fl_Help_View::compare_targets() - replaced, struct used for d-pointer
- //
- int
- Fl_Help_View::compare_targets(const Fl_Help_Target *t0,
- const Fl_Help_Target *t1)
- {
- return 0;
- } // Fl_Help_View::compare_targets()
- //
- // Fl_Help_View::do_align() - Compute alignment for a line in a block.
- //
- int // O - New line
- Fl_Help_View::do_align(Fl_Help_Block *b, // I - Block to add to
- int li, // I - Current line - removed
- int xx, // I - Current X position
- int ca, // I - Current alignment
- int &sl) // IO - Starting link
- {
- int offset = 0; // Alignment offset
- switch (ca) {
- case RIGHT : // Right
- offset = b->w - xx - 6;
- break;
- case CENTER : // Center
- offset = (b->w - xx) / 2;
- break;
- default : // Left
- offset = 0;
- break;
- }
- b->line = b->x + offset; // Left starting position for line
- //if (li < 31) li ++;
- while (sl < nlinks_) {
- links_[sl].x += offset; // X offset of link text
- links_[sl].w += offset; // Width of link text
- sl ++;
- }
- return li;
- } // Fl_Help_View::do_align()
- //
- // Fl_Help_View::draw() - Draw the Fl_Help_View widget.
- //
- void Fl_Help_View::draw()
- {
- char *sp, // Buffer search ptr
- buf[1024], // Text buffer
- attr[1024], // Attribute buffer
- wattr[8], // Width attribute
- hattr[8], // Height attribute
- tag[4]; // tag/element 4-char buf
- const Fl_Help_Block *block; // Pointer to current block
- const char *ptr, // Pointer to text in block
- *attrptr, // Start of attributes ptr
- *tagptr; // Start of tag/element ptr
- int ti = 0, // temp loop var
- bi = 0, // Main loop var
- temp = 0, // temp var
- ss = 0, // Scrollbar size
- qch = 0, // Quote char
- baseh = 0, // baseline offset for images
- line = 0, // Current line
- xx = 0,
- yy = 0,
- ww = 0,
- hh = 0, // Current positions and sizes
- head = 0, // Head/body section flag
- pre = 0, // Pre text flag
- btag = 0, // tag/element fourcc int
- needspace = 0, // Do we need whitespace?
- underline = 0, // Underline text?
- tx = 0,
- ty = 0,
- tw = 0,
- th = 0, // Table cell positions and sizes
- linew = 0, // current line width
- imgw = 0, // Image width
- imgh = 0, // Image height
- brflag = 0; // br flag
- unsigned char font = 0; // Current font
- unsigned char fsize; // Current font size
- Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box to draw
- Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
- // Draw the scrollbar/s and box first
- ww = w();
- hh = h();
- initfont(font, fsize);
- draw_box(bt, x(), y(), ww, hh, bgcolor_);
- ss = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
- if (hscrollbar_.visible()) {
- draw_child(hscrollbar_);
- hh -= ss;
- ti ++;
- }
- if (scrollbar_.visible()) {
- draw_child(scrollbar_);
- ww -= ss;
- ti ++;
- }
- if (ti == 2) {
- fl_color(FL_GRAY);
- fl_rectf(x() + ww - Fl::box_dw(bt) + Fl::box_dx(bt),
- y() + hh - Fl::box_dh(bt) + Fl::box_dy(bt), ss, ss);
- }
- if (!value_) return;
- if (current_view == this && selected) {
- hv_selection_color = FL_SELECTION_COLOR;
- hv_selection_text_color = fl_contrast(textcolor_, FL_SELECTION_COLOR);
- }
- current_pos = 0;
- // Clip the drawing to the inside of the box
- fl_push_clip(x() + Fl::box_dx(bt), y() + Fl::box_dy(bt),
- ww - Fl::box_dw(bt), hh - Fl::box_dh(bt));
- fl_color(textcolor_);
- //printf("hh=%d ss=%d h()=%d\n",hh,ss,h());
- // Draw all visible blocks
- for (bi = 0, block = blocks_; bi < nblocks_; bi ++, block ++)
- if ((block->y + block->h) >= topline_ && block->y < (topline_ + h()))
- {
- line = 0;
- xx = block->line;
- yy = block->y - topline_;
- pre = block->pre;
- //if (!pre) {
- popfont(font, fsize);
- font = block->font; // default font for block
- fsize = block->fsize;
- pushfont(font, fsize);
- //}
- hh = 0;
- needspace = 0;
- brflag = 0;
- linew = 0;
- for (ptr = block->start, sp = buf; ptr < block->end; )
- {
- if ((*ptr == '<' || isspace((*ptr) & 255)) && sp > buf)
- {
- if (!head && !pre) // Draw normal text
- {
- *sp = '\0'; // Nul-terminate
- sp = buf;
- ww = (int)fl_width(buf); // Width of word in buf
- if (needspace && xx > block->x)
- xx += 4;//(int)fl_width(" ");
- baseh = 0; // add baseh offset for text
- if (block->maxh > 0 && block->imgy - topline_ == yy)
- baseh = block->maxh - fsize;
- //if (block->liney) baseh += block->liney;
- hv_draw(buf, xx + x() - leftline_, yy + y() + baseh); // replaces hv_draw(tbuf..
- if (underline) { // Add width for uline spaces after word
- temp = (isspace((*ptr) & 255)) ? (int)fl_width(" ") : 0;
- fl_xyline(xx + x() - leftline_, yy + y() + 1 + baseh,
- xx + x() - leftline_ + ww + temp);
- }
- xx += ww;
- current_pos = ptr - value_;
- if ((fsize + 2) > hh) hh = fsize + 2; // Set hh
- needspace = 0;
- }
- else if (!head && pre) // Draw pre text
- {
- // this code is buggy and conflicts with other stuff
- // don't think it's needed but leaving it just in case
- /* while (isspace((*ptr) & 255)) {
- if (*ptr == '\n') {
- *sp = '\0';
- sp = buf;
- hv_draw("|", xx + x() - leftline_, yy + y());
- if (underline)
- fl_xyline(xx + x() - leftline_, yy + y() + 1,
- xx + x() - leftline_ + (int)fl_width(buf));
- current_pos = ptr - value_;
- //if (line < 31) line ++;
- xx = block->line;
- yy += hh;
- hh = fsize + 2;
- }
- else if (*ptr == '\t') {
- ti = linew / (int)fl_width(" "); // number of chars
- temp = 8 - (ti & 7); // number of tabs
- for (ti = 0; ti < temp; ti ++) // pre tabs width fix
- *(sp ++) = ' ';
- }
- else
- *(sp ++) = ' ';
- if ((fsize + 2) > hh) hh = fsize + 2;
- ptr ++;
- }
- if (sp > buf) { the code below was in here */
- *sp = '\0'; // Nul-terminate
- sp = buf;
- ww = (int)fl_width(buf);
- //printf("b->x=%d b->w=%d xx=%d ww=%d linew=%d ptr=%c buf=%s\n",
- // block->x,block->w,xx,ww,linew,*ptr,buf);
- baseh = 0; // add baseh offset for pre text
- if (block->maxh > 0 && block->imgy - topline_ == yy)
- baseh = block->maxh - fsize;
- hv_draw(buf, xx + x() - leftline_, yy + y() + baseh);
- if (underline)
- fl_xyline(xx + x() - leftline_, yy + y() + 1 + baseh,
- xx + x() - leftline_ + ww);
- xx += ww;
- linew += ww;
- current_pos = ptr - value_;
- // } // if (sp > buf)
- needspace = 0;
- }
- else
- {
- sp = buf;
- while (isspace((*ptr) & 255)) ptr ++;
- current_pos = ptr - value_;
- }
- brflag = 0;
- }
- if (*ptr == '<')
- {
- tagptr = ptr; // Start of tag
- ptr ++;
- if (!strncmp(ptr, "!--", 3)) { // Found "!--"
- ptr += 3;
- if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
- ptr += 3;
- continue;
- }
- else
- break;
- }
- while (*ptr && *ptr != '>' && !isspace((*ptr) & 255))
- if (sp < (buf + sizeof(buf) - 1))
- *(sp ++) = *(ptr ++); // added ()
- else
- ptr ++;
- *sp = '\0'; // Nul-terminate
- sp = buf;
- attrptr = ptr; // Start of attributes
- while (*ptr && *ptr != '>') ptr ++;
- if (*ptr == '>') ptr ++;
- // Set the supposed start of printed eord here
- current_pos = ptr - value_;
- btag = strlen(buf); // store strlen
- if (btag > 4) btag = 4; // limit
- for (ti = 0; ti < btag; ti ++) // abbreviate tag, to uppercase
- tag[ti] = toupper(buf[ti]);
- for (ti = btag; ti < 4; ti ++) // set chars after to nul
- tag[ti] = 0;
- if (buf[0] != '/' && btag > 3) tag[3] = 0; // eg. HTML=HTM
- btag = CMD(tag[0],tag[1],tag[2],tag[3]); // tag fourcc int
- // End of command reached
- if (btag == CMD('A',0,0,0)) // 'A'
- {
- if (get_attr(attrptr, "HREF", attr, sizeof(attr))) {
- fl_color(linkcolor_);
- underline = 1;
- }
- }
- else if (btag == CMD('/','A',0,0)) // '/A'
- {
- fl_color(textcolor_);
- underline = 0;
- }
- else if (btag == CMD('B',0,0,0) ||
- btag == CMD('S','T','R',0)) // 'B' 'STRONG'
- {
- font = font_style(font, FL_BOLD);
- pushfont(font, fsize);
- }
- else if (btag == CMD('/','B',0,0) ||
- btag == CMD('/','S','T','R')) // '/B' '/STRONG'
- {
- popfont(font, fsize);
- }
- else if (btag == CMD('B','L','O',0) ||
- btag == CMD('D','L',0,0) ||
- btag == CMD('U','L',0,0) ||
- btag == CMD('O','L',0,0) ||
- btag == CMD('D','D',0,0) ||
- btag == CMD('D','T',0,0)) // 'BLOCKQUOTE' 'DL'OL'UL'
- {
- }
- else if (btag == CMD('/','B','L','O') ||
- btag == CMD('/','D','L',0) ||
- btag == CMD('/','O','L',0) ||
- btag == CMD('/','U','L',0)) // '/BLOCKQUOTE' '/DL'/OL'/UL'
- {
- }
- else if (btag == CMD('B','O','D',0)) // 'BODY'
- {
- head = 0;
- }
- else if (btag == CMD('B','R',0,0)) // 'BR'
- {
- }
- else if (btag == CMD('C','E','N',0)) // 'CENTER'
- {
- }
- else if (btag == CMD('C','O','D',0) ||
- btag == CMD('T','T',0,0)) // 'CODE' 'TT'
- {
- font = monofont_;
- pushfont(font, fsize);
- }
- else if (btag == CMD('/','C','O','D') ||
- btag == CMD('/','T','T',0)) // '/CODE' '/TT'
- {
- popfont(font, fsize);
- }
- else if (btag == CMD('D','I','V',0)) // 'DIV'
- {
- }
- else if (btag == CMD('F','O','N',0)) // 'FONT'
- {
- if (get_attr(attrptr, "COLOR", attr, sizeof(attr)))
- fl_color(get_color(attr, textcolor_));
- if (get_attr(attrptr, "FACE", attr, sizeof(attr)))
- font = font_face(attr);
- //tempsize = fsize;
- if (get_attr(attrptr, "SIZE", attr, sizeof(attr))) {
- if (isdigit(attr[0])) // Absolute size
- fsize = (int)(fontsize_ * pow(1.2, atof(attr) - 3.0));
- else // Relative size
- fsize = (int)(fsize * pow(1.2, atof(attr) - 3.0));
- }
- pushfont(font, fsize);
- if (fsize + 2 > hh) hh = fsize + 2; // set hh
- }
- else if (btag == CMD('/','F','O','N')) // '/FONT'
- {
- fl_color(textcolor_);
- //tempsize = fsize;
- popfont(font, fsize);
- if (fsize + 2 > hh) hh = fsize + 2; // set hh
- }
- else if (tag[0] == 'H' && isdigit(tag[1])) // 'H1'
- {
- if (tag[1] < '7') { // ignore if > h6
- font = font_style(font, FL_BOLD);
- switch (tag[1]) { // header sizes
- case '1' : fsize = 24; break;
- case '2' : fsize = 18; break;
- case '3' : fsize = 16; break;
- case '4' : fsize = 14; break;
- case '5' : fsize = 12; break;
- case '6' : fsize = 10; break;
- }
- pushfont(font, fsize);
- }
- }
- else if (btag == CMD('/','H',tag[2],0) && isdigit(tag[2])) // '/H1'
- {
- if (tag[2] < '7') // ignore if > h6
- popfont(font, fsize);
- }
- else if (btag == CMD('H','E','A',0)) // 'HEAD'
- {
- head = 1;
- }
- else if (btag == CMD('/','H','E','A')) // '/HEAD'
- {
- head = 0;
- }
- else if (btag == CMD('H','R',0,0)) // 'HR'
- { // rem'd new line, added hr shadow
- tx = x() - leftline_; // hr x
- ty = yy + y() - fsize; // hr y
- int height, width, lx1, lx2, half1, half2;
- int isStandard = 1;
- char myattr[8], *mydash, myattr_dash[9];
- if(get_attr ( attrptr, "COLOR", myattr, sizeof ( myattr ) ))
- {
- fl_color(get_color( myattr, FL_BLACK ));
- isStandard = 0;
- } else fl_color(FL_BLACK);
- if(get_attr ( attrptr, "DASH", myattr_dash, sizeof ( myattr_dash ) ))
- {
- for(unsigned int i=0; i<sizeof(myattr_dash); i++)
- if(myattr_dash[i] > '0')
- myattr_dash[i] -= '0';
- mydash = myattr_dash;
- isStandard = 0;
- }
- else mydash = NULL;
- if(get_attr ( attrptr, "HEIGHT", myattr, sizeof ( myattr ) ))
- {
- height = atoi ( myattr );
- fl_line_style(FL_SOLID | FL_CAP_SQUARE, height, mydash);
- isStandard = 0;
- }
- if(get_attr ( attrptr, "WIDTH", myattr, sizeof ( myattr ) )){
- width = get_length( myattr );
- isStandard = 0;
- }
- else
- width = block->w + tx;
- switch ( get_align ( attrptr, LEFT ) )
- {
- case CENTER :
- half1 = block->w / 2;
- half2 = width / 2;
- lx1 = block->x + tx + half1 - half2;
- lx2 = block->w + tx - half1 + half2;
- isStandard = 0;
- break;
- case RIGHT :
- lx1 = block->w + tx - width;
- lx2 = block->w + tx;
- isStandard = 0;
- break;
- default :
- lx1 = block->x + tx;
- lx2 = width;
- break;
- }
- if(isStandard){
- fl_line(block->x + tx, ty, block->w + tx, ty);
- fl_color(224, 224, 224); // light grey
- fl_line(block->x + tx, ty + 1, block->w + tx, ty + 1); // shadow
- } else {
- fl_line ( lx1, ty, lx2, ty );
- fl_line_style(0); //reset line style
- }
- fl_color(textcolor_); // reset
- hh = fsize + 2; // set hh
- }
- else if (btag == CMD('H','T','M',0)) // 'HTML'
- {
- }
- else if (btag == CMD('I',0,0,0) ||
- btag == CMD('E','M',0,0)) // 'I' 'EM'
- {
- font = font_style(font, FL_ITALIC);
- pushfont(font, fsize);
- }
- else if (btag == CMD('/','I',0,0) ||
- btag == CMD('/','E','M',0)) // '/I' '/EM'
- {
- popfont(font, fsize);
- }
- else if (btag == CMD('I','M','G',0)) // 'IMG'
- {
- imgw = imgh = 0; // reset
- if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
- imgw = get_length(wattr);
- if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
- imgh = get_length(hattr);
- img = 0; // rem'd NULL
- if (get_attr(attrptr, "SRC", attr, sizeof(attr))) {
- img = get_image(attr, imgw, imgh);
- if (!imgw) imgw = img->w();
- if (!imgh) imgh = img->h();
- }
- if (!imgw || !imgh) {
- if (!get_attr(attrptr, "ALT", attr, sizeof(attr))) // rem'd == 0
- strcpy(attr, "IMG");
- }
- ww = imgw;
- if (needspace && xx > block->x)
- xx += (int)fl_width(" ");
- if (img) {
- baseh = block->maxh - imgh; // add baseh offset
- img->draw(xx + x() - leftline_,
- yy + y() - fl_height() + fl_descent() + baseh); // rem'd + 2
- // Seb was here - freeing broken_image causes an XServer XFreePixmap crash
- if ((void*)img != &broken_image) img->release();
- }
- xx += ww;
- if (imgh + 2 > hh) hh = imgh + 2; // Set img hh
- needspace = 0;
- brflag = 0;
- }
- else if (btag == CMD('K','B','D',0)) // 'KBD'
- {
- font = font_style(monofont_, FL_BOLD);
- pushfont(font, fsize);
- }
- else if (btag == CMD('/','K','B','D')) // '/KBD'
- {
- popfont(font, fsize);
- }
- else if (btag == CMD('L','I',0,0)) // 'LI'
- {
- // rem'd hv_draw and symbol font stuff
- tx = xx - fsize + x() - leftline_; // bullet x
- ty = yy + y() - 6; // bullet y
- get_attr(attrptr, "TYPE", attr, sizeof(attr)); // bullet type
- if (!strncasecmp(attr, "disc", 4) ||
- !strncasecmp(attr, "disk", 4)) { // li > ul > ul nest
- fl_arc(tx, ty, 5, 5, 0, 360);
- fl_rectf(tx + 1, ty + 1, 3, 3);
- }
- else if (!strncasecmp(attr, "circle", 6))
- fl_arc(tx, ty, 5, 5, 0, 360);
- else if (!strncasecmp(attr, "square", 6))
- fl_rectf(tx, ty, 5, 5);
- else if (block->type == 1) { // disc/disk
- fl_arc(tx, ty, 5, 5, 0, 360);
- fl_rectf(tx + 1, ty + 1, 3, 3);
- }
- else if (block->type == 2) // circle
- fl_arc(tx, ty, 5, 5, 0, 360);
- else if (block->type >= 3) // square
- fl_rectf(tx, ty, 5, 5);
- else { // default
- fl_arc(tx, ty, 5, 5, 0, 360);
- fl_rectf(tx + 1, ty + 1, 3, 3);
- }
- }
- else if (btag == CMD('/','L','I',0)) // '/LI'
- {
- }
- else if (btag == CMD('N','O','S',0)) // 'NOSCRIPT'
- { // we don't support scripting so we won't skip this
- }
- else if (btag == CMD('P',0,0,0)) // 'P'
- {
- }
- else if (btag == CMD('P','R','E',0)) // 'PRE'
- {
- linew = 0;
- pre = 1;
- //font = monofont_;
- //fsize = fontsize_;
- //pushfont(font, fsize);
- tx = block->x - leftline_;
- ty = block->y - topline_ - fsize;
- tw = block->w - block->x - 2;
- th = block->h + fsize + (fsize / 4);
- if (tx < 0) {
- tw += tx;
- tx = 0;
- }
- if (ty < 0) {
- th += ty;
- ty = 0;
- }
- tx += x();
- ty += y();
- if (block->bgcolor != bgcolor_) {
- fl_color(block->bgcolor);
- fl_rectf(tx, ty, tw, th);
- fl_color(textcolor_);
- }
- if (block->border){
- fl_rect ( tx, ty, tw, th );
- }
- }
- else if (btag == CMD('/','P','R','E')) // '/PRE'
- {
- //popfont(font, fsize);
- pre = 0;
- }
- else if (btag == CMD('S','C','R',0)) // 'SCRIPT'
- {
- while (ptr) { // skip scripting
- ptr = strstr(ptr, "</");
- if (!strncasecmp(ptr, "</SCRIPT>", 9)) break;
- }
- if (ptr) { // found </script>
- ptr += 9;
- continue;
- }
- else // not found
- break;
- }
- else if (btag == CMD('T','A','B',0)) // 'TABLE'
- {
- }
- else if (btag == CMD('T','D',0,0) ||
- btag == CMD('T','H',0,0)) // 'TD' 'TH'
- {
- /*if (btag == CMD('T','H',0,0))
- font = serifont_ | FL_BOLD;
- else
- font = serifont_;
- fsize = fontsize_;
- pushfont(font, fsize);*/
- fl_color(textcolor_); // fixes /a td bug
- underline = 0;
- tx = block->x - 4 - leftline_; //-4 -> left padding
- ty = block->y - topline_ - fsize - 3; //-3 -> top padding
- tw = block->w - block->x + (tr_td_adjust_ ? 6 : 7); // +7 -> right size
- th = block->h + fsize - (tr_td_adjust_ ? 6 : 5); // -5 -> bottom size
- if (tx < 0) {
- tw += tx;
- tx = 0;
- }
- if (ty < 0) {
- th += ty;
- ty = 0;
- }
- tx += x();
- ty += y();
- if (block->bgcolor != bgcolor_) {
- fl_color(block->bgcolor);
- fl_rectf(tx, ty, tw, th);
- fl_color(textcolor_);
- }
- if (block->border){
- fl_color ( block->border_color );
- fl_line_style(FL_SOLID | FL_CAP_SQUARE, block->border, NULL);
- fl_rect ( tx, ty, tw, th );
- fl_line_style(0);
- fl_color ( textcolor_ );
- }
- }
- else if (btag == CMD('/','T','D',0) ||
- btag == CMD('/','T','H',0)) // '/TD' '/TH'
- {
- //popfont(font, fsize);
- }
- else if (btag == CMD('T','I','T',0)) // 'TITLE'
- {
- head = 1;
- }
- else if (btag == CMD('T','R',0,0)) // 'TR'
- {
- }
- else if (btag == CMD('U',0,0,0)) // 'U'
- {
- underline = 1;
- }
- else if (btag == CMD('/','U',0,0)) // '/U'
- {
- underline = 0;
- }
- else if (btag == CMD('V','A','R',0)) // 'VAR'
- {
- font = font_style(monofont_, FL_ITALIC);
- pushfont(font, fsize);
- }
- else if (btag == CMD('/','V','A','R')) // '/VAR'
- {
- popfont(font, fsize);
- }
- else if (btag == CMD('A','B','B',0) || // 'ABBR'
- btag == CMD('A','C','R',0) || // 'ACRONYM'
- btag == CMD('A','D','D',0) || // 'ADDRESS'
- btag == CMD('A','P','P',0) || // 'APPLET'
- btag == CMD('A','R','E',0) || // 'AREA'
- btag == CMD('B','A','S',0) || // 'BASE' 'BASEFONT'
- btag == CMD('B','D','O',0) || // 'BDO'
- btag == CMD('B','G','S',0) || // 'BGSOUND'
- btag == CMD('B','I','G',0) || // 'BIG'
- btag == CMD('B','L','I',0) || // 'BLINK'
- btag == CMD('B','U','T',0) || // 'BUTTON'
- btag == CMD('C','A','P',0) || // 'CAPTION'
- btag == CMD('C','I','T',0) || // 'CITE'
- btag == CMD('C','O','L',0) || // 'COL' 'COLGROUP'
- btag == CMD('D','E','L',0) || // 'DEL'
- btag == CMD('D','F','N',0) || // 'DFN'
- btag == CMD('D','I','R',0) || // 'DIR'
- btag == CMD('E','M','B',0) || // 'EMBED'
- btag == CMD('F','I','E',0) || // 'FIELDSET'
- btag == CMD('F','O','R',0) || // 'FORM'
- btag == CMD('F','R','A',0) || // 'FRAME' 'FRAMESET'
- btag == CMD('I','F','R',0) || // 'IFRAME'
- btag == CMD('I','N','P',0) || // 'INPUT'
- btag == CMD('I','N','S',0) || // 'INS'
- btag == CMD('I','S','I',0) || // 'ISINDEX'
- btag == CMD('L','A','B',0) || // 'LABEL'
- btag == CMD('L','E','G',0) || // 'LEGEND'
- btag == CMD('L','I','N',0) || // 'LINK'
- btag == CMD('M','A','P',0) || // 'MAP'
- btag == CMD('M','A','R',0) || // 'MARQUEE'
- btag == CMD('M','E','N',0) || // 'MENU'
- btag == CMD('M','E','T',0) || // 'META'
- btag == CMD('M','U','L',0) || // 'MULTICOL'
- btag == CMD('N','O','B',0) || // 'NOBR'
- btag == CMD('N','O','F',0) || // 'NOFRAMES'
- btag == CMD('O','B','J',0) || // 'OBJECT'
- btag == CMD('O','P','T',0) || // 'OPTGROUP' 'OPTION'
- btag == CMD('P','A','R',0) || // 'PARAM'
- btag == CMD('Q',0,0,0) || // 'Q'
- btag == CMD('S',0,0,0) || // 'S'
- btag == CMD('S','A','M',0) || // 'SAMP'
- btag == CMD('S','E','L',0) || // 'SELECT'
- btag == CMD('S','M','A',0) || // 'SMALL'
- btag == CMD('S','P','A',0) || // 'SPACER' 'SPAN'
- btag == CMD('S','T','R',0) || // 'STRIKE'
- btag == CMD('S','T','Y',0) || // 'STYLE'
- btag == CMD('S','U','B',0) || // 'SUB'
- btag == CMD('S','U','P',0) || // 'SUP'
- btag == CMD('T','B','O',0) || // 'TBODY'
- btag == CMD('T','E','X',0) || // 'TEXTAREA'
- btag == CMD('T','F','O',0) || // 'TFOOT'
- btag == CMD('T','H','E',0) || // 'THEAD'
- btag == CMD('W','B','R',0) || // 'WBR'
- btag == CMD('X','M','P',0)) // 'XMP'
- ; // unsupported tags
- else if (tag[0] == '!' && isalpha(tag[1])) // '!DOCTYPE' etc
- ;
- else if (tag[0] == '?' && isalpha(tag[1])) // '?XMP' etc
- ;
- else if (tag[0] == '/' && isalpha(tag[1])) // unrecognized end tag
- ;
- else if (!head) // unrecognized tag so draw it
- {
- hv_draw("<", xx + x() - leftline_, yy + y()); // draw '<' char
- xx += (int)fl_width("<"); // add width of '<' char
- linew += (int)fl_width("<");
- ptr = tagptr + 1; // start of tag + 1
- }
- } // if (*ptr == '<')
- else if (*ptr == '\n' && pre) // '\n' char in pre
- {
- *sp = '\0'; // Nul-terminate
- sp = buf;
- hv_draw(buf, xx + x() - leftline_, yy + y());
- //hh = fsize + 2; // Set hh
- linew = 0;
- needspace = 0;
- ptr ++;
- current_pos = ptr - value_;
- }
- else if (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
- {
- if (pre) {
- if (*ptr == ' ')
- *(sp ++) = ' '; // added ()
- else if (*ptr == '\t') {
- ti = linew / (int)fl_width(" "); // number of chars, monospace
- temp = 8 - (ti & 7); // number of tabs 1..8
- for (ti = 0; ti < temp; ti ++) // pre tabs width fix
- *(sp ++) = ' '; // added ()
- }
- }
- ptr ++;
- if (!pre) current_pos = ptr - value_;
- needspace = 1; // Set need space flag
- }
- else if (*ptr == '&') // '&' char ref
- {
- ptr ++;
- qch = quote_char(ptr);
- if (qch < 0) // Not char ref
- *(sp ++) = '&';
- else { // replaces else if (temp == 0)
- *(sp ++) = qch; // added ()
- ptr = strchr(ptr, ';') + 1; // skip past semi-colon char
- }
- if ((fsize + 2) > hh) hh = fsize + 2; // Set hh
- }
- else
- {
- *(sp ++) = *(ptr ++); // added ()
- if ((fsize + 2) > hh) hh = fsize + 2; // Set hh
- }
- } // for (ptr = block->start ...)
- *sp = '\0'; // Nul-terminate
- if (sp > buf) // Still something left to parse
- {
- ww = (int)fl_width(buf); // Width of word
- if (!head && !pre) { // Normal text
- if (needspace && xx > block->x)
- xx += (int)fl_width(" ");
- }
- if (!head) { // Draw text
- baseh = 0; // add baseh offset for missed text
- if (block->maxh > 0 && block->imgy - topline_ == yy)
- baseh = block->maxh - fsize;
- //if (block->liney) baseh += block->liney;
- hv_draw(buf, xx + x() - leftline_, yy + y() + baseh);
- if (underline)
- fl_xyline(xx + x() - leftline_, yy + y() + 1 + baseh,
- xx + x() - leftline_ + ww);
- current_pos = ptr - value_;
- }
- }
- } // for (bi = 0 ...)
- fl_pop_clip();
- } // Fl_Help_View::draw()
- //
- // Fl_Help_View::end_selection() - End text selection.
- //
- void Fl_Help_View::end_selection(int cb) // I - Set clipboard, opt
- {
- if (!selected || current_view != this) return;
- // Convert the select part of our html text into some kind of
- // somewhat readable ASCII and store it in the selection buffer
- char spacec = 0, pre = 0, tempc = 0, endc = 0;
- int len = strlen(value_),
- in = 0, xx = 0;
- char *text = (char*)malloc(len + 1),
- *dp = text;
- const char *sp = value_,
- *cmdp,
- *srcp;
- while (true) // was for (;;)
- {
- tempc = *(sp ++); // added ()
- if (tempc == 0) break;
- if (tempc == '<') { // Begin of some html command. Skip until we find a '>'
- cmdp = sp;
- while (true) { // was for (;;)
- tempc = *(sp ++); // added ()
- if (tempc == 0 || tempc == '>') break;
- }
- if (tempc == 0) break;
- // Do something with this command, the replacement string must
- // not be longer that the command itself plus '<' and '>'
- srcp = 0; // rem'd NULL
- switch (command(cmdp)) {
- case CMD('p','r','e', 0 ): pre = 1; break;
- case CMD('/','p','r','e'): pre = 0; break;
- case CMD('t','d', 0 , 0 ):
- case CMD('p', 0 , 0 , 0 ):
- case CMD('/','p', 0 , 0 ):
- case CMD('b','r', 0 , 0 ): srcp = "\n"; break;
- case CMD('l','i', 0 , 0 ): srcp = "\n * "; break;
- case CMD('/','h','1', 0 ):
- case CMD('/','h','2', 0 ):
- case CMD('/','h','3', 0 ):
- case CMD('/','h','4', 0 ):
- case CMD('/','h','5', 0 ):
- case CMD('/','h','6', 0 ): srcp = "\n\n"; break;
- case CMD('t','r', 0 , 0 ):
- case CMD('h','1', 0 , 0 ):
- case CMD('h','2', 0 , 0 ):
- case CMD('h','3', 0 , 0 ):
- case CMD('h','4', 0 , 0 ):
- case CMD('h','5', 0 , 0 ):
- case CMD('h','6', 0 , 0 ): srcp = "\n\n"; break;
- case CMD('d','t', 0 , 0 ): srcp = "\n "; break;
- case CMD('d','d', 0 , 0 ): srcp = "\n - "; break;
- }
- in = sp - value_;
- if (srcp && in > selection_first && in <= selection_last) {
- while (*srcp)
- *(dp ++) = *(srcp ++); // added ()
- tempc = srcp[-1];
- spacec = (isspace(tempc & 255)) ? ' ' : tempc;
- }
- continue;
- }
- if (tempc == '&') { // Special characters
- xx = quote_char(sp);
- if (xx >= 0) {
- tempc = (char)xx;
- while (true) { // was for (;;)
- endc = *(sp ++); // added ()
- if (!endc || endc == ';') break;
- }
- }
- }
- in = sp - value_;
- if (in > selection_first && in <= selection_last) {
- if (!pre && isspace(tempc & 255)) tempc = ' ';
- if (spacec != ' ' || tempc != ' ')
- *(dp ++) = tempc; // added ()
- spacec = tempc;
- }
- }
- *dp = 0;
- Fl::copy(text, strlen(text), cb);
- free(text);
- } // Fl_Help_View::end_selection()
- //
- // Fl_Help_View::extend_selection() - Extend current text selection.
- //
- char // O - True if text selection changed
- Fl_Help_View::extend_selection()
- {
- if (Fl::event_is_click()) return 0;
- //printf("old selection_first=%d, selection_last=%d\n",
- // selection_first, selection_last);
- int sf = selection_first,
- sl = selection_last;
- selected = 1;
- mouse_x = Fl::event_x();
- mouse_y = Fl::event_y();
- draw_mode = 2; // End selection mode
- fl_begin_offscreen(Fl_Help_View_buffer);
- draw();
- fl_end_offscreen();
- draw_mode = 0;
- if (selection_push_first < selection_drag_first) {
- selection_first = selection_push_first;
- }
- else {
- selection_first = selection_drag_first;
- }
- if (selection_push_last > selection_drag_last) {
- selection_last = selection_push_last;
- }
- else {
- selection_last = selection_drag_last;
- }
- //printf("new selection_first=%d, selection_last=%d\n",
- // selection_first, selection_last);
- if (sf != selection_first || sl != selection_last) { // was ! =
- // puts("REDRAW!!!\n");
- return 1;
- }
- else {
- // puts("");
- return 0;
- }
- } // Fl_Help_View::extend_selection()
- //
- // Fl_Help_View::fileislink() - Was link clicked or nav button?
- //
- int Fl_Help_View::fileislink() // O - Link clicked
- {
- return d->islink;
- }
- //
- // Fl_Help_View::filepath() - Set value file path string.
- //
- void Fl_Help_View::filepath(const char *fp) // I - Current file path
- {
- if (!fp) return; // null
- d->ispath = 1; // path is used
- if (!d->islink) // nav button
- strlcpy(d->lpath, d->path, sizeof(d->lpath)); // set last path
- strlcpy(d->path, fp, sizeof(d->path)); // set path
- }
- //
- // Fl_Help_View::filepath() - Get value file path string.
- //
- char *Fl_Help_View::filepath() // O - Current file path
- {
- return d->path;
- }
- //
- // Fl_Help_View::find() - Find the specified string.
- //
- int // O - Matching position or -1 if not found
- Fl_Help_View::find(const char *sp, // I - String to find
- int pos) // I - Starting position, opt
- {
- int ti = 0, // Temp looping var
- cref = 0; // Current char ref
- Fl_Help_Block *block; // Current block
- const char *bptr, // Block matching pointer
- *cptr, // Start of current comparison pointer
- *sptr; // Search string pointer
- // Range check input and value
- if (!sp || !value_) return -1;
- if (pos < 0 || pos >= (int)strlen(value_))
- pos = 0;
- else if (pos > 0)
- pos ++;
- // Look for the string
- for (ti = nblocks_, block = blocks_; ti > 0; ti --, block ++)
- {
- if (block->end < (value_ + pos))
- continue;
- if (block->start < (value_ + pos))
- bptr = value_ + pos;
- else
- bptr = block->start;
- for (sptr = sp, cptr = bptr; *sptr && *bptr && bptr < block->end; bptr ++)
- {
- if (*bptr == '<') { // Skip to end of element
- while (*bptr && bptr < block->end && *bptr != '>')
- bptr ++;
- continue;
- }
- else if (*bptr == '&') { // Decode HTML entity
- cref = quote_char(bptr + 1);
- if (cref < 0) // Not char ref
- cref = '&';
- else
- bptr = strchr(bptr + 1, ';') + 1;
- }
- else
- cref = *bptr;
- if (tolower(*sptr) == tolower(cref))
- sptr ++;
- else { // No match, so reset to start of search
- sptr = sp;
- cptr ++;
- bptr = cptr;
- }
- } // for (sptr = sp ...)
- if (!*sptr) { // Found a match!
- topline(block->y - block->h);
- return (block->end - value_);
- }
- } // for (ti = nblocks_ ...)
- return -1; // No match!
- } // Fl_Help_View::find()
- //
- // Fl_Help_View::find_link() - Find the link at the given position.
- //
- Fl_Help_Link * // O - Link pointer
- Fl_Help_View::find_link(int xx, // I - X position
- int yy) // I - Y position
- {
- int ti = 0;
- Fl_Help_Link *linkp;
- for (ti = nlinks_, linkp = links_; ti > 0; ti --, linkp ++) {
- if (xx >= linkp->x && xx < linkp->w &&
- yy >= linkp->y && yy < linkp->h)
- break;
- }
- return (ti) ? linkp : 0; // Was link found? - rem'd NULL
- } // Fl_Help_View::find_link()
- //
- // Fl_Help_View::follow_link() - Follow the specified link.
- //
- void Fl_Help_View::follow_link(Fl_Help_Link *lp) // I - Link pointer
- {
- char target[32], // Current target
- dir[1024], // Current directory
- temp[1024], // Temporary filename
- *tptr,
- *sptr,
- *dirp; // Pointer into temporary filename
- const char *namep = lp->filename; // link filename
- const char *vlink_name;
- char *link_to_free = NULL;
- if( link_ ){ //call link function to give it a chance to cancel it
- vlink_name = (*link_)(this, namep, lp->name);
- if(!vlink_name) return;
- if(vlink_name != namep){
- link_to_free = (char*) vlink_name;
- namep = vlink_name;
- }
- }
- strlcpy(target, lp->name, sizeof(target));
- clear_selection(); // Clear text selection
- set_changed(); // Set widget value was changed
- //printf(" follow_link namep=(%s)\n",namep);
- //printf(" follow_link filename_=(%s)\n",filename_);
- if (namep[0] && strcmp(namep, filename_)) // Link not same as filename_
- {
- if (strchr(directory_, ':') && !strchr(namep, ':')) // rem'd != 0 and == 0
- { // dir is absolute, lp is relative
- if (namep[0] == '/') { // lp is absolute
- strlcpy(temp, directory_, sizeof(temp));
- if ((tptr = strrchr(strchr(temp, ':') + 3, '/')) != 0) // get filename
- strlcpy(tptr, namep, sizeof(temp)-(tptr - temp)); // remove filename
- else
- strlcat(temp, namep, sizeof(temp));
- }
- else // lp just filename
- snprintf(temp, sizeof(temp), "%s/%s", directory_, namep);
- }
- else if (namep[0] != '/' && !strchr(namep, ':')) // rem'd == 0
- { // Relative path
- if (directory_[0]) // Add filename
- snprintf(temp, sizeof(temp), "%s/%s", directory_, namep);
- else {
- dirp = getcwd(dir, sizeof(dir)); // getcwd can fail and return wrong dir, bug?
- snprintf(temp, sizeof(temp), "%s/%s", dir, namep); // No end '/' char from getcwd
- }
- }
- else // Use lp
- strlcpy(temp, namep, sizeof(temp));
- if (d->ispath) { // path is used
- strlcpy(temp, d->path, sizeof(temp)); // ?
- if (namep[0] == '/' || namep[1] == ':' || // absolute or remote
- !strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) ||
- !strncmp(namep, "https:", 6) || !strncmp(namep, "ipp:", 4) ||
- !strncmp(namep, "mailto:", 7) || !strncmp(namep, "news:", 5))
- strlcpy(temp, namep, sizeof(temp));
- else if (!strncasecmp(namep, "javascript:history", 18)) {
- strlcpy(temp, namep, sizeof(temp));
- if (!(d->nstyle & HV_NONAVIGATE)) { // user navigation
- strlcpy(temp, d->lpath, sizeof(temp)); // use last path
- if (!d->lpath[0]) // last path empty
- strlcpy(temp, d->path, sizeof(temp)); // use path
- d->isnav = 1; // set is nav link
- }
- }
- else if ((tptr = strrchr(temp, '/'))) // relative path, add filename
- strlcpy(tptr + 1, namep, sizeof(temp)-(tptr + 1 - temp));
- }
- if (target[0]) { // Add target
- strlcat(temp, "#", sizeof(temp)); // was snprintf(temp + strlen..
- strlcat(temp, target, sizeof(temp));
- }
- while ((tptr = strstr(temp, "/.."))) { // remove ../ from path
- for (sptr = tptr - 1; sptr > temp; sptr --)
- if (*sptr == '/') break; // seek back to last dir
- if (sptr == temp) break; // nothing to remove
- *sptr = '\0'; // nul-terminate
- strlcat(temp, tptr + 3, sizeof(temp)); // add rest of path
- }
- while ((tptr = strstr(temp, "/./"))) { // remove ./ from path
- *tptr = '\0';
- strlcat(temp, tptr + 2, sizeof(temp));
- }
- if (d->ispath) { // path is used
- if (!strncasecmp(temp, "javascript:history", 18)) { // store js
- strlcpy(d->lpath, d->path, sizeof(d->lpath)); // last path
- strlcpy(d->path, temp, sizeof(d->path)); // link for history
- }
- else if ((tptr = strrchr(temp, '/'))) { // store valid ext
- if (strstr(tptr, ".htm") || strstr(tptr, ".txt")) {
- strlcpy(d->lpath, d->path, sizeof(d->lpath)); // last path
- strlcpy(d->path, temp, sizeof(d->path)); // link for history
- }
- }
- }
- //printf(" follow_link d->path=(%s)\n",d->path);
- //printf(" follow_link temp=(%s)\n",temp);
- load(temp); // Load filename
- }
- else if (target[0]) // Target in link
- {
- if (d->ispath) { // path is used
- if ((tptr = strrchr(d->path, '#'))) *tptr = '\0'; // remove target
- strlcat(d->path, "#", sizeof(d->path));
- strlcat(d->path, target, sizeof(d->path));
- load(d->path); // load target for history
- } else topline(target); // rem'd
- }
- //else topline(0); leftline(0); // rem'd
- /*printf("\nFl_Help_Target\n");
- printf(" targets=%s\n",d->targets->filename);
- printf(" linkp=%s\n",d->linkp->filename);
- printf(" ispush=%d\n",d->ispush);
- printf(" islink=%d\n",d->islink);
- printf(" resized=%d\n",d->resized);
- printf(" ispath=%d\n",d->ispath);
- printf(" nstyle=%d\n",d->nstyle);
- printf(" top=%d\n",d->top);
- printf(" ltop=%d\n",d->ltop);
- printf(" isnav=%d\n",d->isnav);
- printf(" rwidth=%d\n",d->rwidth);
- printf(" rtime=%d\n",d->rtime);
- printf(" rsec=%d\n",d->rsec);
- printf(" rmil=%d\n",d->rmil);
- printf(" path=%s\n",d->path);
- printf(" lpath=%s\n",d->lpath);*/
- if(link_to_free) free(link_to_free);
- } // Fl_Help_View::follow_link()
- //
- // Fl_Help_View::font_face() - Get a font face from a list of names.
- //
- // Usage: parses a comma-separated string of font names in order of
- // preference and returns the font face.
- int // O - font face or base font list index
- Fl_Help_View::font_face(const char *sp) // I - name of font to find
- {
- char buf[100],
- namebuf[100]; // buffers
- const char *listp,
- *namep; // pointers
- int ti = 0,
- tj = 0,
- tk = 0, // temp loop vars
- tnum = 0,
- lnum = 0,
- fnum = 0, // temp/last/font counters
- nfonts = 0,
- nfaces = 0, // numbers
- temp = 0,
- slen = 0,
- dfont = 0; // misc
- unsigned char flen[10]; // font name lengths
- slen = strlen(sp); // string length
- if (!slen) return 0; // sp not valid
- if (slen > 255) slen = 255; // set max length
- for (ti = 0, listp = sp, nfaces = 0; ti < slen; ti ++, listp ++) {
- if (ti == slen - 1 || *listp == ',') { // end or ',' char
- if (nfaces < 8 && *(listp + 1) != ',') { // skip ",,"
- flen[nfaces] = ti; // store positions
- if (ti == slen - 1) flen[nfaces] = ti + 1;
- nfaces ++; // count faces
- }
- }
- }
- for (ti = nfaces - 1; ti > 0; ti --) { // calc string lengths
- temp = flen[ti] - flen[ti - 1] - 1;
- flen[ti] = temp;
- }
- nfonts = Fl::set_fonts(0); // get ISO8859-1 fonts, ignore rest
- for (ti = 0, listp = sp; ti < nfaces; ti ++) // main loop
- {
- while (*listp == ',') listp ++; // skip ',' chars
- if (flen[ti] > sizeof(buf)-1) flen[ti] = sizeof(buf)-1; // max buffer size
- for (tj = 0, tk = 0; tj < flen[ti]; tj ++) { // remove spaces in font names
- if (isspace(listp[tj])) continue;
- else if (listp[tj] == '-') break;
- buf[tk] = tolower(listp[tj]); // copy char to lowercase
- tk ++;
- }
- buf[tj] = '\0'; // nul-terminate
- fnum = (uchar)*buf - 97; // first letter index, a = 0
- if (fnum < 0 || fnum > 25) continue; // not a..z, assume font starts with letter
- tnum = flet_[fnum]; // current face index, loop start
- for (tj = fnum + 1; tj < 27; tj ++) {
- if (flet_[tj] > 0) {
- lnum = flet_[tj]; break; // last face index, loop end
- }
- }
- slen = strlen(buf); // first word length
- for (tj = tnum; tj < lnum; tj ++) { // find current font
- fnum = face_[tj][0]; // base font index
- namep = Fl::get_font_name((Fl_Font)fnum, &temp); // fltk font name
- for (tk = 0, temp = 0; namep[tk] != '\0'; tk ++) { // remove spaces in font name
- if (isspace(namep[tk])) continue;
- else if (namep[tk] == '-') break;
- namebuf[temp] = tolower(namep[tk]); // copy chars to lowercase
- temp ++;
- }
- namebuf[tk] = '\0'; // nul-terminate
- if (!strncmp(namebuf, buf, slen)) // found name
- return fnum;
- }
- if (!dfont) { // check default fonts
- if (!strncmp(buf, "courier", 7)) dfont = monofont_;
- if (!strncmp(buf, "times", 5)) dfont = serifont_;
- if (!strncmp(buf, "helvetica", 9)) dfont = sansfont_;
- }
- }
- return dfont;
- } // Fl_Help_View::font_face()
- //
- // Fl_Help_View::font_style() - Get a font style from a font list index.
- //
- // Usage: the font style argument takes the values:
- // medium as 0, bold as 1, italic as 2, plus as 3.
- int // O - font list index
- Fl_Help_View::font_style(int fi, // I - font list index
- unsigned char fs) // I - font style 0..3
- {
- int ti = 0; // temp loop var
- if (fs > 3 || fi >= (int)sizeof(fref_)) return 0; // avoid crash
- for (ti = 0; ti <= 3; ti ++) // find style
- if (fi == face_[fref_[fi]][ti]) break;
- ti |= fs; // combine bits
- return face_[fref_[fi]][ti];
- } // Fl_Help_View::font_style()
- //
- // Fl_Help_View::format() - Format the help text.
- //
- void Fl_Help_View::format()
- {
- char *sp, // Pointer into buffer
- *tp, // temp char pointer
- *ap, // attribute pointer
- buf[1024], // Text buffer
- attr[1024], // Attribute buffer
- wattr[1024], // Width attribute buffer
- hattr[1024], // Height attribute buffer
- linkdest[1024], // Link destination
- tcss[1024], // temp css
- tchar[1024], // temp char buffer
- csstag[255], // css tag buffer
- tag[4]; // tag/element 4-char buf
- const char *ptr, // Pointer into block
- *attrptr, // Start of attributes ptr
- *tagptr; // Start of tag/element ptr
- int ti = 0,
- tj = 0, // Temp loop var
- done = 0, // Are we done yet?
- row = 0, // Current table row (block number)
- talign = 0, // Current alignment
- newalign = 0, // New alignment
- head = 0, // Head/body section flag
- needspace = 0, // Do we need whitespace?
- table_width = 0, // Width of table
- table_offset = 0, // Offset of table
- column = 0, // Current table column number
- line = 0, // Current line in block
- links = 0, // Links for current line
- trpop = 0, // tr popped flag
- pflag = 0, // p flag
- brflag = 0, // br flag
- liflag = 0, // li flag
- listnest = 0, // list nest
- tdline = 0, // td line
- colspan = 0, // COLSPAN attribute
- qch = 0, // Quote char
- dx = 0,
- dy = 0, // Boxtype position offsets
- dw = 0,
- dh = 0, // Boxtype sizes
- ss = 0, // Scrollbar size
- temph = 0,
- tempw = 0, // Temp scrollbar sizes
- tempx = 0,
- tempy = 0, // temp positions
- linew = 0, // current line width
- imgw = 0, // Image width
- imgh = 0, // Image height
- hwidth = 0, // horizontal window width
- ulnest = 0, // ul nest type
- ntables = 0, // number of nested tables
- fonty = 0;
- int columns[HV_64], // Column widths
- cells[HV_64], // Cells in the current row
- tcolumns[HV_64][HV_16], // nested table column widths
- tcells[HV_64][HV_16], // nested table cell blocks
- rowdata[3][HV_16], // row data - row,column,block
- tfonts[HV_16 + 1], // table fonts - d->nfonts
- ultype[HV_16]; // ul type array, 10 nesting levels should do
- unsigned char thsize,
- tfsize; // font sizes
- fl_margins margins(default_margin_); // Left margin stack
- Fl_Help_Block *block, // Current block
- *cell, // Current table cell
- b, // current block object
- *tempb = 0; // temp block
- //*cssb = 0; // current css block - not used
- Fl_Color tclr,
- rclr, // Table/row background color
- tbclr[2][HV_16]; // nested table/tr bgcolor
- Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box to draw
- Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
- // zero arrays
- memset(columns, 0, sizeof(columns));
- memset(cells, 0, sizeof(cells));
- memset(rowdata, 0, sizeof(rowdata));
- memset(tcolumns, 0, sizeof(tcolumns));
- memset(tcells, 0, sizeof(tcells));
- memset(tfonts, 0, sizeof(tfonts));
- memset(ultype, 0, sizeof(ultype));
- memset(tbclr, 0, sizeof(tbclr));
- // Reset document width
- ss = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
- hsize_ = w() - ss - Fl::box_dw(bt);
- hwidth = hsize_; // used in add_block instead of hsize_
- //printf("\n FORMAT\n%s",value_);
- done = 0;
- while (!done)
- {
- // Reset state variables
- done = 1;
- nblocks_ = 0;
- nlinks_ = 0;
- ntargets_ = 0;
- size_ = 0;
- bgcolor_ = color();
- textcolor_ = textcolor();
- linkcolor_ = fl_contrast(FL_BLUE, color());
- tclr = rclr = bgcolor_;
- for (ti = 0; ti < HV_16; ti ++)
- tbclr[0][ti] = tbclr[1][ti] = bgcolor_;
- strcpy(title_, "Untitled");
- if (!value_) return;
- // Setup for formatting
- initfont(b.font, b.fsize);
- line = 0;
- links = 0;
- column = 0;
- b.x = margins.clear();
- b.y = b.fsize + 2;
- b.w = 0;
- b.h = 0;
- b.border = 0;
- b.border_color = FL_BLACK;
- b.pre = 0;
- b.tag = 0;
- b.bgcolor = bgcolor_;
- block = add_block(b, value_, hwidth);
- row = 0;
- head = 0;
- talign = LEFT;
- newalign = LEFT;
- needspace = 0;
- linkdest[0] = '\0';
- table_offset = 0;
- trpop = 0;
- pflag = 1;
- brflag = 0;
- liflag = 0;
- listnest = 0;
- ulnest = 0;
- thsize = 0;
- tfsize = 0;
- ntables = -1;
- tdline = 0;
- linew = 0;
- for (ptr = value_, sp = buf; *ptr; ) // Parse from value_
- {
- if ((*ptr == '<' || isspace((*ptr) & 255)) && sp > buf)
- {
- *sp = '\0'; // Nul-terminate
- b.w = (int)fl_width(buf); // Get width
- if (!head && !b.pre) // Normal text
- {
- if (b.w > hsize_) { // Reformat
- hsize_ = b.w;
- done = 0; // rem'd break; in all reformat checks, not needed
- }
- if (needspace && b.x > block->x)
- b.w += (int)fl_width(" ");
- // no new line if word too long and no word before it
- if (!(b.x < 7 && b.w > block->w) && (b.x + b.w > block->w)) {
- block->end = ptr - strlen(buf); // end line on last word
- line = do_align(block, 0, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- b.y += b.h; //b.y = block->y + block->h;
- b.h = 0;
- line = 0;
- block = add_block(b, ptr - strlen(buf), (row) ? block->w : hwidth);
- }
- if (linkdest[0])
- add_link(linkdest, b.x, b.y - b.fsize, b.w, b.fsize);
- b.x += b.w;
- if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
- needspace = 0;
- }
- else if (!head && b.pre) // Pre text
- {
- if (linkdest[0]) // Add a link as needed
- add_link(linkdest, b.x, b.y - b.h, b.w, b.h);
- b.x += b.w;
- linew += b.w;
- if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
- while (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
- {
- if (*ptr == '\n') { // '\n' char
- if (b.x > hsize_) break;
- block->end = ptr;
- line = do_align(block, 0, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- b.y += b.h; //b.y = block->y + block->h;
- b.h = 0;
- line = 0;
- linew = 0;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- //b.h = b.fsize + 2; // Set b.h
- }
- else if (*ptr == '\t') {
- ti = linew / (int)fl_width(" "); // number of chars, monospace
- tempw = 8 - (ti & 7); // number of tabs 1..8
- b.x += tempw * (int)fl_width(" "); // pre tabs width fix
- linew += tempw * (int)fl_width(" ");
- }
- else {
- b.x += (int)fl_width(" ");
- linew += (int)fl_width(" ");
- }
- if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
- ptr ++;
- }
- if (b.x > hsize_) { // Reformat
- hsize_ = b.x + 4;
- done = 0;
- }
- needspace = 0;
- }
- else // Handle normal text or stuff in the <HEAD> section
- {
- while (isspace((*ptr) & 255)) ptr ++;
- }
- //printf("b->line=%d b.x=%d b.w=%d b->x=%d b->w=%d b->y=%d b->h=%d b.y=%d b.h=%d buf=%s\n",
- // block->line, b.x, b.w, block->x, block->w, block->y, block->h, b.y, b.h, buf);
- pflag = 0; // reset flags
- brflag = 0;
- sp = buf;
- }
- if (*ptr == '<')
- {
- tagptr = ptr; // Start of tag
- ptr ++;
- if (!strncmp(ptr, "!--", 3)) { // Found "!--"
- ptr += 3;
- if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
- ptr += 3;
- continue;
- }
- else
- break;
- }
- while (*ptr && *ptr != '>' && !isspace((*ptr) & 255))
- if (sp < (buf + sizeof(buf) - 1))
- *(sp ++) = *(ptr ++); // added ()
- else
- ptr ++;
- *sp = '\0'; // Nul-terminate
- sp = buf;
- // puts(buf);
- attrptr = ptr; // Start of attributes
- while (*ptr && *ptr != '>') ptr ++;
- if (*ptr == '>') ptr ++;
- b.tag = strlen(buf); // store strlen
- for (ti = 0; ti < b.tag; ti ++) // set css class tag
- csstag[ti] = buf[ti];
- csstag[ti] = '\0'; // nul-terminate
- if (get_attr(attrptr, "CLASS", tchar, sizeof(tchar))) {
- strlcat(csstag, ".", sizeof(csstag));
- strlcat(csstag, tchar, sizeof(csstag));
- }
- if (b.tag > 4) b.tag = 4; // limit
- for (ti = 0; ti < b.tag; ti ++) // set abbreviate tag, uppercase
- tag[ti] = toupper(buf[ti]);
- for (ti = b.tag; ti < 4; ti ++) // set chars after to nul
- tag[ti] = 0;
- if (buf[0] != '/' && b.tag > 3) tag[3] = 0; // eg. HTML=HTM
- b.tag = CMD(tag[0],tag[1],tag[2],tag[3]); // tag fourcc int
- //printf("buf=%s len=%d tag=%c%c%c%c, \n",
- // buf,strlen(buf),tag[0],tag[1],tag[2],tag[3]);
- // End of command reached
- if (b.tag == CMD('A',0,0,0)) // 'A'
- {
- if (get_attr(attrptr, "NAME", attr, sizeof(attr)))
- add_target(attr, b.y - b.fsize - 2);
- if (get_attr(attrptr, "HREF", attr, sizeof(attr)))
- strlcpy(linkdest, attr, sizeof(linkdest));
- }
- else if (b.tag == CMD('/','A',0,0)) // '/A'
- {
- linkdest[0] = '\0';
- }
- else if (b.tag == CMD('B',0,0,0) ||
- b.tag == CMD('S','T','R',0)) // 'B' 'STRONG'
- {
- b.font = font_style(b.font, FL_BOLD);
- pushfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('/','B',0,0) ||
- b.tag == CMD('/','S','T','R')) // '/B' '/STRONG'
- {
- popfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('B','L','O',0) ||
- b.tag == CMD('D','L',0,0) ||
- b.tag == CMD('U','L',0,0) ||
- b.tag == CMD('O','L',0,0) ||
- b.tag == CMD('D','D',0,0) ||
- b.tag == CMD('D','T',0,0)) // 'BLOCKQUOTE' 'DL'OL'UL'
- {
- // todo: dd and dt need their own section, similar to li
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = LEFT;
- if (b.tag == CMD('U','L',0,0)) { // ul
- ulnest ++; // inc ul nest type
- if (ulnest < 10) {
- get_attr(attrptr, "TYPE", attr, sizeof(attr)); // bullet types
- if (!strncasecmp(attr, "disc", 4) ||
- !strncasecmp(attr, "disk", 4))
- ultype[ulnest] = 1;
- else if (!strncasecmp(attr, "circle", 6))
- ultype[ulnest] = 2;
- else if (!strncasecmp(attr, "square", 6))
- ultype[ulnest] = 3;
- }
- }
- if (b.tag == CMD('B','L','O',0) ||
- b.tag == CMD('D','L',0,0) ||
- b.tag == CMD('O','L',0,0) ||
- b.tag == CMD('U','L',0,0)) { // blockquote, dl, ol, ul
- b.x = margins.push(40); // changed 4 * b.fsize
- if (!pflag && !listnest) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- listnest ++; // inc list nest
- }
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('/','B','L','O') ||
- b.tag == CMD('/','D','L',0) ||
- b.tag == CMD('/','O','L',0) ||
- b.tag == CMD('/','U','L',0)) // '/BLOCKQUOTE' '/DL'/OL'/UL'
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y += b.h;
- if (b.tag == CMD('/','U','L',0)) { // /ul
- if (ulnest < 9) ultype[ulnest] = 0; // reset ul type
- if (ulnest > 0) ulnest --; // dec ul nest type
- }
- if (listnest > 0) listnest --; // dec list nest
- if (!pflag && !listnest) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- b.x = margins.pop();
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- else if (b.tag == CMD('B','O','D',0)) // 'BODY'
- {
- if (get_attr(attrptr, "BGCOLOR", attr, sizeof(attr)))
- b.bgcolor = bgcolor_ = get_color(attr, color());
- if (get_attr(attrptr, "TEXT", attr, sizeof(attr)))
- textcolor_ = get_color(attr, textcolor());
- if (get_attr(attrptr, "LINK", attr, sizeof(attr)))
- linkcolor_ = get_color(attr, fl_contrast(FL_BLUE, color()));
- parse_css(b, csstag, tchar);
- if (b.fsize < fontsize_) b.fsize = fontsize_; // force min size
- pushfont(b.font, b.fsize);
- serifont_ = b.font; // body overrides default font but not size
- }
- else if (b.tag == CMD('B','R',0,0)) // 'BR'
- {
- block->end = tagptr;
- line = do_align(block, 0, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- if (brflag) b.h = b.fsize + 2; // set b.h
- block->h += b.h;
- b.y = block->y + block->h; //b.y += b.h;
- brflag = 1;
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- }
- else if (b.tag == CMD('C','E','N',0)) // 'CENTER'
- {
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = CENTER;
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign = CENTER;
- }
- else if (b.tag == CMD('/','C','E','N')) // '/CENTER'
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y += b.h;
- talign = LEFT;
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- else if (b.tag == CMD('C','O','D',0) ||
- b.tag == CMD('T','T',0,0)) // 'CODE' 'TT'
- {
- b.font = monofont_;
- pushfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('/','C','O','D') ||
- b.tag == CMD('/','T','T',0)) // '/CODE' '/TT'
- {
- popfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('D','I','V',0)) // 'DIV'
- {
- if (get_attr(attrptr, "ID", attr, sizeof(attr)))
- add_target(attr, b.y - b.fsize - 2);
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = LEFT;
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('/','D','I','V')) // '/DIV'
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y += b.h;
- talign = LEFT;
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- else if (b.tag == CMD('F','O','N',0)) // 'FONT'
- {
- if (get_attr(attrptr, "FACE", attr, sizeof(attr)))
- b.font = font_face(attr);
- tfsize = b.fsize; // store b.fsize
- if (get_attr(attrptr, "SIZE", attr, sizeof(attr))) {
- if (isdigit(attr[0])) // Absolute size
- b.fsize = (int)(fontsize_ * pow(1.2, atoi(attr) - 3.0));
- else // Relative size
- b.fsize = (int)(b.fsize * pow(1.2, atoi(attr)));
- }
- pushfont(b.font, b.fsize);
- //if (fonty != b.y && !block->maxh) {
- //block->liney = abs(b.fsize - tfsize);
- //b.h = b.fsize + 2; // set b.h
- //}
- fonty = b.y; // set font y
- }
- else if (b.tag == CMD('/','F','O','N')) // '/FONT'
- {
- tfsize = b.fsize; // store b.fsize
- popfont(b.font, b.fsize);
- //if (fonty != b.y && !block->maxh) {
- //block->liney = abs(b.fsize - tfsize);
- //b.h = b.fsize + 2; // set b.h
- //}
- fonty = b.y; // set font y
- }
- else if (tag[0] == 'H' && isdigit(tag[1])) // 'H1'
- {
- if (tag[1] < '7') { // ignore if > 6
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = LEFT;
- //Added target
- if (get_attr(attrptr, "ID", attr, sizeof(attr)))
- add_target(attr, b.y - b.fsize - 2);
- thsize = b.fsize; // store b.fsize
- b.font = font_style(b.font, FL_BOLD);
- switch (tag[1]) { // header sizes
- case '1' : b.fsize = 24; break;
- case '2' : b.fsize = 18; break;
- case '3' : b.fsize = 16; break;
- case '4' : b.fsize = 14; break;
- case '5' : b.fsize = 12; break;
- case '6' : b.fsize = 10; break;
- }
- pushfont(b.font, b.fsize);
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- b.y += b.fsize - thsize + (thsize / 4); // add offset
- block->h += b.fsize - thsize + (thsize / 4);
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- }
- else if (b.tag == CMD('/','H',tag[2],0) && isdigit(tag[2])) // '/H1'
- {
- if (tag[2] < '7') { // ignore if > 6
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y += b.h;
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- b.y -= b.fsize - thsize;// + (thsize / 4); // sub offset
- block->h -= b.fsize - thsize;// + (thsize / 4);
- popfont(b.font, b.fsize);
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- }
- else if (b.tag == CMD('H','E','A',0)) // 'HEAD'
- {
- head = 1;
- }
- else if (b.tag == CMD('/','H','E','A')) // '/HEAD'
- {
- head = 0;
- }
- else if (b.tag == CMD('H','R',0,0)) // 'HR'
- {
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- if(get_attr ( attrptr, "VHEIGHT", attr, sizeof ( attr ) ))
- {
- block->h += atoi ( attr );;
- } else {
- block->h += b.h;
- }
- b.y = block->y + block->h;
- newalign = LEFT;
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- //block->y -= (b.fsize / 2); // hr line offset
- //b.y += fontsize_ + 2; // end paragraph
- //block->h += fontsize_ + 2;
- //pflag = 1;
- b.h = b.fsize + 2; // set b.h - rem: ??
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('H','T','M',0)) // 'HTML'
- {
- }
- else if (b.tag == CMD('I',0,0,0) ||
- b.tag == CMD('E','M',0,0)) // 'I' 'EM'
- {
- b.font = font_style(b.font, FL_ITALIC);
- pushfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('/','I',0,0) ||
- b.tag == CMD('/','E','M',0)) // '/I' '/EM'
- {
- popfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('I','M','G',0)) // 'IMG'
- {
- imgw = imgh = 0; // reset
- if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
- imgw = get_length(wattr);
- if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
- imgh = get_length(hattr);
- img = 0; // rem'd NULL
- if (get_attr(attrptr, "SRC", attr, sizeof(attr))) {
- img = get_image(attr, imgw, imgh);
- imgw = img->w();
- imgh = img->h();
- }
- b.w = imgw;
- if (b.w > hsize_) { // Reformat
- hsize_ = b.w;
- done = 0;
- }
- if (needspace && b.x > block->x)
- b.w += (int)fl_width(" ");
- if ((b.x + b.w) > block->w) {
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- b.y = block->y + block->h; //b.y += b.h;
- line = 0;
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- }
- if (linkdest[0])
- add_link(linkdest, b.x, b.y - imgh, b.w, imgh);
- b.x += b.w;
- if ((imgh + 2) > b.h) b.h = imgh + 2; // Set img b.h
- needspace = 0;
- if (imgh > block->maxh)
- block->maxh = imgh; // max image height
- block->imgy = b.y; // y position of image
- pflag = 0; // reset p flag
- brflag = 0;
- }
- else if (b.tag == CMD('K','B','D',0)) // 'KBD'
- {
- b.font = font_style(monofont_, FL_BOLD);
- pushfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('/','K','B','D')) // '/KBD'
- {
- popfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('L','I',0,0)) // 'LI'
- {
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (!liflag && !listnest) { // push li, if not nested
- b.x = margins.push(b.fsize);
- liflag = 1;
- }
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = LEFT;
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- // li > ul > ul nest
- if (ulnest > 9) // square if out of bounds
- block->type = 3;
- else if (ultype[ulnest]) // ul type
- block->type = ultype[ulnest];
- else if (ulnest > 1) // ul nest type
- block->type = ulnest;
- else // none or ul nest type disc/disk
- block->type = 1;
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('/','L','I',0)) // '/LI'
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y += b.h;
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- else if (b.tag == CMD('L','I','N',0)) // 'LINK'
- {
- if (get_attr(attrptr, "HREF", tchar, sizeof(tchar)))
- strlcpy(tcss, tchar, sizeof(tcss));
- for (ti = 0; tcss[ti] != '\0'; ti ++) // replace '\' chars
- if (tcss[ti] == '\\') tcss[ti] = '/';
- if (tcss[0] == '/' || tcss[1] == ':') // absolute
- strlcpy(tchar, tcss, sizeof(tchar));
- else { // relative
- if (d->ispath) { // path is used
- strlcpy(tchar, d->path, sizeof(tchar));
- if ((tp = strrchr(tchar, '/'))) // replace filename
- strlcpy(tp + 1, tcss, sizeof(tchar)-(tp + 1 - tchar));
- }
- else { // use directory
- strlcpy(tchar, directory_, sizeof(tchar));
- if (tchar[strlen(tchar)-1] != '/')
- strlcat(tchar, "/", sizeof(tchar)); // add '/' to dir
- strlcat(tchar, tcss, sizeof(tchar));
- }
- }
- while ((tp = strstr(tchar, "/.."))) { // remove ../ from path
- for (ap = tp - 1; ap > tchar; ap --)
- if (*ap == '/') break; // seek back to last dir
- if (ap == tchar) break; // nothing to remove
- *ap = '\0'; // nul-terminate
- strlcat(tchar, tp + 3, sizeof(tchar)); // add rest of path
- }
- while ((tp = strstr(tchar, "/./"))) { // remove ./ from path
- *tp = '\0';
- strlcat(tchar, tp + 2, sizeof(tchar));
- }
- if ((tp = strrchr(tcss, '.'))) { // check valid ext
- if (strstr(tp, ".css")) load_css(tchar);
- }
- tcss[0] = '\0'; // reset
- }
- else if (b.tag == CMD('N','O','S',0)) // 'NOSCRIPT'
- { // we don't support scripting so we won't skip this
- }
- else if (b.tag == CMD('P',0,0,0)) // 'P'
- { // && !b.pre fixme?
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = LEFT;
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- block = add_block(b, tagptr, (row) ? block->w: hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('/','P',0,0)) // '/P'
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- else if (b.tag == CMD('P','R','E',0)) // 'PRE'
- {
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y = block->y + block->h;
- newalign = LEFT;
- linew = 0;
- b.pre = 1;
- b.font = monofont_;
- b.fsize = fontsize_;
- parse_css(b, csstag, tchar);
- pushfont(b.font, b.fsize);
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
- }
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('/','P','R','E')) // '/PRE'
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- block->h += b.h;
- b.y += b.h;
- for (ti = nblocks_ - 1, tj = 0; ti > 0; ti --) { // find start block index
- tempb = blocks_ + ti;
- if (tempb->tag == CMD('P','R','E',0)) tj = 1; // pre line
- if (tj && tempb->tag != CMD('P','R','E',0)) {
- tempb = blocks_ + ti + 1; // + 1 gets first pre
- break;
- }
- }
- tempb->h = block->y - tempb->y; // recalculate h
- if (!pflag) {
- b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1; }
- b.pre = 0;
- popfont(b.font, b.fsize);
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- else if (b.tag == CMD('S','C','R',0)) // 'SCRIPT'
- {
- while (ptr) { // skip scripting
- ptr = strstr(ptr, "</");
- if (!strncasecmp(ptr, "</SCRIPT>", 9)) break;
- }
- if (ptr) { // found </script>
- ptr += 9;
- continue;
- }
- else // not found
- break;
- }
- else if (b.tag == CMD('T','A','B',0)) // 'TABLE'
- {
- if (ntables >= 0) { // store row data
- rowdata[0][ntables] = row; // row
- rowdata[1][ntables] = column; // column
- rowdata[2][ntables] = block - blocks_; // block number
- tbclr[0][ntables] = tclr; // table bgcolor
- tbclr[1][ntables] = rclr; // tr bgcolor
- for (ti = 0; ti < HV_64; ti ++) {
- tcolumns[ti][ntables] = columns[ti]; // cell columns
- tcells[ti][ntables] = cells[ti]; // cell blocks
- if (columns[ti] == 0) break;
- }
- }
- if (ntables < HV_16) ntables ++; // max limit
- tfonts[ntables] = d->nfonts; // number of fonts
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h + 8; // add tr gap offset, wrong line gaps
- b.y = block->y + block->h;
- newalign = LEFT;
- b.border = 0; // Reset
- b.border_color = FL_BLACK; // Reset
- if (get_attr(attrptr, "BORDER", attr, sizeof(attr)))
- b.border = atoi(attr);
- if (get_attr(attrptr, "BORDERCOLOR", attr, sizeof(attr)))
- b.border_color = get_color(attr, FL_BLACK);
- get_attr(attrptr, "BGCOLOR", attr, sizeof(attr));
- tclr = rclr = get_color(attr, bgcolor_);
- memset(columns, 0, sizeof(columns)); // zero for new table
- format_table(table_width, columns, tagptr, b.x, 0);
- if ((b.x + table_width) > hsize_) { // Reformat
- //printf("\nb.x=%d, table_width=%d, hsize_=%d\n\n",
- // b.x, table_width, hsize_);
- hsize_ = b.x + table_width;
- for (ti = 0; ti < HV_64; ti ++)
- if (columns[ti] == 0) break; // num columns
- hsize_ += 6 * ti; // add internal borders
- done = 0;
- }
- switch (get_align(attrptr, talign)) {
- default :
- table_offset = 0; break;
- case CENTER :
- table_offset = ((hsize_ - table_width) / 2) - fontsize_; break;
- case RIGHT :
- table_offset = hsize_ - table_width - fontsize_ - default_margin_; break;
- }
- block = add_block(b, tagptr, (row) ? block->w : hwidth);
- column = 0;
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, talign);
- }
- else if (b.tag == CMD('/','T','A','B')) // '/TABLE'
- {
- if (row) { // no /tr
- line = do_align(block, line, b.x, newalign, links);
- if (tdline) { // td was popped
- block->line = tdline; tdline = 0; } // last line in td
- block->end = ptr;
- block->h += b.h;
- talign = LEFT;
- if (b.h == 0) b.h = b.fsize + 2; // empty td on end of row
- b.x = blocks_[row].x;
- b.y = blocks_[row].y + blocks_[row].h;
- for (cell = blocks_ + row + 1; cell <= block; cell ++)
- if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
- block = blocks_ + row; // current row block ptr
- block->h = b.y - block->y + 2;
- for (ti = 0; ti < column; ti ++)
- if (cells[ti]) { // cell block exists
- cell = blocks_ + cells[ti]; // get cell block ptr
- cell->h = block->h;
- }
- b.y = block->y + block->h - 4; // tr gap offset between rows
- block = add_block(b, ptr, hwidth);
- needspace = 0;
- row = 0; // reset row block number
- line = 0;
- }
- line = do_align(block, line, b.x, newalign, links);
- if (tdline) { block->line = tdline; tdline = 0; } // td popped
- block->end = ptr;
- b.x = block->x;
- b.h = 0; // reset b.h
- block->h += b.h; // may be needed if no /tr
- b.y += b.h + 8; // add tr gap offset, wrong line gaps
- if (!trpop) { b.x = margins.pop(); row = 0; } // pop tr indent
- trpop = 0; // reset tr popped
- b.x = margins.current();
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- d->nfonts = tfonts[ntables] + 1; // number of fonts + 1 for pop
- popfont(b.font, b.fsize); // tables not popping last font fix
- if (ntables >= 0) ntables --; // min limit
- if (ntables >= 0) { // restore row data
- row = rowdata[0][ntables]; // row
- column = rowdata[1][ntables]; // column
- cell = blocks_ + rowdata[2][ntables] + 1; // table block
- b.x = block->x = cell->x; // nested table popping cell margin fix
- block->w = cell->w;
- tclr = tbclr[0][ntables]; // table bgcolor
- rclr = tbclr[1][ntables]; // tr bgcolor
- for (ti = 0; ti < HV_64; ti ++) {
- columns[ti] = tcolumns[ti][ntables]; // cell columns
- // nested table overwriting cell heights fix
- cells[ti] = tcells[ti][ntables]; // cell blocks
- if (tcolumns[ti][ntables] == 0) break;
- }
- // nested table drawn below row height fix
- cell->y -= 4; // table y offset
- tempy = cell->y; // table block y
- for (cell = cell; cell <= block; cell ++) // find tr, td, th
- if (cell->tag == CMD('T','R',0,0) ||
- cell->tag == CMD('T','D',0,0) ||
- cell->tag == CMD('T','H',0,0)) break;
- tempy = cell->y - tempy; // get row height
- for (cell = cell; cell <= block; cell ++)
- cell->y -= tempy; // move table up
- block->h -= 2; // /table h offset
- }
- //printf("/table ntables=%d tempx=%d b.x=%d b->x=%d\n",
- // ntables,tempx,b.x,block->x);
- }
- else if (b.tag == CMD('T','D',0,0) ||
- b.tag == CMD('T','H',0,0)) // 'TD' 'TH'
- {
- if (!row) { // no tr
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- memset(cells, 0, sizeof(cells)); // zero for new row
- b.y = block->y + block->h - 4; // tr gap offset between rows
- block = add_block(b, tagptr, hwidth);
- row = block - blocks_; // next row block number
- column = 0;
- b.h = 0;
- needspace = 0;
- line = 0;
- trpop = 0; // reset tr popped
- }
- if (row) {
- line = do_align(block, line, b.x, newalign, links);
- if (tdline) { block->line = tdline; tdline = 0; } // td popped
- block->end = tagptr;
- block->h += b.h;
- b.y = blocks_[row].y;
- pflag = 1;
- b.x = blocks_[row].x;
- if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
- b.x += 3 + table_offset; // rem'd + b.fsize
- for (ti = 0; ti < column; ti ++)
- b.x += columns[ti] + 6;
- margins.push(b.x - margins.current());
- //printf("td ntables=%d tempx=%d b.x=%d b->x=%d\n",
- // ntables,tempx,b.x,block->x);
- colspan = 1; // Reset
- if (get_attr(attrptr, "COLSPAN", attr, sizeof(attr)))
- colspan = atoi(attr);
- for (ti = 0, b.w = -6; ti < colspan; ti ++)
- b.w += columns[column + ti] + 6;
- if (block->end == block->start && nblocks_ > 1) {
- nblocks_ --;
- block --;
- }
- if (ntables >= 0)
- d->nfonts = tfonts[ntables]; // pop number of fonts
- b.font = serifont_;
- b.fsize = fontsize_;
- parse_css(b, csstag, tchar);
- if (b.tag == CMD('T','H',0,0)) // th
- b.font = font_style(b.font, FL_BOLD);
- pushfont(b.font, b.fsize);
- block = add_block(b, tagptr, b.x + b.w);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = get_align(attrptr, (tag[1] == 'H') ? CENTER : LEFT);
- talign = newalign;
- cells[column] = block - blocks_; // set cell block number
- column += colspan;
- get_attr(attrptr, "BGCOLOR", attr, sizeof(attr));
- block->bgcolor = get_color(attr, rclr);
- }
- }
- else if (b.tag == CMD('/','T','D',0) ||
- b.tag == CMD('/','T','H',0)) // '/TD' '/TH'
- {
- if (row) {
- line = do_align(block, 0, b.x, newalign, links);
- talign = LEFT;
- //popfont(b.font, b.fsize);
- tdline = block->line; // store td line
- b.x = margins.pop();
- pflag = 0; // reset p flag?
- //printf("/td ntables=%d tempx=%d b.x=%d b->x=%d\n",
- // ntables,tempx,b.x,block->x);
- }
- }
- else if (b.tag == CMD('T','I','T',0)) // 'TITLE'
- {
- // Copy the title in the document
- tp = title_ + sizeof(title_) - 1;
- for (sp = title_; *ptr != '<' && *ptr && sp < tp; )
- *(sp ++) = *(ptr ++); // added ()
- *sp = '\0'; // Nul-terminate
- sp = buf;
- }
- else if (b.tag == CMD('T','R',0,0)) // 'TR'
- {
- for (ti = nblocks_ - 1; ti > 0; ti --) { // find last block index
- tempb = blocks_ + ti;
- if (tempb->tag == CMD('T','A','B',0) || tempb->tag == CMD('/','T','A','B') ||
- tempb->tag == CMD('T','D',0,0) || tempb->tag == CMD('T','H',0,0) ||
- tempb->tag == CMD('T','R',0,0) || tempb->tag == CMD('/','T','R',0))
- break; // found table/tr/td tag
- }
- tempx = 0; // no /tr flag
- if (row && tempb->tag != CMD('T','A','B',0)) { // skip first tr after table
- line = do_align(block, line, b.x, newalign, links);
- if (tdline) { // td was popped
- block->line = tdline; tdline = 0; } // last line in td
- block->end = ptr;
- block->h += b.h;
- talign = LEFT;
- if (b.h == 0) b.h = b.fsize + 2; // empty td on end of row
- tempx = b.x;
- b.x = blocks_[row].x;
- b.y = blocks_[row].y + blocks_[row].h;
- for (cell = blocks_ + row + 1; cell <= block; cell ++)
- if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
- block = blocks_ + row; // current row block ptr
- block->h = b.y - block->y + 2;
- for (ti = 0; ti < column; ti ++)
- if (cells[ti]) { // cell block exists
- cell = blocks_ + cells[ti]; // get cell block ptr
- cell->h = block->h;
- }
- if (tempx) block->x = tempx;
- b.y = block->y + block->h - 4; // tr gap offset between rows
- block = add_block(b, ptr, hwidth);
- needspace = 0;
- row = 0; // reset row block number
- line = 0;
- }
- block->end = tagptr;
- line = do_align(block, line, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- if (row) {
- b.y = blocks_[row].y + blocks_[row].h;
- for (cell = blocks_ + row + 1; cell <= block; cell ++)
- if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
- block = blocks_ + row; // current row block ptr
- block->h = b.y - block->y + 2;
- for (ti = 0; ti < column; ti ++)
- if (cells[ti]) { // cell block exists
- cell = blocks_ + cells[ti]; // get cell block ptr
- cell->h = block->h;
- }
- }
- memset(cells, 0, sizeof(cells)); // zero for new row
- b.y = block->y + block->h - 4; // tr gap offset between rows
- block = add_block(b, tagptr, hwidth);
- row = block - blocks_; // next row block number
- column = 0;
- b.h = 0;
- needspace = 0;
- line = 0;
- trpop = 0; // reset tr popped
- get_attr(attrptr, "BGCOLOR", attr, sizeof(attr));
- rclr = get_color(attr, tclr);
- }
- else if (b.tag == CMD('/','T','R',0)) // '/TR'
- {
- if (row) { // tr
- line = do_align(block, line, b.x, newalign, links);
- if (tdline) { // td was popped
- block->line = tdline; tdline = 0; } // last line in td
- block->end = ptr;
- block->h += b.h;
- talign = LEFT;
- if (b.h == 0) b.h = b.fsize + 2; // empty td on end of row
- b.x = blocks_[row].x;
- b.y = blocks_[row].y + blocks_[row].h;
- for (cell = blocks_ + row + 1; cell <= block; cell ++)
- if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
- block = blocks_ + row; // current row block ptr
- block->h = b.y - block->y + 2;
- for (ti = 0; ti < column; ti ++)
- if (cells[ti]) { // cell block exists
- cell = blocks_ + cells[ti]; // get cell block ptr
- cell->h = block->h;
- }
- b.y = block->y + block->h - 4; // tr gap offset between rows
- //printf("/tr row=%d column=%d b.h=%d b->h=%d b->y=%d b.y=%d\n",
- // row,column,b.h,block->h,block->y,b.y);
- block = add_block(b, ptr, hwidth);
- needspace = 0;
- row = 0; // reset row block number
- line = 0;
- }
- else // start margins pop /tr - rem: nested table fix?
- {
- line = do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- b.x = block->x;
- block->h += b.h;
- b.y += b.h;
- trpop = 1; // set tr popped
- b.x = margins.pop(); // pop tr
- while (isspace((*ptr) & 255)) ptr ++;
- block = add_block(b, ptr, hwidth);
- b.h = 0;
- needspace = 0;
- line = 0;
- newalign = talign;
- }
- }
- else if (b.tag == CMD('U',0,0,0)) // 'U'
- {
- }
- else if (b.tag == CMD('V','A','R',0)) // 'VAR'
- {
- b.font = font_style(monofont_, FL_ITALIC);
- pushfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('/','V','A','R')) // '/VAR'
- {
- popfont(b.font, b.fsize);
- }
- else if (b.tag == CMD('A','B','B',0) || // 'ABBR'
- b.tag == CMD('A','C','R',0) || // 'ACRONYM'
- b.tag == CMD('A','D','D',0) || // 'ADDRESS'
- b.tag == CMD('A','P','P',0) || // 'APPLET'
- b.tag == CMD('A','R','E',0) || // 'AREA'
- b.tag == CMD('B','A','S',0) || // 'BASE' 'BASEFONT'
- b.tag == CMD('B','D','O',0) || // 'BDO'
- b.tag == CMD('B','G','S',0) || // 'BGSOUND'
- b.tag == CMD('B','I','G',0) || // 'BIG'
- b.tag == CMD('B','L','I',0) || // 'BLINK'
- b.tag == CMD('B','U','T',0) || // 'BUTTON'
- b.tag == CMD('C','A','P',0) || // 'CAPTION'
- b.tag == CMD('C','I','T',0) || // 'CITE'
- b.tag == CMD('C','O','L',0) || // 'COL' 'COLGROUP'
- b.tag == CMD('D','E','L',0) || // 'DEL'
- b.tag == CMD('D','F','N',0) || // 'DFN'
- b.tag == CMD('D','I','R',0) || // 'DIR'
- b.tag == CMD('E','M','B',0) || // 'EMBED'
- b.tag == CMD('F','I','E',0) || // 'FIELDSET'
- b.tag == CMD('F','O','R',0) || // 'FORM'
- b.tag == CMD('F','R','A',0) || // 'FRAME' 'FRAMESET'
- b.tag == CMD('I','F','R',0) || // 'IFRAME'
- b.tag == CMD('I','N','P',0) || // 'INPUT'
- b.tag == CMD('I','N','S',0) || // 'INS'
- b.tag == CMD('I','S','I',0) || // 'ISINDEX'
- b.tag == CMD('L','A','B',0) || // 'LABEL'
- b.tag == CMD('L','E','G',0) || // 'LEGEND'
- b.tag == CMD('L','I','N',0) || // 'LINK'
- b.tag == CMD('M','A','P',0) || // 'MAP'
- b.tag == CMD('M','A','R',0) || // 'MARQUEE'
- b.tag == CMD('M','E','N',0) || // 'MENU'
- b.tag == CMD('M','E','T',0) || // 'META'
- b.tag == CMD('M','U','L',0) || // 'MULTICOL'
- b.tag == CMD('N','O','B',0) || // 'NOBR'
- b.tag == CMD('N','O','F',0) || // 'NOFRAMES'
- b.tag == CMD('O','B','J',0) || // 'OBJECT'
- b.tag == CMD('O','P','T',0) || // 'OPTGROUP' 'OPTION'
- b.tag == CMD('P','A','R',0) || // 'PARAM'
- b.tag == CMD('Q',0,0,0) || // 'Q'
- b.tag == CMD('S',0,0,0) || // 'S'
- b.tag == CMD('S','A','M',0) || // 'SAMP'
- b.tag == CMD('S','E','L',0) || // 'SELECT'
- b.tag == CMD('S','M','A',0) || // 'SMALL'
- b.tag == CMD('S','P','A',0) || // 'SPACER' 'SPAN'
- b.tag == CMD('S','T','R',0) || // 'STRIKE'
- b.tag == CMD('S','T','Y',0) || // 'STYLE'
- b.tag == CMD('S','U','B',0) || // 'SUB'
- b.tag == CMD('S','U','P',0) || // 'SUP'
- b.tag == CMD('T','B','O',0) || // 'TBODY'
- b.tag == CMD('T','E','X',0) || // 'TEXTAREA'
- b.tag == CMD('T','F','O',0) || // 'TFOOT'
- b.tag == CMD('T','H','E',0) || // 'THEAD'
- b.tag == CMD('W','B','R',0) || // 'WBR'
- b.tag == CMD('X','M','P',0)) // 'XMP'
- ; // unsupported tags
- else if (tag[0] == '!' && isalpha(tag[1])) // '!DOCTYPE' etc
- ;
- else if (tag[0] == '?' && isalpha(tag[1])) // '?XMP' etc
- ;
- else if (tag[0] == '/' && isalpha(tag[1])) // unrecognized end tag
- ;
- else if (!head) // unrecognized tag so draw it
- {
- b.x += (int)fl_width("<"); // add width of '<' char
- linew += (int)fl_width("<");
- ptr = tagptr + 1; // start of tag + 1
- }
- } // if (*ptr == '<')
- else if (*ptr == '\n' && b.pre) // '\n' in pre
- {
- if (linkdest[0])
- add_link(linkdest, b.x, b.y - b.h, b.w, b.h);
- if (b.x > hsize_) { // Reformat
- hsize_ = b.x + 4;
- done = 0;
- }
- block->end = ptr;
- line = do_align(block, 0, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- b.y += b.h; //b.y = block->y + block->h;
- line = 0;
- linew = 0;
- block = add_block(b, ptr, (row) ? block->w : hwidth);
- b.h = 0;
- needspace = 0;
- ptr ++;
- }
- else if (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
- {
- needspace = 1;
- ptr ++;
- }
- else if (*ptr == '&' && sp < (buf + sizeof(buf) - 1)) // '&' char ref
- {
- ptr ++;
- qch = quote_char(ptr);
- if (qch < 0)
- *(sp ++) = '&'; // added ()
- else {
- *(sp ++) = qch; // added ()
- ptr = strchr(ptr, ';') + 1;
- }
- if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
- }
- else // Other char
- {
- if (sp < (buf + sizeof(buf) - 1))
- *(sp ++) = *(ptr ++); // added ()
- else
- ptr ++;
- if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
- }
- //if (d->resized && block->y + block->h > topline_ + h())
- //break; // if resizing big page skip non-visible region
- } // for (ptr = value_ ...)
- if (sp > buf) // Still something left to parse
- {
- if (!head) // Normal text... b.pre fixme?
- {
- *sp = '\0'; // Nul-terminate
- b.w = (int)fl_width(buf);
- //printf("line = %d, b.x = %d, b.w = %d, block->x = %d, block->w = %d\n",
- // line, b.x, b.w, block->x, block->w);
- if (b.w > hsize_) { // Reformat
- hsize_ = b.w;
- done = 0;
- }
- if (needspace && b.x > block->x)
- b.w += (int)fl_width(" ");
- // no new line if word too long and no word before it
- if (!(b.x < 7 && b.w > block->w) && (b.x + b.w) > block->w) {
- block->end = ptr - strlen(buf);
- line = do_align(block, 0, b.x, newalign, links);
- b.x = block->x;
- block->h += b.h;
- b.y += b.h; //b.y = block->y + block->h;
- b.h = 0;
- line = 0;
- block = add_block(b, ptr - strlen(buf), (row) ? block->w : hwidth);
- }
- if (linkdest[0])
- add_link(linkdest, b.x, b.y - b.fsize, b.w, b.fsize);
- b.x += b.w;
- }
- }
- do_align(block, line, b.x, newalign, links);
- block->end = ptr;
- size_ = b.y + b.h;
- //if (d->resized && block->y + block->h > topline_ + h())
- //break; // if resizing big page skip non-visible region
- } // while (!done)
- d->isnew = 0; // reset - so we know a repeat call to format per page, to stabilize malloc
- //printf("margins.depth_=%d\n", margins.depth_);
- if (ntargets_ > 1)
- qsort(d->targets, ntargets_, sizeof(Fl_Help_Link),
- (compare_func_t)cmp_targets);
- dx = Fl::box_dw(bt) - Fl::box_dx(bt);
- dy = Fl::box_dh(bt) - Fl::box_dy(bt);
- ss = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
- dw = Fl::box_dw(bt) + ss;
- dh = Fl::box_dh(bt);
- //if (d->resized && block->y + block->h > topline_ + h())
- //return; // if resizing big page skip resizing scrollbars
- if (hsize_ > (w() - dw))
- {
- hscrollbar_.show();
- dh += ss;
- if (size_ < (h() - dh)) {
- scrollbar_.hide();
- hscrollbar_.resize(x() + Fl::box_dx(bt), y() + h() - ss - dy,
- w() - Fl::box_dw(bt), ss);
- }
- else {
- scrollbar_.show();
- scrollbar_.resize(x() + w() - ss - dx, y() + Fl::box_dy(bt),
- ss, h() - ss - Fl::box_dh(bt));
- hscrollbar_.resize(x() + Fl::box_dx(bt), y() + h() - ss - dy,
- w() - ss - Fl::box_dw(bt), ss);
- }
- }
- else // If hsize_ <= (w() - dw)
- {
- hscrollbar_.hide();
- if (size_ < (h() - dh))
- scrollbar_.hide();
- else {
- scrollbar_.resize(x() + w() - ss - dx, y() + Fl::box_dy(bt),
- ss, h() - Fl::box_dh(bt));
- scrollbar_.show();
- }
- }
- // Reset scrolling if it needs to be
- if (scrollbar_.visible()) {
- temph = h() - Fl::box_dh(bt);
- if (hscrollbar_.visible()) temph -= ss;
- if ((topline_ + temph) > size_) topline(size_ - temph);
- else topline(topline_);
- }
- else
- topline(0);
- if (hscrollbar_.visible()) {
- tempw = w() - ss - Fl::box_dw(bt);
- if (leftline_ + tempw > hsize_)
- leftline(hsize_ - tempw);
- else
- leftline(leftline_);
- }
- else
- leftline(0);
- } // Fl_Help_View::format()
- //
- // Fl_Help_View::format_table() - replaced, code moved
- //
- void Fl_Help_View::format_table(int *tw, // O - Total table width
- int *maxcols, // O - Column widths
- const char *tp) // I - Table start pointer
- {
- return;
- } // Fl_Help_View::format_table()
- //
- // Fl_Help_View::format_table() - Format a table.
- //
- const char * // O - table end pointer
- Fl_Help_View::format_table(int &tw, // O - Total table width
- int *maxcols, // O - Column widths
- const char *tp, // I - Table start pointer
- int xx, // I - x position of table
- int rc) // I - recursive counter
- {
- char *sp, // Pointer into buffer
- buf[1024], // Text buffer
- attr[1024], // Other attribute
- wattr[1024], // WIDTH attribute
- hattr[1024], // HEIGHT attribute
- tag[4]; // tag/element 4-char buf
- const char *ptr, // Pointer into table
- *attrptr, // Start of attributes ptr
- *tagptr, // Start of tag/element ptr
- *endp; // table end pointer
- int col = 0, // Current column
- numcells = 0, // Number of cells
- colspan = 0, // COLSPAN attribute
- linew = 0, // Current line width
- tempw = 0, // Temporary width
- maxlinew = 0, // Maximum width
- mincellw = 0, // minimum table width
- maxcellw = 0, // total width of cells
- colspanw = 0, // colspan width
- scalew = 0, // Table scaled width
- hwidth = 0, // horizontal window width
- tsize = 0, // table size
- incell = 0, // In a table cell?
- head = 0, // head/body section flag
- pre = 0, // Pre text flag
- btag = 0, // tag/element fourcc int
- needspace = 0, // Do we need whitespace?
- ti = 0, // temp loop var
- imgw = 0, // Image width
- imgh = 0, // Image height
- qch = 0, // Quote char
- nfonts = 0, // local font stack index
- font = 0; // Current font
- unsigned char fsize; // Current font size
- int mincols[HV_64], // Minimum widths for each column
- widths[HV_64], // td width attributes
- colspans[HV_64], // min width in colspan cells
- columns[HV_64], // nested table column widths
- fonts[HV_64][2]; // local font stack
- Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
- Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box size
- tw = 0; // Clear widths
- endp = 0; // rem'd NULL
- // zero arrays
- memset(mincols, 0, sizeof(mincols));
- memset(widths, 0, sizeof(widths));
- memset(colspans, 0, sizeof(colspans));
- memset(columns, 0, sizeof(columns));
- hwidth = w() - (scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size()) - Fl::box_dw(bt);
- font = fonts[nfonts][0] = serifont_; // initfont
- fsize = fonts[nfonts][1] = fontsize_;
- fl_font(font, fsize);
- //printf("\nFORMAT_TABLE %d\n",tp - value_);
- col = -1;
- linew = 0;
- incell = 0;
- // Scan the table
- for (ptr = tp, sp = buf; *ptr; )
- {
- if ((*ptr == '<' || isspace((*ptr) & 255)) && sp > buf)
- {
- if (needspace) { // Check width
- *(sp ++) = ' '; // added ()
- needspace = 0;
- }
- *sp = '\0'; // Nul-terminate
- sp = buf;
- if (incell && !head && !pre) // Normal text
- {
- tempw = (int)fl_width(buf); // Width of current word
- if (tempw > mincols[col] && colspan <= 1)
- mincols[col] = tempw; // ignore if colspan > 1
- if (tempw > colspans[col] && colspan > 1) {
- colspans[col] = tempw; // colspans
- colspans[col] -= 6 * (colspan - 1); // sub internal borders
- if (colspans[col] < 6 * (colspan - 1))
- colspans[col] = tempw; // reset thin cell widths
- colspans[col + 1] = colspan;
- }
- linew += tempw;
- if (linew > maxlinew) maxlinew = linew;
- }
- else if (incell && !head && pre) // pre text
- {
- tempw = (int)fl_width(buf); // Width of current word
- linew += tempw; // pre text in tables not increasing cell width fix
- if (linew > maxlinew) maxlinew = linew;
- //printf("ptr=%c head=%d pre=%d incell=%d tw=%d lw=%d %s\n",
- // *ptr,head,pre,incell,tempw,linew,buf);
- if (*ptr == '\n') { // newline char
- if (linew > mincols[col] && colspan <= 1)
- mincols[col] = linew; // ignore if colspan > 1
- if (linew > colspans[col] && colspan > 1) {
- colspans[col] = linew; // colspans
- colspans[col] -= 5 * (colspan - 1); // sub internal borders
- if (colspans[col] < 5 * (colspan - 1))
- colspans[col] = linew; // reset thin cell widths
- colspans[col + 1] = colspan;
- }
- }
- else if (*ptr == '\t') { // tab char
- ti = linew / (int)fl_width(" "); // number of chars, monospace
- tempw = 7 - (ti & 7); // number of tabs 0..7
- if (tempw) // pre tabs width fix
- linew += tempw * (int)fl_width(" ");
- }
- }
- }
- if (*ptr == '<')
- {
- tagptr = ptr; // Start of tag
- ptr ++; // inc ptr
- sp = buf; // reset sp
- if (!strncmp(ptr, "!--", 3)) { // Found "!--"
- ptr += 3;
- if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
- ptr += 3;
- continue;
- }
- else
- break;
- }
- while (*ptr && *ptr != '>' && !isspace((*ptr) & 255)) // was for loop
- if (sp < (buf + sizeof(buf) - 1))
- *(sp ++) = *(ptr ++); // added ()
- else
- ptr ++;
- *sp = '\0'; // Nul-terminate
- sp = buf;
- attrptr = ptr; // Start of attributes
- while (*ptr && *ptr != '>') ptr ++;
- if (*ptr == '>') ptr ++;
- btag = strlen(buf); // store strlen
- if (btag > 4) btag = 4; // limit
- for (ti = 0; ti < btag; ti ++) // abbreviate tag, to uppercase
- tag[ti] = toupper(buf[ti]);
- for (ti = btag; ti < 4; ti ++) // set chars after to nul
- tag[ti] = 0;
- if (buf[0] != '/' && btag > 3) tag[3] = 0; // eg. HTML=HTM
- btag = CMD(tag[0],tag[1],tag[2],tag[3]); // tag as int
- // End of command reached
- if (btag == CMD('A',0,0,0)) // 'A'
- {
- }
- else if (btag == CMD('B',0,0,0) ||
- btag == CMD('S','T','R',0)) // 'B' 'STRONG'
- {
- font = font_style(font, FL_BOLD);
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','B',0,0) ||
- btag == CMD('/','S','T','R')) // '/B' '/STRONG'
- {
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('B','L','O',0) ||
- btag == CMD('D','L',0,0) ||
- btag == CMD('U','L',0,0) ||
- btag == CMD('O','L',0,0) ||
- btag == CMD('D','D',0,0) ||
- btag == CMD('D','T',0,0)) // 'BLOCKQUOTE' 'DL'OL'UL'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('/','B','L','O') ||
- btag == CMD('/','D','L',0) ||
- btag == CMD('/','O','L',0) ||
- btag == CMD('/','U','L',0)) // '/BLOCKQUOTE' '/DL'/OL'/UL'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('B','O','D',0)) // 'BODY'
- {
- }
- else if (btag == CMD('B','R',0,0)) // 'BR'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('C','E','N',0)) // 'CENTER'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('/','C','E','N')) // '/CENTER'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('C','O','D',0) ||
- btag == CMD('T','T',0,0)) // 'CODE' 'TT'
- {
- font = monofont_;
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','C','O','D') ||
- btag == CMD('/','T','T',0)) // '/CODE' '/TT'
- {
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('D','I','V',0)) // 'DIV'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('/','D','I','V')) // '/DIV'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('F','O','N',0)) // 'FONT'
- {
- if (get_attr(attrptr, "FACE", attr, sizeof(attr)))
- font = font_face(attr);
- if (get_attr(attrptr, "SIZE", attr, sizeof(attr))) {
- if (isdigit(attr[0])) // Absolute size
- fsize = (int)(fontsize_ * pow(1.2, atoi(attr) - 3.0));
- else // Relative size
- fsize = (int)(fsize * pow(1.2, atoi(attr)));
- }
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','F','O','N')) // '/FONT'
- {
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (tag[0] == 'H' && isdigit(tag[1])) // 'H1'
- {
- linew = 0;
- needspace = 0;
- font = font_style(font, FL_BOLD);
- switch (tag[1]) { // header sizes
- case '1' : fsize = 24; break;
- case '2' : fsize = 18; break;
- case '3' : fsize = 16; break;
- case '4' : fsize = 14; break;
- case '5' : fsize = 12; break;
- case '6' : fsize = 10; break;
- default : fsize = fontsize_; font = serifont_; break;
- }
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','H',tag[2],0) && isdigit(tag[2])) // '/H1'
- {
- linew = 0;
- needspace = 0;
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('H','E','A',0)) // 'HEAD'
- {
- head = 1;
- }
- else if (btag == CMD('/','H','E','A')) // '/HEAD'
- {
- head = 0;
- }
- else if (btag == CMD('H','R',0,0)) // 'HR'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('H','T','M',0)) // 'HTML'
- {
- }
- else if (btag == CMD('I',0,0,0) ||
- btag == CMD('E','M',0,0)) // 'I' 'EM'
- {
- font = font_style(font, FL_ITALIC);
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','I',0,0) ||
- btag == CMD('/','E','M',0)) // '/I' '/EM'
- {
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('I','M','G',0)) // 'IMG'
- {
- if (incell) {
- imgw = imgh = 0; // reset
- if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
- imgw = get_length(wattr);
- if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
- imgh = get_length(hattr);
- img = 0; // rem'd NULL
- if (get_attr(attrptr, "SRC", attr, sizeof(attr))) {
- img = get_image(attr, imgw, imgh); // Use src values
- imgw = img->w();
- imgh = img->h();
- }
- if (imgw > mincols[col]) mincols[col] = imgw;
- linew += imgw;
- if (needspace) {
- linew += (int)fl_width(" ");
- needspace = 0;
- }
- if (linew > maxlinew) maxlinew = linew;
- }
- }
- else if (btag == CMD('K','B','D',0)) // 'KBD'
- {
- font = font_style(monofont_, FL_BOLD);
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','K','B','D')) // '/KBD'
- {
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('L','I',0,0)) // 'LI'
- {
- linew = 0;
- needspace = 0;
- linew += fsize; // changed 4 * fsize
- }
- else if (btag == CMD('/','L','I',0)) // '/LI'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('N','O','S',0)) // 'NOSCRIPT'
- { // we don't support scripting so we won't skip this
- }
- else if (btag == CMD('P',0,0,0)) // 'P'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('/','P',0,0)) // '/P'
- {
- linew = 0;
- needspace = 0;
- }
- else if (btag == CMD('P','R','E',0)) // 'PRE'
- {
- linew = 0;
- needspace = 0;
- pre = 1;
- font = monofont_;
- fsize = fontsize_;
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','P','R','E')) // '/PRE'
- {
- linew = 0;
- needspace = 0;
- pre = 0;
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('S','C','R',0)) // 'SCRIPT'
- {
- while (ptr) { // skip scripting
- ptr = strstr(ptr, "</");
- if (!strncasecmp(ptr, "</SCRIPT>", 9)) break;
- }
- if (ptr) { // found </script>
- ptr += 9;
- continue;
- }
- else // not found
- break;
- }
- else if (btag == CMD('T','A','B',0)) // 'TABLE'
- {
- linew = 0; // cell width not reset before nested table fix
- needspace = 0;
- if (tagptr > tp) { // nested table
- if (rc < HV_16) // limit recursive function
- endp = format_table(scalew, columns, tagptr, xx, rc + 1);
- if (endp) ptr = endp; // to skip nested table
- for (ti = 0; ti < HV_64; ti ++)
- if (columns[ti] == 0) break; // num columns
- scalew += ti * 6; // add internal borders
- if (scalew > mincols[col]) // set nested width
- mincols[col] = scalew;
- linew += scalew;
- if (linew > maxlinew) maxlinew = linew;
- linew = 0; // cell width not reset after nested table fix
- needspace = 0;
- }
- }
- else if (btag == CMD('/','T','A','B')) // '/TABLE'
- {
- //printf("%s col = %d, colspan = %d, numcells = %d\n",
- // buf, col, colspan, numcells);
- if (col >= 0) { // This is a hack to support COLSPAN
- ti = colspan; // ignore if colspan > 1
- maxlinew /= colspan;
- while (colspan > 0) {
- if (maxlinew > maxcols[col] && ti <= 1)
- maxcols[col] = maxlinew;
- col ++;
- colspan --;
- }
- }
- endp = ptr; // store nested table end ptr
- break; // exit for (ptr = tp ...) loop
- }
- else if (btag == CMD('T','D',0,0) ||
- btag == CMD('T','H',0,0)) // 'TD' 'TH'
- {
- //printf("BEFORE col = %d, colspan = %d, numcells = %d\n",
- // col, colspan, numcells);
- if (col >= 0) { // This is a hack to support COLSPAN
- ti = colspan; // ignore if colspan > 1
- maxlinew /= colspan;
- while (colspan > 0) {
- if (maxlinew > maxcols[col] && ti <= 1)
- maxcols[col] = maxlinew;
- col ++;
- colspan --;
- }
- }
- else
- col ++;
- colspan = 1; // Reset
- if (get_attr(attrptr, "COLSPAN", attr, sizeof(attr)))
- colspan = atoi(attr);
- //printf("AFTER col = %d, colspan = %d, numcells = %d\n",
- // col, colspan, numcells);
- if (col + colspan >= numcells)
- numcells = col + colspan;
- linew = 0;
- needspace = 0;
- incell = 1;
- if (btag == CMD('T','H',0,0)) // th
- font = font_style(serifont_, FL_BOLD);
- else
- font = serifont_;
- fsize = fontsize_;
- nfonts = 0; // pop all fonts off stack, no need for anything more
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- maxlinew = 0; // Reset
- if (get_attr(attrptr, "WIDTH", attr, sizeof(attr))) {
- maxlinew = get_length(attr, hsize_ - xx);
- if (maxlinew > widths[col])
- widths[col] = maxlinew; // store widths
- }
- //printf("maxlinew = %d\n", maxlinew);
- }
- else if (btag == CMD('/','T','D',0) ||
- btag == CMD('/','T','H',0)) // '/TD' '/TH'
- {
- incell = 0;
- }
- else if (btag == CMD('T','I','T',0)) // 'TITLE'
- {
- }
- else if (btag == CMD('T','R',0,0)) // 'TR'
- {
- //printf("%s col = %d, colspan = %d, numcells = %d\n",
- // buf, col, colspan, numcells);
- if (col >= 0) { // This is a hack to support COLSPAN
- ti = colspan; // ignore if colspan > 1
- maxlinew /= colspan;
- while (colspan > 0) {
- if (maxlinew > maxcols[col] && ti <= 1)
- maxcols[col] = maxlinew;
- col ++;
- colspan --;
- }
- }
- linew = 0;
- needspace = 0;
- incell = 0;
- col = -1;
- maxlinew = 0;
- }
- else if (btag == CMD('/','T','R',0)) // '/TR'
- {
- //printf("%s col = %d, colspan = %d, numcells = %d\n",
- // buf, col, colspan, numcells);
- if (col >= 0) { // This is a hack to support COLSPAN
- ti = colspan; // ignore if colspan > 1
- maxlinew /= colspan;
- while (colspan > 0) {
- if (maxlinew > maxcols[col] && ti <= 1)
- maxcols[col] = maxlinew;
- col ++;
- colspan --;
- }
- }
- linew = 0;
- needspace = 0;
- incell = 0;
- col = -1;
- maxlinew = 0;
- }
- else if (btag == CMD('U',0,0,0)) // 'U'
- {
- }
- else if (btag == CMD('V','A','R',0)) // 'VAR'
- {
- font = font_style(monofont_, FL_ITALIC);
- if (nfonts < HV_64 - 1) nfonts ++; // pushfont
- fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
- }
- else if (btag == CMD('/','V','A','R')) // '/VAR'
- {
- if (nfonts > 0) nfonts --; // popfont
- fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
- }
- else if (btag == CMD('A','B','B',0) || // 'ABBR'
- btag == CMD('A','C','R',0) || // 'ACRONYM'
- btag == CMD('A','D','D',0) || // 'ADDRESS'
- btag == CMD('A','P','P',0) || // 'APPLET'
- btag == CMD('A','R','E',0) || // 'AREA'
- btag == CMD('B','A','S',0) || // 'BASE' 'BASEFONT'
- btag == CMD('B','D','O',0) || // 'BDO'
- btag == CMD('B','G','S',0) || // 'BGSOUND'
- btag == CMD('B','I','G',0) || // 'BIG'
- btag == CMD('B','L','I',0) || // 'BLINK'
- btag == CMD('B','U','T',0) || // 'BUTTON'
- btag == CMD('C','A','P',0) || // 'CAPTION'
- btag == CMD('C','I','T',0) || // 'CITE'
- btag == CMD('C','O','L',0) || // 'COL' 'COLGROUP'
- btag == CMD('D','E','L',0) || // 'DEL'
- btag == CMD('D','F','N',0) || // 'DFN'
- btag == CMD('D','I','R',0) || // 'DIR'
- btag == CMD('E','M','B',0) || // 'EMBED'
- btag == CMD('F','I','E',0) || // 'FIELDSET'
- btag == CMD('F','O','R',0) || // 'FORM'
- btag == CMD('F','R','A',0) || // 'FRAME' 'FRAMESET'
- btag == CMD('I','F','R',0) || // 'IFRAME'
- btag == CMD('I','N','P',0) || // 'INPUT'
- btag == CMD('I','N','S',0) || // 'INS'
- btag == CMD('I','S','I',0) || // 'ISINDEX'
- btag == CMD('L','A','B',0) || // 'LABEL'
- btag == CMD('L','E','G',0) || // 'LEGEND'
- btag == CMD('L','I','N',0) || // 'LINK'
- btag == CMD('M','A','P',0) || // 'MAP'
- btag == CMD('M','A','R',0) || // 'MARQUEE'
- btag == CMD('M','E','N',0) || // 'MENU'
- btag == CMD('M','E','T',0) || // 'META'
- btag == CMD('M','U','L',0) || // 'MULTICOL'
- btag == CMD('N','O','B',0) || // 'NOBR'
- btag == CMD('N','O','F',0) || // 'NOFRAMES'
- btag == CMD('O','B','J',0) || // 'OBJECT'
- btag == CMD('O','P','T',0) || // 'OPTGROUP' 'OPTION'
- btag == CMD('P','A','R',0) || // 'PARAM'
- btag == CMD('Q',0,0,0) || // 'Q'
- btag == CMD('S',0,0,0) || // 'S'
- btag == CMD('S','A','M',0) || // 'SAMP'
- btag == CMD('S','E','L',0) || // 'SELECT'
- btag == CMD('S','M','A',0) || // 'SMALL'
- btag == CMD('S','P','A',0) || // 'SPACER' 'SPAN'
- btag == CMD('S','T','R',0) || // 'STRIKE'
- btag == CMD('S','T','Y',0) || // 'STYLE'
- btag == CMD('S','U','B',0) || // 'SUB'
- btag == CMD('S','U','P',0) || // 'SUP'
- btag == CMD('T','B','O',0) || // 'TBODY'
- btag == CMD('T','E','X',0) || // 'TEXTAREA'
- btag == CMD('T','F','O',0) || // 'TFOOT'
- btag == CMD('T','H','E',0) || // 'THEAD'
- btag == CMD('W','B','R',0) || // 'WBR'
- btag == CMD('X','M','P',0)) // 'XMP'
- ; // unsupported tags
- else if (tag[0] == '!' && isalpha(tag[1])) // '!DOCTYPE' etc
- ;
- else if (tag[0] == '?' && isalpha(tag[1])) // '?XMP' etc
- ;
- else if (tag[0] == '/' && isalpha(tag[1])) // unrecognized end tag
- ;
- else if (!head) // unrecognized tag so draw it
- {
- linew += (int)fl_width("<"); // add width of '<' char
- ptr = tagptr + 1; // start of tag + 1
- }
- } // if (*ptr == '<')
- else if (*ptr == '\n' && pre) // '\n' in pre
- {
- linew = 0;
- needspace = 0;
- ptr ++;
- }
- else if (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
- {
- needspace = 1;
- ptr ++;
- }
- else if (*ptr == '&' && sp < (buf + sizeof(buf) - 1)) // '&' char ref
- {
- ptr ++;
- qch = quote_char(ptr);
- if (qch < 0) // Not char ref
- *(sp ++) = '&'; // added ()
- else {
- *(sp ++) = qch; // added ()
- ptr = strchr(ptr, ';') + 1;
- }
- }
- else // Other char
- {
- if (sp < (buf + sizeof(buf) - 1))
- *(sp ++) = *(ptr ++); // added ()
- else
- ptr ++;
- }
- } // for (ptr = tp ...)
- // Now that we have scanned the entire table,
- // adjust the table and cell widths to fit on the screen
- if (numcells == 0) return endp;
- // colspan widths
- for (col = 0; col < numcells; col ++)
- {
- if (colspans[col] > 0) { // check width of colspans
- colspanw = colspans[col]; // colspan width
- colspan = colspans[col + 1]; // colspan
- for (ti = col; ti < col + colspan; ti ++)
- mincellw += mincols[ti]; // total width of mincols
- if (colspans[col] > mincellw) { // pad columns with colspans
- for (ti = col, maxcellw = 0; ti < col + colspan; ti ++) {
- if (maxcols[ti] == 0) maxcols[ti] = 1; // set min width
- maxcellw += maxcols[ti]; // total width of cells
- colspanw -= mincols[ti]; // colspans remainder width
- }
- if (!maxcellw) maxcellw = 1; // avoid divide by zero
- for (ti = col; ti < col + colspan; ti ++) {
- tempw = (maxcols[ti] * 100) / maxcellw; // as percent
- scalew = (colspanw * tempw) / 100; // as value
- maxcols[ti] = mincols[ti] + scalew;
- }
- }
- col += colspan - 1; // skip past colspan
- }
- }
- // get min width of table from colspans
- for (col = 0, mincellw = 0; col < numcells; col ++) {
- if (colspans[col] > 0) {
- mincellw += colspans[col]; // min table width
- col += colspans[col + 1] - 1; // skip past colspan
- }
- else
- mincellw += mincols[col];
- }
- if (mincellw > hwidth) { // if table wider than window
- tsize = mincellw;
- tsize += 6 * numcells;
- tsize += xx + 4; // add 4 pixels in case width is hsize_
- if (tsize > hsize_) tsize = hsize_;
- }
- else
- tsize = hwidth;
- tw = 0; // Reset
- if (get_attr(tp + 6, "WIDTH", attr, sizeof(attr)))
- tw = get_length(attr, tsize - xx);
- //printf("numcells = %d, tw = %d, tsize = %d\n", numcells, tw, tsize);
- if (tw == 0) // get max table width
- maxlinew = tsize - xx;
- else
- maxlinew = tw;
- maxlinew -= 6 * numcells; // sub internal borders
- tw -= 6 * numcells;
- if (tsize > hwidth) { // if table wider than window sub 4 pixels
- maxlinew -= 4; // this is needed
- tw -= 4;
- }
- if (tw < 0) tw = 0;
- //printf(" tw = %d, maxlinew = %d, xx = %d, hsize_ = %d, mincellw = %d\n",
- // tw, maxlinew, xx, hsize_, mincellw);
- if (mincellw > maxlinew) // resize if colspans too wide
- tw = mincellw + xx;
- for (col = 0, linew = 0; col < numcells; col ++)
- linew += maxcols[col]; // Add up the widths
- if (!linew) linew = 1; // avoid divide by zero
- //for (col = 0; col < numcells; col ++)
- // printf(" maxcols[%d] = %d, mincols[%d] = %d, widths[%d] = %d, colspans[%d] = %d\n",
- // col, maxcols[col], col, mincols[col],
- // col, widths[col], col, colspans[col]);
- //printf("linew = %d, w() = %d\n", linew, w());
- scalew = tw;
- if (tw == 0) { // Adjust the width if needed
- if (linew > maxlinew)
- scalew = maxlinew;
- else
- scalew = linew;
- }
- if (linew < scalew) // Table width is too small
- {
- //printf("Scaling table up to scalew %d from linew %d\n", scalew, linew);
- scalew -= linew; // get remainder width
- //printf("adjusted scalew = %d\n", scalew);
- // scale table up
- for (col = 0; col < numcells; col ++) {
- tempw = (maxcols[col] * 100) / linew; // as percent
- maxcols[col] += (tempw * scalew) / 100; // as value
- }
- // td widths
- for (col = 0, ti = 0, tempw = 0; col < numcells; col ++) {
- if (widths[col] > 0 && mincols[col] > widths[col]) {
- tempw += maxcols[col] - mincols[col]; // remainder
- maxcols[col] = mincols[col]; // set to minwidth
- }
- if (!widths[col]) ti ++; // unspecified widths
- }
- if (!ti) ti = 1; // avoid divide by zero
- for (col = 0; col < numcells; col ++) {
- if (!widths[col])
- maxcols[col] += tempw / ti; // add remainder fractions
- }
- }
- else if (linew > scalew) // Table width is too big
- {
- //printf("Scaling table down to scalew %d from linew %d\n", scalew, linew);
- for (col = 0; col < numcells; col ++) {
- linew -= mincols[col];
- scalew -= mincols[col];
- }
- if (!linew) linew = 1; // avoid divide by zero
- //printf("adjusted linew = %d, scalew = %d\n", linew, scalew);
- for (col = 0; col < numcells; col ++) {
- maxcols[col] -= mincols[col];
- maxcols[col] = scalew * maxcols[col] / linew;
- maxcols[col] += mincols[col];
- }
- }
- else if (tw == 0) // Not sure if this is needed
- tw = linew;
- if (tw == 0) // tw still zero
- for (col = 0; col < numcells; col ++)
- tw += maxcols[col];
- for (col = 0, maxcellw = 0; col < numcells; col ++)
- maxcellw += maxcols[col]; // total width of cells
- if (tw > maxcellw) { // add remainder to last column
- tempw = tw - maxcellw;
- maxcols[numcells - 1] += tempw;
- }
- //printf("FINAL tw = %d\n", tw);
- //for (col = 0; col < numcells; col ++)
- // printf(" maxcols[%d] = %d\n", col, maxcols[col]);
- return endp; // table end pointer
- } // Fl_Help_View::format_table()
- //
- // Fl_Help_View::free_data() - Free memory used for the document.
- //
- void Fl_Help_View::free_data()
- {
- if (value_) // Release all images
- {
- const char *ptr, // Pointer into block
- *attrptr; // Start of attributes ptr
- char *sp, // Pointer into buffer
- buf[1024], // Text buffer
- attr[1024], // Attribute buffer
- wattr[1024], // Width attribute buffer
- hattr[1024]; // Height attribute buffer
- Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
- int imgw = 0, // Image width
- imgh = 0; // Image height
- for (ptr = value_; *ptr; )
- {
- if (*ptr == '<')
- {
- ptr ++;
- if (!strncmp(ptr, "!--", 3)) { // Found "!--"
- ptr += 3;
- if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
- ptr += 3;
- continue;
- }
- else
- break;
- }
- sp = buf;
- while (*ptr && *ptr != '>' && !isspace((*ptr) & 255))
- if (sp < (buf + sizeof(buf) - 1))
- *(sp ++) = *(ptr ++); // added ()
- else
- ptr ++;
- *sp = '\0'; // Nul-terminate
- attrptr = ptr; // Start of attributes
- while (*ptr && *ptr != '>') ptr ++;
- if (*ptr == '>') ptr ++;
- if (!strcasecmp(buf, "IMG"))
- {
- imgw = imgh = 0; // reset
- if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
- imgw = get_length(wattr);
- if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
- imgh = get_length(hattr);
- img = 0; // rem'd NULL
- if (get_attr(attrptr, "SRC", attr, sizeof(attr)))
- { // Release the image twice to free it from memory
- img = get_image(attr, imgw, imgh);
- // Seb was here - freeing a broken_image causes an XFreePixmap crash
- if((void*)img != &broken_image) {
- img->release();
- if(img->refcount() > 0) img->release();
- }
- }
- }
- } // if (*ptr == '<')
- else
- ptr ++;
- } // for (ptr = value_ ...)
- free((void *)value_);
- value_ = 0; // reset
- } // if (value_)
- if (!d->isnew) { // is new page
- free((void *)d->csstext); // values
- free((void *)d->cssword);
- free((void *)d->cssurl);
- d->csstext = 0;
- d->cssword = 0;
- d->cssurl = 0;
- d->cssurllen = 0; // lengths
- d->csswordlen = 0;
- d->csstextlen = 0;
- serifont_ = FL_TIMES; // default font
- }
- d->isnew = 1; // set
- // Free all of the arrays
- if (nblocks_) { // Free blocks
- free(blocks_);
- ablocks_ = 0;
- nblocks_ = 0;
- blocks_ = 0;
- }
- if (nlinks_) { // Free links
- free(links_);
- alinks_ = 0;
- nlinks_ = 0;
- links_ = 0;
- }
- if (ntargets_) { // Free targets
- free(d->targets);
- atargets_ = 0;
- ntargets_ = 0;
- d->targets = 0;
- }
- } // Fl_Help_View::free_data()
- //
- // Fl_Help_View::get_align() - Get an alignment attribute.
- //
- int // O - Alignment
- Fl_Help_View::get_align(const char *ap, // I - Start of attrs pointer
- int da) // I - Default alignment
- {
- char buf[255]; // Alignment value
- if (!get_attr(ap, "ALIGN", buf, sizeof(buf))) // rem'd == 0
- return da; // no align attribute
- if (!strcasecmp(buf, "CENTER"))
- return CENTER; // 0
- else if (!strcasecmp(buf, "RIGHT"))
- return RIGHT; // -1
- else
- return LEFT; // 1
- } // Fl_Help_View::get_align()
- //
- // Fl_Help_View::get_attr() - Get an attribute value from the string.
- //
- const char * // O - Pointer to buf or NULL
- Fl_Help_View::get_attr(const char *ap, // I - Start of attributes pointer
- const char *np, // I - Name of attribute
- char *buf, // O - Buffer for attribute value
- int sb) // I - Sizeof buf
- {
- char name[255], // Name from string
- *ptr, // Pointer into name or value
- quote; // Quote char
- buf[0] = '\0';
- while (*ap && *ap != '>')
- {
- while (isspace((*ap) & 255)) ap ++;
- if (*ap == '>' || !*ap) return 0; // rem'd NULL
- for (ptr = name; *ap && !isspace((*ap) & 255) && *ap != '=' && *ap != '>'; )
- if (ptr < (name + sizeof(name) - 1)) // Read in the attribute name
- *(ptr ++) = *(ap ++); // added ()
- else
- ap ++;
- *ptr = '\0';
- if (isspace((*ap) & 255) || !*ap || *ap == '>')
- buf[0] = '\0';
- else
- {
- if (*ap == '=') ap ++;
- for (ptr = buf; *ap && !isspace((*ap) & 255) && *ap != '>'; )
- if (*ap == '\'' || *ap == '\"') { // Read in the attribute value
- quote = *(ap ++); // added () same as quote=*ap;ap++;
- while (*ap && *ap != quote)
- if ((ptr - buf + 1) < sb) // Sizeof buf
- *(ptr ++) = *(ap ++); // added () same as *ptr=*ap;ptr++;ap++;
- else
- ap ++;
- if (*ap == quote) ap ++;
- }
- else if ((ptr - buf + 1) < sb) // Sizeof buf
- *(ptr ++) = *(ap ++); // added ()
- else
- ap ++;
- *ptr = '\0';
- }
- if (!strcasecmp(np, name)) // Name of attribute matches
- return buf;
- else
- buf[0] = '\0';
- if (*ap == '>') return 0; // rem'd NULL
- } // while (*ap ...)
- return 0; // rem'd NULL
- } // Fl_Help_View::get_attr()
- //
- // Fl_Help_View::get_color() - Get an alignment attribute.
- //
- Fl_Color // O - Color value
- Fl_Help_View::get_color(const char *np, // I - Color name
- Fl_Color dc) // I - Default color value
- {
- int ti = 0, // Looping var
- rgb = 0,
- red = 0,
- green = 0,
- blue = 0, // RGB values
- temp = 0; // temp var
- static const struct { // Color name table
- const char *name;
- int r,
- g,
- b; // Red, green, blue
- }
- colors[] = {
- { "black", 0x00, 0x00, 0x00 },
- { "red", 0xff, 0x00, 0x00 },
- { "green", 0x00, 0x80, 0x00 },
- { "yellow", 0xff, 0xff, 0x00 },
- { "blue", 0x00, 0x00, 0xff },
- { "magenta", 0xff, 0x00, 0xff },
- { "fuchsia", 0xff, 0x00, 0xff },
- { "cyan", 0x00, 0xff, 0xff },
- { "aqua", 0x00, 0xff, 0xff },
- { "white", 0xff, 0xff, 0xff },
- { "gray", 0x80, 0x80, 0x80 },
- { "grey", 0x80, 0x80, 0x80 },
- { "lime", 0x00, 0xff, 0x00 },
- { "maroon", 0x80, 0x00, 0x00 },
- { "navy", 0x00, 0x00, 0x80 },
- { "olive", 0x80, 0x80, 0x00 },
- { "purple", 0x80, 0x00, 0x80 },
- { "silver", 0xc0, 0xc0, 0xc0 },
- { "teal", 0x00, 0x80, 0x80 }
- };
- if (!np || !np[0]) return dc; // No name
- if (np[0] != '#') // check no hash
- for (ti = 0, rgb = 0; np[ti] != '\0'; ti ++) {
- if (isalpha(np[ti])) rgb |= 1; // name if 1
- if (isdigit(np[ti])) rgb |= 2; // decimal if 2
- if (rgb == 3) break; // hex with no hash
- }
- if (np[0] == '#' || rgb == 3) // Do hex color lookup
- {
- if (rgb == 3) temp = 0; else temp = 1; // set name offset
- rgb = strtol(np + temp, 0, 16); // rem'd NULL
- if (strlen(np) > 4) { // 24-bit
- red = rgb >> 16;
- green = (rgb >> 8) & 255;
- blue = rgb & 255;
- }
- else { // 16-bit?
- red = (rgb >> 8) * 17;
- green = ((rgb >> 4) & 15) * 17;
- blue = (rgb & 15) * 17;
- }
- return fl_rgb_color((uchar)red, (uchar)green, (uchar)blue);
- }
- else // Do color name lookup
- {
- temp = sizeof(colors) / sizeof(colors[0]);
- for (ti = 0; ti < temp; ti ++)
- if (!strcasecmp(np, colors[ti].name)) {
- return fl_rgb_color(colors[ti].r, colors[ti].g, colors[ti].b);
- }
- return dc; // Color not found
- }
- } // Fl_Help_View::get_color()
- //
- // Fl_Help_View::get_css_value() - Outputs the value of a given css property to buffer.
- //
- int // O - true if value exists, false otherwise
- Fl_Help_View::get_css_value(const char *sp, // I - selector
- const char *pp, // I - property
- char *vp) // O - value
- {
- int ti = 0,
- tj = 0,
- tk = 0,
- tword = 0,
- tcount = 0, // temp vars
- issel = 0,
- isblock = 0,
- isclass = 0,
- order = 0, // misc vars
- si = 0,
- slen = 0,
- plen = 0,
- blen = 0,
- vlen = 0;
- char *tp = 0; // ptr
- if (strchr(pp, '-')) blen = strchr(pp, '-') - pp; // base property length
- plen = strlen(pp); // property length
- slen = strlen(sp); // selector length
- if (strstr(sp, ".")) isclass = 1; // class ptr
- while (tk < 2) { // find selector
- for (ti = 0; ti < d->csswordlen; ti ++) { // word loop
- tword = *(d->cssword + ti); // word offset
- tp = d->csstext + tword; // word ptr
- if (isblock && *tp == '}') { issel = 0; isblock = 0; break; } // close block
- if (isblock) {
- if (!strncasecmp(tp, pp, plen)) { // full property
- for (tj = *(d->cssword + ti + 1); tcount < 255; tj ++) { // value is next word
- if (*(d->csstext + tj) == ';') break; // end of value
- else {
- *(vp + tcount) = *(d->csstext + tj); // copy value
- tcount ++; // count word length
- }
- }
- *(vp + tcount) = '\0'; // nul-terminate
- return 1; // success
- }
- else if (blen) { // base property
- if (!strncasecmp(tp, pp, blen) && !si) si = ti; // store index
- }
- }
- if (issel && *tp == '{') isblock = 1; // open block
- if (!isblock && !strncasecmp(tp, sp, slen)) {
- if (isclass) // source has class
- issel = 2; // found match
- else if (*(tp + slen) != '.')
- issel = 1; // match if target no class
- }
- }
- if (!issel && isclass) { // class not found, find selector
- slen = strstr(sp, ".") - sp; // remove class name
- isclass = 0; // reset
- }
- tk ++; // second try without class name
- }
- if (si) { // found base but not full property
- for (tj = *(d->cssword + si + 1); tcount < 255; tj ++) { // value is next word
- if (*(d->csstext + tj) == ';') break; // end of value
- else {
- *(vp + tcount) = *(d->csstext + tj); // copy value
- if (isspace(*(vp + tcount))) *(vp + tcount) = '\0'; // split words
- tcount ++; // count word length
- }
- }
- *(vp + tcount) = '\0'; // nul-terminate
- for (tj = 0, ti = 0; tj < tcount; tj ++) { // shorthand recognition rules
- if (*(vp + tj) == '\0') ti = 0; else ti ++;
- if (ti == 1) { // first letter of word
- vlen = strlen(vp + tj); // word length
- if (!strncasecmp(pp, "background", 10)) // background shorthand
- {
- if (!strncasecmp(vp + tj, "none", 4) ||
- !strncasecmp(vp + tj, "left", 4) ||
- !strncasecmp(vp + tj, "right", 5) ||
- !strncasecmp(vp + tj, "inherit", 7)) order = 0; // nothing
- else if (*(vp + tj) == '#' ||
- !strncasecmp(vp + tj, "rgb", 3) ||
- !strncasecmp(vp + tj, "transparent", 11)) order = 1; // color
- else if (!strncasecmp(vp + tj, "url", 3)) order = 2; // image
- else if (!strncasecmp(vp + tj, "repeat", 6) ||
- !strncasecmp(vp + tj, "no-repeat", 9)) order = 3; // repeat
- else if (!strncasecmp(vp + tj, "scroll", 6) ||
- !strncasecmp(vp + tj, "fixed", 5)) order = 4; // attachment
- else if (isdigit(*(vp + tj)) ||
- !strncasecmp(vp + tj, "top", 3) ||
- !strncasecmp(vp + tj, "center", 6) ||
- !strncasecmp(vp + tj, "bottom", 6)) { // position
- // todo: count words to ; if one then replace \0 with ' ' - or just replace next '\0'
- order = 5; }
- else if (!strncasecmp(vp + tj, "black", 5) ||
- !strncasecmp(vp + tj, "red", 3) ||
- !strncasecmp(vp + tj, "green", 5) ||
- !strncasecmp(vp + tj, "yellow", 6) ||
- !strncasecmp(vp + tj, "blue", 4) ||
- !strncasecmp(vp + tj, "magenta", 7) ||
- !strncasecmp(vp + tj, "fuchsia", 7) ||
- !strncasecmp(vp + tj, "cyan", 4) ||
- !strncasecmp(vp + tj, "aqua", 4) ||
- !strncasecmp(vp + tj, "white", 5) ||
- !strncasecmp(vp + tj, "gray", 4) ||
- !strncasecmp(vp + tj, "grey", 4) ||
- !strncasecmp(vp + tj, "lime", 4) ||
- !strncasecmp(vp + tj, "maroon", 6) ||
- !strncasecmp(vp + tj, "navy", 4) ||
- !strncasecmp(vp + tj, "olive", 5) ||
- !strncasecmp(vp + tj, "purple", 6) ||
- !strncasecmp(vp + tj, "silver", 6) ||
- !strncasecmp(vp + tj, "teal", 4)) order = 1; // color name
- if (!strncmp(pp, "background-color", 16) && order == 1) break;
- if (!strncmp(pp, "background-image", 16) && order == 2) break;
- if (!strncmp(pp, "background-repeat", 17) && order == 3) break;
- if (!strncmp(pp, "background-attachment", 21) && order == 4) break;
- if (!strncmp(pp, "background-position", 19) && order == 5) break;
- order = 0; // reset
- }
- else if (!strncasecmp(pp, "border", 6)) // border shorthand
- {
- // todo: border-width-style-color
- }
- else if (!strncasecmp(pp, "font", 4)) // font shorthand
- {
- if (isdigit(*(vp + tj))) { // number
- if (vlen == 3 && isdigit(*(vp + tj + 2))) order = 3; // weight
- else order = 4; // size
- }
- else if (isalpha(*(vp + tj))) { // word
- if (!strncasecmp(vp + tj, "normal", 6) ||
- !strncasecmp(vp + tj, "lighter", 7) || // weight
- !strncasecmp(vp + tj, "inherit", 7)) order = 0; // nothing
- else if (!strncasecmp(vp + tj, "italic", 6) ||
- !strncasecmp(vp + tj, "oblique", 7)) order = 1; // style
- else if (!strncasecmp(vp + tj, "small-caps", 10)) order = 2; // variant
- else if (!strncasecmp(vp + tj, "bold", 4)) order = 3; // weight
- else if (!strncasecmp(vp + tj, "x-", 2) ||
- !strncasecmp(vp + tj, "xx-", 3) ||
- !strncasecmp(vp + tj, "small", 5) ||
- !strncasecmp(vp + tj, "medium", 6) ||
- !strncasecmp(vp + tj, "large", 5)) order = 4; // size
- else order = 5; // family
- }
- if (!strncmp(pp, "font-style", 10) && order == 1) break;
- if (!strncmp(pp, "font-variant", 12) && order == 2) break;
- if (!strncmp(pp, "font-weight", 11) && order == 3) break;
- if (!strncmp(pp, "font-size", 9) && order == 4) break;
- if (!strncmp(pp, "font-family", 11) && order == 5) break;
- order = 0; // reset
- }
- else if (!strncasecmp(pp, "margin", 6) ||
- !strncasecmp(pp, "padding", 7)) // margin/padding shorthand
- {
- // todo: margin-top-right-bottom-left - padding has same keywords
- }
- else if (!strncasecmp(pp, "outline", 7)) // outline shorthand
- {
- // todo: outline-color-style-width
- }
- }
- }
- if (order && tj) { // copy word to start of buffer
- for (ti = 0; ti < vlen; ti ++) *(vp + ti) = *(vp + tj + ti);
- *(vp + vlen) = '\0'; // nul-terminate
- }
- return 1; // success
- }
- return 0; // failure
- } // Fl_Help_View::get_css_value
- //
- // Fl_Help_View::get_font_size() - Get a height value for font-size.
- //
- int // O - height value
- Fl_Help_View::get_font_size(const char *hp) // I - height pointer
- {
- int ti = 0, // temp var
- upos = 0, // unit position - %,in,cm,mm,em,ex,pt,pc,px
- slen = 0, // src length
- val = 0; // integer value
- char buf[8]; // buffer
- if (!hp || !hp[0]) return 0; // no height
- slen = strlen(hp);
- if (slen > 8) slen = 8; // max length
- for (val = 0; val < slen; val ++) {
- if (isalpha(*(hp + val)) || *(hp + val) == '%') {
- upos = val;
- break; // unit position
- }
- }
- if (!upos) val = slen; // no unit
- for (ti = 0; ti < val; ti ++)
- buf[ti] = *(hp + ti); // copy value to buffer
- val = atoi(buf); // to int
- if (*(hp + upos) == '%') { // percent
- if (val > 100) val = 100;
- else if (val < 0) val = 0;
- val = (val * fontsize_) / 100;
- }
- else if (!strncmp(hp + upos, "em", 2)) // em
- val = val * fontsize_;
- else if (!strncasecmp(hp + upos, "ex", 2)) // ex
- val = fontsize_ / val;
- // note: pt, pica, cm, mm, in are all relative to screen size
- // currently they equate to px - http://hsivonen.iki.fi/units
- if (val > 48) val = 48; // max
- else if (val < 8) val = 8; // min
- return val;
- } // Fl_Help_View::get_font_size()
- //
- // Fl_Help_View::get_image() - Get an inline image.
- //
- Fl_Shared_Image * // O - Image pointer
- Fl_Help_View::get_image(const char *np, // Image filename
- int iw, // Image width
- int ih) // Image height
- {
- const char *namep; // Local filename
- char dir[1024], // Current directory
- temp[1024], // Temporary filename
- *tptr,
- *dirp; // Pointer into temporary name
- Fl_Shared_Image *imgp; // Image pointer
- // See if the image can be found
- if (strchr(directory_, ':') && !strchr(np, ':')) // rem'd != 0 and == 0
- { // dir has ':' char and np doesn't
- if (np[0] == '/') { // Has sub-path
- strlcpy(temp, directory_, sizeof(temp));
- if ((tptr = strrchr(strchr(temp, ':') + 3, '/')) != 0) // get filename
- strlcpy(tptr, np, sizeof(temp)-(tptr - temp)); // remove filename
- else
- strlcat(temp, np, sizeof(temp));
- }
- else // Just filename
- snprintf(temp, sizeof(temp), "%s/%s", directory_, np);
- if (link_)
- namep = (*link_)(this, temp, 0);
- else
- namep = temp;
- }
- else if (np[0] != '/' && !strchr(np, ':')) // rem'd == 0
- {
- if (directory_[0])
- snprintf(temp, sizeof(temp), "%s/%s", directory_, np);
- else {
- dirp = getcwd(dir, sizeof(dir)); // getcwd can fail and return wrong dir, bug?
- snprintf(temp, sizeof(temp), "%s/%s", dir, np); // No end '/' char from getcwd
- }
- if (link_)
- namep = (*link_)(this, temp, 0);
- else
- namep = temp;
- }
- else if (link_)
- namep = (*link_)(this, np, 0);
- else
- namep = np;
- //if (namep) printf(" get_image namep=(%s)\n",namep);
- //printf(" get_image d->path=(%s)\n",d->path);
- if (d->ispath) { // path is used
- strlcpy(temp, d->path, sizeof(temp));
- if ((tptr = strrchr(temp, '/'))) // tptr valid, add filename
- strlcpy(tptr + 1, np, sizeof(temp)-(tptr + 1 - temp));
- namep = temp;
- }
- if (!namep) return 0;
- if (!strncmp(namep, "file:", 5)) namep += 5; // Adjust for file:
- if (!(imgp = Fl_Shared_Image::get(namep, iw, ih))) // rem'd == 0
- imgp = (Fl_Shared_Image *)&broken_image;
- return imgp;
- } // Fl_Help_View::get_image()
- //
- // Fl_Help_View::get_length() - Get a length value either absolute or %.
- //
- int // O - Length value
- Fl_Help_View::get_length(const char *lp) // I - Length pointer
- {
- int val = 0; // Integer value
- if (!lp || !lp[0]) return 0; // No length
- val = atoi(lp);
- if (lp[strlen(lp) - 1] == '%') { // Calc percent
- if (val > 100) val = 100;
- else if (val < 0) val = 0;
- val = val * (hsize_ - (scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size())) / 100; // val from hsize_
- }
- return val;
- } // Fl_Help_View::get_length()
- //
- // Fl_Help_View::get_length() - Get a length value of a given width.
- //
- int // O - Length value
- Fl_Help_View::get_length(const char *lp, // I - Length pointer
- int hw) // I - horizontal width
- {
- int val = 0; // Integer value
- if (!lp || !lp[0]) return 0; // No length
- val = atoi(lp);
- if (lp[strlen(lp) - 1] == '%') { // Calc percent
- if (val > 100) val = 100;
- else if (val < 0) val = 0;
- val = val * hw / 100; // get value from hw
- }
- return val;
- } // Fl_Help_View::get_length()
- //
- // Fl_Help_View::gettopline() - Get current topline in document.
- //
- int Fl_Help_View::gettopline() // O - Current topline
- {
- return d->top;
- }
- //
- // Fl_Help_View::handle() - Handle events in the widget.
- //
- int // O - True if we handled it, false otherwise
- Fl_Help_View::handle(int event) // I - Event to handle
- {
- int xx = 0,
- yy = 0, // Mouse positions
- hh = 0; // window height
- Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box type
- xx = Fl::event_x() - x() + leftline_; // Get mouse
- yy = Fl::event_y() - y() + topline_;
- if (d->resized && !Fl::event_buttons()) { // mouse up outside window
- d->resized = 0; // reset d->resized
- format(); // make sure text is wrapped to window
- }
- switch (event)
- {
- case FL_FOCUS: // Set keyboard focus
- redraw(); // Set widget to draw
- return 1;
- case FL_UNFOCUS: // Reset keyboard focus
- clear_selection(); // Clear text selection
- redraw(); // Set widget to draw
- return 1;
- case FL_ENTER : // Mouse pointer entered widget
- Fl_Group::handle(event);
- return 1;
- case FL_LEAVE : // Mouse pointer left widget
- d->top = topline(); // set top
- fl_cursor(FL_CURSOR_DEFAULT); // Default icon, usually arrow
- break;
- case FL_MOVE: // Mouse pointer was moved with no button pushed
- hh = h() + topline_ - Fl::box_dy(bt); // get bottom of window
- if (hscrollbar_.visible()) hh -= (scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size());
- if (yy > hh) hh = -1; // mouse over hscrollbar so no active link
- if (find_link(xx, yy) && hh > 0) // mouse y in bounds
- fl_cursor(FL_CURSOR_HAND); // Hand icon
- else
- fl_cursor(FL_CURSOR_DEFAULT);
- return 1;
- case FL_PUSH: // Mouse button was pushed
- if (Fl_Group::handle(event)) return 1;
- d->linkp = find_link(xx, yy);
- if (d->linkp) {
- d->ispush = 1; // set link is pushed
- fl_cursor(FL_CURSOR_HAND);
- return 1;
- }
- if (begin_selection()) {
- fl_cursor(FL_CURSOR_INSERT); // I-beam icon
- return 1;
- }
- fl_cursor(FL_CURSOR_DEFAULT);
- return 1;
- case FL_DRAG: // Mouse pointer was moved with button pushed
- if (d->ispush) { // link is pushed
- if (Fl::event_is_click()) {
- fl_cursor(FL_CURSOR_HAND);
- } else {
- fl_cursor(FL_CURSOR_DEFAULT); // Should be "FL_CURSOR_CANCEL" if we had it
- }
- return 1;
- }
- if (current_view == this && selection_push_last) {
- if (extend_selection()) redraw(); // Set widget to draw
- fl_cursor(FL_CURSOR_INSERT);
- return 1;
- }
- fl_cursor(FL_CURSOR_DEFAULT);
- return 1;
- case FL_RELEASE: // Mouse button was released
- if (d->ispush) { // link is pushed
- if (Fl::event_is_click()) {
- d->top = topline(); // set top
- d->islink = 1; // set islink
- follow_link(d->linkp);
- }
- fl_cursor(FL_CURSOR_DEFAULT);
- d->ispush = 0; // reset link is pushed - was d->linkp = 0;
- return 1;
- }
- if (current_view == this && selection_push_last) {
- end_selection();
- return 1;
- }
- return 1;
- case FL_SHORTCUT: { // Shortcut key was pushed
- char ascii = Fl::event_text()[0];
- switch (ascii) {
- case CTRL('A'): select_all(); redraw(); return 1; // Set widget to draw
- case CTRL('C'):
- case CTRL('X'): end_selection(1); return 1;
- }
- break; }
- }
- return Fl_Group::handle(event);
- } // Fl_Help_View::handle()
- //
- // Fl_Help_View::hv_draw() - Draws text.
- //
- // Note: This function must be optimized for speed!
- void Fl_Help_View::hv_draw(const char *tp, // I - Text to draw
- int xx, // I - X position of text
- int yy) // I - Y position of text
- {
- int width = 0, // Width of text
- first = 0, // First selected position
- last = 0; // Last selected position
- if (selected && current_view == this &&
- current_pos < selection_last &&
- current_pos >= selection_first) { // Selected text
- Fl_Color clr = fl_color();
- fl_color(hv_selection_color);
- width = (int)fl_width(tp);
- if (current_pos + (int)strlen(tp) < selection_last)
- width += (int)fl_width(" ");
- fl_rectf(xx, yy + fl_descent() - fl_height(), width, fl_height());
- fl_color(hv_selection_text_color);
- fl_draw(tp, xx, yy);
- fl_color(clr);
- }
- else { // Normal text
- fl_draw(tp, xx, yy);
- }
- if (draw_mode) // Text is being selected
- {
- width = (int)fl_width(tp);
- if (mouse_x >= xx && mouse_x < xx + width) {
- if (mouse_y >= yy - fl_height() + fl_descent() &&
- mouse_y <= yy + fl_descent()) {
- first = current_pos;
- // use 'quote_char' to calculate true length of HTML string
- last = first + strlen(tp);
- if (draw_mode == 1) { // Begin selection mode
- selection_push_first = first;
- selection_push_last = last;
- }
- else { // End selection mode
- selection_drag_first = first;
- selection_drag_last = last;
- }
- }
- }
- }
- } // Fl_Help_View::hv_draw()
- //
- // Fl_Help_View::leftline() - Set the left line position.
- //
- void Fl_Help_View::leftline(int xx) // I - Left line position
- {
- if (!value_) return;
- int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
- if (hsize_ < w() - scrollsize || xx < 0)
- xx = 0;
- else if (xx > hsize_)
- xx = hsize_;
- leftline_ = xx;
- hscrollbar_.value(leftline_, w() - scrollsize, 0, hsize_);
- redraw(); // Set widget to draw
- } // Fl_Help_View::leftline()
- //
- // Fl_Help_View::load() - Load the specified file.
- //
- int // O - 0 on success, -1 on error
- Fl_Help_View::load(const char *fp) // I - File to load, may have target
- {
- FILE *filep; // File to read from
- size_t fsize; // file size
- long len = 0; // Length of file
- char *target, // Target in file
- *slash; // Directory separator
- const char *namep; // Local filename
- char error[1024], // Error buffer
- newname[1024]; // New filename buffer
- clear_selection(); // Clear text selection
- strlcpy(newname, fp, sizeof(newname));
- if ((target = strrchr(newname, '#'))) // Last '#' char - rem'd != 0
- *(target ++) = '\0'; // Remove target - added ()
- if (link_)
- namep = (*link_)(this, newname, 0); // Link transform
- else
- namep = filename_; // Current filename
- //printf(" load namep=(%s) d->nstyle=%d\n",namep,d->nstyle);
- if (!(d->nstyle & HV_NONAVIGATE)) // user navigation, continue load
- namep = newname;
- if (!newname[0]) // avoid error
- strlcpy(newname, "(null)", sizeof(newname));
- if (!namep) return -1; // No file was loaded, fail
- if (!strncmp(newname, "ftp:", 4) || !strncmp(newname, "http:", 5) ||
- !strncmp(newname, "https:", 6) || !strncmp(newname, "ipp:", 4) ||
- !strncmp(newname, "mailto:", 7) || !strncmp(newname, "news:", 5))
- return -1; // last path is remote link, fail
- if (!d->ispath) { // path not used
- strlcpy(d->lpath, filename_, sizeof(d->lpath)); // last path
- strlcpy(filename_, newname, sizeof(filename_)); // dir + filename
- strlcpy(directory_, newname, sizeof(directory_)); // dir only
- }
- // Note: We do not support Windows backslashes,
- // since they are illegal in URLs
- if (!(slash = strrchr(directory_, '/'))) // rem'd == 0
- directory_[0] = '\0'; // No '/' char
- else if (slash > directory_ && slash[-1] != '/')
- *slash = '\0'; // Remove filename, assumes filename exists
- //if (value_) { free((void *)value_); value_ = 0; } // rem'd
- free_data(); // free last document
- if (!strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) ||
- !strncmp(namep, "https:", 6) || !strncmp(namep, "ipp:", 4) ||
- !strncmp(namep, "mailto:", 7) || !strncmp(namep, "news:", 5))
- { // Remote link
- snprintf(error, sizeof(error),
- "<HTML><HEAD><TITLE>Error - %s</TITLE></HEAD>"
- "<BODY><H2>Error - %s</H2>"
- "<P>Unable to find the address at <A HREF=\"%s\">%s</A></P>"
- "<P><LI>No handler exists for this URI scheme</LI></P>",
- strerror(errno), strerror(errno), namep, namep);
- value_ = strdup(error); // Duplicate
- }
- else // Local link
- {
- if (!strncmp(namep, "file:", 5)) namep += 5; // Adjust for file:
- if ((filep = fopen(namep, "rb"))) { // Binary - rem'd != 0
- fseek(filep, 0, SEEK_END);
- len = ftell(filep);
- rewind(filep); // like fseek(fp, 0, SEEK_SET)
- value_ = (const char *)calloc(len + 1, 1); // malloc but zero'd
- fsize = fread((void *)value_, 1, len, filep);
- fclose(filep);
- }
- else { // File not opened
- snprintf(error, sizeof(error),
- "<HTML><HEAD><TITLE>Error - File not found</TITLE></HEAD>"
- "<BODY><H2>Error - File not found</H2>"
- "<P>Unable to find the file at %s</P>"
- "<P><LI><A HREF=\"javascript:history.back()\">Back</A></LI></P>",
- namep);
- value_ = strdup(error); // Duplicate
- }
- }
- //printf(" load d->ltop=%d d->top=%d topline()=%d\n",d->ltop,d->top,topline());
- if (!(!(d->nstyle & HV_NONAVIGATE) && d->isnav) && d->islink)
- d->ltop = d->top; // leave if user nav and nav link, link clicked
- format();
- if (target) // Target in link
- topline(target);
- else
- topline(0);
- if (!(d->nstyle & HV_NONAVIGATE) && d->isnav) {
- topline(d->ltop); // user navigation and is nav link
- d->isnav = 0; // reset isnav
- }
- if (!strcmp(d->path, d->lpath)) topline(d->ltop); // remote link
- if (d->islink) d->top = topline(); // link clicked, set top
- leftline(0); // added
- return 0; // File was loaded, success
- } // Fl_Help_View::load()
- //
- // Fl_Help_View::load_css() - Loads a css file.
- //
- int // O - 0 if file loaded, -1 if error
- Fl_Help_View::load_css(const char *fp) // I - file to load
- {
- FILE *filep; // file to read from
- size_t fsize; // file size
- int ti = 0,
- tj = 0,
- isblock = 0,
- isstr = 0,
- tcount = 0,
- tstart = 0,
- *tpi; // temp vars
- long len = 0; // length of file
- const char *namep; // local filename
- char *tp; // temp ptr
- namep = fp;
- if (!namep) return -1; // no file handle, fail
- if (!d->cssurl) { // first url
- d->cssurllen = 1;
- d->cssurl = (char *)calloc(1024, 1); // init zero'd
- strlcpy(d->cssurl, namep, 1024);
- }
- else { // next url
- for (ti = 0; ti < d->cssurllen; ti ++) {
- tp = d->cssurl + (ti * 1024);
- if (!strcmp(tp, namep)) len = 1; // url match
- }
- if (len != 1) { // no match, add new url
- d->cssurl = (char *)realloc((void *)d->cssurl, (d->cssurllen + 1) * 1024);
- tp = d->cssurl + (d->cssurllen * 1024);
- strlcpy(tp, namep, 1024);
- d->cssurllen ++;
- }
- }
- if (len == 1) return -1; // url match, fail
- if (!strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) ||
- !strncmp(namep, "https:", 6))
- {
- return -1; // remote link, fail
- }
- else // local link
- {
- if (!strncmp(namep, "file:", 5)) namep += 5; // adjust for file:
- if ((filep = fopen(namep, "rb"))) { // binary - rem'd != 0
- fseek(filep, 0, SEEK_END);
- len = ftell(filep);
- rewind(filep); // like fseek(fp, 0, SEEK_SET)
- if (!d->csstext) { // first file
- d->csstext = (char *)calloc(len + 1, 1); // init zero'd
- tp = d->csstext;
- d->csstextlen = len;
- }
- else { // next file
- d->csstext = (char *)realloc((void *)d->csstext, d->csstextlen + len + 1);
- tp = d->csstext + d->csstextlen;
- tstart = d->csstextlen; // start of file
- d->csstextlen += len; // total file length
- }
- *(tp + len) = '\0'; // nul-terminate file
- fsize = fread((void *)tp, 1, len, filep);
- fclose(filep);
- for (ti = 0; ti < len; ti ++) { // count words
- if (isspace(*(tp + ti))) tj = 0; // no word
- else tj ++; // letter count
- if (*(tp + ti) == '{') { tj = 1; isblock = 1; } // block
- if (*(tp + ti) == '"') { if (isstr) isstr = 0; else isstr = 1; } // string
- if (!isblock) { // outside block
- if (*(tp + ti) == ',') { // special char
- tj = 1; ti ++;
- while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space
- }
- }
- else if (!isstr) { // inside block - ignore if in string
- if (*(tp + ti) == ':' || *(tp + ti) == ';') { // special char
- tj = 1; ti ++;
- while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space
- }
- }
- if (*(tp + ti) == '}') { tj = 1; isblock = 0; } // block
- if (tj == 1) tcount ++; // next word
- if (*(tp + ti) == '{' || *(tp + ti) == '}') tj = 0; // single char word
- }
- if (!d->cssword) { // first file
- d->cssword = (int *)calloc(tcount + 1, sizeof(int)); // init zero'd
- tpi = d->cssword;
- d->csswordlen = tcount;
- }
- else { // next file
- d->cssword = (int *)realloc((void *)d->cssword, (d->csswordlen + tcount + 1) * sizeof(int));
- tpi = d->cssword + d->csswordlen;
- d->csswordlen += tcount; // total word count
- }
- *(tpi + tcount) = d->csstextlen; // set last int
- for (ti = 0, isblock = 0, isstr = 0, tcount = 0; ti < len; ti ++) { // store word offsets
- if (isspace(*(tp + ti))) tj = 0; // no word
- else tj ++; // letter count
- if (*(tp + ti) == '{') { tj = 1; isblock = 1; } // block
- if (*(tp + ti) == '"') { if (isstr) isstr = 0; else isstr = 1; } // string
- if (!isblock) { // outside block
- if (*(tp + ti) == ',') { // special char
- tj = 1; ti ++;
- while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space
- }
- }
- else if (!isstr) { // inside block - ignore if in string
- if (*(tp + ti) == ':' || *(tp + ti) == ';') { // special char
- tj = 1; ti ++;
- while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space
- }
- }
- if (*(tp + ti) == '}') { tj = 1; isblock = 0; } // block
- if (tj == 1) {
- *(tpi + tcount) = ti + tstart; // word offset
- tcount ++; // next word
- if (*(tp + ti) == '{' || *(tp + ti) == '}') tj = 0; // single char word
- }
- }
- }
- else
- return -1; // file not opened, failure
- }
- return 0; // file was loaded, success
- } // Fl_Help_View::load_css()
- //
- // Fl_Help_View::parse_css() - Parses all supported css properties.
- //
- void Fl_Help_View::parse_css(Fl_Help_Block &b, // O - current block
- const char *sp, // I - selector ptr
- char *buf) // O - text buffer
- {
- if (get_css_value(sp, "background-color", buf)) // background
- b.bgcolor = get_color(buf, color());
- // todo: image/repeat/attachment/position
- if (get_css_value(sp, "font-family", buf)) // font
- b.font = font_face(buf); // altered by style & weight
- if (get_css_value(sp, "font-style", buf)) {
- if (!strncasecmp(buf, "italic", 6) ||
- !strncasecmp(buf, "oblique", 7))
- b.font = font_style(b.font, FL_ITALIC);
- }
- if (get_css_value(sp, "font-weight", buf)) {
- if (!strncasecmp(buf, "bold", 4))
- b.font = font_style(b.font, FL_BOLD);
- }
- if (get_css_value(sp, "font-size", buf)) {
- b.fsize = get_font_size(buf) + 2;
- }
- return;
- } // Fl_Help_View::parse_css()
- //
- // Fl_Help_View::popfont() - Pop from font stack.
- //
- void Fl_Help_View::popfont(int &fi,
- unsigned char &fs) { // pop font
- if (d->nfonts > 0) d->nfonts --;
- fl_font(fi = d->fonts[d->nfonts][0], fs = d->fonts[d->nfonts][1]);
- }
- //
- // Fl_Help_View::pushfont() - Push to font stack.
- //
- void Fl_Help_View::pushfont(int fi,
- unsigned char fs) { // push font
- if (d->nfonts < 99) d->nfonts ++;
- fl_font(d->fonts[d->nfonts][0] = fi, d->fonts[d->nfonts][1] = fs);
- }
- //
- // Fl_Help_View::resize() - Resize the help widget.
- //
- void Fl_Help_View::resize(int xx, // I - New left position
- int yy, // I - New top position
- int ww, // I - New width
- int hh) // I - New height
- {
- long time = 0,
- sec = 0,
- mil = 0; // timer vars
- Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // box to draw
- Fl_Widget::resize(xx, yy, ww, hh); // Resize help widget
- int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
- scrollbar_.resize(x() + w() - scrollsize - Fl::box_dw(bt) + Fl::box_dx(bt),
- y() + Fl::box_dy(bt), scrollsize, h() - scrollsize - Fl::box_dh(bt));
- hscrollbar_.resize(x() + Fl::box_dx(bt),
- y() + h() - scrollsize - Fl::box_dh(bt) + Fl::box_dy(bt),
- w() - scrollsize - Fl::box_dw(bt), scrollsize);
- // delay calls to format to avoid hangs on very large pages
- if (abs(w() - d->rwidth) > 2) { // moved more than 2 pixels
- fl_gettime(&sec, &mil); // find how long since last format
- time = MIL(d->rsec, d->rmil, sec, mil);
- if (time > d->rtime || !d->resized) { // enough time has passed
- d->resized = 1; // set d->resized
- format();
- fl_gettime(&d->rsec, &d->rmil); // find how long this format took
- d->rtime = MIL(d->rsec, d->rmil, sec, mil);
- d->rtime /= 2; // wait half the time format took
- d->rwidth = w(); // store window width
- }
- }
- } // Fl_Help_View::resize()
- //
- // Fl_Help_View::select_all() - Select all text.
- //
- void Fl_Help_View::select_all()
- {
- clear_global_selection();
- if (!value_) return;
- current_view = this;
- selection_drag_last = selection_last = strlen(value_);
- selected = 1;
- } // Fl_Help_View::select_all()
- //
- // Fl_Help_View::setstyle() - set the html style flag
- //
- void Fl_Help_View::setstyle(int flag) // I - style flag to set
- {
- d->nstyle = flag; // wasn't working as a method..
- }
- //
- // Fl_Help_View::topline() - Set the top line to the named target.
- //
- void Fl_Help_View::topline(const char *np) // I - Target name
- {
- Fl_Help_Link key, // Target name key
- *target; // Pointer to matching target
- if (ntargets_ == 0) return;
- strlcpy(key.name, np, sizeof(key.name));
- target = (Fl_Help_Link *)bsearch(&key, d->targets, ntargets_,
- sizeof(Fl_Help_Link),
- (compare_func_t)cmp_targets);
- if (target) topline(target->y); // Target found - rem'd != 0
- } // Fl_Help_View::topline()
- //
- // Fl_Help_View::topline() - Set the top line by number.
- //
- void Fl_Help_View::topline(int yy) // I - Top line number
- {
- if (!value_) return;
- int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
- if (size_ < h() - scrollsize || yy < 0)
- yy = 0;
- else if (yy > size_)
- yy = size_;
- topline_ = yy;
- scrollbar_.value(topline_, h() - scrollsize, 0, size_);
- do_callback();
- redraw(); // Set widget to draw
- d->top = topline_; // set top
- } // Fl_Help_View::topline()
- //
- // Fl_Help_View::value() - Set the help text directly.
- //
- // Note: called by nav buttons, also after follow_link
- void Fl_Help_View::value(const char *tp) // I - Text to view
- {
- if (!tp) return; // Null
- char target[32]; // current target
- target[0] = '\0';
- if (d->islink) { // link clicked
- if (d->linkp) // link exists
- strlcpy(target, d->linkp->name, sizeof(target));
- d->islink = 0; // reset islink
- if (!(d->nstyle & HV_NONAVIGATE)) return; // file was loaded
- }
- if (!tp[0]) { // text buffer empty
- char error[1024]; // error buffer
- const char *namep = 0; // local filename
- if (d->ispath) namep = d->path; // path is used
- else if (filename_[0]) namep = filename_;
- if (!namep[0]) namep = "(null)";
- if (!strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) ||
- !strncmp(namep, "https:", 6) || !strncmp(namep, "ipp:", 4) ||
- !strncmp(namep, "mailto:", 7) || !strncmp(namep, "news:", 5)) {
- snprintf(error, sizeof(error),
- "<HTML><HEAD><TITLE>Error - Server not found</TITLE></HEAD>"
- "<BODY><H2>Error - Server not found</H2>"
- "<P>Unable to find the address at <A HREF=\"%s\">%s</A></P>"
- "<P><LI>No handler exists for this URI scheme</LI></P>",
- namep, namep);
- }
- else {
- snprintf(error, sizeof(error),
- "<HTML><HEAD><TITLE>Error - File not found</TITLE></HEAD>"
- "<BODY><H2>Error - File not found</H2>"
- "<P>Unable to find the file at %s</P>", namep);
- if (d->lpath[0]) // last path exists
- snprintf(error + strlen(error), sizeof(error) - strlen(error),
- "<P><LI><A HREF=\"javascript:history.back()\">Back</A></P>");
- }
- clear_selection(); // clear text selection
- set_changed(); // set widget value was changed
- free_data(); // free last document
- value_ = strdup(error); // duplicate
- format();
- topline(0);
- leftline(0);
- return; // we're done
- }
- //printf(" value target=(%s) d->ispath=%d\n",target,d->ispath);
- //printf(" value d->path=(%s) d->islink=%d\n",d->path,d->islink);
- clear_selection(); // Clear text selection
- set_changed(); // Set widget value was changed
- free_data(); // Free last document
- value_ = strdup(tp); // Duplicate
- if (d->islink) d->ltop = d->top; // link clicked, last top
- format();
- if (target[0]) // new link with target
- topline(target); // set position on page
- else // no target
- topline(0);
- if (d->islink) d->top = topline(); // link clicked, set top
- leftline(0);
- } // Fl_Help_View::value()
- //
- // Fl_Help_View::~Fl_Help_View() - Destroy a Fl_Help_View widget.
- //
- Fl_Help_View::~Fl_Help_View()
- {
- clear_selection(); // Clear text selection
- free_data(); // Free last document
- free(d); // free d-pointer
- } // Fl_Help_View::~Fl_Help_View()
- //
- // 'command()' - Convert a command with up to four letters into an uint.
- //
- static unsigned int // O - Fourcc int
- command(const char *cmdp) // I - Command pointer
- {
- unsigned int ret = (tolower(cmdp[0]) << 24);
- char cc = cmdp[1];
- if (cc == '>' || cc == ' ' || cc == 0) return ret;
- ret |= (tolower(cc) << 16);
- cc = cmdp[2];
- if (cc == '>' || cc == ' ' || cc == 0) return ret;
- ret |= (tolower(cc) << 8);
- cc = cmdp[3];
- if (cc == '>' || cc == ' ' || cc == 0) return ret;
- ret |= tolower(cc);
- cc = cmdp[4];
- if (cc == '>' || cc == ' ' || cc == 0) return ret;
- return 0;
- } // command()
- //
- // 'quote_char()' - Return the character code associated with a quoted char.
- //
- static int // O - Code or -1 on error
- quote_char(const char *qp, // I - Quoted string
- int fc) // I - true to return what font char uses, opt
- {
- // updated table to HTML 4
- // http://www.alanwood.net/demos/ansi.html
- static struct
- {
- const char *name; // str pointer
- int namelen, // str length
- cdata, // character reference data
- code, // ANSI/Unicode char code
- mac, // Mac Roman char code
- sym; // what font does char use? 0 = current, 1 = Symbol
- }
- *nameptr, // pointer into names array
- names[] = // quoting names
- {
- //should be ordered for binary search
- { "AElig;", 6, 198, 198, 174, ENC(0,0) }, // Latin capital AE
- { "Aacute;", 7, 193, 193, 231, ENC(0,0) }, // Latin capital A acute
- { "Acirc;", 6, 194, 194, 229, ENC(0,0) }, // Latin capital A circumflex
- { "Agrave;", 7, 192, 192, 203, ENC(0,0) }, // Latin capital A grave
- { "Alpha;", 6, 913, 'A', 'A', ENC(1,1) }, // Greek capital Alpha
- { "Aring;", 6, 197, 197, 129, ENC(0,0) }, // Latin capital A ring above
- { "Atilde;", 7, 195, 195, 204, ENC(0,0) }, // Latin capital A tilde
- { "Auml;", 5, 196, 196, 128, ENC(0,0) }, // Latin capital A umlaut
- { "Beta;", 5, 914, 'B', 'B', ENC(1,1) }, // Greek capital Beta
- { "Ccedil;", 7, 199, 199, 130, ENC(0,0) }, // Latin capital C cedilla
- { "Chi;", 4, 935, 'C', 'C', ENC(1,1) }, // Greek capital Chi
- { "Dagger;", 7, 8225, 135, 224, ENC(0,0) }, // double dagger
- { "Delta;", 6, 916, 'D', 'D', ENC(1,1) }, // Greek capital Delta
- { "ETH;", 4, 208, 208, 198, ENC(0,1) }, // Latin capital ETH *
- { "Eacute;", 7, 201, 201, 131, ENC(0,0) }, // Latin capital E acute
- { "Ecirc;", 6, 202, 202, 230, ENC(0,0) }, // Latin capital E circumflex
- { "Egrave;", 7, 200, 200, 233, ENC(0,0) }, // Latin capital E grave
- { "Epsilon;",8, 917, 'E', 'E', ENC(1,1) }, // Greek capital Epsilon
- { "Eta;", 4, 919, 'H', 'H', ENC(1,1) }, // Greek capital Eta
- { "Euml;", 5, 203, 203, 232, ENC(0,0) }, // Latin capital E umlaut
- { "Gamma;", 6, 915, 'G', 'G', ENC(1,1) }, // Greek capital Gamma
- { "Iacute;", 7, 205, 205, 234, ENC(0,0) }, // Latin capital I acute
- { "Icirc;", 6, 206, 206, 235, ENC(0,0) }, // Latin capital I circumflex
- { "Igrave;", 7, 204, 204, 237, ENC(0,0) }, // Latin capital I grave
- { "Iota;", 5, 921, 'I', 'I', ENC(1,1) }, // Greek capital Iota
- { "Iuml;", 5, 207, 207, 236, ENC(0,0) }, // Latin capital I umlaut
- { "Kappa;", 6, 922, 'K', 'K', ENC(1,1) }, // Greek capital Kappa
- { "Lambda;", 7, 923, 'L', 'L', ENC(1,1) }, // Greek capital Lambda
- { "Mu;", 3, 924, 'M', 'M', ENC(1,1) }, // Greek capital Mu
- { "Ntilde;", 7, 209, 209, 132, ENC(0,0) }, // Latin capital N tilde
- { "Nu;", 3, 925, 'N', 'N', ENC(1,1) }, // Greek capital Nu
- { "OElig;", 6, 338, 140, 206, ENC(0,0) }, // Latin capital ligature OE
- { "Oacute;", 7, 211, 211, 238, ENC(0,0) }, // Latin capital O acute
- { "Ocirc;", 6, 212, 212, 239, ENC(0,0) }, // Latin capital O circumflex
- { "Ograve;", 7, 210, 210, 241, ENC(0,0) }, // Latin capital O grave
- { "Omega;", 6, 937, 'W', 'W', ENC(1,1) }, // Greek capital Omega # 189 in Mac Roman
- { "Omicron;",8, 927, 'O', 'O', ENC(1,1) }, // Greek capital Omicron
- { "Oslash;", 7, 216, 216, 175, ENC(0,0) }, // Latin capital O stroke
- { "Otilde;", 7, 213, 213, 205, ENC(0,0) }, // Latin capital O tilde
- { "Ouml;", 5, 214, 214, 133, ENC(0,0) }, // Latin capital O umlaut
- { "Phi;", 4, 934, 'F', 'F', ENC(1,1) }, // Greek capital Phi
- { "Pi;", 3, 928, 'P', 'P', ENC(1,1) }, // Greek capital Pi
- { "Prime;", 6, 8243, 178, 178, ENC(1,1) }, // double prime
- { "Psi;", 4, 936, 'Y', 'Y', ENC(1,1) }, // Greek capital Psi
- { "Rho;", 4, 929, 'R', 'R', ENC(1,1) }, // Greek capital Rho
- { "Scaron;", 7, 352, 138, 223, ENC(0,1) }, // Latin capital S caron *
- { "Sigma;", 6, 931, 'S', 'S', ENC(1,1) }, // Greek capital Sigma
- { "THORN;", 6, 222, 222, 167, ENC(0,1) }, // Latin capital THORN *
- { "Tau;", 4, 932, 'T', 'T', ENC(1,1) }, // Greek capital Tau
- { "Theta;", 6, 920, 'Q', 'Q', ENC(1,1) }, // Greek capital Theta
- { "Uacute;", 7, 218, 218, 242, ENC(0,0) }, // Latin capital U acute
- { "Ucirc;", 6, 219, 219, 243, ENC(0,0) }, // Latin capital U circumflex
- { "Ugrave;", 7, 217, 217, 244, ENC(0,0) }, // Latin capital U grave
- { "Upsilon;",8, 933, 'U', 'U', ENC(1,1) }, // Greek capital Upsilon
- { "Uuml;", 5, 220, 220, 134, ENC(0,0) }, // Latin capital U umlaut
- { "Xi;", 3, 926, 'X', 'X', ENC(1,1) }, // Greek capital Xi
- { "Yacute;", 7, 221, 221, 217, ENC(0,1) }, // Latin capital Y acute *
- { "Yuml;", 5, 376, 159, 217, ENC(0,0) }, // Latin capital Y umlaut
- { "Zeta;", 5, 918, 'Z', 'Z', ENC(1,1) }, // Greek capital Zeta
- { "aacute;", 7, 225, 225, 135, ENC(0,0) }, // Latin small a acute
- { "acirc;", 6, 226, 226, 137, ENC(0,0) }, // Latin small a circumflex
- { "acute;", 6, 180, 180, 171, ENC(0,0) }, // acute accent
- { "aelig;", 6, 230, 230, 190, ENC(0,0) }, // Latin small ae
- { "agrave;", 7, 224, 224, 136, ENC(0,0) }, // Latin small a grave
- { "alefsym;",8, 8501, 192, 192, ENC(1,1) }, // alef symbol
- { "alpha;", 6, 945, 'a', 'a', ENC(1,1) }, // Greek small alpha
- { "amp;", 4, 38, '&', '&', ENC(0,0) }, // ampersand
- { "and;", 4, 8743, 217, 217, ENC(1,1) }, // logical and
- { "ang;", 4, 8736, 208, 208, ENC(1,1) }, // angle
- { "aring;", 6, 229, 229, 140, ENC(0,0) }, // Latin small a ring above
- { "asymp;", 6, 8776, 187, 197, ENC(1,0) }, // almost equal to #
- { "atilde;", 7, 227, 227, 139, ENC(0,0) }, // Latin small a tilde
- { "auml;", 5, 228, 228, 138, ENC(0,0) }, // Latin small a umlaut
- { "bdquo;", 6, 8222, 132, 227, ENC(0,0) }, // double low-9 quotation mark
- { "beta;", 5, 946, 'b', 'b', ENC(1,1) }, // Greek small beta
- { "brvbar;", 7, 166, 166, 240, ENC(0,1) }, // broken bar *
- { "bull;", 5, 8226, 183, 165, ENC(1,0) }, // bullet
- { "cap;", 4, 8745, 199, 199, ENC(1,1) }, // intersection
- { "ccedil;", 7, 231, 231, 141, ENC(0,0) }, // Latin small c cedilla
- { "cedil;", 6, 184, 184, 252, ENC(0,0) }, // cedilla
- { "cent;", 5, 162, 162, 162, ENC(0,0) }, // cent sign
- { "chi;", 4, 967, 'c', 'c', ENC(1,1) }, // Greek small chi
- { "circ;", 5, 710, 136, 246, ENC(0,0) }, // modifier circumflex accent
- { "clubs;", 6, 9827, 167, 167, ENC(1,1) }, // black club suit
- { "cong;", 5, 8773, '@', '@', ENC(1,1) }, // approximately equal to
- { "copy;", 5, 169, 169, 169, ENC(0,0) }, // copyright sign
- { "crarr;", 6, 8629, 191, 191, ENC(1,1) }, // carriage return arrow
- { "cup;", 4, 8746, 200, 200, ENC(1,1) }, // union
- { "curren;", 7, 164, 164, 251, ENC(0,1) }, // currency sign *
- { "dArr;", 5, 8659, 223, 223, ENC(1,1) }, // down double arrow
- { "dagger;", 7, 8224, 134, 160, ENC(0,0) }, // dagger
- { "darr;", 5, 8595, 175, 175, ENC(1,1) }, // down arrow
- { "deg;", 4, 176, 176, 161, ENC(0,0) }, // degree sign
- { "delta;", 6, 948, 'd', 'd', ENC(1,1) }, // Greek small delta
- { "diams;", 6, 9830, 168, 168, ENC(1,1) }, // black diamond suit
- { "divide;", 7, 247, 247, 214, ENC(0,0) }, // division sign
- { "eacute;", 7, 233, 233, 142, ENC(0,0) }, // Latin small e acute
- { "ecirc;", 6, 234, 234, 144, ENC(0,0) }, // Latin small e circumflex
- { "egrave;", 7, 232, 232, 143, ENC(0,0) }, // Latin small e grave
- { "empty;", 6, 8709, 198, 198, ENC(1,1) }, // empty set
- { "emsp;", 5, 8195, ' ', ' ', ENC(0,0) }, // em space - NA
- { "ensp;", 5, 8194, ' ', ' ', ENC(0,0) }, // en space - NA
- { "epsilon;",8, 949, 'e', 'e', ENC(1,1) }, // Greek small epsilon
- { "equiv;", 6, 8801, 186, 186, ENC(1,1) }, // identical to
- { "eta;", 4, 951, 'h', 'h', ENC(1,1) }, // Greek small eta
- { "eth;", 4, 240, 240, 182, ENC(0,1) }, // Latin small eth *
- { "euml;", 5, 235, 235, 145, ENC(0,0) }, // Latin small e umlaut
- { "euro;", 5, 8364, 'C', 219, ENC(0,0) }, // euro sign
- { "exist;", 6, 8707, '$', '$', ENC(1,1) }, // there exists
- { "fnof;", 5, 402, 166, 196, ENC(1,0) }, // Latin small f hook
- { "forall;", 7, 8704, '\"','\"',ENC(1,1) }, // for all
- { "frac12;", 7, 189, 189, 255, ENC(0,1) }, // vulgar fraction 1/2 *
- { "frac14;", 7, 188, 188, 254, ENC(0,1) }, // vulgar fraction 1/4 *
- { "frac34;", 7, 190, 190, 250, ENC(0,1) }, // vulgar fraction 3/4 *
- { "frasl;", 6, 8260, 164, 218, ENC(1,0) }, // fraction slash #
- { "gamma;", 6, 947, 'g', 'g', ENC(1,1) }, // Greek small gamma
- { "ge;", 3, 8805, 179, 179, ENC(1,0) }, // greater-than or equal to #
- { "gt;", 3, 62, '>', '>', ENC(0,0) }, // greater-than sign
- { "hArr;", 5, 8660, 219, 219, ENC(1,1) }, // horizontal double arrow
- { "harr;", 5, 8596, 171, 171, ENC(1,1) }, // horizontal arrow
- { "hearts;", 7, 9829, 169, 169, ENC(1,1) }, // black heart suit
- { "hellip;", 7, 8230, 188, 201, ENC(1,0) }, // horizontal ellipsis
- { "iacute;", 7, 237, 237, 146, ENC(0,0) }, // Latin small i acute
- { "icirc;", 6, 238, 238, 148, ENC(0,0) }, // Latin small i circumflex
- { "iexcl;", 6, 161, 161, 193, ENC(0,0) }, // inverted exclamation mark
- { "igrave;", 7, 236, 236, 147, ENC(0,0) }, // Latin small i grave
- { "image;", 6, 8465, 193, 193, ENC(1,1) }, // blackletter capital I, imaginary part
- { "infin;", 6, 8734, 165, 176, ENC(1,0) }, // infinity #
- { "int;", 4, 8747, 242, 186, ENC(1,0) }, // integral #
- { "iota;", 5, 953, 'i', 'i', ENC(1,1) }, // Greek small iota
- { "iquest;", 7, 191, 191, 192, ENC(0,0) }, // inverted question mark
- { "isin;", 5, 8712, 206, 206, ENC(1,1) }, // element of
- { "iuml;", 5, 239, 239, 149, ENC(0,0) }, // Latin small i umlaut
- { "kappa;", 6, 954, 'k', 'k', ENC(1,1) }, // Greek small kappa
- { "lArr;", 5, 8656, 220, 220, ENC(1,1) }, // left double arrow
- { "lambda;", 7, 955, 'l', 'l', ENC(1,1) }, // Greek small lambda
- { "lang;", 5, 9001, 225, 225, ENC(1,1) }, // left-pointing angle bracket
- { "laquo;", 6, 171, 171, 199, ENC(0,0) }, // left double angle quotation
- { "larr;", 5, 8592, 172, 172, ENC(1,1) }, // left arrow
- { "lceil;", 6, 8968, 233, 233, ENC(1,1) }, // left ceiling
- { "ldquo;", 6, 8220, 147, 210, ENC(0,0) }, // left double quotation mark
- { "le;", 3, 8804, 163, 178, ENC(1,0) }, // less-than or equal to #
- { "lfloor;", 7, 8970, 235, 235, ENC(1,1) }, // left floor
- { "lowast;", 7, 8727, '*', '*', ENC(1,1) }, // asterisk operator
- { "loz;", 4, 9674, 224, 215, ENC(1,0) }, // lozenge #
- { "lrm;", 4, 8206, ' ', ' ', ENC(0,0) }, // left-to-right mark - NA
- { "lsaquo;", 7, 8249, 225, 220, ENC(1,0) }, // single left angle quotation
- { "lsquo;", 6, 8216, 145, 212, ENC(0,0) }, // left single quotation mark
- { "lt;", 3, 60, '<', '<', ENC(0,0) }, // less-than sign
- { "macr;", 5, 175, 175, 248, ENC(0,0) }, // macron
- { "mdash;", 6, 8212, 190, 209, ENC(1,0) }, // em dash
- { "micro;", 6, 181, 181, 181, ENC(0,0) }, // micro sign
- { "middot;", 7, 183, 183, 225, ENC(0,0) }, // middle dot
- { "minus;", 6, 8722, 190, 190, ENC(1,1) }, // minus sign
- { "mu;", 3, 956, 'm', 'm', ENC(1,1) }, // Greek small mu
- { "nabla;", 6, 8711, 209, 209, ENC(1,1) }, // nabla
- { "nbsp;", 5, 160, ' ', ' ', ENC(0,0) }, // no-break space, 160/202
- { "ndash;", 6, 8211, '-', 208, ENC(1,0) }, // en dash
- { "ne;", 3, 8800, 185, 173, ENC(1,0) }, // not equal to #
- { "ni;", 3, 8715, '\'','\'',ENC(1,1) }, // contains as member
- { "not;", 4, 172, 172, 194, ENC(0,0) }, // not sign
- { "notin;", 6, 8713, 207, 207, ENC(1,1) }, // not an element of
- { "nsub;", 5, 8836, 203, 203, ENC(1,1) }, // not a subset of
- { "ntilde;", 7, 241, 241, 150, ENC(0,0) }, // Latin small n tilde
- { "nu;", 3, 957, 'n', 'n', ENC(1,1) }, // Greek small nu
- { "oacute;", 7, 243, 243, 151, ENC(0,0) }, // Latin small o acute
- { "ocirc;", 6, 244, 244, 153, ENC(0,0) }, // Latin small o circumflex
- { "oelig;", 6, 339, 156, 207, ENC(0,0) }, // Latin small ligature oe
- { "ograve;", 7, 242, 242, 152, ENC(0,0) }, // Latin small o grave
- { "oline;", 6, 8254, '_', '_', ENC(1,1) }, // overline
- { "omega;", 6, 969, 'w', 'w', ENC(1,1) }, // Greek small omega
- { "omicron;",8, 959, 'o', 'o', ENC(1,1) }, // Greek small omicron
- { "oplus;", 6, 8853, 197, 197, ENC(1,1) }, // circled plus
- { "or;", 3, 8744, 218, 218, ENC(1,1) }, // logical or
- { "ordf;", 5, 170, 170, 187, ENC(0,0) }, // feminine ordinal indicator
- { "ordm;", 5, 186, 186, 188, ENC(0,0) }, // masculine ordinal indicator
- { "oslash;", 7, 248, 248, 191, ENC(0,0) }, // Latin small o stroke
- { "otilde;", 7, 245, 245, 155, ENC(0,0) }, // Latin small o tilde
- { "otimes;", 7, 8855, 196, 196, ENC(1,1) }, // circled times
- { "ouml;", 5, 246, 246, 154, ENC(0,0) }, // Latin small o umlaut
- { "para;", 5, 182, 182, 166, ENC(0,0) }, // pilcrow sign
- { "part;", 5, 8706, 182, 182, ENC(1,0) }, // partial differential #
- { "permil;", 7, 8240, 137, 228, ENC(0,0) }, // per mille sign
- { "perp;", 5, 8869, '^', '^', ENC(1,1) }, // up tack
- { "phi;", 4, 966, 'j', 'j', ENC(1,1) }, // Greek small phi, 'f' is phi variant
- { "pi;", 3, 960, 'p', 'p', ENC(1,1) }, // Greek small pi # 185 in Mac Roman
- { "piv;", 4, 982, 'v', 'v', ENC(1,1) }, // Greek small pi variant
- { "plusmn;", 7, 177, 177, 177, ENC(0,0) }, // plus-minus sign
- { "pound;", 6, 163, 163, 163, ENC(0,0) }, // pound sign
- { "prime;", 6, 8242, 162, 162, ENC(1,1) }, // prime
- { "prod;", 5, 8719, 213, 184, ENC(1,0) }, // n-ary product #
- { "prop;", 5, 8733, 181, 181, ENC(1,1) }, // proportional to
- { "psi;", 4, 968, 'y', 'y', ENC(1,1) }, // Greek small psi
- { "quot;", 5, 34, '\"','\"',ENC(0,0) }, // quotation mark
- { "rArr;", 5, 8658, 222, 222, ENC(1,1) }, // right double arrow
- { "radic;", 6, 8730, 214, 195, ENC(1,0) }, // square root #
- { "rang;", 5, 9002, 241, 241, ENC(1,1) }, // right-pointing angle bracket
- { "raquo;", 6, 187, 187, 200, ENC(0,0) }, // right double angle quotation
- { "rarr;", 5, 8594, 174, 174, ENC(1,1) }, // right arrow
- { "rceil;", 6, 8969, 249, 249, ENC(1,1) }, // right ceiling
- { "rdquo;", 6, 8221, 148, 211, ENC(0,0) }, // right double quotation mark
- { "real;", 5, 8476, 194, 194, ENC(1,1) }, // blackletter capital R, real part
- { "reg;", 4, 174, 174, 168, ENC(0,0) }, // registered sign
- { "rfloor;", 7, 8971, 251, 251, ENC(1,1) }, // right floor
- { "rho;", 4, 961, 'r', 'r', ENC(1,1) }, // Greek small rho
- { "rlm;", 4, 8207, ' ', ' ', ENC(0,0) }, // right-to-left mark - NA
- { "rsaquo;", 7, 8250, 241, 221, ENC(1,0) }, // single right angle quotation
- { "rsquo;", 6, 8217, 146, 213, ENC(0,0) }, // right single quotation mark
- { "sbquo;", 6, 8218, 130, 226, ENC(0,0) }, // single low-9 quotation mark
- { "scaron;", 7, 353, 154, 222, ENC(0,1) }, // Latin small s caron *
- { "sdot;", 5, 8901, 215, 215, ENC(1,1) }, // dot operator
- { "sect;", 5, 167, 167, 164, ENC(0,0) }, // section sign
- { "shy;", 4, 173, 173, '-', ENC(0,0) }, // soft hyphen
- { "sigma;", 6, 962, 's', 's', ENC(1,1) }, // Greek small sigma
- { "sigmaf;", 7, 963, 'V', 'V', ENC(1,1) }, // Greek small sigma final variant
- { "sim;", 4, 8764, '~', '~', ENC(1,1) }, // tilde operator
- { "spades;", 7, 9824, 170, 170, ENC(1,1) }, // black spade suit
- { "sub;", 4, 8834, 204, 204, ENC(1,1) }, // subset of
- { "sube;", 5, 8838, 205, 205, ENC(1,1) }, // subset of or equal to
- { "sum;", 4, 8721, 229, 183, ENC(1,0) }, // n-ary summation #
- { "sup1;", 5, 185, 185, 245, ENC(0,1) }, // superscript one *
- { "sup2;", 5, 178, 178, 253, ENC(0,1) }, // superscript two *
- { "sup3;", 5, 179, 179, 249, ENC(0,1) }, // superscript three *
- { "sup;", 4, 8835, 201, 201, ENC(1,1) }, // superset of
- { "supe;", 5, 8839, 202, 202, ENC(1,1) }, // superset of or equal to
- { "szlig;", 6, 223, 223, 167, ENC(0,0) }, // Latin small sharp s
- { "tau;", 4, 964, 't', 't', ENC(1,1) }, // Greek small tau
- { "there4;", 7, 8756, '\\','\\',ENC(1,1) }, // therefore
- { "theta;", 6, 952, 'q', 'q', ENC(1,1) }, // Greek small theta
- { "thetasym;",9, 977,'J', 'J', ENC(1,1) }, // Greek small theta variant
- { "thinsp;", 7, 8201, ' ', ' ', ENC(0,0) }, // thin space - NA
- { "thorn;", 6, 254, 254, 164, ENC(0,1) }, // Latin small thorn *
- { "tilde;", 6, 732, 152, 247, ENC(0,0) }, // small tilde
- { "times;", 6, 215, 215, 'x', ENC(0,0) }, // multiplication sign
- { "trade;", 6, 8482, 228, 170, ENC(1,0) }, // trade mark sign
- { "uArr;", 5, 8657, 221, 221, ENC(1,1) }, // up double arrow
- { "uacute;", 7, 250, 250, 156, ENC(0,0) }, // Latin small u acute
- { "uarr;", 5, 8593, 173, 173, ENC(1,1) }, // up arrow
- { "ucirc;", 6, 251, 251, 158, ENC(0,0) }, // Latin small u circumflex
- { "ugrave;", 7, 249, 249, 157, ENC(0,0) }, // Latin small u grave
- { "uml;", 4, 168, 168, 172, ENC(0,0) }, // diaeresis/umlaut
- { "upsih;", 6, 978, 161, 111, ENC(1,1) }, // Greek capital upsilon hook variant
- { "upsilon;",8, 965, 'u', 'u', ENC(1,1) }, // Greek small upsilon
- { "uuml;", 5, 252, 252, 159, ENC(0,0) }, // Latin small u umlaut
- { "weierp;", 7, 8472, 195, 195, ENC(1,1) }, // script capital P, power set
- { "xi;", 3, 958, 'x', 'x', ENC(1,1) }, // Greek small xi
- { "yacute;", 7, 253, 253, 216, ENC(0,1) }, // Latin small y acute *
- { "yen;", 4, 165, 165, 180, ENC(0,0) }, // yen sign
- { "yuml;", 5, 255, 255, 216, ENC(0,0) }, // Latin small y umlaut
- { "zeta;", 5, 950, 'z', 'z', ENC(1,1) }, // Greek small zeta
- { "zwj;", 4, 8205, ' ', ' ', ENC(0,0) }, // zero width joiner - NA
- { "zwnj;", 5, 8204, ' ', ' ', ENC(0,0) }, // nzero width non-joiner - NA
- };
- if (!strchr(qp, ';')) return -1; // No semi-colon char
- int ifirst, ilast, temp;
- ilast = ( int ) ( sizeof ( names ) / sizeof ( names[0] ) ) - 1; // array size / element size
- if (*qp == '#') // Numeric character reference
- {
- if (*(qp + 1) == 'x' || *(qp + 1) == 'X') // Hexadecimal number
- temp = strtol(qp + 2, 0, 16); // Base-16 str to long - rem'd NULL
- else // Decimal number
- temp = atoi(qp + 1); // Convert str to int
- if (fc) // check font char arg
- {
- ifirst = 0;
- while ( ifirst <= ilast )
- {
- int mid = ( ifirst + ilast ) / 2; // compute mid point.
- nameptr = names + mid;
- int icmp = strncmp ( qp, nameptr->name, nameptr->namelen );
- if ( icmp > 0 )
- ifirst = mid + 1; // repeat search in top half.
- else if ( icmp < 0 )
- ilast = mid - 1; // repeat search in bottom half.
- else // found it. return
- return nameptr->sym;
- }
- return 0; // cdata not found, use current font
- }
- return temp;
- }
- ifirst = 0;
- while ( ifirst <= ilast )
- {
- int mid = ( ifirst + ilast ) / 2; // compute mid point.
- nameptr = names + mid;
- int icmp = strncmp ( qp, nameptr->name, nameptr->namelen );
- if ( icmp > 0 )
- ifirst = mid + 1; // repeat search in top half.
- else if ( icmp < 0 )
- ilast = mid - 1; // repeat search in bottom half.
- else
- {
- // found it. return
- if(fc) return nameptr->sym;
- return ENC(nameptr->code, nameptr->mac);
- }
- }
- return -1; // Entity character reference not found
- } // quote_char()
- //
- // 'hscrollbar_callback()' - Callback for the horizontal scrollbar.
- //
- static void hscrollbar_callback(Fl_Widget *s, // I - Scrollbar handle
- void *)
- {
- ((Fl_Help_View *)(s->parent()))->leftline(int(((Fl_Scrollbar*)s)->value()));
- } // hscrollbar_callback()
- //
- // 'scrollbar_callback()' - Callback for the scrollbar.
- //
- static void scrollbar_callback(Fl_Widget *s, // I - Scrollbar handle
- void *)
- {
- ((Fl_Help_View *)(s->parent()))->topline(int(((Fl_Scrollbar*)s)->value()));
- } // scrollbar_callback()
- //
- // End of "$Id: Fl_Help_View.cxx 6091 2008-04-11 11:12:16Z matt $".
- //
|