123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396 |
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/config.mk a/config.mk
- --- b/config.mk 1970-01-01 03:00:00.000000000 +0300
- +++ a/config.mk 2021-09-16 09:19:40.891396586 +0300
- @@ -0,0 +1,62 @@
- +#
- +# FreeType 2 configuration rules for UNIX platforms
- +#
- +
- +
- +# Copyright (C) 1996-2021 by
- +# David Turner, Robert Wilhelm, and Werner Lemberg.
- +#
- +# This file is part of the FreeType project, and may only be used, modified,
- +# and distributed under the terms of the FreeType project license,
- +# LICENSE.TXT. By continuing to use, modify, or distribute this file you
- +# indicate that you have read the license and understand and accept it
- +# fully.
- +
- +# We need these declarations here since unix-def.mk is a generated file.
- +PLATFORM_DIR := $(TOP_DIR)/builds/unix
- +PLATFORM := unix
- +
- +have_mk := $(wildcard $(OBJ_DIR)/unix-def.mk)
- +ifneq ($(have_mk),)
- + # We are building FreeType 2 not in the src tree.
- + include $(OBJ_DIR)/unix-def.mk
- + include $(OBJ_DIR)/unix-cc.mk
- +else
- + include $(PLATFORM_DIR)/unix-def.mk
- + include $(PLATFORM_DIR)/unix-cc.mk
- +endif
- +
- +ifdef BUILD_PROJECT
- +
- + .PHONY: clean_project distclean_project
- +
- + # Now include the main sub-makefile. It contains all the rules used to
- + # build the library with the previous variables defined.
- + #
- + include $(TOP_DIR)/builds/$(PROJECT).mk
- +
- +
- + # The cleanup targets.
- + #
- + clean_project: clean_project_unix
- + distclean_project: distclean_project_unix
- +
- +
- + # This final rule is used to link all object files into a single library.
- + # It is part of the system-specific sub-Makefile because not all
- + # librarians accept a simple syntax like
- + #
- + # librarian library_file {list of object files}
- + #
- + $(PROJECT_LIBRARY): $(OBJECTS_LIST)
- + ifdef CLEAN_LIBRARY
- + -$(CLEAN_LIBRARY) $(NO_OUTPUT)
- + endif
- + $(LINK_LIBRARY)
- +
- + include $(TOP_DIR)/builds/unix/install.mk
- +
- +endif
- +
- +
- +# EOF
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/configure a/configure
- --- b/configure 2021-02-13 10:16:54.000000000 +0200
- +++ a/configure 2021-09-16 09:15:05.050379727 +0300
- @@ -13,6 +13,8 @@
- # Call the `configure' script located in `builds/unix'.
- #
-
- +export LDFLAGS="$LDFLAGS -lm"
- +
- rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk
-
- # respect GNUMAKE environment variable for backward compatibility
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/devel/ftoption.h a/devel/ftoption.h
- --- b/devel/ftoption.h 2021-07-15 13:09:04.000000000 +0300
- +++ a/devel/ftoption.h 2021-09-16 09:15:05.050379727 +0300
- @@ -629,6 +629,16 @@
- */
- #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
- + /*************************************************************************/
- + /* */
- + /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */
- + /* all additional infinality patches, which are configured via env */
- + /* variables. */
- + /* */
- + /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */
- + /* defined. */
- + /* */
- +#define FT_CONFIG_OPTION_INFINALITY_PATCHSET
-
- /**************************************************************************
- *
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/include/freetype/config/ftoption.h a/include/freetype/config/ftoption.h
- --- b/include/freetype/config/ftoption.h 2021-07-15 13:09:04.000000000 +0300
- +++ a/include/freetype/config/ftoption.h 2021-09-16 09:15:05.051379735 +0300
- @@ -112,18 +112,21 @@
- #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
-
-
- - /**************************************************************************
- - *
- - * Uncomment the line below if you want to activate LCD rendering
- - * technology similar to ClearType in this build of the library. This
- - * technology triples the resolution in the direction color subpixels. To
- - * mitigate color fringes inherent to this technology, you also need to
- - * explicitly set up LCD filtering.
- - *
- - * When this macro is not defined, FreeType offers alternative LCD
- - * rendering technology that produces excellent output.
- - */
- -/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
- + /*************************************************************************/
- + /* */
- + /* Uncomment the line below if you want to activate LCD rendering */
- + /* technology similar to ClearType in this build of the library. This */
- + /* technology triples the resolution in the direction color subpixels. */
- + /* To mitigate color fringes inherent to this technology, you also need */
- + /* to explicitly set up LCD filtering. */
- + /* */
- + /* Note that this feature is covered by several Microsoft patents */
- + /* and should not be activated in any default build of the library. */
- + /* When this macro is not defined, FreeType offers alternative LCD */
- + /* rendering technology that produces excellent output without LCD */
- + /* filtering. */
- + /* */
- +#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
-
-
- /**************************************************************************
- @@ -631,6 +634,17 @@
- */
- #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
- + /*************************************************************************/
- + /* */
- + /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */
- + /* all additional infinality patches, which are configured via env */
- + /* variables. */
- + /* */
- + /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */
- + /* defined. */
- + /* */
- +#define FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +
-
- /**************************************************************************
- *
- @@ -688,8 +702,8 @@
- * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
- */
- /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */
- -#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2
- -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */
- +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */
- +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 )
-
-
- /**************************************************************************
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/include/freetype/internal/ftobjs.h a/include/freetype/internal/ftobjs.h
- --- b/include/freetype/internal/ftobjs.h 2021-02-13 10:16:54.000000000 +0200
- +++ a/include/freetype/internal/ftobjs.h 2021-09-16 09:15:05.051379735 +0300
- @@ -278,12 +278,14 @@
- #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
-
- typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
- + FT_Render_Mode render_mode,
- FT_Byte* weights );
-
-
- /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
- FT_BASE( void )
- ft_lcd_filter_fir( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- FT_LcdFiveTapFilter weights );
-
- #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
- @@ -908,6 +910,7 @@
- FT_DebugHook_Func debug_hooks[4];
-
- #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- + FT_Int lcd_extra; /* number of extra pixels */
- FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
- FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
- #else
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/autofit/aflatin.c a/src/autofit/aflatin.c
- --- b/src/autofit/aflatin.c 2021-07-12 15:07:00.000000000 +0300
- +++ a/src/autofit/aflatin.c 2021-09-16 09:15:05.051379735 +0300
- @@ -22,7 +22,10 @@
- #include "afglobal.h"
- #include "aflatin.h"
- #include "aferrors.h"
- -
- +#include "strings.h"
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "../base/ftinf.h"
- +#endif
-
- /**************************************************************************
- *
- @@ -33,6 +36,10 @@
- #undef FT_COMPONENT
- #define FT_COMPONENT aflatin
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +FT_Pos infinality_cur_width = 0;
- +#endif
- +
-
- /* needed for computation of round vs. flat segments */
- #define FLAT_THRESHOLD( x ) ( x / 14 )
- @@ -1174,7 +1181,10 @@
- FT_Pos delta;
- AF_LatinAxis axis;
- FT_UInt nn;
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + FT_Bool adjust_heights = FALSE;
- + if(ftinf) adjust_heights=ftinf->autohint_increase_glyph_heights;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
-
- if ( dim == AF_DIMENSION_HORZ )
- {
- @@ -1202,7 +1212,7 @@
- {
- AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT];
- AF_LatinBlue blue = NULL;
- -
- + int threshold = 40;
-
- for ( nn = 0; nn < Axis->blue_count; nn++ )
- {
- @@ -1212,7 +1222,12 @@
- break;
- }
- }
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( adjust_heights &&
- + metrics->root.scaler.face->size->metrics.x_ppem < 15 &&
- + metrics->root.scaler.face->size->metrics.x_ppem > 5 )
- + threshold = 52;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- if ( blue )
- {
- FT_Pos scaled;
- @@ -1369,7 +1384,13 @@
-
- /* a blue zone is only active if it is less than 3/4 pixels tall */
- dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );
- +
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* Do at low ppems ( ~< 200 ), in order to prevent fringes */
- + if ( dist <= 256 && dist >= -256 )
- +#else
- if ( dist <= 48 && dist >= -48 )
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- {
- #if 0
- FT_Pos delta1;
- @@ -1420,7 +1441,12 @@
- delta2 = -delta2;
-
- blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* Round to prevent fringes */
- + blue->shoot.fit = FT_PIX_ROUND( blue->ref.fit - delta2 );
- +#else
- blue->shoot.fit = blue->ref.fit - delta2;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
-
- #endif
-
- @@ -2583,7 +2609,10 @@
- dist = edge->fpos - blue->shoot.org;
- if ( dist < 0 )
- dist = -dist;
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* round down to pixels */
- + /*dist = FT_MulFix( dist, scale ) & ~63;*/
- +#endif
- dist = FT_MulFix( dist, scale );
- if ( dist < best_dist )
- {
- @@ -2748,8 +2777,17 @@
- FT_Pos dist = width;
- FT_Int sign = 0;
- FT_Int vertical = ( dim == AF_DIMENSION_VERT );
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + FT_Int infinality_dist = 0;
- + FT_UInt autohint_snap_stem_height = 0;
- + if( ftinf ) autohint_snap_stem_height=ftinf->autohint_snap_stem_height;
- + if ( autohint_snap_stem_height > 100 )
- + autohint_snap_stem_height = 100;
- + else if ( autohint_snap_stem_height < 0 )
- + autohint_snap_stem_height = 0;
-
- -
- + if ( autohint_snap_stem_height == 0 )
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
- axis->extra_light )
- return width;
- @@ -2759,9 +2797,76 @@
- dist = -width;
- sign = 1;
- }
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* Calculate snap value differently than standard freetype */
- + if ( autohint_snap_stem_height > 0 &&
- + ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
- + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) )
- + {
- + infinality_dist = af_latin_snap_width( axis->widths,
- + axis->width_count, dist );
- +
- + if ( metrics->root.scaler.face->size->metrics.x_ppem > 9 &&
- + axis->width_count > 0 &&
- + abs( axis->widths[0].cur - infinality_dist ) < 32 &&
- + axis->widths[0].cur > 52 )
- + {
- + const char *style_name=metrics->root.scaler.face->style_name;
- + if ( style_name!=NULL &&
- + ( strstr( style_name, "Regular" ) ||
- + strstr( style_name, "Book" ) ||
- + strstr( style_name, "Medium" ) ||
- + strcmp( style_name, "Italic" ) == 0 ||
- + strcmp( style_name, "Oblique" ) == 0 )
- + )
- + {
- + /* regular weight */
- + if ( axis->widths[0].cur < 64 )
- + infinality_dist = 64;
- + else if ( axis->widths[0].cur < 88 )
- + infinality_dist = 64;
- + else if ( axis->widths[0].cur < 160 )
- + infinality_dist = 128;
- + else if ( axis->widths[0].cur < 240 )
- + infinality_dist = 190;
- + else infinality_dist = ( infinality_dist ) & ~63;
- + }
- + else
- + {
- + /* bold gets a different threshold */
- + if ( axis->widths[0].cur < 64 )
- + infinality_dist = 64 ;
- + else if ( axis->widths[0].cur < 108 )
- + infinality_dist = 64;
- + else if ( axis->widths[0].cur < 160 )
- + infinality_dist = 128;
- + else if ( axis->widths[0].cur < 222 )
- + infinality_dist = 190;
- + else if ( axis->widths[0].cur < 288 )
- + infinality_dist = 254;
- + else infinality_dist = ( infinality_dist + 16 ) & ~63;
- + }
- +
- + }
- + if ( infinality_dist < 52 )
- + {
- + if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 )
- + {
- + if ( infinality_dist < 32 )
- + infinality_dist = 32;
- + }
- + else
- + infinality_dist = 64;
- + }
- + }
- + else if ( autohint_snap_stem_height < 100 &&
- + ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
- + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) )
- +#else
-
- if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
- ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- {
- /* smooth hinting process: very lightly quantize the stem width */
-
- @@ -2853,6 +2958,9 @@
- }
- }
- else
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( autohint_snap_stem_height < 100 )
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- {
- /* strong hinting process: snap the stem width to integer pixels */
-
- @@ -2860,7 +2968,10 @@
-
-
- dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( autohint_snap_stem_height > 0 )
- + goto Done_Width;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- if ( vertical )
- {
- /* in the case of vertical hinting, always round */
- @@ -2923,6 +3034,32 @@
- }
-
- Done_Width:
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( axis->widths[0].cur > 42 )
- + /* weighted average */
- + dist = (dist * ( 100 - autohint_snap_stem_height )
- + + infinality_dist * autohint_snap_stem_height ) / 100;
- +
- + {
- + int factor = 100;
- + if ( axis->standard_width < 100 )
- + factor = axis->standard_width;
- +
- + if ( metrics->root.scaler.face->size->metrics.x_ppem >= 9 && dist < 52 )
- + dist += ( (52 - dist) * factor ) / 100;
- + if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 && dist < 32 )
- + dist += ( (32 - dist) * factor ) / 100;
- +
- + if ( axis->standard_width > 100 &&
- + metrics->root.scaler.face->size->metrics.x_ppem >= 11 &&
- + dist < 64 )
- + dist = 64;
- + if ( axis->standard_width > 100 &&
- + metrics->root.scaler.face->size->metrics.x_ppem >= 9 &&
- + dist < 52 )
- + dist = 52;
- + }
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- if ( sign )
- dist = -dist;
-
- @@ -2941,6 +3078,8 @@
- FT_Pos dist, base_delta;
- FT_Pos fitted_width;
-
- +/* if fitted_width causes stem_edge->pos to land basically on top of an existing
- + * stem_edge->pos, then add or remove 64. Need to figure out a way to do this */
-
- dist = stem_edge->opos - base_edge->opos;
- base_delta = base_edge->pos - base_edge->opos;
- @@ -3548,8 +3687,11 @@
- int dim;
-
- AF_LatinAxis axis;
- -
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + FT_Int emboldening_strength = 0;
- + FT_Bool use_various_tweaks = FALSE;
- + if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- error = af_glyph_hints_reload( hints, outline );
- if ( error )
- goto Exit;
- @@ -3595,7 +3737,11 @@
- }
-
- af_glyph_hints_save( hints, outline );
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + {
- + infinality_cur_width = metrics->axis->widths[0].cur;
- + }
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- Exit:
- return error;
- }
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/autofit/aflatin.h a/src/autofit/aflatin.h
- --- b/src/autofit/aflatin.h 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/autofit/aflatin.h 2021-09-16 09:15:05.051379735 +0300
- @@ -64,6 +64,9 @@
-
- #define AF_LATIN_MAX_WIDTHS 16
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + extern FT_Pos infinality_cur_width;
- +#endif
-
- #define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */
- #define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/autofit/afmodule.c a/src/autofit/afmodule.c
- --- b/src/autofit/afmodule.c 2021-07-12 15:07:00.000000000 +0300
- +++ a/src/autofit/afmodule.c 2021-09-16 09:15:05.051379735 +0300
- @@ -21,6 +21,10 @@
- #include "afloader.h"
- #include "aferrors.h"
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "../base/ftinf.h"
- +#endif
- +
- #ifdef FT_DEBUG_AUTOFIT
-
- #ifndef FT_MAKE_OPTION_SINGLE_OBJECT
- @@ -405,6 +409,9 @@
- module->fallback_style = AF_STYLE_FALLBACK;
- module->default_script = AF_SCRIPT_DEFAULT;
- module->no_stem_darkening = TRUE;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if(ftinf) module->no_stem_darkening = !ftinf->stem_darkening_autofit;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
-
- module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
- module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftbase.c a/src/base/ftbase.c
- --- b/src/base/ftbase.c 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/base/ftbase.c 2021-09-16 09:15:05.051379735 +0300
- @@ -36,6 +36,9 @@
- #include "ftstream.c"
- #include "fttrigon.c"
- #include "ftutil.c"
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "ftinf.c"
- +#endif
-
-
- /* END */
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinf.c a/src/base/ftinf.c
- --- b/src/base/ftinf.c 1970-01-01 03:00:00.000000000 +0300
- +++ a/src/base/ftinf.c 2021-09-16 09:15:05.052379743 +0300
- @@ -0,0 +1,363 @@
- +#include <stdlib.h>
- +#include "ftinf.h"
- +#define true 1
- +#define false 0
- +
- +#define on 1
- +#define off 0
- +#define end (-128)
- +
- +#define sw2pv 18 /* STEM_WIDTH_2_PPEM */
- +#define maxp 100 /* MAX_PPEM */
- +
- +typedef signed char pv; /* ppm and values type */
- +/* the arrays start with existence flag + values */
- +typedef struct sa_rules_s {
- + const char *name;
- + pv always_use_100[1+4+1];
- + pv brightness[1+2+1];
- + pv contrast[1+2+1];
- + pv edge_detection[1+4+1];
- + pv m[1+4+1];
- + pv bearing_correction[1+2+1];
- + pv spacing[1+5+1];
- + pv start[1+5+1];
- + pv stem_scaling[1+6+1];
- + pv stem_translating[1+2+1];
- + pv stem_translating_only[1+10+1];
- + pv stem_widths[1+4]; /* these end with maxp */
- + pv synthesize_stems[1+2+1];
- +} sa_rules_t;
- +
- +#pragma GCC diagnostic ignored "-Wpedantic" /* C99 struct initializer tags are needed */
- +#pragma GCC diagnostic ignored "-Wunused-function"
- +
- +const ftinf_t *ftinf;
- +/* final settings, updated from environment */
- +ftinf_t _env;
- +
- +/* rules and hashing function */
- +#include "ftinf_rh.c"
- +
- +/* rules selection */
- +void ftinf_fill_stem_values( Stem_Data *stem_values,
- + const char *family, int ppem, int use_known ){
- + /* set the defaults */
- + stem_values->bearing_correction = TRUE;
- + stem_values->brightness = 0.0;
- + stem_values->contrast = 0.0;
- + stem_values->edge_detection = FALSE;
- + stem_values->m = -1;
- + stem_values->stem_scaling = -1;
- + stem_values->stem_spacing = -1;
- + stem_values->stem_start = -1;
- + stem_values->stem_translating = 0;
- + stem_values->stem_translating_only = -1024;
- + stem_values->stem_width = -1;
- + stem_values->synth_stems = FALSE;
- + stem_values->use_100 = FALSE;
- + /* pick from known rules if requested and they exist for current family */
- + if( !use_known )
- + return;
- + else {
- + const sa_rules_t *r=ftinf_rules( family );
- + int i;
- + if( r==NULL ) return;
- + if( r->stem_widths[0]==on )
- + for( i=1; r->stem_widths[i]!=maxp; ++i )
- + if( ppem < r->stem_widths[i] ){
- + stem_values->stem_width = i-1;
- + break;
- + }
- +
- + if( r->stem_scaling[0]==on )
- + for( i=1; r->stem_scaling[i]!=end; i+=2 )
- + if( ppem==r->stem_scaling[i] ){
- + stem_values->stem_scaling = r->stem_scaling[i+1];
- + break;
- + }
- +
- + if( r->m[0]==on )
- + for( i=1; r->m[i]!=end; i+=2 )
- + if( ppem==r->m[i] ){
- + stem_values->m = r->m[i+1];
- + break;
- + }
- +
- + if( r->stem_translating_only[0]==on )
- + for( i=1; r->stem_translating_only[i]!=end; i+=2 )
- + if( ppem==r->stem_translating_only[i] || r->stem_translating_only[i]==0 ){
- + stem_values->stem_translating_only = r->stem_translating_only[i+1];
- + break;
- + }
- +
- + if( r->stem_translating[0]==on )
- + for( i=1; r->stem_translating[i]!=end; i+=2 )
- + if( ppem==r->stem_translating[i] || r->stem_translating[i]==0 ){
- + stem_values->stem_translating = r->stem_translating[i+1];
- + break;
- + }
- +
- + if( r->always_use_100[0]==on )
- + for( i=1; r->always_use_100[i]!=end; i+=2 )
- + if( ppem>=r->always_use_100[i] && ppem<=r->always_use_100[i+1] ){
- + stem_values->use_100 = TRUE;
- + break;
- + }
- +
- + if( r->synthesize_stems[0]==on )
- + for( i=1; r->synthesize_stems[i]!=end; i+=2 )
- + if( ppem>=r->synthesize_stems[i] && ppem<=r->synthesize_stems[i+1] ){
- + stem_values->synth_stems = TRUE;
- + break;
- + }
- +
- + if( r->edge_detection[0]==on )
- + for( i=1; r->edge_detection[i]!=end; i+=2 )
- + if( ppem>=r->edge_detection[i] && ppem<=r->edge_detection[i+1] ){
- + stem_values->edge_detection = TRUE;
- + break;
- + }
- +
- + if( r->bearing_correction[0]==on )
- + for( i=1; r->bearing_correction[i]!=end; i+=2 )
- + if( ppem>=r->bearing_correction[i] && ppem<=r->bearing_correction[i+1] ){
- + stem_values->bearing_correction = FALSE;
- + break;
- + }
- +
- +#if(0)
- + if( r->brightness[0]==on )
- + for( i=1; r->brightness[i]!=end; i+=2 )
- + if( ppem==r->brightness[i]||r->brightness[i]==0 ){
- + stem_values->brightness=r->brightness[i+1]*(1.0f/300.0f);
- + break;
- + }
- +
- + if( r->contrast[0]==on )
- + for( i=1; r->contrast[i]!=end; i+=2 )
- + if( ppem==r->contrast[i]||r->contrast[i]==0 ){
- + stem_values->contrast=r->contrast[i+1]*(1.0f/300.0f);
- + break;
- + }
- + if( r->spacing[0]==on ){
- + /* not used by original code */
- + }
- + if( r->start[0]==on ){
- + /* not used by original code */
- + }
- +#endif
- + }
- + return;
- +}
- +
- +void ftinf_get_bc( const char *family, int ppem, float *brightness, float *contrast ){
- + const sa_rules_t *r=ftinf_rules( family );
- + *brightness=0;
- + *contrast=0;
- + if( r ){
- + int i;
- + if( r->brightness[0]==on )
- + for( i=1; r->brightness[i]!=end; i+=2 )
- + if( ppem==r->brightness[i]||r->brightness[i]==0 ){
- + *brightness=r->brightness[i+1]*(1.0f/300.0f);
- + break;
- + }
- +
- + if( r->contrast[0]==on )
- + for( i=1; r->contrast[i]!=end; i+=2 )
- + if( ppem==r->contrast[i]||r->contrast[i]==0 ){
- + *contrast=r->contrast[i+1]*(1.0f/300.0f);
- + break;
- + }
- + }
- + return;
- +}
- +
- +static int
- +bool_val( const char *s ){
- + if ( s != NULL )
- + return strcasecmp(s, "true") == 0
- + || strcasecmp(s, "1") == 0
- + || strcasecmp(s, "on") == 0
- + || strcasecmp(s, "yes") ==0;
- + else
- + return 0;
- +}
- +
- +static int
- +int_val( const char *s, int min, int max ){
- + int val;
- + sscanf ( s, "%d", &val );
- + if ( val > max )
- + val = max;
- + else if ( val < min )
- + val = min;
- + return val;
- +}
- +
- +/* settings and hashing function */
- +#include "ftinf_sh.c"
- +
- +/*
- + Get active Infinality settings
- + */
- +void ftinf_env(){
- + const char *s;
- + ftinf=ftinf_settings( getenv( "INFINALITY_FT" ) );
- +
- + if( ftinf==NULL ){
- + ftinf=ftinf_settings( "ultimate3" );
- + /* this should always succeed */
- +#if(0)
- + if( ftinf==NULL ){
- + /* put an error here */
- + exit(-1);
- + }
- +#endif
- + }
- + _env=ftinf[0]; /* copy as defaults */
- +
- + /* check if custom environment values are set and update with them */
- + s=getenv( "INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS" );
- + if( s ) _env.autohint_increase_glyph_heights=bool_val( s );
- + s=getenv( "INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT" );
- + if( s ) _env.autohint_snap_stem_height=int_val( s, 0, 100 );
- + s=getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" );
- + if( s ) _env.use_various_tweaks=bool_val( s );
- + s=getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" );
- + if( s ) _env.use_known_settings_on_selected_fonts=bool_val(s);
- +#if(0) /* not used (naming error also) */
- + s=getenv( "INFINALITY_FT_AUTOHINT_MINIMUM_STEM_WIDTH" );
- + if( s ) _env.autohint_minimum_stem_height=int_val( s, 0, 100 );
- +#endif
- + s=getenv( "INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE" );
- + if( s ) sscanf( s, "%d", &_env.stem_snapping_sliding_scale );
- + s=getenv( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" );
- + if( s ) sscanf( s, "%d", &_env.stem_alignment_strength );
- + s=getenv( "INFINALITY_FT_STEM_DARKENING_AUTOFIT" );
- + if( s ) _env.stem_darkening_autofit=bool_val( s );
- + s=getenv( "INFINALITY_FT_STEM_DARKENING_CFF" );
- + if( s ) _env.stem_darkening_cff=bool_val( s );
- + s=getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" );
- + if( s ) sscanf( s, "%d", &_env.stem_fitting_strength );
- + s=getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" );
- + if( s ) _env.chromeos_style_sharpening_strength=int_val( s, 0, 100 );
- + s=getenv( "INFINALITY_FT_BRIGHTNESS" );
- + if( s ) sscanf( s, "%d", &_env.brightness );
- + s=getenv( "INFINALITY_FT_CONTRAST" );
- + if( s ) sscanf( s, "%d", &_env.contrast );
- + s=getenv( "INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH" );
- + if( s ) _env.windows_style_sharpening_strength=int_val( s, 0, 100 );
- + s=getenv( "INFINALITY_FT_GAMMA_CORRECTION" );
- + if( s ){
- + float *f=_env.gamma_correction;
- + sscanf ( s, "%f %f", &f[0], &f[1] );
- + if( f[1] < 1.0f ) f[1]=1.0f;
- + }
- + s=getenv( "INFINALITY_FT_FRINGE_FILTER_STRENGTH" );
- + if( s ) sscanf( s, "%d", &_env.fringe_filter_strength );
- + s=getenv( "INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH" );
- + if( s ) sscanf( s, "%d", &_env.grayscale_filter_strength );
- + s=getenv( "INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH" );
- + if( s ) sscanf( s, "%d", &_env.autohint_horizontal_stem_darken_strength );
- + s=getenv( "INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH" );
- + if( s ) sscanf( s, "%d", &_env.autohint_vertical_stem_darken_strength );
- + s=getenv( "INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE" );
- + if( s ) sscanf( s, "%d", &_env.global_embolden_x_value );
- + s=getenv( "INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE" );
- + if( s ) sscanf( s, "%d", &_env.global_embolden_y_value );
- + s=getenv( "INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE" );
- + if( s ) sscanf( s, "%d", &_env.bold_embolden_x_value );
- + s=getenv( "INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE" );
- + if( s ) sscanf( s, "%d", &_env.bold_embolden_y_value );
- + s=getenv( "INFINALITY_FT_FILTER_PARAMS" );
- + if( s ) {
- + int *f=_env.filter_params;
- + if( sscanf( s, "%d %d %d %d %d", f+1, f+2, f+3, f+4, f+5 )==5 )
- + f[0]=on;
- + else
- + f[0]=off; /* FIXME: put a warning? */
- + }
- + /* do the range verifications as in original code */
- + if ( _env.stem_snapping_sliding_scale > maxp )
- + _env.stem_snapping_sliding_scale = 0;
- + else if ( _env.stem_snapping_sliding_scale < 0 )
- + _env.stem_snapping_sliding_scale = 0;
- + if (_env.stem_snapping_sliding_scale < 11 &&
- + _env.stem_snapping_sliding_scale > 0 )
- + _env.stem_snapping_sliding_scale = 11;
- +
- + if ( _env.stem_alignment_strength > 100 )
- + _env.stem_alignment_strength = 100;
- + else if ( _env.stem_alignment_strength < 0 )
- + _env.stem_alignment_strength = 0;
- +
- + if ( _env.stem_fitting_strength > 100 )
- + _env.stem_fitting_strength = 100;
- + else if ( _env.stem_fitting_strength < 0 )
- + _env.stem_fitting_strength = 0;
- +
- + if ( _env.chromeos_style_sharpening_strength > 100 )
- + _env.chromeos_style_sharpening_strength = 100;
- + else if ( _env.chromeos_style_sharpening_strength < 0 )
- + _env.chromeos_style_sharpening_strength = 0;
- +
- + if ( _env.brightness > 100 )
- + _env.brightness = 100;
- + else if ( _env.brightness < -100 )
- + _env.brightness = 0;
- +
- + if ( _env.contrast > 100 )
- + _env.contrast = 100;
- + else if ( _env.contrast < -100 )
- + _env.contrast = 0;
- +
- + if ( _env.windows_style_sharpening_strength > 100 )
- + _env.windows_style_sharpening_strength = 100;
- + else if ( _env.windows_style_sharpening_strength < 0 )
- + _env.windows_style_sharpening_strength = 0;
- +
- + if ( _env.fringe_filter_strength > 100 )
- + _env.fringe_filter_strength = 100;
- + else if ( _env.fringe_filter_strength < 0 )
- + _env.fringe_filter_strength = 0;
- +
- + if ( _env.grayscale_filter_strength > 100 )
- + _env.grayscale_filter_strength = 100;
- + else if ( _env.grayscale_filter_strength < 0 )
- + _env.grayscale_filter_strength = 0;
- +
- + if ( _env.autohint_horizontal_stem_darken_strength > 100 )
- + _env.autohint_horizontal_stem_darken_strength = 100;
- + else if ( _env.autohint_horizontal_stem_darken_strength < 0 )
- + _env.autohint_horizontal_stem_darken_strength = 0;
- +
- + if ( _env.autohint_vertical_stem_darken_strength > 100 )
- + _env.autohint_vertical_stem_darken_strength = 100;
- + else if ( _env.autohint_horizontal_stem_darken_strength < 0 )
- + _env.autohint_vertical_stem_darken_strength = 0;
- +
- + if ( _env.global_embolden_x_value > 128 )
- + _env.global_embolden_x_value = 128;
- + else if ( _env.global_embolden_x_value < -128 )
- + _env.global_embolden_x_value = -128;
- +
- + if ( _env.global_embolden_y_value > 128 )
- + _env.global_embolden_y_value = 128;
- + else if ( _env.global_embolden_y_value < -128 )
- + _env.global_embolden_y_value = -128;
- +
- + if ( _env.bold_embolden_x_value > 128 )
- + _env.bold_embolden_x_value = 128;
- + else if (_env.bold_embolden_x_value < -128 )
- + _env.bold_embolden_x_value = -128;
- +
- + if ( _env.bold_embolden_y_value > 128 )
- + _env.bold_embolden_y_value = 128;
- + else if ( _env.bold_embolden_y_value < -128 )
- + _env.bold_embolden_y_value = -128;
- +
- + /* point to the combined and checked settings */
- + ftinf=&_env;
- +}
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinf.h a/src/base/ftinf.h
- --- b/src/base/ftinf.h 1970-01-01 03:00:00.000000000 +0300
- +++ a/src/base/ftinf.h 2021-09-16 09:15:05.052379743 +0300
- @@ -0,0 +1,66 @@
- +#ifndef _FTINF_H_
- +#define _FTINF_H_
- +/*
- + Stem snapping rules
- + (base freetype typedefs assumed already included)
- + */
- +typedef struct
- +{
- + FT_Int stem_width;
- + FT_Int stem_spacing;
- + FT_Int stem_start;
- + FT_Int stem_scaling;
- + FT_Int stem_translating_only;
- + FT_Int stem_translating;
- + float brightness;
- + float contrast;
- + FT_Bool use_100;
- + FT_Bool synth_stems;
- + FT_Bool edge_detection;
- + FT_Bool bearing_correction;
- + FT_Int m;
- +} Stem_Data;
- +
- +/*
- + Infinality settings
- + */
- +typedef struct ftinf_s {
- + const char *name;
- + int autohint_horizontal_stem_darken_strength;
- + int autohint_snap_stem_height;
- + int autohint_increase_glyph_heights;
- + int autohint_vertical_stem_darken_strength;
- + int bold_embolden_x_value;
- + int bold_embolden_y_value;
- + int brightness;
- + int chromeos_style_sharpening_strength;
- + int contrast;
- + int filter_params[6]; /* 1st one used as existence flag */
- + int fringe_filter_strength;
- + float gamma_correction[2];
- + int global_embolden_x_value;
- + int global_embolden_y_value;
- + int grayscale_filter_strength;
- + int stem_alignment_strength;
- + int stem_darkening_autofit;
- + int stem_darkening_cff;
- + int stem_fitting_strength;
- + int stem_snapping_sliding_scale;
- + int use_known_settings_on_selected_fonts;
- + int use_various_tweaks;
- + int windows_style_sharpening_strength;
- +} ftinf_t;
- +
- +extern FT_Pos infinality_cur_width; /* defined in aflatin.c */
- +
- +extern const ftinf_t *ftinf; /* active settings */
- +
- +extern void ftinf_fill_stem_values( Stem_Data *stem_values,
- + const char *family, int ppem, int use_known );
- +extern void ftinf_get_bc( const char *family, int ppem,
- + float *brightness, float *contrast );
- +
- +/* get values from environment (FIXME: maybe update with using user files) */
- +extern void ftinf_env();
- +
- +#endif
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinf_rh.c a/src/base/ftinf_rh.c
- --- b/src/base/ftinf_rh.c 1970-01-01 03:00:00.000000000 +0300
- +++ a/src/base/ftinf_rh.c 2021-09-16 09:15:05.052379743 +0300
- @@ -0,0 +1,626 @@
- +/* ANSI-C code produced by gperf version 3.1 */
- +/* Command-line: gperf --output-file=ftinf_rh.c ftinf_rh.gperf */
- +/* Computed positions: -k'1,$' */
- +
- +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
- + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
- + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
- + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
- + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
- + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
- + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
- + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
- + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
- + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
- + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
- + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
- + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
- + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
- + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
- + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
- + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
- + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
- + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
- + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
- + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
- + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
- + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
- +/* The character set is not based on ISO-646. */
- +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
- +#endif
- +
- +#line 9 "ftinf_rh.gperf"
- +
- +#include <ctype.h>
- +static const struct sa_rules_s* _rules_get( const char*str, unsigned len );
- +/* maximum key range = 82, duplicates = 0 */
- +
- +#ifdef __GNUC__
- +__inline
- +#else
- +#ifdef __cplusplus
- +inline
- +#endif
- +#endif
- +static unsigned int
- +_rules_hash (register const char *str, register unsigned int len)
- +{
- + static const unsigned char asso_values[] =
- + {
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 0, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 5, 45, 5,
- + 35, 25, 35, 35, 50, 45, 85, 85, 0, 25,
- + 40, 5, 0, 85, 50, 20, 20, 0, 10, 10,
- + 85, 10, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- + 85, 85, 85, 85, 85, 85
- + };
- + return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]];
- +}
- +
- +#ifdef __GNUC__
- +__inline
- +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
- +__attribute__ ((__gnu_inline__))
- +#endif
- +#endif
- +const struct sa_rules_s *
- +_rules_get (register const char *str, register unsigned int len)
- +{
- + enum
- + {
- + TOTAL_KEYWORDS = 58,
- + MIN_WORD_LENGTH = 3,
- + MAX_WORD_LENGTH = 24,
- + MIN_HASH_VALUE = 3,
- + MAX_HASH_VALUE = 84
- + };
- +
- + static const struct sa_rules_s wordlist[] =
- + {
- +#line 15 "ftinf_rh.gperf"
- +{ .name="---",
- + .synthesize_stems={on, 13, 13, end}
- +},
- +#line 253 "ftinf_rh.gperf"
- +{ .name="ubuntu",
- + .always_use_100={on, 12, 13, 15, 15, end}
- +},
- +#line 31 "ftinf_rh.gperf"
- +{ .name="arial",
- + .always_use_100={on, 0, maxp, end},
- + .edge_detection={on, 11, 11, 13, 13, end},
- + .spacing={on, 10, 11, 23, 25, 30, end},
- + .start={on, 11, 18, 23, 30, 30, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 16, 8, 32, 9, 32, 16, -24, end}
- +},
- +#line 87 "ftinf_rh.gperf"
- +{ .name="corbel",
- + .stem_translating_only={on, 10, 16, end},
- + .stem_widths={on, 10, 21, maxp}
- +},
- +#line 71 "ftinf_rh.gperf"
- +{ .name="canwell",
- + .stem_scaling={on, 13, 0, end}
- +},
- +#line 216 "ftinf_rh.gperf"
- +{ .name="pragmata",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 67 "ftinf_rh.gperf"
- +{ .name="cantarell",
- + .stem_translating_only={on, 11, 0, 12, 0, end},
- + .stem_widths={on, 10, 22, maxp,}
- +},
- +#line 39 "ftinf_rh.gperf"
- +{ .name="arimo",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end}
- +},
- +#line 207 "ftinf_rh.gperf"
- +{ .name="optima",
- + .brightness={on, 0, -20, end},
- + .contrast={on, 0, 25, end},
- + .stem_scaling={on, 17, 1, end},
- + .stem_translating_only={on, 10, 0, 11, 0, 12, 0, end}
- +},
- +#line 63 "ftinf_rh.gperf"
- +{ .name="candara",
- + .stem_scaling={on, 14, 1, 17, 1, end},
- + .stem_translating_only={on, 10, 16, end}
- +},
- +#line 77 "ftinf_rh.gperf"
- +{ .name="comfortaa",
- + .stem_widths={on, 10, 19, 22, maxp},
- + .stem_scaling={on, 11, 0, end}
- +},
- +#line 161 "ftinf_rh.gperf"
- +{ .name="liberation mono",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 18 "ftinf_rh.gperf"
- +{ .name="andale mono",
- + .always_use_100={on, 0, maxp, end},
- + .stem_scaling={on, 11, 1, end},
- + .stem_widths={on, 10, 21, maxp,}
- +},
- +#line 256 "ftinf_rh.gperf"
- +{ .name="verdana",
- + .always_use_100={on, 0, 14, 16, maxp, end},
- + .stem_scaling={on, 12, 1, 15, 1, end},
- + .stem_translating_only={on, 8, 16, 15, 16, 14, 32, 18, 32, 19, 24, end}
- +},
- +#line 74 "ftinf_rh.gperf"
- +{ .name="century gothic",
- + .stem_widths={on, 10, 22, maxp,}
- +},
- +#line 91 "ftinf_rh.gperf"
- +{ .name="courier new",
- + .always_use_100={on, 12, 12, end},
- + .edge_detection={on, 10, 12, end},
- + .m={on, 13, 1, 14, 1, end}
- +},
- +#line 23 "ftinf_rh.gperf"
- +{ .name="arial narrow",
- + .stem_widths={on, 10, 21, maxp,}
- +},
- +#line 185 "ftinf_rh.gperf"
- +{ .name="luxi sans",
- + .always_use_100={on, 13, 13, end},
- + .stem_widths={on, 10, 17, sw2pv, maxp,}
- +},
- +#line 225 "ftinf_rh.gperf"
- +{ .name="samba",
- + .stem_scaling={on, 11, 0, end}
- +},
- +#line 233 "ftinf_rh.gperf"
- +{ .name="tahoma",
- + .always_use_100={on, 11, 11, 14, maxp, end},
- + .edge_detection={on, 11, 11, end},
- + .spacing={on, 10, 12, 18, 18, 30, end},
- + .start={on, 14, 17, 30, 100, 100, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 7, 32, 8, 32, 9, 32, end},
- +},
- +#line 164 "ftinf_rh.gperf"
- +{ .name="liberation sans narrow",
- + .stem_widths={on,10, 22, maxp,}
- +},
- +#line 81 "ftinf_rh.gperf"
- +{ .name="consolas",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating_only={on, 8, 32, 9, 32, end},
- + .stem_widths={on, 10, 20, maxp,},
- + .stem_scaling={on, 11, 1, end}
- +},
- +#line 203 "ftinf_rh.gperf"
- +{ .name="open sans",
- + .stem_translating_only={on, 10, 16, 9, 16, end},
- + .stem_widths={on, 10, 20, maxp,}
- +},
- +#line 167 "ftinf_rh.gperf"
- +{ .name="liberation sans",
- + .edge_detection={on, 11, 11, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end},
- + .stem_widths={on,10, 19, maxp,}
- +},
- +#line 193 "ftinf_rh.gperf"
- +{ .name="monaco",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 101 "ftinf_rh.gperf"
- +{ .name="cousine",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 176 "ftinf_rh.gperf"
- +{ .name="lucida grande",
- + .stem_scaling={on, 13, 1, end},
- + .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end},
- + .stem_widths={on, 10, 16, sw2pv, maxp},
- +},
- +#line 173 "ftinf_rh.gperf"
- +{ .name="lucida console",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 196 "ftinf_rh.gperf"
- +{ .name="myriad pro",
- + .stem_scaling={on, 14, 1, 17, 1, end},
- + .stem_translating_only={on, 10, 16, 11, 0, 9, 16, end}
- +},
- +#line 26 "ftinf_rh.gperf"
- +{ .name="arial unicode ms",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end}
- +},
- +#line 213 "ftinf_rh.gperf"
- +{ .name="palatino linotype",
- + .edge_detection={on, 0, 100, end}
- +},
- +#line 181 "ftinf_rh.gperf"
- +{ .name="lucida sans unicode",
- + .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end},
- + .stem_widths={on,10, 16, sw2pv, maxp,}
- +},
- +#line 140 "ftinf_rh.gperf"
- +{ .name="futura",
- + .stem_widths={on, 10, 14, sw2pv, maxp,}
- +},
- +#line 147 "ftinf_rh.gperf"
- +{ .name="georgia",
- + .stem_translating_only={on, 13, 16, 14, 16, 15, 0, end}
- +},
- +#line 125 "ftinf_rh.gperf"
- +{ .name="freemono",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 200 "ftinf_rh.gperf"
- +{ .name="nina",
- + .stem_scaling={on, 11, 0, 12, 0, 13, 0, end}
- +},
- +#line 121 "ftinf_rh.gperf"
- +{ .name="essential pragmatapro",
- + .always_use_100={on, 0, maxp, end},
- + .m={on, 13, 0, 14, 0, end}
- +},
- +#line 247 "ftinf_rh.gperf"
- +{ .name="trebuchet ms",
- + .always_use_100={on, 13, 13, end},
- + .stem_scaling={on, 13, 0, 17, 0, 20, 1, end},
- + .stem_translating_only={on, 10, 16, 11, 0, 8, 32, 9, 32, end},
- + .stem_widths={on, 10, 17, sw2pv, maxp,}
- +},
- +#line 114 "ftinf_rh.gperf"
- +{ .name="droid sans mono",
- + .m={on, 12, 0, end}
- +},
- +#line 104 "ftinf_rh.gperf"
- +{ .name="dejavu sans mono",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating_only={on, 7, 16, 8, 32, 9, 16, end}
- +},
- +#line 57 "ftinf_rh.gperf"
- +{ .name="calibri",
- + .always_use_100={on, 23, maxp, end},
- + .stem_scaling={on, 15, 1, 17, 1, 18, 1, end},
- + .stem_translating_only={on, 10, 16, 15, 0, end},
- + .stem_widths={on, 1, 10, 19, maxp,}
- +},
- +#line 156 "ftinf_rh.gperf"
- +{ .name="inconsolata",
- + .stem_scaling={on, 12, 1, 15, 1, end},
- + .stem_translating_only={on, 10, 24, 9, 32, end},
- + .stem_widths={on, 10, 23, maxp,},
- +},
- +#line 96 "ftinf_rh.gperf"
- +{ .name="courier",
- + .always_use_100={on, 0, maxp, end},
- + .m={on, 13, 1, 14, 1, end},
- + .stem_translating_only={on, 13, 16, 15, 0, end}
- +},
- +#line 128 "ftinf_rh.gperf"
- +{ .name="freesans",
- + .always_use_100={on, 0, maxp, end},
- + .edge_detection={on, 11, 11, 13, 13, end},
- + .spacing={on, 10, 12, 18, 18, 30, end},
- + .start={on, 10, 18, 18, 25, 30, end},
- + .stem_scaling={on, 16, 0, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 16, 9, 8, end}
- +},
- +#line 150 "ftinf_rh.gperf"
- +{ .name="gill sans",
- + .stem_widths={on, 10, 17, sw2pv, maxp,}
- +},
- +#line 117 "ftinf_rh.gperf"
- +{ .name="droid sans",
- + .always_use_100={on, 12, 12, 15, 15, end},
- + .stem_translating_only={on, 8, 16, 9, 16, end}
- +},
- +#line 108 "ftinf_rh.gperf"
- +{ .name="dejavu sans",
- + .always_use_100={on, 10, 14, 16, 17, end},
- + .m={on, 12, 0, end},
- + .stem_scaling={on, 12, 1, end},
- + .stem_translating_only={on, 8, 16, 15, -20, end}
- +},
- +#line 219 "ftinf_rh.gperf"
- +{ .name="raleway",
- + .stem_scaling={on, 15, 0, end}
- +},
- +#line 153 "ftinf_rh.gperf"
- +{ .name="helvetica cy",
- + .stem_widths={on, 10, 23, maxp,}
- +},
- +#line 228 "ftinf_rh.gperf"
- +{ .name="segoe ui",
- + .always_use_100={on, 11, 12, 14, 14, end},
- + .stem_translating_only={on, 10, 0, 7, 32, 8, 16, 9, 24, end},
- + .stem_widths={on, 10, 23, maxp,}
- +},
- +#line 48 "ftinf_rh.gperf"
- +{ .name="bitstream vera sans mono",
- + .always_use_100={on, 0, maxp, end}
- +},
- +#line 241 "ftinf_rh.gperf"
- +{ .name="times new roman",
- + .always_use_100={on, 14, 14, 16, 16, end},
- + .bearing_correction={0, 100, end},
- + .stem_scaling={on, 17, 1, end},
- + .stem_translating_only={on, 17, 8, end}
- +},
- +#line 222 "ftinf_rh.gperf"
- +{ .name="rokkitt",
- + .stem_widths={on, 10, 21, maxp,}
- +},
- +#line 143 "ftinf_rh.gperf"
- +{ .name="garamond",
- + .brightness={on, 0, -20, end},
- + .contrast={on, 0, 25, end}
- +},
- +#line 137 "ftinf_rh.gperf"
- +{ .name="freeserif",
- + .stem_scaling={on, 13, 1, 17, 1, end}
- +},
- +#line 189 "ftinf_rh.gperf"
- +{ .name="microsoft sans serif",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end}
- +},
- +#line 44 "ftinf_rh.gperf"
- +{ .name="baskerville",
- + .brightness={on, 0, -20, end},
- + .contrast={on, 0, 25, end}
- +},
- +#line 51 "ftinf_rh.gperf"
- +{ .name="bitstream vera sans",
- + .always_use_100={on, 10, 14, 16, 17, end},
- + .m={on, 12, 0, end},
- + .stem_scaling={on ,12, 1, end},
- + .stem_translating_only={on, 8, 16, end}
- +}
- + };
- +
- + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- + {
- + register int key = _rules_hash (str, len);
- +
- + if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
- + {
- + register const struct sa_rules_s *resword;
- +
- + switch (key - 3)
- + {
- + case 0:
- + resword = &wordlist[0];
- + goto compare;
- + case 3:
- + resword = &wordlist[1];
- + goto compare;
- + case 7:
- + resword = &wordlist[2];
- + goto compare;
- + case 8:
- + resword = &wordlist[3];
- + goto compare;
- + case 9:
- + resword = &wordlist[4];
- + goto compare;
- + case 10:
- + resword = &wordlist[5];
- + goto compare;
- + case 11:
- + resword = &wordlist[6];
- + goto compare;
- + case 12:
- + resword = &wordlist[7];
- + goto compare;
- + case 13:
- + resword = &wordlist[8];
- + goto compare;
- + case 14:
- + resword = &wordlist[9];
- + goto compare;
- + case 16:
- + resword = &wordlist[10];
- + goto compare;
- + case 17:
- + resword = &wordlist[11];
- + goto compare;
- + case 18:
- + resword = &wordlist[12];
- + goto compare;
- + case 19:
- + resword = &wordlist[13];
- + goto compare;
- + case 21:
- + resword = &wordlist[14];
- + goto compare;
- + case 23:
- + resword = &wordlist[15];
- + goto compare;
- + case 24:
- + resword = &wordlist[16];
- + goto compare;
- + case 26:
- + resword = &wordlist[17];
- + goto compare;
- + case 27:
- + resword = &wordlist[18];
- + goto compare;
- + case 28:
- + resword = &wordlist[19];
- + goto compare;
- + case 29:
- + resword = &wordlist[20];
- + goto compare;
- + case 30:
- + resword = &wordlist[21];
- + goto compare;
- + case 31:
- + resword = &wordlist[22];
- + goto compare;
- + case 32:
- + resword = &wordlist[23];
- + goto compare;
- + case 33:
- + resword = &wordlist[24];
- + goto compare;
- + case 34:
- + resword = &wordlist[25];
- + goto compare;
- + case 35:
- + resword = &wordlist[26];
- + goto compare;
- + case 36:
- + resword = &wordlist[27];
- + goto compare;
- + case 37:
- + resword = &wordlist[28];
- + goto compare;
- + case 38:
- + resword = &wordlist[29];
- + goto compare;
- + case 39:
- + resword = &wordlist[30];
- + goto compare;
- + case 41:
- + resword = &wordlist[31];
- + goto compare;
- + case 43:
- + resword = &wordlist[32];
- + goto compare;
- + case 44:
- + resword = &wordlist[33];
- + goto compare;
- + case 45:
- + resword = &wordlist[34];
- + goto compare;
- + case 46:
- + resword = &wordlist[35];
- + goto compare;
- + case 48:
- + resword = &wordlist[36];
- + goto compare;
- + case 49:
- + resword = &wordlist[37];
- + goto compare;
- + case 52:
- + resword = &wordlist[38];
- + goto compare;
- + case 53:
- + resword = &wordlist[39];
- + goto compare;
- + case 54:
- + resword = &wordlist[40];
- + goto compare;
- + case 58:
- + resword = &wordlist[41];
- + goto compare;
- + case 59:
- + resword = &wordlist[42];
- + goto compare;
- + case 60:
- + resword = &wordlist[43];
- + goto compare;
- + case 61:
- + resword = &wordlist[44];
- + goto compare;
- + case 62:
- + resword = &wordlist[45];
- + goto compare;
- + case 63:
- + resword = &wordlist[46];
- + goto compare;
- + case 64:
- + resword = &wordlist[47];
- + goto compare;
- + case 69:
- + resword = &wordlist[48];
- + goto compare;
- + case 70:
- + resword = &wordlist[49];
- + goto compare;
- + case 71:
- + resword = &wordlist[50];
- + goto compare;
- + case 72:
- + resword = &wordlist[51];
- + goto compare;
- + case 74:
- + resword = &wordlist[52];
- + goto compare;
- + case 75:
- + resword = &wordlist[53];
- + goto compare;
- + case 76:
- + resword = &wordlist[54];
- + goto compare;
- + case 77:
- + resword = &wordlist[55];
- + goto compare;
- + case 78:
- + resword = &wordlist[56];
- + goto compare;
- + case 81:
- + resword = &wordlist[57];
- + goto compare;
- + }
- + return 0;
- + compare:
- + {
- + register const char *s = resword->name;
- +
- + if (*str == *s && !strcmp (str + 1, s + 1))
- + return resword;
- + }
- + }
- + }
- + return 0;
- +}
- +#line 261 "ftinf_rh.gperf"
- +
- +
- +static const sa_rules_t*
- +ftinf_rules( const char *name ){
- + if( name ){
- + enum {
- + max_wlen=31
- + };
- + char buf[max_wlen+1];
- + int len=strlen( name );
- + if( len <= max_wlen ){
- + int i;
- + for( i=0; i<len; ++i )
- + buf[i]=tolower( name[i] );
- + buf[len]='\0';
- + return _rules_get( buf, len );
- + }
- + }
- + return NULL;
- +}
- +/*
- + gperf --output-file=ftinf_rh.c ftinf_rh.gperf
- +*/
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinf_rh.gperf a/src/base/ftinf_rh.gperf
- --- b/src/base/ftinf_rh.gperf 1970-01-01 03:00:00.000000000 +0300
- +++ a/src/base/ftinf_rh.gperf 2021-09-16 09:15:05.052379743 +0300
- @@ -0,0 +1,283 @@
- +%struct-type
- +%define slot-name name
- +%enum
- +%switch=1
- +%readonly-tables
- +%omit-struct-type
- +%define lookup-function-name _rules_get
- +%define hash-function-name _rules_hash
- +%{
- +#include <ctype.h>
- +static const struct sa_rules_s* _rules_get( const char*str, unsigned len );
- +%}
- +struct sa_rules_s;
- +%%
- +{ .name="---",
- + .synthesize_stems={on, 13, 13, end}
- +},
- +{ .name="andale mono",
- + .always_use_100={on, 0, maxp, end},
- + .stem_scaling={on, 11, 1, end},
- + .stem_widths={on, 10, 21, maxp,}
- +},
- +{ .name="arial narrow",
- + .stem_widths={on, 10, 21, maxp,}
- +},
- +{ .name="arial unicode ms",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end}
- +},
- +{ .name="arial",
- + .always_use_100={on, 0, maxp, end},
- + .edge_detection={on, 11, 11, 13, 13, end},
- + .spacing={on, 10, 11, 23, 25, 30, end},
- + .start={on, 11, 18, 23, 30, 30, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 16, 8, 32, 9, 32, 16, -24, end}
- +},
- +{ .name="arimo",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end}
- +},
- +{ .name="baskerville",
- + .brightness={on, 0, -20, end},
- + .contrast={on, 0, 25, end}
- +},
- +{ .name="bitstream vera sans mono",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="bitstream vera sans",
- + .always_use_100={on, 10, 14, 16, 17, end},
- + .m={on, 12, 0, end},
- + .stem_scaling={on ,12, 1, end},
- + .stem_translating_only={on, 8, 16, end}
- +},
- +{ .name="calibri",
- + .always_use_100={on, 23, maxp, end},
- + .stem_scaling={on, 15, 1, 17, 1, 18, 1, end},
- + .stem_translating_only={on, 10, 16, 15, 0, end},
- + .stem_widths={on, 1, 10, 19, maxp,}
- +},
- +{ .name="candara",
- + .stem_scaling={on, 14, 1, 17, 1, end},
- + .stem_translating_only={on, 10, 16, end}
- +},
- +{ .name="cantarell",
- + .stem_translating_only={on, 11, 0, 12, 0, end},
- + .stem_widths={on, 10, 22, maxp,}
- +},
- +{ .name="canwell",
- + .stem_scaling={on, 13, 0, end}
- +},
- +{ .name="century gothic",
- + .stem_widths={on, 10, 22, maxp,}
- +},
- +{ .name="comfortaa",
- + .stem_widths={on, 10, 19, 22, maxp},
- + .stem_scaling={on, 11, 0, end}
- +},
- +{ .name="consolas",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating_only={on, 8, 32, 9, 32, end},
- + .stem_widths={on, 10, 20, maxp,},
- + .stem_scaling={on, 11, 1, end}
- +},
- +{ .name="corbel",
- + .stem_translating_only={on, 10, 16, end},
- + .stem_widths={on, 10, 21, maxp}
- +},
- +{ .name="courier new",
- + .always_use_100={on, 12, 12, end},
- + .edge_detection={on, 10, 12, end},
- + .m={on, 13, 1, 14, 1, end}
- +},
- +{ .name="courier",
- + .always_use_100={on, 0, maxp, end},
- + .m={on, 13, 1, 14, 1, end},
- + .stem_translating_only={on, 13, 16, 15, 0, end}
- +},
- +{ .name="cousine",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="dejavu sans mono",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating_only={on, 7, 16, 8, 32, 9, 16, end}
- +},
- +{ .name="dejavu sans",
- + .always_use_100={on, 10, 14, 16, 17, end},
- + .m={on, 12, 0, end},
- + .stem_scaling={on, 12, 1, end},
- + .stem_translating_only={on, 8, 16, 15, -20, end}
- +},
- +{ .name="droid sans mono",
- + .m={on, 12, 0, end}
- +},
- +{ .name="droid sans",
- + .always_use_100={on, 12, 12, 15, 15, end},
- + .stem_translating_only={on, 8, 16, 9, 16, end}
- +},
- +{ .name="essential pragmatapro",
- + .always_use_100={on, 0, maxp, end},
- + .m={on, 13, 0, 14, 0, end}
- +},
- +{ .name="freemono",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="freesans",
- + .always_use_100={on, 0, maxp, end},
- + .edge_detection={on, 11, 11, 13, 13, end},
- + .spacing={on, 10, 12, 18, 18, 30, end},
- + .start={on, 10, 18, 18, 25, 30, end},
- + .stem_scaling={on, 16, 0, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 16, 9, 8, end}
- +},
- +{ .name="freeserif",
- + .stem_scaling={on, 13, 1, 17, 1, end}
- +},
- +{ .name="futura",
- + .stem_widths={on, 10, 14, sw2pv, maxp,}
- +},
- +{ .name="garamond",
- + .brightness={on, 0, -20, end},
- + .contrast={on, 0, 25, end}
- +},
- +{ .name="georgia",
- + .stem_translating_only={on, 13, 16, 14, 16, 15, 0, end}
- +},
- +{ .name="gill sans",
- + .stem_widths={on, 10, 17, sw2pv, maxp,}
- +},
- +{ .name="helvetica cy",
- + .stem_widths={on, 10, 23, maxp,}
- +},
- +{ .name="inconsolata",
- + .stem_scaling={on, 12, 1, 15, 1, end},
- + .stem_translating_only={on, 10, 24, 9, 32, end},
- + .stem_widths={on, 10, 23, maxp,},
- +},
- +{ .name="liberation mono",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="liberation sans narrow",
- + .stem_widths={on,10, 22, maxp,}
- +},
- +{ .name="liberation sans",
- + .edge_detection={on, 11, 11, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end},
- + .stem_widths={on,10, 19, maxp,}
- +},
- +{ .name="lucida console",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="lucida grande",
- + .stem_scaling={on, 13, 1, end},
- + .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end},
- + .stem_widths={on, 10, 16, sw2pv, maxp},
- +},
- +{ .name="lucida sans unicode",
- + .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end},
- + .stem_widths={on,10, 16, sw2pv, maxp,}
- +},
- +{ .name="luxi sans",
- + .always_use_100={on, 13, 13, end},
- + .stem_widths={on, 10, 17, sw2pv, maxp,}
- +},
- +{ .name="microsoft sans serif",
- + .always_use_100={on, 0, maxp, end},
- + .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end}
- +},
- +{ .name="monaco",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="myriad pro",
- + .stem_scaling={on, 14, 1, 17, 1, end},
- + .stem_translating_only={on, 10, 16, 11, 0, 9, 16, end}
- +},
- +{ .name="nina",
- + .stem_scaling={on, 11, 0, 12, 0, 13, 0, end}
- +},
- +{ .name="open sans",
- + .stem_translating_only={on, 10, 16, 9, 16, end},
- + .stem_widths={on, 10, 20, maxp,}
- +},
- +{ .name="optima",
- + .brightness={on, 0, -20, end},
- + .contrast={on, 0, 25, end},
- + .stem_scaling={on, 17, 1, end},
- + .stem_translating_only={on, 10, 0, 11, 0, 12, 0, end}
- +},
- +{ .name="palatino linotype",
- + .edge_detection={on, 0, 100, end}
- +},
- +{ .name="pragmata",
- + .always_use_100={on, 0, maxp, end}
- +},
- +{ .name="raleway",
- + .stem_scaling={on, 15, 0, end}
- +},
- +{ .name="rokkitt",
- + .stem_widths={on, 10, 21, maxp,}
- +},
- +{ .name="samba",
- + .stem_scaling={on, 11, 0, end}
- +},
- +{ .name="segoe ui",
- + .always_use_100={on, 11, 12, 14, 14, end},
- + .stem_translating_only={on, 10, 0, 7, 32, 8, 16, 9, 24, end},
- + .stem_widths={on, 10, 23, maxp,}
- +},
- +{ .name="tahoma",
- + .always_use_100={on, 11, 11, 14, maxp, end},
- + .edge_detection={on, 11, 11, end},
- + .spacing={on, 10, 12, 18, 18, 30, end},
- + .start={on, 14, 17, 30, 100, 100, end},
- + .stem_translating={on, 11, 32, end},
- + .stem_translating_only={on, 7, 32, 8, 32, 9, 32, end},
- +},
- +{ .name="times new roman",
- + .always_use_100={on, 14, 14, 16, 16, end},
- + .bearing_correction={0, 100, end},
- + .stem_scaling={on, 17, 1, end},
- + .stem_translating_only={on, 17, 8, end}
- +},
- +{ .name="trebuchet ms",
- + .always_use_100={on, 13, 13, end},
- + .stem_scaling={on, 13, 0, 17, 0, 20, 1, end},
- + .stem_translating_only={on, 10, 16, 11, 0, 8, 32, 9, 32, end},
- + .stem_widths={on, 10, 17, sw2pv, maxp,}
- +},
- +{ .name="ubuntu",
- + .always_use_100={on, 12, 13, 15, 15, end}
- +},
- +{ .name="verdana",
- + .always_use_100={on, 0, 14, 16, maxp, end},
- + .stem_scaling={on, 12, 1, 15, 1, end},
- + .stem_translating_only={on, 8, 16, 15, 16, 14, 32, 18, 32, 19, 24, end}
- +},
- +%%
- +
- +static const sa_rules_t*
- +ftinf_rules( const char *name ){
- + if( name ){
- + enum {
- + max_wlen=31
- + };
- + char buf[max_wlen+1];
- + int len=strlen( name );
- + if( len <= max_wlen ){
- + int i;
- + for( i=0; i<len; ++i )
- + buf[i]=tolower( name[i] );
- + buf[len]='\0';
- + return _rules_get( buf, len );
- + }
- + }
- + return NULL;
- +}
- +/*
- + gperf --output-file=ftinf_rh.c ftinf_rh.gperf
- +*/
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinf_sh.c a/src/base/ftinf_sh.c
- --- b/src/base/ftinf_sh.c 1970-01-01 03:00:00.000000000 +0300
- +++ a/src/base/ftinf_sh.c 2021-09-16 09:15:05.052379743 +0300
- @@ -0,0 +1,463 @@
- +/* ANSI-C code produced by gperf version 3.1 */
- +/* Command-line: gperf --output-file=ftinf_sh.c ftinf_sh.gperf */
- +/* Computed positions: -k'1,$' */
- +
- +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
- + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
- + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
- + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
- + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
- + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
- + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
- + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
- + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
- + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
- + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
- + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
- + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
- + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
- + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
- + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
- + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
- + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
- + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
- + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
- + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
- + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
- + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
- +/* The character set is not based on ISO-646. */
- +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
- +#endif
- +
- +#line 9 "ftinf_sh.gperf"
- +
- +#include <ctype.h>
- +static const struct ftinf_s* _settings_get( const char*str, unsigned len);
- +/* maximum key range = 37, duplicates = 0 */
- +
- +#ifdef __GNUC__
- +__inline
- +#else
- +#ifdef __cplusplus
- +inline
- +#endif
- +#endif
- +static unsigned int
- +_settings_hash (register const char *str, register unsigned int len)
- +{
- + static const unsigned char asso_values[] =
- + {
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 13,
- + 8, 30, 25, 20, 40, 10, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 5, 40, 0,
- + 0, 0, 40, 40, 10, 0, 40, 40, 15, 5,
- + 10, 0, 10, 40, 40, 0, 0, 0, 0, 0,
- + 0, 0, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- + 40, 40, 40, 40, 40, 40
- + };
- + return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]];
- +}
- +
- +#ifdef __GNUC__
- +__inline
- +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
- +__attribute__ ((__gnu_inline__))
- +#endif
- +#endif
- +const struct ftinf_s *
- +_settings_get (register const char *str, register unsigned int len)
- +{
- + enum
- + {
- + TOTAL_KEYWORDS = 22,
- + MIN_WORD_LENGTH = 3,
- + MAX_WORD_LENGTH = 14,
- + MIN_HASH_VALUE = 3,
- + MAX_HASH_VALUE = 39
- + };
- +
- + static const struct ftinf_s wordlist[] =
- + {
- +#line 76 "ftinf_sh.gperf"
- +{ .name="osx",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_vertical_stem_darken_strength=25,
- + .bold_embolden_x_value=16,
- + .brightness=10,
- + .contrast=20,
- + .filter_params={on, 3, 32, 38, 32, 3},
- + .gamma_correction={1000, 80},
- + .global_embolden_y_value=8,
- + .grayscale_filter_strength=25,
- +},
- +#line 37 "ftinf_sh.gperf"
- +{ .name="ipad",
- + .filter_params={on, 0, 0, 100, 0, 0},
- + .gamma_correction={1000, 80},
- + .grayscale_filter_strength=100
- +},
- +#line 114 "ftinf_sh.gperf"
- +{ .name="shove",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=100,
- + .stem_fitting_strength=100,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true
- +},
- +#line 126 "ftinf_sh.gperf"
- +{ .name="ubuntu",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_vertical_stem_darken_strength=25,
- + .brightness=-10,
- + .contrast=15,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={1000, 80},
- + .use_various_tweaks=true
- +},
- +#line 27 "ftinf_sh.gperf"
- +{ .name="classic",
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .filter_params={on, 6, 25, 38, 25, 6},
- + .gamma_correction={0, 100},
- + .use_various_tweaks=true
- +},
- +#line 34 "ftinf_sh.gperf"
- +{ .name="disabled",
- + .gamma_correction={0, 100},
- +},
- +#line 100 "ftinf_sh.gperf"
- +{ .name="sharpened",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=25,
- + .stem_fitting_strength=25,
- + .stem_snapping_sliding_scale=40,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=65
- +},
- +#line 42 "ftinf_sh.gperf"
- +{ .name="infinality",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=25,
- + .stem_fitting_strength=25,
- + .stem_snapping_sliding_scale=40,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=5
- +},
- +#line 15 "ftinf_sh.gperf"
- +{ .name="custom",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 8, 24, 48, 24, 8},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=75,
- + .stem_fitting_strength=50,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true
- +},
- +#line 180 "ftinf_sh.gperf"
- +{ .name="vanilla",
- + .filter_params={on, 6, 25, 38, 25, 6},
- + .gamma_correction={0, 100},
- +},
- +#line 184 "ftinf_sh.gperf"
- +{ .name="windows7light",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .contrast=20,
- + .filter_params={on, 20, 25, 38, 25, 05},
- + .fringe_filter_strength=100,
- + .gamma_correction={1000, 160},
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=100
- +},
- +#line 226 "ftinf_sh.gperf"
- +{ .name="windowsxplight",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .brightness=20,
- + .contrast=30,
- + .filter_params={on, 6, 25, 44, 25, 6},
- + .fringe_filter_strength=100,
- + .gamma_correction={1000, 120},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=65
- +},
- +#line 64 "ftinf_sh.gperf"
- +{ .name="nudge",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=25,
- + .stem_fitting_strength=15,
- + .stem_snapping_sliding_scale=30,
- + .use_various_tweaks=true,
- +},
- +#line 144 "ftinf_sh.gperf"
- +{ .name="ultimate2",
- + .filter_params={on, 6, 22, 36, 22, 6},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +#line 197 "ftinf_sh.gperf"
- +{ .name="windows7",
- + .filter_params={on, 20, 25, 42, 25, 06},
- + .fringe_filter_strength=100,
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_vertical_stem_darken_strength=25,
- + .windows_style_sharpening_strength=65,
- + .gamma_correction={1000, 120},
- + .brightness=10,
- + .contrast=20,
- + .use_various_tweaks=true,
- + .autohint_snap_stem_height=100,
- + .use_known_settings_on_selected_fonts=true,
- +},
- +#line 210 "ftinf_sh.gperf"
- +{ .name="windowsxp",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .brightness=10,
- + .contrast=20,
- + .filter_params={on, 6, 25, 44, 25, 6},
- + .fringe_filter_strength=100,
- + .gamma_correction={1000, 120},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=65
- +},
- +#line 56 "ftinf_sh.gperf"
- +{ .name="linux",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 6, 25, 44, 25, 6},
- + .gamma_correction={0, 100},
- + .use_various_tweaks=true
- +},
- +#line 135 "ftinf_sh.gperf"
- +{ .name="ultimate1",
- + .filter_params={on, 4, 22, 38, 22, 4},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +#line 87 "ftinf_sh.gperf"
- +{ .name="push",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=75,
- + .stem_fitting_strength=50,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true
- +},
- +#line 171 "ftinf_sh.gperf"
- +{ .name="ultimate5",
- + .filter_params={on, 12, 28, 42, 28, 12},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +#line 162 "ftinf_sh.gperf"
- +{ .name="ultimate4",
- + .filter_params={on, 10, 25, 37, 25, 10},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +#line 153 "ftinf_sh.gperf"
- +{ .name="ultimate3",
- + .filter_params={on, 8, 24, 36, 24, 8},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +}
- + };
- +
- + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- + {
- + register int key = _settings_hash (str, len);
- +
- + if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
- + {
- + register const struct ftinf_s *resword;
- +
- + switch (key - 3)
- + {
- + case 0:
- + resword = &wordlist[0];
- + goto compare;
- + case 1:
- + resword = &wordlist[1];
- + goto compare;
- + case 2:
- + resword = &wordlist[2];
- + goto compare;
- + case 3:
- + resword = &wordlist[3];
- + goto compare;
- + case 4:
- + resword = &wordlist[4];
- + goto compare;
- + case 5:
- + resword = &wordlist[5];
- + goto compare;
- + case 6:
- + resword = &wordlist[6];
- + goto compare;
- + case 7:
- + resword = &wordlist[7];
- + goto compare;
- + case 8:
- + resword = &wordlist[8];
- + goto compare;
- + case 9:
- + resword = &wordlist[9];
- + goto compare;
- + case 10:
- + resword = &wordlist[10];
- + goto compare;
- + case 11:
- + resword = &wordlist[11];
- + goto compare;
- + case 12:
- + resword = &wordlist[12];
- + goto compare;
- + case 14:
- + resword = &wordlist[13];
- + goto compare;
- + case 15:
- + resword = &wordlist[14];
- + goto compare;
- + case 16:
- + resword = &wordlist[15];
- + goto compare;
- + case 17:
- + resword = &wordlist[16];
- + goto compare;
- + case 19:
- + resword = &wordlist[17];
- + goto compare;
- + case 21:
- + resword = &wordlist[18];
- + goto compare;
- + case 26:
- + resword = &wordlist[19];
- + goto compare;
- + case 31:
- + resword = &wordlist[20];
- + goto compare;
- + case 36:
- + resword = &wordlist[21];
- + goto compare;
- + }
- + return 0;
- + compare:
- + {
- + register const char *s = resword->name;
- +
- + if (*str == *s && !strcmp (str + 1, s + 1))
- + return resword;
- + }
- + }
- + }
- + return 0;
- +}
- +#line 242 "ftinf_sh.gperf"
- +
- +
- +static const ftinf_t*
- +ftinf_settings( const char *name ){
- + if( name ){
- + enum {
- + max_wlen=31
- + };
- + char buf[max_wlen+1];
- + int len=strlen( name );
- + if( len <= max_wlen ){
- + int i;
- + for( i=0; i<len; ++i )
- + buf[i]=tolower( name[i] );
- + buf[len]='\0';
- + return _settings_get( buf, len );
- + }
- + }
- + return NULL;
- +}
- +/*
- + gperf --output-file=ftinf_sh.c ftinf_sh.gperf
- +*/
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinf_sh.gperf a/src/base/ftinf_sh.gperf
- --- b/src/base/ftinf_sh.gperf 1970-01-01 03:00:00.000000000 +0300
- +++ a/src/base/ftinf_sh.gperf 2021-09-16 09:15:05.052379743 +0300
- @@ -0,0 +1,264 @@
- +%struct-type
- +%define slot-name name
- +%enum
- +%switch=1
- +%readonly-tables
- +%omit-struct-type
- +%define lookup-function-name _settings_get
- +%define hash-function-name _settings_hash
- +%{
- +#include <ctype.h>
- +static const struct ftinf_s* _settings_get( const char*str, unsigned len);
- +%}
- +struct ftinf_s;
- +%%
- +{ .name="custom",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 8, 24, 48, 24, 8},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=75,
- + .stem_fitting_strength=50,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true
- +},
- +{ .name="classic",
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .filter_params={on, 6, 25, 38, 25, 6},
- + .gamma_correction={0, 100},
- + .use_various_tweaks=true
- +},
- +{ .name="disabled",
- + .gamma_correction={0, 100},
- +},
- +{ .name="ipad",
- + .filter_params={on, 0, 0, 100, 0, 0},
- + .gamma_correction={1000, 80},
- + .grayscale_filter_strength=100
- +},
- +{ .name="infinality",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=25,
- + .stem_fitting_strength=25,
- + .stem_snapping_sliding_scale=40,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=5
- +},
- +{ .name="linux",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 6, 25, 44, 25, 6},
- + .gamma_correction={0, 100},
- + .use_various_tweaks=true
- +},
- +{ .name="nudge",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=25,
- + .stem_fitting_strength=15,
- + .stem_snapping_sliding_scale=30,
- + .use_various_tweaks=true,
- +},
- +{ .name="osx",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_vertical_stem_darken_strength=25,
- + .bold_embolden_x_value=16,
- + .brightness=10,
- + .contrast=20,
- + .filter_params={on, 3, 32, 38, 32, 3},
- + .gamma_correction={1000, 80},
- + .global_embolden_y_value=8,
- + .grayscale_filter_strength=25,
- +},
- +{ .name="push",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=75,
- + .stem_fitting_strength=50,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true
- +},
- +{ .name="sharpened",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=25,
- + .stem_fitting_strength=25,
- + .stem_snapping_sliding_scale=40,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=65
- +},
- +{ .name="shove",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_increase_glyph_heights=true,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=100,
- + .stem_fitting_strength=100,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true
- +},
- +{ .name="ubuntu",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_vertical_stem_darken_strength=25,
- + .brightness=-10,
- + .contrast=15,
- + .filter_params={on, 11, 22, 38, 22, 11},
- + .gamma_correction={1000, 80},
- + .use_various_tweaks=true
- +},
- +{ .name="ultimate1",
- + .filter_params={on, 4, 22, 38, 22, 4},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +{ .name="ultimate2",
- + .filter_params={on, 6, 22, 36, 22, 6},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +{ .name="ultimate3",
- + .filter_params={on, 8, 24, 36, 24, 8},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +{ .name="ultimate4",
- + .filter_params={on, 10, 25, 37, 25, 10},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +{ .name="ultimate5",
- + .filter_params={on, 12, 28, 42, 28, 12},
- + .fringe_filter_strength=25,
- + .gamma_correction={0, 100},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=25
- +},
- +{ .name="vanilla",
- + .filter_params={on, 6, 25, 38, 25, 6},
- + .gamma_correction={0, 100},
- +},
- +{ .name="windows7light",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .contrast=20,
- + .filter_params={on, 20, 25, 38, 25, 05},
- + .fringe_filter_strength=100,
- + .gamma_correction={1000, 160},
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=100
- +},
- +{ .name="windows7",
- + .filter_params={on, 20, 25, 42, 25, 06},
- + .fringe_filter_strength=100,
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_vertical_stem_darken_strength=25,
- + .windows_style_sharpening_strength=65,
- + .gamma_correction={1000, 120},
- + .brightness=10,
- + .contrast=20,
- + .use_various_tweaks=true,
- + .autohint_snap_stem_height=100,
- + .use_known_settings_on_selected_fonts=true,
- +},
- +{ .name="windowsxp",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .brightness=10,
- + .contrast=20,
- + .filter_params={on, 6, 25, 44, 25, 6},
- + .fringe_filter_strength=100,
- + .gamma_correction={1000, 120},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=65
- +},
- +{ .name="windowsxplight",
- + .autohint_horizontal_stem_darken_strength=10,
- + .autohint_snap_stem_height=100,
- + .autohint_vertical_stem_darken_strength=25,
- + .brightness=20,
- + .contrast=30,
- + .filter_params={on, 6, 25, 44, 25, 6},
- + .fringe_filter_strength=100,
- + .gamma_correction={1000, 120},
- + .stem_alignment_strength=15,
- + .stem_fitting_strength=15,
- + .stem_snapping_sliding_scale=30,
- + .use_known_settings_on_selected_fonts=true,
- + .use_various_tweaks=true,
- + .windows_style_sharpening_strength=65
- +},
- +%%
- +
- +static const ftinf_t*
- +ftinf_settings( const char *name ){
- + if( name ){
- + enum {
- + max_wlen=31
- + };
- + char buf[max_wlen+1];
- + int len=strlen( name );
- + if( len <= max_wlen ){
- + int i;
- + for( i=0; i<len; ++i )
- + buf[i]=tolower( name[i] );
- + buf[len]='\0';
- + return _settings_get( buf, len );
- + }
- + }
- + return NULL;
- +}
- +/*
- + gperf --output-file=ftinf_sh.c ftinf_sh.gperf
- +*/
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftinit.c a/src/base/ftinit.c
- --- b/src/base/ftinit.c 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/base/ftinit.c 2021-09-16 09:15:05.052379743 +0300
- @@ -43,6 +43,10 @@
- #include <freetype/internal/ftdebug.h>
- #include <freetype/ftmodapi.h>
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "ftinf.h"
- +#endif
- +
-
- /**************************************************************************
- *
- @@ -224,10 +228,14 @@
- error = FT_New_Library( memory, alibrary );
- if ( error )
- FT_Done_Memory( memory );
- - else
- + else {
- FT_Add_Default_Modules( *alibrary );
- -
- FT_Set_Default_Properties( *alibrary );
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* get Infinality settings */
- + ftinf_env();
- +#endif
- + }
-
- return error;
- }
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftlcdfil.c a/src/base/ftlcdfil.c
- --- b/src/base/ftlcdfil.c 2021-07-05 06:41:53.000000000 +0300
- +++ a/src/base/ftlcdfil.c 2021-09-16 09:15:05.052379743 +0300
- @@ -17,11 +17,15 @@
-
-
- #include <freetype/internal/ftdebug.h>
- -
- #include <freetype/ftlcdfil.h>
- #include <freetype/ftimage.h>
- #include <freetype/internal/ftobjs.h>
-
- +#include <math.h>
- +#include <string.h>
- +#include <strings.h>
- +#include "ftinf.h"
- +
-
- #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
-
- @@ -76,13 +80,13 @@
- /* FIR filter used by the default and light filters */
- FT_BASE_DEF( void )
- ft_lcd_filter_fir( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- FT_LcdFiveTapFilter weights )
- {
- FT_UInt width = (FT_UInt)bitmap->width;
- FT_UInt height = (FT_UInt)bitmap->rows;
- FT_Int pitch = bitmap->pitch;
- FT_Byte* origin = bitmap->buffer;
- - FT_Byte mode = bitmap->pixel_mode;
-
-
- /* take care of bitmap flow */
- @@ -90,7 +94,7 @@
- origin += pitch * (FT_Int)( height - 1 );
-
- /* horizontal in-place FIR filter */
- - if ( mode == FT_PIXEL_MODE_LCD && width >= 2 )
- + if ( mode == FT_RENDER_MODE_LCD && width >= 2 )
- {
- FT_Byte* line = origin;
-
- @@ -133,7 +137,7 @@
- }
-
- /* vertical in-place FIR filter */
- - else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 2 )
- + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 )
- {
- FT_Byte* column = origin;
-
- @@ -182,13 +186,13 @@
- /* intra-pixel filter used by the legacy filter */
- static void
- _ft_lcd_filter_legacy( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- FT_Byte* weights )
- {
- FT_UInt width = (FT_UInt)bitmap->width;
- FT_UInt height = (FT_UInt)bitmap->rows;
- FT_Int pitch = bitmap->pitch;
- FT_Byte* origin = bitmap->buffer;
- - FT_Byte mode = bitmap->pixel_mode;
-
- static const unsigned int filters[3][3] =
- {
- @@ -205,7 +209,7 @@
- origin += pitch * (FT_Int)( height - 1 );
-
- /* horizontal in-place intra-pixel filter */
- - if ( mode == FT_PIXEL_MODE_LCD && width >= 3 )
- + if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
- {
- FT_Byte* line = origin;
-
- @@ -242,7 +246,7 @@
- }
- }
- }
- - else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 3 )
- + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
- {
- FT_Byte* column = origin;
-
- @@ -298,6 +302,7 @@
-
- ft_memcpy( library->lcd_weights, weights, FT_LCD_FILTER_FIVE_TAPS );
- library->lcd_filter_func = ft_lcd_filter_fir;
- + library->lcd_extra = 2;
-
- return FT_Err_Ok;
- }
- @@ -309,11 +314,37 @@
- FT_Library_SetLcdFilter( FT_Library library,
- FT_LcdFilter filter )
- {
- - static const FT_LcdFiveTapFilter default_weights =
- - { 0x08, 0x4d, 0x56, 0x4d, 0x08 };
- static const FT_LcdFiveTapFilter light_weights =
- { 0x00, 0x55, 0x56, 0x55, 0x00 };
-
- +#ifndef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + static const FT_LcdFiveTapFilter default_weights =
- + { 0x08, 0x4d, 0x56, 0x4d, 0x08 };
- +#else
- + FT_LcdFiveTapFilter default_weights;
- + if( ftinf && ftinf->filter_params[0] )
- + {
- + const int *f=ftinf->filter_params;
- + /* Assume we were given integers [0-100] get them to [0-255] */
- + int val; /* 2611=2.55*1024 */
- + val=(f[1]*2611+512)>>10; if( val > 255 ) val=255;
- + default_weights[0] = (FT_Byte) val;
- + val=(f[2]*2611+512)>>10; if( val > 255 ) val=255;
- + default_weights[1] = (FT_Byte) val;
- + val=(f[3]*2611+512)>>10; if( val > 255 ) val=255;
- + default_weights[2] = (FT_Byte) val;
- + val=(f[4]*2611+512)>>10; if( val > 255 ) val=255;
- + default_weights[3] = (FT_Byte) val;
- + val=(f[5]*2611+512)>>10; if( val > 255 ) val=255;
- + default_weights[4] = (FT_Byte) val;
- + } else {
- + default_weights[0]=0x08;
- + default_weights[1]=0x4d;
- + default_weights[2]=0x56;
- + default_weights[3]=0x4d;
- + default_weights[4]=0x08;
- + }
- +#endif
-
- if ( !library )
- return FT_THROW( Invalid_Library_Handle );
- @@ -322,6 +353,7 @@
- {
- case FT_LCD_FILTER_NONE:
- library->lcd_filter_func = NULL;
- + library->lcd_extra = 0;
- break;
-
- case FT_LCD_FILTER_DEFAULT:
- @@ -329,6 +361,7 @@
- default_weights,
- FT_LCD_FILTER_FIVE_TAPS );
- library->lcd_filter_func = ft_lcd_filter_fir;
- + library->lcd_extra = 2;
- break;
-
- case FT_LCD_FILTER_LIGHT:
- @@ -336,6 +369,7 @@
- light_weights,
- FT_LCD_FILTER_FIVE_TAPS );
- library->lcd_filter_func = ft_lcd_filter_fir;
- + library->lcd_extra = 2;
- break;
-
- #ifdef USE_LEGACY
- @@ -343,6 +377,7 @@
- case FT_LCD_FILTER_LEGACY:
- case FT_LCD_FILTER_LEGACY1:
- library->lcd_filter_func = _ft_lcd_filter_legacy;
- + library->lcd_extra = 0;
- break;
-
- #endif
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftobjs.c a/src/base/ftobjs.c
- --- b/src/base/ftobjs.c 2021-07-15 13:09:04.000000000 +0300
- +++ a/src/base/ftobjs.c 2021-09-16 09:15:05.053379751 +0300
- @@ -45,7 +45,9 @@
- #ifdef FT_CONFIG_OPTION_MAC_FONTS
- #include "ftbase.h"
- #endif
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "ftinf.h"
- +#endif
-
- #ifdef FT_DEBUG_LEVEL_TRACE
-
- @@ -99,6 +101,11 @@
-
- #define GRID_FIT_METRICS
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include <strings.h>
- +#include <stdlib.h>
- +#include "../autofit/aflatin.h"
- +#endif
-
- /* forward declaration */
- static FT_Error
- @@ -777,6 +784,25 @@
- ft_lookup_glyph_renderer( FT_GlyphSlot slot );
-
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + static void
- + ft_glyphslot_enlarge_metrics( FT_GlyphSlot slot,
- + FT_Render_Mode mode )
- + {
- + FT_Glyph_Metrics* metrics = &slot->metrics;
- + FT_Pos enlarge_cbox = 0;
- +
- +
- + /* enlarge for grayscale rendering */
- + if ( mode == FT_RENDER_MODE_NORMAL )
- + enlarge_cbox = 64;
- +
- + metrics->horiBearingX -= enlarge_cbox;
- + metrics->width += 2 * enlarge_cbox;
- + }
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- +
- +
- #ifdef GRID_FIT_METRICS
- static void
- ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot,
- @@ -843,8 +869,18 @@
- FT_Bool autohint = FALSE;
- FT_Module hinter;
- TT_Face ttface = (TT_Face)face;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
-
- + FT_Bool use_various_tweaks = FALSE;
- + if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks;
-
- + /* Force autohint if no tt instructions */
- + /* NOTE: NEEDS TO BE RUN LATER IN CODE???? */
- + /*if ( use_various_tweaks &&
- + ttface->num_locations &&
- + ttface->max_profile.maxSizeOfInstructions == 0 )
- + load_flags |= FT_LOAD_FORCE_AUTOHINT;*/
- +#endif
- if ( !face || !face->size || !face->glyph )
- return FT_THROW( Invalid_Face_Handle );
-
- @@ -946,6 +982,18 @@
- {
- FT_AutoHinter_Interface hinting;
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( use_various_tweaks )
- + {
- + /* Force slight hinting over full hinting always */
- + load_flags &= ~FT_LOAD_TARGET_LCD;
- + load_flags &= ~FT_LOAD_TARGET_LCD_V;
- + load_flags &= ~FT_LOAD_TARGET_MONO;
- + load_flags &= ~FT_LOAD_TARGET_NORMAL;
- + load_flags |= FT_LOAD_TARGET_LIGHT;
- + /*printf("%d ", load_flags);*/
- + }
- +#endif
-
- /* try to load embedded bitmaps first if available */
- /* */
- @@ -991,6 +1039,18 @@
- if ( error )
- goto Exit;
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + infinality_cur_width = 0;
- +
- + {
- + /* fix for sdl_ttf */
- + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
- +
- + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
- + ft_glyphslot_enlarge_metrics( slot, mode );
- + }
- +#endif
- +
- if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
- {
- /* check that the loaded outline is correct */
- @@ -5353,6 +5413,11 @@
- /* That's ok now */
- *alibrary = library;
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* get Infinality settings */
- + ftinf_env();
- +#endif
- +
- return FT_Err_Ok;
- }
-
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftoutln.c a/src/base/ftoutln.c
- --- b/src/base/ftoutln.c 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/base/ftoutln.c 2021-09-16 09:15:05.053379751 +0300
- @@ -22,6 +22,9 @@
- #include <freetype/internal/ftdebug.h>
- #include <freetype/fttrigon.h>
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "ftinf.h"
- +#endif
-
- /**************************************************************************
- *
- @@ -907,8 +910,14 @@
- {
- FT_Vector* points;
- FT_Int c, first, last;
- - FT_Orientation orientation;
- -
- + FT_Int orientation;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + FT_Bool use_various_tweaks = FALSE;
- + if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks;
- +
- + if ( use_various_tweaks )
- + ystrength = FT_PIX_FLOOR ( ystrength );
- +#endif
-
- if ( !outline )
- return FT_THROW( Invalid_Outline );
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/ftsynth.c a/src/base/ftsynth.c
- --- b/src/base/ftsynth.c 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/base/ftsynth.c 2021-09-16 09:15:05.053379751 +0300
- @@ -22,6 +22,9 @@
- #include <freetype/ftoutln.h>
- #include <freetype/ftbitmap.h>
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "ftinf.h"
- +#endif
-
- /**************************************************************************
- *
- @@ -92,7 +95,10 @@
- FT_Face face;
- FT_Error error;
- FT_Pos xstr, ystr;
- -
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + FT_Bool use_various_tweaks = FALSE;
- + if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks;
- +#endif
-
- if ( !slot )
- return;
- @@ -110,8 +116,16 @@
- ystr = xstr;
-
- if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
- + {
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( use_various_tweaks )
- + (void)FT_Outline_EmboldenXY( &slot->outline,
- + xstr,
- + FT_PIX_FLOOR( ystr ) );
- + else
- +#endif
- FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
- -
- + }
- else /* slot->format == FT_GLYPH_FORMAT_BITMAP */
- {
- /* round to full pixels */
- @@ -149,6 +163,9 @@
-
- slot->metrics.width += xstr;
- slot->metrics.height += ystr;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( !use_various_tweaks )
- +#endif
- slot->metrics.horiAdvance += xstr;
- slot->metrics.vertAdvance += ystr;
- slot->metrics.horiBearingY += ystr;
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/base/rules.mk a/src/base/rules.mk
- --- b/src/base/rules.mk 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/base/rules.mk 2021-09-16 09:15:05.053379751 +0300
- @@ -44,6 +44,7 @@
- $(BASE_DIR)/ftfntfmt.c \
- $(BASE_DIR)/ftgloadr.c \
- $(BASE_DIR)/fthash.c \
- + $(BASE_DIR)/ftinf.c \
- $(BASE_DIR)/ftlcdfil.c \
- $(BASE_DIR)/ftobjs.c \
- $(BASE_DIR)/ftoutln.c \
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/cff/cffobjs.c a/src/cff/cffobjs.c
- --- b/src/cff/cffobjs.c 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/cff/cffobjs.c 2021-09-16 09:15:05.053379751 +0300
- @@ -42,6 +42,9 @@
- #include <freetype/internal/psaux.h>
- #include <freetype/internal/services/svcfftl.h>
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include "../base/ftinf.h"
- +#endif
-
- /**************************************************************************
- *
- @@ -1177,6 +1180,9 @@
- driver->hinting_engine = FT_HINTING_ADOBE;
-
- driver->no_stem_darkening = TRUE;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if(ftinf) driver->no_stem_darkening = !ftinf->stem_darkening_cff;
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
-
- driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
- driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
- diff -Nbur --exclude builds --exclude '*.orig' --exclude objs b/src/smooth/ftsmooth.c a/src/smooth/ftsmooth.c
- --- b/src/smooth/ftsmooth.c 2021-02-13 10:16:54.000000000 +0200
- +++ a/src/smooth/ftsmooth.c 2021-09-16 09:19:36.749340217 +0300
- @@ -24,6 +24,28 @@
-
- #include "ftsmerrs.h"
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +#include <math.h>
- +#include FT_BITMAP_H
- +#include <string.h>
- +#include <strings.h>
- +#include FT_OUTLINE_H
- +#include "../base/ftinf.h"
- +
- +#define verbose FALSE
- +#define STVALUES if (verbose) \
- + printf ( "scale:%f translate:%ld ", *scale_value, *translate_value );
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
- +
- + /* initialize renderer -- init its raster */
- + static FT_Error
- + ft_smooth_init( FT_Renderer render )
- + {
- + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
- +
- + return 0;
- + }
- +
-
- /* sets render-specific mode */
- static FT_Error
- @@ -76,367 +98,2440 @@
- FT_Outline_Get_CBox( &slot->outline, cbox );
- }
-
- - typedef struct TOrigin_
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + static FT_Fixed FT_FixedFromFloat(float f)
- {
- - unsigned char* origin; /* pixmap origin at the bottom-left */
- - int pitch; /* pitch to go down one row */
- + short value = f;
- + unsigned short fract = (f - value) * 0xFFFF;
-
- - } TOrigin;
-
- -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- + return (FT_Fixed)((long)value << 16 | (unsigned long)fract );
- + }
-
- - /* initialize renderer -- init its raster */
- - static FT_Error
- - ft_smooth_init( FT_Renderer render )
- +
- + /* ChromeOS sharpening algorithm */
- + /* soften the sub-pixel anti-aliasing and sharpen */
- + static void
- + _ft_lcd_chromeos_sharpen( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_Byte cutoff,
- + double gamma_value )
- + {
- + static FT_Bool initialized_gamma = FALSE;
- + static unsigned short gamma_ramp[256];
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + int ii;
- +
- + if ( !initialized_gamma )
- + {
- + initialized_gamma = TRUE;
- + /* linear to voltage */
- + for ( ii = 0; ii < 256; ii++ )
- + {
- + gamma_ramp[ii] = (unsigned char)
- + ( pow( (double)ii / 255.0, gamma_value ) * 255.0f );
- + if ( gamma_ramp[ii] < cutoff )
- + gamma_ramp[ii] = 0;
- + }
- + }
- +
- + /* horizontal in-place sub-pixel sharpening filter */
- + if ( mode == FT_RENDER_MODE_LCD )
- {
- - FT_Vector* sub = render->root.library->lcd_geometry;
- + FT_Byte* line = bitmap->buffer;
-
-
- - /* set up default subpixel geometry for striped RGB panels. */
- - sub[0].x = -21;
- - sub[0].y = 0;
- - sub[1].x = 0;
- - sub[1].y = 0;
- - sub[2].x = 21;
- - sub[2].y = 0;
- + for ( ; height > 0; height--, line += bitmap->pitch )
- + {
- + FT_UInt xx;
-
- - render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
-
- - return 0;
- + for ( xx = 0; xx < width; xx++ )
- + line[xx] = gamma_ramp[line[xx]];
- + }
- + }
- + }
- +
- + /* simple linear scale to handle various sliding values */
- + float
- + sliding_scale ( int min_value,
- + int max_value,
- + float min_amount,
- + float max_amount,
- + int cur_value )
- + {
- +
- + float m = ( min_amount - max_amount ) / (float)( min_value - max_value );
- + float result = ( ( (float)cur_value * m) + ( max_amount - max_value * m ) ) ;
- +
- + if ( min_amount < max_amount )
- + {
- + if ( result < min_amount )
- + return min_amount;
- + if ( result > max_amount )
- + return max_amount;
- + }
- + else
- + {
- + if ( result < max_amount )
- + return max_amount;
- + if ( result > min_amount )
- + return min_amount;
- + }
- +
- + return result;
- + }
- +
- +
- + /* brightness and contrast adjustment on the bitmap */
- + static FT_Bool
- + _ft_bitmap_bc ( FT_Bitmap* bitmap,
- + float brightness,
- + float contrast )
- + {
- +
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* line = bitmap->buffer;
- + FT_UInt xx;
- +
- +
- + if ( brightness == 0 && contrast == 0 )
- + return FALSE;
- +
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch )
- + {
- + for ( xx = 0; xx < width - 1; xx += 1 )
- + {
- + if ( line[xx] > 0)
- + {
- + float value = (float)( 255 - line[xx] ) / 256.0;
- + FT_Int result = 0;
- +
- + if ( brightness < 0.0 )
- + value = value * ( 1.0 + brightness );
- + else
- + value = value + ( ( 1.0 - value ) * brightness );
- +
- + value = ( value - 0.5 ) *
- + ( tan ( ( contrast + 1.0 ) * 3.141592/4.0 ) ) + 0.5;
- +
- + result = (FT_Int)( 255.0 - value * 256.0 );
- +
- + if ( result < 0 )
- + result = 0;
- + if ( result > 255 )
- + result = 255;
- +
- + line[xx] = result;
- + }
- + }
- + }
- + return TRUE;
- }
-
-
- - /* This function writes every third byte in direct rendering mode */
- + /* Filter to mimic Windows-style sharpening */
- + /* Determined via 100% experimentation. */
- static void
- - ft_smooth_lcd_spans( int y,
- - int count,
- - const FT_Span* spans,
- - TOrigin* target )
- + _ft_lcd_windows_sharpen( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_UInt strength,
- + FT_Library library )
- + {
- +
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* new_line;
- + FT_Byte* line = bitmap->buffer;
- + FT_Bitmap new_bitmap;
- +
- +
- + FT_Bitmap_Init( &new_bitmap );
- + FT_Bitmap_Copy( library, bitmap, &new_bitmap );
- + new_line = (&new_bitmap)->buffer;
- +
- + if (strength > 0)
- + for (height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch, new_line += bitmap->pitch )
- + {
- + FT_UInt xx, threshold = 128;
- + FT_Byte* prevline = line - bitmap->pitch;
- + FT_Byte* nextline = line + bitmap->pitch;
- + FT_Byte* new_prevline = new_line - bitmap->pitch;
- + FT_Byte* new_nextline = new_line + bitmap->pitch;
- +
- + for ( xx = 1; xx < width - 1; xx += 1 )
- {
- - unsigned char* dst_line = target->origin - y * target->pitch;
- - unsigned char* dst;
- - unsigned short w;
- + /* subpixel grid sp11 sp21 sp31 */
- + /* where sp22 is sp12 sp22 sp32 */
- + /* current subpixel. sp13 sp23 sp33 */
- +
- + FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff,
- + prevdiff, nextdiff, sp11, sp21, sp31, sp12, sp22, sp32,
- + sp13, sp23, sp33;
- +
- + sp12 = line [xx-1];
- + sp22 = line [xx];
- + sp32 = line [xx+1];
-
- + if ( height == bitmap->rows )
- + {
- + prevtotal = sp11 = sp21 = sp31 = 0;
- + prevdiff = sp22;
- + lefttotal = sp12 + sp13;
- + righttotal = sp32 + sp33;
- + }
- + else
- + {
- + prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1];
- + sp11 = prevline [xx-1];
- + sp21 = prevline [xx];
- + sp31 = prevline [xx+1];
- + prevdiff = sp22 - sp21;
- + lefttotal = sp11 + sp12 + sp13;
- + righttotal = sp31 + sp32 + sp33;
- + }
-
- - for ( ; count--; spans++ )
- - for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 )
- - *dst = spans->coverage;
- + if ( height == 1 )
- + {
- + nexttotal = sp13 = sp23 = sp33 = 0;
- + nextdiff = sp22;
- + lefttotal = sp11 + sp12;
- + righttotal = sp31 + sp32;
- + }
- + else
- + {
- + nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1];
- + sp13 = nextline [xx-1];
- + sp23 = nextline [xx];
- + sp33 = nextline [xx+1];
- + nextdiff = sp23 - sp22;
- + lefttotal = sp11 + sp12 + sp13;
- + righttotal = sp31 + sp32 + sp33;
- }
-
- + sidesdiff = lefttotal - righttotal;
-
- - static FT_Error
- - ft_smooth_raster_lcd( FT_Renderer render,
- - FT_Outline* outline,
- - FT_Bitmap* bitmap )
- + if ( sidesdiff < 0 )
- + sidesdiff *= -1;
- +
- + if ( prevdiff < 0 )
- + prevdiff *= -1;
- +
- + if ( nextdiff < 0 )
- + nextdiff *= -1;
- +
- + /* if the current pixel is less than threshold, and greater than 0 */
- + if ( sp22 <= threshold && sp22 > 0 )
- {
- - FT_Error error = FT_Err_Ok;
- - FT_Vector* sub = render->root.library->lcd_geometry;
- - FT_Pos x, y;
- + /* A pixel is horizontally isolated if: */
- + /* 1: All upper adjecent pixels are >= threshold */
- + if ( prevtotal >= nexttotal &&
- + abs( sp11 - sp12 ) > 5 &&
- + abs( sp21 - sp22 ) > 5 &&
- + abs( sp31 - sp32 ) > 5 && /* not a vert stem end */
- + sp11 >= threshold &&
- + sp21 >= threshold &&
- + sp31 >= threshold &&
- + abs( sp23 - sp22 ) > 15 ) /* not on a vert stem */
- + {
- + /* darken upper adjacent subpixel; lighten current */
- + if ( height != (FT_UInt)bitmap->rows )
- + new_prevline[xx] += ( ( 255 - new_prevline[xx] )
- + * strength ) / 100 ;
-
- - FT_Raster_Params params;
- - TOrigin target;
- + new_line[xx] -= ( new_line[xx] * strength ) / 100;
-
- + if ( height != 1 && height != (FT_UInt)bitmap->rows )
- + if ( new_nextline[xx] > 155 + ( 100 - strength ) )
- + new_prevline[xx] = 255;
-
- - /* Render 3 separate coverage bitmaps, shifting the outline. */
- - /* Set up direct rendering to record them on each third byte. */
- - params.source = outline;
- - params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
- - params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans;
- - params.user = ⌖
- -
- - params.clip_box.xMin = 0;
- - params.clip_box.yMin = 0;
- - params.clip_box.xMax = bitmap->width;
- - params.clip_box.yMax = bitmap->rows;
- -
- - if ( bitmap->pitch < 0 )
- - target.origin = bitmap->buffer;
- - else
- - target.origin = bitmap->buffer
- - + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
- -
- - target.pitch = bitmap->pitch;
- -
- - FT_Outline_Translate( outline,
- - -sub[0].x,
- - -sub[0].y );
- - error = render->raster_render( render->raster, ¶ms );
- - x = sub[0].x;
- - y = sub[0].y;
- - if ( error )
- - goto Exit;
- + }
- + else if ( nexttotal > prevtotal &&
- + abs( sp13 - sp12 ) > 5 &&
- + abs( sp23 - sp22 ) > 5 &&
- + abs( sp33 - sp32 ) > 5 &&
- + /* 2: All lower adjecent pixels are >= threshold */
- + sp13 >= threshold &&
- + sp23 >= threshold &&
- + sp33 >= threshold &&
- + abs( sp22 - sp21 ) > 15 )
- + {
- + /* darken lower adjacent subpixel; lighten current */
- + if ( height != 1 )
- + new_nextline[xx] += ( 255 - new_nextline[xx] ) * strength / 100;
-
- - target.origin++;
- - FT_Outline_Translate( outline,
- - sub[0].x - sub[1].x,
- - sub[0].y - sub[1].y );
- - error = render->raster_render( render->raster, ¶ms );
- - x = sub[1].x;
- - y = sub[1].y;
- - if ( error )
- - goto Exit;
- + new_line[xx] -= ( new_line[xx] * strength ) / 100;
-
- - target.origin++;
- - FT_Outline_Translate( outline,
- - sub[1].x - sub[2].x,
- - sub[1].y - sub[2].y );
- - error = render->raster_render( render->raster, ¶ms );
- - x = sub[2].x;
- - y = sub[2].y;
- + if ( height != 1 )
- + if ( new_nextline[xx] > 155 + ( 100 - strength ) )
- + new_nextline[xx] = 255;
-
- - Exit:
- - FT_Outline_Translate( outline, x, y );
- + }
- + }
- + else if ( sp22 > threshold && sp22 < 255 )
- + {
- + if ( sp11 <= threshold &&
- + abs( sp13 - sp12 ) > 5 &&
- + abs( sp23 - sp22 ) > 5 &&
- + abs( sp33 - sp32 ) > 5 &&
- + sp21 <= threshold &&
- + sp31 <= threshold &&
- + prevtotal <= nexttotal &&
- + abs( sp22 - sp21 ) > 15 )
- + {
- + /* bring this subpixel 1/3 of the way to 255 at 100% strength */
- + new_line[xx] += ( strength * ( 255 - new_line[xx] ) ) / 100;
-
- - return error;
- + if ( height != (FT_UInt)bitmap->rows )
- + new_prevline[xx] -= ( new_prevline[xx] * strength ) / 300;
- }
- + else if ( sp13 <= threshold &&
- + abs( sp11 - sp12 ) > 5 &&
- + abs( sp21 - sp22 ) > 5 &&
- + abs( sp31 - sp32 ) > 5 &&
- + sp23 <= threshold &&
- + sp33 <= threshold &&
- + nexttotal < prevtotal &&
- + abs( sp23 - sp22 ) > 15 )
- + {
- + new_line[xx] += ( strength * ( 255 - new_line[xx] ) ) / 100;
-
- + if ( height != 1 )
- + new_nextline[xx] -= ( new_nextline[xx] * strength ) / 300;
- + }
- + }
- + }
- + }
- + FT_Bitmap_Copy( library, &new_bitmap, bitmap);
- + FT_Bitmap_Done( library, &new_bitmap );
- + }
-
- - static FT_Error
- - ft_smooth_raster_lcdv( FT_Renderer render,
- - FT_Outline* outline,
- - FT_Bitmap* bitmap )
- +
- + static void
- + _ft_lcd_darken_x ( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_UInt strength,
- + FT_Library library )
- {
- - FT_Error error = FT_Err_Ok;
- - int pitch = bitmap->pitch;
- - FT_Vector* sub = render->root.library->lcd_geometry;
- - FT_Pos x, y;
-
- - FT_Raster_Params params;
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* new_line;
- + FT_Byte* line = bitmap->buffer;
- + FT_Bitmap new_bitmap;
- + int factor1, factor2;
- + int bias = 0;
-
- + FT_Bitmap_Init( &new_bitmap );
-
- - params.target = bitmap;
- - params.source = outline;
- - params.flags = FT_RASTER_FLAG_AA;
- + FT_Bitmap_Copy( library, bitmap, &new_bitmap );
- + new_line = (&new_bitmap)->buffer;
-
- - /* Render 3 separate coverage bitmaps, shifting the outline. */
- - /* Notice that the subpixel geometry vectors are rotated. */
- - /* Triple the pitch to render on each third row. */
- - bitmap->pitch *= 3;
- - bitmap->rows /= 3;
- -
- - FT_Outline_Translate( outline,
- - -sub[0].y,
- - sub[0].x );
- - error = render->raster_render( render->raster, ¶ms );
- - x = sub[0].y;
- - y = -sub[0].x;
- - if ( error )
- - goto Exit;
- + if ( strength > 0 )
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch, new_line += bitmap->pitch )
- + {
- + FT_UInt xx;
- + FT_Byte* prevline = line - bitmap->pitch;
- + FT_Byte* nextline = line + bitmap->pitch;
-
- - bitmap->buffer += pitch;
- - FT_Outline_Translate( outline,
- - sub[0].y - sub[1].y,
- - sub[1].x - sub[0].x );
- - error = render->raster_render( render->raster, ¶ms );
- - x = sub[1].y;
- - y = -sub[1].x;
- - bitmap->buffer -= pitch;
- - if ( error )
- - goto Exit;
- + for ( xx = 1; xx < width - 1; xx += 1 )
- + {
- + /* subpixel grid sp11 sp21 sp31 */
- + /* where sp22 is sp12 sp22 sp32 */
- + /* current subpixel. sp13 sp23 sp33 */
-
- - bitmap->buffer += 2 * pitch;
- - FT_Outline_Translate( outline,
- - sub[1].y - sub[2].y,
- - sub[2].x - sub[1].x );
- - error = render->raster_render( render->raster, ¶ms );
- - x = sub[2].y;
- - y = -sub[2].x;
- - bitmap->buffer -= 2 * pitch;
- + FT_Int sp21, sp12, sp22, sp32, sp23;
-
- - Exit:
- - FT_Outline_Translate( outline, x, y );
- + sp12 = line [xx-1];
- + sp22 = line [xx];
- + sp32 = line [xx+1];
-
- - bitmap->pitch /= 3;
- - bitmap->rows *= 3;
- + if ( height == bitmap->rows )
- + sp21 = 0;
- + else
- + sp21 = prevline [xx];
- +
- + if ( height == 1 )
- + sp23 = 0;
- + else
- + sp23 = nextline [xx];
- +
- + /* darken subpixel if neighbor above and below are much less than */
- + /* safer but less effective */
- + factor1 = 5;
- + factor2 = 5;
- +
- + /* make matches in the middle of glyph slightly darker */
- + /*if (height > 1 && height < (FT_UInt)bitmap->rows) bias = 1;*/
- +
- + if ( sp22 > factor1 * sp21 &&
- + sp22 > factor1 * sp23 &&
- + sp22 > factor2 &&
- + sp12 > 16 &&
- + sp32 > 16 )
- + if ( new_line[xx] < ( strength * 255 ) / 100 )
- + new_line[xx] = (strength * 255 ) / 100
- + + bias * ( 255 - ( strength * 255 ) / 100 ) / 3;
-
- - return error;
- + }
- + }
- + FT_Bitmap_Copy( library, &new_bitmap, bitmap );
- + FT_Bitmap_Done( library, &new_bitmap );
- }
-
- -#else /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
- - /* initialize renderer -- init its raster */
- - static FT_Error
- - ft_smooth_init( FT_Renderer render )
- + static void
- + _ft_lcd_darken_y ( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_UInt strength,
- + FT_Library library )
- {
- - /* set up default LCD filtering */
- - FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT );
-
- - render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* new_line;
- + FT_Byte* line = bitmap->buffer;
- + FT_Bitmap new_bitmap;
-
- - return 0;
- +
- + FT_Bitmap_Init( &new_bitmap );
- + FT_Bitmap_Copy( library, bitmap, &new_bitmap );
- + new_line = (&new_bitmap)->buffer;
- +
- + if ( strength > 0 )
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch, new_line += bitmap->pitch )
- + {
- + FT_UInt xx;
- +
- +
- + for ( xx = 1; xx < width - 1; xx += 1 )
- + {
- + if ( line[xx] > line[xx-1] && line[xx] > line[xx+1] )
- + {
- + if (new_line[xx] > 0)
- + new_line[xx] += ( strength * ( 255 - new_line[xx] ) ) / 100;
- + new_line[xx-1] += ( strength * ( 255 - line[xx-1] ) ) / 100;
- + new_line[xx+1] += ( strength * ( 255 - line[xx+1] ) ) / 100;
- + }
- + }
- + }
- + FT_Bitmap_Copy( library, &new_bitmap, bitmap );
- + FT_Bitmap_Done( library, &new_bitmap );
- }
-
-
- - static FT_Error
- - ft_smooth_raster_lcd( FT_Renderer render,
- - FT_Outline* outline,
- - FT_Bitmap* bitmap )
- + static void
- + _ft_bitmap_cap ( FT_Bitmap* bitmap,
- + FT_UInt strength,
- + FT_Library library )
- {
- - FT_Error error = FT_Err_Ok;
- - FT_Vector* points = outline->points;
- - FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
- - FT_Vector* vec;
-
- - FT_Raster_Params params;
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* new_line;
- + FT_Byte* line = bitmap->buffer;
- + FT_UInt cur_value = 0;
- + FT_Bitmap new_bitmap;
-
-
- - params.target = bitmap;
- - params.source = outline;
- - params.flags = FT_RASTER_FLAG_AA;
- + FT_Bitmap_Init( &new_bitmap );
- + FT_Bitmap_Copy( library, bitmap, &new_bitmap );
- + new_line = (&new_bitmap)->buffer;
-
- - /* implode outline */
- - for ( vec = points; vec < points_end; vec++ )
- - vec->x *= 3;
- + if ( strength > 0 )
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch, new_line += bitmap->pitch )
- + {
- + FT_UInt xx;
-
- - /* render outline into the bitmap */
- - error = render->raster_render( render->raster, ¶ms );
-
- - /* deflate outline */
- - for ( vec = points; vec < points_end; vec++ )
- - vec->x /= 3;
- + for ( xx = 1; xx < width - 1; xx += 1 )
- + {
- + cur_value = ( new_line[xx-1] + new_line[xx] + new_line[xx+1] ) / 3;
- + if ( cur_value > ( strength * 255 ) / 100 )
- + {
- + FT_UInt new_factor = ( strength * 255 ) / 100;
- + new_line[xx] = ( new_line[xx] * new_factor ) / cur_value;
- + new_line[xx+1] = ( new_line[xx+1] * new_factor ) / cur_value;
- + new_line[xx-1] = ( new_line[xx-1] * new_factor ) / cur_value;
- + }
- + }
- + }
- + FT_Bitmap_Copy( library, &new_bitmap, bitmap );
- + FT_Bitmap_Done( library, &new_bitmap );
- + }
-
- - return error;
- + static int
- + pseudo_gamma ( int val, float value )
- + {
- + return 256 * ( 1.0f - powf( ( 1.0f - val * (1.0f/256.0f) ), 1.0f / value ) );
- }
-
- +#if(0)
- + static void
- + _ft_bitmap_embolden ( FT_Bitmap* bitmap,
- + FT_UInt strength,
- + FT_Library library )
- + {
-
- - static FT_Error
- - ft_smooth_raster_lcdv( FT_Renderer render,
- - FT_Outline* outline,
- - FT_Bitmap* bitmap )
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* new_line;
- + FT_Byte* line = bitmap->buffer;
- + FT_Bitmap new_bitmap;
- + FT_UInt xx;
- +
- +
- + FT_Bitmap_Init(&new_bitmap);
- + FT_Bitmap_Copy(library, bitmap, &new_bitmap);
- + new_line = (&new_bitmap)->buffer;
- +
- + if ( strength > 0 )
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch, new_line += bitmap->pitch )
- {
- - FT_Error error = FT_Err_Ok;
- - FT_Vector* points = outline->points;
- - FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
- - FT_Vector* vec;
- + for ( xx = 1; xx < width - 1; xx += 1 )
- + {
- + FT_Int new_value = 0;
-
- - FT_Raster_Params params;
-
- + new_value = ( strength * line [xx-1] ) / 100
- + + pseudo_gamma( line [xx], .75 )
- + + (strength * line [xx+1] ) / 100;
- + if ( new_value > 255 )
- + new_value = 255;
-
- - params.target = bitmap;
- - params.source = outline;
- - params.flags = FT_RASTER_FLAG_AA;
- + new_line[xx] = new_value;
- + }
- + }
- + FT_Bitmap_Copy( library, &new_bitmap, bitmap );
- + FT_Bitmap_Done( library, &new_bitmap );
- + }
-
- - /* implode outline */
- - for ( vec = points; vec < points_end; vec++ )
- - vec->y *= 3;
-
- - /* render outline into the bitmap */
- - error = render->raster_render( render->raster, ¶ms );
-
- - /* deflate outline */
- - for ( vec = points; vec < points_end; vec++ )
- - vec->y /= 3;
- + static void
- + _ft_bitmap_gamma ( FT_Bitmap* bitmap,
- + float strength )
- + {
-
- - return error;
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* line = bitmap->buffer;
- + FT_UInt xx;
- +
- +
- + if ( strength > 0 )
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch )
- + {
- +
- + for ( xx = 1; xx < width - 1; xx += 1 )
- + {
- + if ( abs( line[xx-1] - line[xx] ) < 20 ||
- + abs( line[xx+1] - line[xx] ) < 20 )
- + line [xx] = pseudo_gamma( line [xx], strength ) ;
- + }
- + }
- + }
- +#endif
- +
- + /* Fringe filter */
- + static void
- + _ft_lcd_fringe_filter ( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_UInt strength,
- + FT_Library library )
- + {
- +
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* new_line;
- + FT_Byte* line = bitmap->buffer;
- + FT_Bitmap new_bitmap;
- +
- +
- + FT_Bitmap_Init(&new_bitmap);
- +
- + line = bitmap->buffer;
- + FT_Bitmap_Copy( library, bitmap, &new_bitmap );
- + new_line = (&new_bitmap)->buffer;
- +
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch, new_line += bitmap->pitch )
- + {
- + /* Threshold set to 1/2 pixel intensity */
- + FT_UInt xx, threshold = 128;
- +
- + /* Hack to make this work when bitmap is at first or last line */
- + FT_Int fudge = bitmap->pitch * (height == (FT_UInt)bitmap->rows);
- +
- + FT_Byte* prevline = line - bitmap->pitch + fudge;
- + FT_Byte* nextline = line + bitmap->pitch;
- +
- +
- + for ( xx = 1; xx < width - 1; xx += 1 )
- + {
- + /* subpixel grid sp11 sp21 sp31 */
- + /* where sp22 is sp12 sp22 sp32 */
- + /* current subpixel. sp13 sp23 sp33 */
- +
- + FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff,
- + leftdiff, rightdiff, prevdiff, nextdiff, sp11, sp21, sp31,
- + sp12, sp22, sp32, sp13, sp23, sp33;
- +
- + sp12 = line [xx-1];
- + sp22 = line [xx];
- + sp32 = line [xx+1];
- +
- + /* if at max height fake out some values */
- + if ( height == (FT_UInt)bitmap->rows )
- + {
- + prevtotal = sp11 = sp21 = sp31 = 0;
- + prevdiff = sp22;
- + lefttotal = sp12 + sp13;
- + righttotal = sp32 + sp33;
- + }
- + else
- + {
- + prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1];
- + sp11 = prevline [xx-1];
- + sp21 = prevline [xx];
- + sp31 = prevline [xx+1];
- + prevdiff = sp22 - sp21;
- + lefttotal = sp11 + sp12 + sp13;
- + righttotal = sp31 + sp32 + sp33;
- + }
- +
- + /* if at min height fake out some values */
- + if ( height == 1 )
- + {
- + nexttotal = sp13 = sp23 = sp33 = 0;
- + nextdiff = sp22;
- + lefttotal = sp11 + sp12;
- + righttotal = sp31 + sp32;
- + }
- + else
- + {
- + nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1];
- + sp13 = nextline [xx-1];
- + sp23 = nextline [xx];
- + sp33 = nextline [xx+1];
- + nextdiff = sp23 - sp22;
- + lefttotal = sp11 + sp12 + sp13;
- + righttotal = sp31 + sp32 + sp33;
- + }
- +
- + sidesdiff = lefttotal - righttotal;
- + leftdiff = sp22 - sp12;
- + rightdiff = sp32 - sp22;
- +
- + if ( sidesdiff < 0 )
- + sidesdiff *= -1;
- +
- + if ( prevdiff < 0 )
- + prevdiff *= -1;
- +
- + if ( nextdiff < 0 )
- + nextdiff *= -1;
- +
- + if ( leftdiff < 0 )
- + leftdiff *= -1;
- +
- + if ( rightdiff < 0 )
- + rightdiff *= -1;
- +
- + /* if the current subpixel is less than threshold, and varies only
- + slightly to left or right, lighten it */
- + if ( sp22 <= threshold && sp22 > 0 &&
- + ( leftdiff < 10 || rightdiff < 10 ) )
- + {
- + /* A pixel is horizontally isolated if: */
- + /* 1: All upper adjecent subpixels are >= threshold and all lower
- + adjacent ones are essentially white */
- + if ( prevtotal >= nexttotal &&
- + sp11 >= threshold &&
- + sp21 >= threshold &&
- + sp31 >= threshold &&
- + sp13 < 2 &&
- + sp23 < 2 &&
- + sp33 < 2 )
- +
- + {
- + new_line[xx] -= ( new_line[xx] * strength ) / 100;
- +
- + if ( leftdiff < 10 )
- + /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */
- + new_line[xx-1] -= ( new_line[xx-1] * strength ) / 200;
- +
- + if ( rightdiff < 10 )
- + /* OPPORTUNITY FOR IMPROVEMENT */
- + new_line[xx+1] -= ( new_line[xx+1] * strength ) / 200;
- + }
- + else if ( nexttotal > prevtotal &&
- + /* 2: the inverse of above */
- + sp13 >= threshold &&
- + sp23 >= threshold &&
- + sp33 >= threshold &&
- + sp11 < 2 &&
- + sp21 < 2 &&
- + sp31 < 2 )
- + {
- + new_line[xx] -= ( new_line[xx] * strength ) / 100;
- +
- + if ( leftdiff < 10 )
- + /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */
- + new_line[xx-1] -= ( new_line[xx-1] * strength ) / 200;
- +
- + if ( rightdiff < 10 )
- + /* OPPORTUNITY FOR IMPROVEMENT */
- + new_line[xx+1] -= ( new_line[xx+1] * strength ) / 200;
- + }
- + }
- + /* otherwise if the current subpixel is more than threshold, and varies
- + slightly to left or right, darken it */
- + else if ( sp22 > threshold &&
- + sp22 < 255 &&
- + ( leftdiff < 10 ||
- + rightdiff < 10 ) )
- + {
- + if ( sp11 <= 2 &&
- + sp21 <= 2 &&
- + sp31 <= 2 &&
- + sp13 >= threshold &&
- + sp23 >= threshold &&
- + sp33 >= threshold &&
- + prevtotal < nexttotal )
- + new_line[xx] += ( ( 255 - new_line[xx] ) * strength ) / 100;
- +
- + else if ( sp13 <= 2 &&
- + sp23 <= 2 &&
- + sp33 <= 2 &&
- + nexttotal < prevtotal &&
- + sp11 >= threshold &&
- + sp21 >= threshold &&
- + sp31 >= threshold )
- + new_line[xx] += ( ( 255 - new_line[xx] ) * strength ) / 100;
- +
- + }
- }
- + }
- + FT_Bitmap_Copy( library, &new_bitmap, bitmap );
- + FT_Bitmap_Done( library, &new_bitmap );
- + }
- +
- +
- + /* Grayscale filter */
- + static void
- + _ft_lcd_grayscale_filter ( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_UInt strength,
- + FT_Library library )
- + {
- +
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* line = bitmap->buffer;
- +
- +
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch )
- + {
- + FT_UInt xx;
-
- -#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
- -/* Oversampling scale to be used in rendering overlaps */
- -#define SCALE ( 1 << 2 )
- + for ( xx = 0; xx < width - 1; xx += 3 )
- + {
- + FT_UInt total = line [xx] + line [xx + 1] + line [xx + 2];
- + line[xx] = ( ( 100 - strength ) * line[xx]
- + + strength * ( total / 3 ) ) / 100;
- + line[xx+1] = ( ( 100 - strength ) * line[xx+1]
- + + strength * ( total / 3 ) ) / 100;
- + line[xx+2] = ( ( 100 - strength ) * line[xx+2]
- + + strength * ( total / 3 ) ) / 100;
- + }
- + }
- + }
- +
- +/*
- + These need to be in sync with params inside ftinf.c
- + (not ideal but perhaps better than making these public)
- + */
- +#define STEM_WIDTH_2_PPEM 18
- +#define MAX_PPEM 100
- +
- + typedef struct Stem_Segment_
- + {
- + FT_Long x1;
- + FT_Long x2;
- + FT_Int y;
- + } Stem_Segment;
- +
- + typedef struct Stem_Center_
- + {
- + FT_Long x;
- + FT_Long y;
- + FT_Long w;
- + FT_Long x1;
- + FT_Long x2;
- + } Stem_Center;
- +
- + typedef struct Stem_
- + {
- + FT_Long center;
- + FT_Long count;
- + FT_Long rcount; /* used to count within a range in possible stems */
- + FT_Long width;
- + FT_Long height;
- + FT_Short zone; /* 1 2 or 3 */
- + FT_Bool generated;
- + } Stem;
-
- - /* This function averages inflated spans in direct rendering mode */
- static void
- - ft_smooth_overlap_spans( int y,
- - int count,
- - const FT_Span* spans,
- - TOrigin* target )
- + swap_stem ( Stem* s1, Stem* s2 )
- {
- - unsigned char* dst = target->origin - ( y / SCALE ) * target->pitch;
- - unsigned short x;
- - unsigned int cover, sum;
- + Stem s;
- + s.center = s1->center;
- + s.count = s1->count;
- + s.rcount = s1->rcount;
- + s.width = s1->width;
- + s.zone = s1->zone;
- + s.generated = s1->generated;
- +
- + s1->center = s2->center;
- + s1->count = s2->count;
- + s1->rcount = s2->rcount;
- + s1->width = s2->width;
- + s1->zone = s2->zone;
- + s1->generated = s2->generated;
- +
- + s2->center = s.center;
- + s2->count = s.count;
- + s2->rcount = s.rcount;
- + s2->width = s.width;
- + s2->zone = s.zone;
- + s2->generated = s.generated;
- + }
- +
- + /* Stem alignment for bitmaps; A hack with very nice results */
- + /* Ideally this could be implemented on the outline, prior to
- + * rasterization. Possible future enhancement is to use the
- + * warper code to achieve this */
- + static void
- + _lcd_stem_align ( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_GlyphSlot slot,
- + FT_Long* translate_value,
- + float* scale_value,
- + FT_UInt alignment_strength,
- + FT_UInt fitting_strength,
- + float* embolden_value
- + )
- + {
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- +
- + Stem_Segment* segments;
- + Stem_Segment* leftmost_segment;
- + Stem_Segment* rightmost_segment;
- + Stem_Segment* leftmost_segment_not_extrema;
- + Stem_Segment* rightmost_segment_not_extrema;
- + Stem* stems;
- + Stem* possible_stems;
- + Stem* leftmost_stem;
- + Stem* rightmost_stem;
- + Stem_Data* known_stem_values;
- + Stem_Center* centers;
- + FT_Long leftmost_point = width * 256;
- + FT_Long rightmost_point = 0;
- + FT_Long leftmost_point_not_extrema = width * 256;
- + FT_Long rightmost_point_not_extrema = 0;
- + FT_Long num_segments = 0;
- + FT_Long num_centers = 0;
- + FT_Long *stem_centers;
- + FT_UInt h;
- + FT_ULong valid_stems = 0, valid_possible_stems = 0;
- + FT_Long center, stem_matches, stem_matches_ledge;
- + FT_Long stem_matches_redge, next_center, last_matching_center;
- + FT_Long last_matching_ledge, last_matching_redge, this_center;
- + FT_Int max_strength;
- + FT_Byte* line = bitmap->buffer;
- + FT_UInt current_value = 0;
- + FT_UInt xx;
- + FT_Long linearHoriAdvance = slot->linearHoriAdvance >> 10;
- +
- + FT_Int m_horiBearingX = slot->metrics.horiBearingX;
- + FT_Int m_horiAdvance = slot->metrics.horiAdvance;
- + FT_Int m_width = slot->metrics.width;
- + FT_Pos one_pixel = 768;
- + FT_Pos one_third_pixel = 256;
- + FT_Int columns_per_pixel = 3;
- + /*FT_Int extra_columns = 6;*/
- +
- + /* on / off flags for testing different features */
- + FT_Bool strategy_translate_using_closest_stem = TRUE;
- + FT_Bool strategy_scale_to_closest_centers = FALSE;
- + FT_Bool strategy_scale_to_closest_centers_up_only = FALSE;
- + FT_Bool strategy_always_use_distance_ceiling = FALSE;
- + FT_Bool strategy_auto_change_center_offset = TRUE;
- + FT_Bool strategy_use_m_control = FALSE;
- + FT_Bool strategy_correct_out_of_bounds_outlines = FALSE;
- + FT_Bool strategy_also_use_edge_detection_for_stems = FALSE;
- + FT_Bool strategy_use_strengths = TRUE;
- + FT_Bool strategy_synthesize_stems = FALSE;
- + FT_Bool strategy_bearing_correction = TRUE;
- + FT_Bool strategy_use_d_correction = TRUE;
- + FT_Bool strategy_fit_to_width = FALSE;
- + /*FT_Bool strategy_center_glyph = FALSE;*/
- +
- + const FT_Int MIN_PPEM = 7;
- + /*const FT_Int MAX_PPEM = 100;*/
- + const FT_Int MAX_STEMS = 3;
- + FT_Int ppem = 0;
- +
- + Stem_Data stem_data;
- +
- + /* reset to default */
- + *scale_value = 1.0;
- +
- + /* Simply return in odd cases where these don't seem to be set */
- + /* Flash and some pdf viewers will crash otherwise */
- + if ( !slot->face ||
- + !slot->face->size ||
- + !slot->face->size->metrics.x_ppem )
- + return;
- +
- + if ( slot->face->size->metrics.x_ppem > MAX_PPEM )
- + return;
- +
- + if ( slot->face->size->metrics.x_ppem < MIN_PPEM )
- + return;
- +
- + if ( !FT_IS_SCALABLE( slot->face ) )
- + return;
- +
- + ppem = slot->face->size->metrics.x_ppem;
- +
- + if ( ppem < 9 )
- + return;
- + if ( ppem > 20 )
- + strategy_use_m_control = TRUE;
- +
- + /* only perform alignment on styles we know, that aren't bold or italic */
- + /* perhaps detection could be added on those that are not set? */
- + /* Require certain ppems for narrow and light fonts */
- + if( slot->face->style_name )
- + {
- + if ( strcasestr( slot->face->style_name, "Italic" ) ||
- + strcasestr( slot->face->style_name, "Oblique" ) ||
- + strcasestr( slot->face->style_name, "Script" ) ||
- + strcasestr( slot->face->style_name, "Handwriting" ) ||
- + strcasestr( slot->face->style_name, "Bold" ) ||
- + strcasestr( slot->face->style_name, "Black" ) ||
- + ( ( strcasestr( slot->face->style_name, "Extra Thin" ) ||
- + strcasestr( slot->face->style_name, "Extra Light" ) ) &&
- + ppem < 10 ) ||
- + ( strcasestr( slot->face->style_name, "Thin" )
- + && ppem < 10 ) ||
- + ( strcasestr( slot->face->style_name, "Light" )
- + && ppem < 10 ) ||
- + ( strcasestr( slot->face->style_name, "Narrow" )
- + && ppem < 15 ) ||
- + ( strcasestr( slot->face->style_name, "Condensed" )
- + && ppem < 20 ) )
- + return;
- + }
- +
- + if( slot->face->family_name )
- + {
- + if ( strcasestr( slot->face->family_name, "Italic" ) ||
- + strcasestr( slot->face->family_name, "Oblique" ) ||
- + strcasestr( slot->face->family_name, "Script" ) ||
- + strcasestr( slot->face->family_name, "Handwriting" ) ||
- + strcasestr( slot->face->family_name, "Bold" ) ||
- + strcasestr( slot->face->family_name, "Black" ) ||
- + ( ( strcasestr( slot->face->family_name, "Extra Thin" ) ||
- + strcasestr( slot->face->family_name, "Extra Light" ) ) &&
- + ppem < 10 ) ||
- + ( strcasestr( slot->face->family_name, "Thin" )
- + && ppem < 10 ) ||
- + ( strcasestr( slot->face->family_name, "Light" )
- + && ppem < 10 ) ||
- + ( strcasestr( slot->face->family_name, "Narrow" )
- + && ppem < 15 ) ||
- + ( strcasestr( slot->face->family_name, "Condensed" )
- + && ppem < 20 ) )
- + return;
- + }
- + else if ( slot->face->style_flags )
- + {
- + if ( slot->face->style_flags & FT_STYLE_FLAG_ITALIC ||
- + slot->face->style_flags & FT_STYLE_FLAG_BOLD ||
- + FT_IS_TRICKY( slot->face ) )
- + return;
- + }
- + else return;
- +
- + if ( mode != FT_RENDER_MODE_LCD )
- + {
- + columns_per_pixel = 1;
- + one_pixel = 256;
- + one_third_pixel = 85;
- + /*extra_columns = 0;*/
- + /* until this can be figured out just return */
- + /* There are issues with missing glyphs */
- + return;
- + }
- +
- + known_stem_values=&stem_data;
- + if ( ftinf && ftinf->use_known_settings_on_selected_fonts )
- + {
- + ftinf_fill_stem_values( known_stem_values, slot->face->family_name, ppem, TRUE );
- + /* translate value may be set for < 10 */
- + if (known_stem_values->stem_translating_only > -1024 )
- + {
- + *translate_value = known_stem_values->stem_translating_only;
- + return;
- + }
- + if( known_stem_values->bearing_correction == FALSE )
- + strategy_bearing_correction = FALSE;
- + } else
- + ftinf_fill_stem_values( known_stem_values, slot->face->family_name, ppem, FALSE );
- +
- + if ( known_stem_values->use_100 ||
- + known_stem_values->m >= 0 )
- + {
- + alignment_strength = fitting_strength = 100;
- + strategy_use_m_control = TRUE;
- + }
- +
- + if ( known_stem_values->edge_detection )
- + strategy_also_use_edge_detection_for_stems = TRUE;
- +
- + /* Allocate */
- + segments = NULL;
- + leftmost_segment = (Stem_Segment*) malloc( 4*sizeof ( Stem_Segment ) );
- + leftmost_segment_not_extrema = leftmost_segment+1;
- + rightmost_segment = leftmost_segment+2;
- + rightmost_segment_not_extrema = leftmost_segment+3;
- +
- + stems = (Stem*) malloc ( (2*MAX_STEMS+2) * sizeof ( Stem ) );
- + possible_stems = stems+MAX_STEMS;
- + leftmost_stem = possible_stems+MAX_STEMS;
- + rightmost_stem = leftmost_stem + 1;
- + centers = NULL;
- +
- + if ( verbose )
- + printf("\n");
- +
- + /* Initialize */
- + stem_centers=(FT_Long*)calloc( width * 256, sizeof(stem_centers[0]) );
- +
- + rightmost_segment->x1 = 0;
- + rightmost_segment->x2 = 0;
- + rightmost_segment->y = 0;
- + leftmost_segment->x1 = 99999999;
- + leftmost_segment->x2 = 0;
- + leftmost_segment->y = 0;
- +
- + rightmost_segment_not_extrema->x1 = 0;
- + rightmost_segment_not_extrema->x2 = 0;
- + rightmost_segment_not_extrema->y = 0;
- + leftmost_segment_not_extrema->x1 = 99999999;
- + leftmost_segment_not_extrema->x2 = 0;
- + leftmost_segment_not_extrema->y = 0;
- +
- + /* Locate stem centers for later processing */
- + for ( h = (FT_UInt)bitmap->rows; h > 0; h--, line += bitmap->pitch )
- + {
- + current_value = 0;
- + /* Calculate various sums and stem widths of glyph */
- + for ( xx = 0; xx < width; xx += 1 )
- + {
- + /* Reallocate (in blocks of 64) */
- + if( num_segments % 64 == 0 )
- + segments = (Stem_Segment*) realloc
- + ( segments, ( num_segments + 64 ) * sizeof ( Stem_Segment ) );
- +
- + /* if line is white, and now has color, it's the start of a stem */
- + if ( current_value == 0 && line[xx] > 0 )
- + {
- + /* start of stem */
- + segments[num_segments].x1 = 256 * xx + ( 255 - line[xx] );
- + segments[num_segments].y = h;
- + }
- +
- + /* otherwise, if it's currently black and the new value is 0,
- + it's the end of a stem */
- + else if ( ( current_value > 0 && line[xx] == 0 ) ||
- + ( current_value > 0 && xx == width - 1 ) )
- + {
- + FT_Long stem_center_x;
- + segments[num_segments].x2 = 256 * ( xx - 1 ) + line[xx-1];
- +
- + if ( xx == width - 1 )
- + segments[num_segments].x2 += line[xx];
- +
- + /*stem center is average of start and end of stem */
- + stem_center_x = ( segments[num_segments].x2
- + + segments[num_segments].x1 ) / 2;
- +
- + /* Reallocate (in blocks of 32) */
- + if( num_centers % 32 == 0 )
- + centers = (Stem_Center*) realloc
- + ( centers, ( num_centers + 32 ) * sizeof ( Stem_Center ) );
- + centers[num_centers].x = stem_center_x;
- + centers[num_centers].y = h;
- + centers[num_centers].x1 = segments[num_segments].x1;
- + centers[num_centers].x2 = segments[num_segments].x2;
- +
- + num_centers++;
- +
- + stem_centers[stem_center_x] += 1;
- +
- + /* Find left and rightmost points for later calculations */
- + /* OR - Favor ones that aren't on the top or bottom if */
- + /* possible to prevent v and w from getting caught later */
- + if ( segments[num_segments].x1 < leftmost_segment->x1 ||
- + ( segments[num_segments].y > 1 &&
- + segments[num_segments].y < height &&
- + segments[num_segments].x1 == leftmost_segment->x1 ) )
- + {
- + leftmost_segment->x1 = segments[num_segments].x1;
- + leftmost_segment->x2 = segments[num_segments].x2;
- + leftmost_segment->y = h;
- + }
- + if ( segments[num_segments].x2 > rightmost_segment->x2 ||
- + ( segments[num_segments].y > 1 &&
- + segments[num_segments].y < height &&
- + segments[num_segments].x1 == rightmost_segment->x1 ) )
- + {
- + rightmost_segment->x1 = segments[num_segments].x1;
- + rightmost_segment->x2 = segments[num_segments].x2;
- + rightmost_segment->y = h;
- + }
- +
- + if ( segments[num_segments].x1
- + < leftmost_segment_not_extrema->x1 ||
- + ( segments[num_segments].y > 1 &&
- + segments[num_segments].y < height &&
- + segments[num_segments].x1
- + == leftmost_segment_not_extrema->x1 &&
- + h < (FT_UInt)bitmap->rows && h > 0 ) )
- + {
- + leftmost_segment_not_extrema->x1 = segments[num_segments].x1;
- + leftmost_segment_not_extrema->x2 = segments[num_segments].x2;
- + leftmost_segment_not_extrema->y = h;
- + }
- + if ( segments[num_segments].x2
- + > rightmost_segment_not_extrema->x2 ||
- + ( segments[num_segments].y > 1 &&
- + segments[num_segments].y < height &&
- + segments[num_segments].x1
- + == rightmost_segment_not_extrema->x1 &&
- + h < (FT_UInt)bitmap->rows && h > 0 ) )
- + {
- + rightmost_segment_not_extrema->x1 = segments[num_segments].x1;
- + rightmost_segment_not_extrema->x2 = segments[num_segments].x2;
- + rightmost_segment_not_extrema->y = h;
- + }
- +
- + if ( segments[num_segments].x1 < leftmost_point )
- + leftmost_point = segments[num_segments].x1;
- +
- + if ( segments[num_segments].x2 > rightmost_point )
- + rightmost_point = segments[num_segments].x2;
- +
- + if ( segments[num_segments].x1 < leftmost_point_not_extrema &&
- + h < (FT_UInt)bitmap->rows && h > 0 )
- + leftmost_point_not_extrema = segments[num_segments].x1;
- +
- + if ( segments[num_segments].x2 > rightmost_point_not_extrema &&
- + h < (FT_UInt)bitmap->rows && h > 0 )
- + rightmost_point_not_extrema = segments[num_segments].x2;
- +
- + num_segments++;
- + }
- + /* else - other conditions - need some error checking here */
- + current_value = line[xx];
- + }
- + }
- +
- + /* initialize */
- + for ( xx = 0; xx < MAX_STEMS; xx +=1 )
- + {
- + stems[xx].center = 0;
- + stems[xx].count = 0;
- + stems[xx].width = 0;
- + stems[xx].height = 0;
- + possible_stems[xx].center = 0;
- + possible_stems[xx].count = 0;
- + possible_stems[xx].width = 0;
- + possible_stems[xx].height = 0;
- + }
- +
- + valid_stems = 0;
- + valid_possible_stems = 0;
- +
- + /* Determine which centers belong to stems */
- + center = 0;
- +
- + while ( center < num_centers )
- + {
- + /* slope at within which to consider a point part of a stem */
- + /*const FT_UInt slope = 1;
- + const FT_UInt topslope = (256 * 3) / 10; */
- +
- + /* 10 to 20 with 4 matches seems good, */
- + /* but 1 or 2 with 3 stems needs to somehow get included */
- + FT_Int deviation1 = 5;
- + FT_Int deviation2=-1, requirement1 = 4, stem_match_requirement = 3;
- + FT_Int center_difference_in_height;
- + FT_Int center_difference_in_width, valid_center_average;
- + FT_Int smallest_width_ledge, smallest_width_redge;
- + FT_Int x1_difference_in_width, x2_difference_in_width;
- + FT_Bool no_gap_found = FALSE;
- + FT_Bool no_gap_found_ledge = FALSE;
- + FT_Bool no_gap_found_redge = FALSE;
- + FT_Bool stem_detected = FALSE;
- + FT_Int set_width_to, set_center_to;
- +
- + /* seems to not do damage */
- + /* May not be effective */
- + requirement1 = height / 4;
- + if ( requirement1 < 5 )
- + requirement1 = 5;
- + deviation1 = 20;
- + deviation2 = 20;
- +
- + if ( columns_per_pixel == 1 )
- + deviation1 = deviation2 = 10;
- +
- + if ( (FT_Int)bitmap->rows <= 6 )
- + deviation1 = 25;
- +
- + if ( (FT_Int)bitmap->rows <= 6 )
- + deviation2 = 25;
- +
- + if ( columns_per_pixel == 1 &&
- + (FT_Int)bitmap->rows <= 6 )
- + deviation1 = deviation2 = 12;
- +
- + valid_center_average = 0;
- +
- + no_gap_found = no_gap_found_ledge = no_gap_found_redge = FALSE;
- + stem_detected = FALSE;
- +
- + if ( ppem < 11 )
- + requirement1 = 4;
- +
- + if ( ppem > 18 )
- + {
- + stem_match_requirement = height / 4;
- + if ( stem_match_requirement < 3 )
- + stem_match_requirement = 3;
- + }
- +
- + smallest_width_ledge = smallest_width_redge = width * 256;
- + stem_matches = 0;
- + stem_matches_ledge = 0;
- + stem_matches_redge = 0;
- + last_matching_center = -1;
- + last_matching_ledge = -1;
- + last_matching_redge = -1;
- +
- + /* set currently looked at center to center value */
- + this_center = center;
- + next_center = 0;
- +
- + /* For each center, compare with all other centers to see if others */
- + /* match the properties of this one */
- + while ( next_center < num_centers )
- + {
- +
- + /* calculate differences */
- + center_difference_in_width = abs ( centers[this_center].x
- + - centers[next_center].x );
- + center_difference_in_height = abs ( centers[this_center].y
- + - centers[next_center].y );
- + x1_difference_in_width = abs ( centers[this_center].x1
- + - centers[next_center].x1 );
- + x2_difference_in_width = abs ( centers[this_center].x2
- + - centers[next_center].x2 );
- +
- +
- + /* property - stem center points that align */
- + /* if the center is within range, the center is less than */
- + /* 1/2 the height away, and at least one edge is also within range */
- + if ( center_difference_in_width
- + < center_difference_in_height * deviation1 &&
- + center_difference_in_height
- + <= (FT_Int)bitmap->rows / 2 &&
- + /* prevents w from getting caught ---- but also kills m */
- + ( x1_difference_in_width
- + < center_difference_in_height * deviation2 ||
- + x2_difference_in_width
- + < center_difference_in_height * deviation2 ) )
- + {
- + stem_matches += 1;
- + valid_center_average += centers[next_center].x;
- +
- + /* try to find where the matching centers are far apart */
- + if ( last_matching_center >= 0 &&
- + abs( centers[last_matching_center].y
- + - centers[next_center].y ) >= (FT_Int)bitmap->rows / 2 )
- +
- + /* try to find where matching centers are next to each other */
- + if ( last_matching_center >= 0 &&
- + abs( centers[last_matching_center].y
- + - centers[next_center].y ) == 1 )
- + no_gap_found = TRUE;
- +
- + last_matching_center = next_center;
- + }
- +
- + if ( strategy_also_use_edge_detection_for_stems )
- + {
- + /* property - stem left edge points that align */
- + /* if the center is within range, */
- + /* the center is less than 1/2 the height away */
- + if ( x1_difference_in_width
- + < center_difference_in_height * deviation1 &&
- + center_difference_in_height <= (FT_Int)bitmap->rows / 2 )
- + {
- + stem_matches_ledge += 1;
- + /* may not need for edges */
- + /*valid_center_average += centers[next_center].x; */
- +
- + if ( centers[next_center].x2 - centers[next_center].x1
- + < smallest_width_ledge )
- + smallest_width_ledge = centers[next_center].x2
- + - centers[next_center].x1;
- +
- + /* try to find where the matching centers are far apart */
- + if ( last_matching_ledge >= 0 &&
- + abs( centers[last_matching_ledge].y
- + - centers[next_center].y)
- + >= (FT_Int)bitmap->rows / 2 )
- +
- + /* try to find where matching centers are next to each other */
- + if ( last_matching_ledge >= 0 &&
- + abs( centers[last_matching_ledge].y
- + - centers[next_center].y ) == 1 )
- + no_gap_found_ledge = TRUE;
- + last_matching_ledge = next_center;
- + }
- + }
- +
- + if ( strategy_also_use_edge_detection_for_stems )
- + {
- + /* property - stem right edge points that align */
- + /* if the center is within range, the center is less than 1/2 */
- + /* the height away */
- + if ( x2_difference_in_width
- + < center_difference_in_height * deviation1 &&
- + center_difference_in_height
- + <= (FT_Int)bitmap->rows / 2 )
- + {
- + stem_matches_redge += 1;
- + /* may not need for edges */
- + /*valid_center_average += centers[next_center].x; */
- +
- + if ( centers[next_center].x2 - centers[next_center].x1
- + < smallest_width_redge )
- + smallest_width_redge = centers[next_center].x2
- + - centers[next_center].x1;
- +
- + /* try to find where the matching centers are far apart */
- + if ( last_matching_redge >= 0 &&
- + abs( centers[last_matching_redge].y
- + - centers[next_center].y ) >= (FT_Int)bitmap->rows / 2 )
- +
- + /* try to find where matching centers are next to each other */
- + if ( last_matching_redge >= 0 &&
- + abs( centers[last_matching_redge].y
- + - centers[next_center].y ) == 1 )
- + no_gap_found_redge = TRUE;
- +
- + last_matching_redge = next_center;
- + }
- + }
- +
- + next_center++;
- + }
- +
- + if ( stem_matches > 0 )
- + valid_center_average /= stem_matches;
- +
- + if ( ( stem_matches >= stem_match_requirement ||
- + ( ( (FT_Int)bitmap->rows <= 6 || ppem < 11 ) &&
- + stem_matches >= 2 &&
- + abs ( valid_center_average
- + - centers[center].x) < deviation1 /2 ) ||
- + /* try to catch tightly aligned stuff where the matching centers */
- + /* are next to each other only */
- + ( stem_matches == 2 &&
- + abs( valid_center_average
- + - centers[center].x) <= deviation1 /2 &&
- + no_gap_found &&
- + ppem < 18 ) ) &&
- + /* catches things like times 16 u but gets a lot of w's too */
- + /* stem width is less than 1/3 of the bitmap width, */
- + /* or bitmap_width is small */
- + ( centers[center].x2 - centers[center].x1
- + < (m_horiAdvance * 12) / 2 ||
- + m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) )
- + {
- + stem_detected = TRUE;
- + set_width_to = centers[center].x2 - centers[center].x1;
- + set_center_to = centers[center].x;
- + }
- +
- + /* see if edges found anything */
- + if ( strategy_also_use_edge_detection_for_stems && !stem_detected )
- + {
- + /* Require no gap for edges */
- + /* stem width less than 1/3 bitmap width, or bitmap_width is small */
- + /* The stem occurs on the left side of glyph only */
- + if ( ( stem_matches_ledge >= stem_match_requirement &&
- + no_gap_found_ledge ) &&
- + ( centers[center].x2 - centers[center].x1
- + < ( m_horiAdvance * 12 ) / 2 ||
- + m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) &&
- + centers[center].x < ( m_horiAdvance * 12 ) / 2 )
- + {
- + stem_detected = TRUE;
- + set_width_to = smallest_width_ledge;
- + set_center_to = centers[center].x1 + set_width_to / 2;
- + stem_matches = stem_matches_ledge;
- + }
- + /* Require no gap for edges */
- + /* stem width is less than 1/3 bitmap width, or bitmap_width is small */
- + /* The stem occurs on the right side of glyph only */
- + else if ( ( stem_matches_redge >= stem_match_requirement &&
- + no_gap_found_redge ) &&
- + ( centers[center].x2 - centers[center].x1
- + < ( m_horiAdvance * 12 ) / 2 ||
- + m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) &&
- + centers[center].x > (m_horiAdvance * 12) / 2 )
- + {
- + stem_detected = TRUE;
- + set_width_to = smallest_width_redge;
- + set_center_to = centers[center].x2 - set_width_to / 2;
- + stem_matches = stem_matches_redge;
- + }
- + }
- +
- +
- + /*store and/or replace highest occurrences with 3 or more centers */
- + /* because this matched, it will become the top dog regardless */
- + if ( stem_detected && (stem_matches > possible_stems[0].height) )
- + {
- + /* if this is the first stem just go ahead */
- + if ( valid_possible_stems == 0 )
- + {
- + valid_possible_stems = 1;
- + possible_stems[0].center = set_center_to;
- + possible_stems[0].count = stem_matches;
- + possible_stems[0].width = set_width_to;
- + possible_stems[0].height = stem_matches;
- + }
- +
- + /* otherwise, if there is already a stem */
- + else if ( valid_possible_stems == 1 )
- + {
- + /* if stem is within range of existing one, replace existing one */
- +
- + /* if the stem isn't within the range of this one swap it with */
- + /* next one first */
- + if ( abs ( set_center_to - possible_stems[0].center )
- + >= one_pixel * 2 )
- + {
- + swap_stem ( &possible_stems[0], &possible_stems[1] );
- + valid_possible_stems = 2;
- + }
- + possible_stems[0].center = set_center_to;
- + possible_stems[0].count = stem_matches;
- + possible_stems[0].width = set_width_to;
- + possible_stems[0].height = stem_matches;
- + }
- +
- + /* otherwise if there are already 2 stems */
- + else if ( valid_possible_stems >= 2 )
- + {
- + /* if the stem is within the range of existing one, replace */
- + /* existing one */
- + if ( abs ( set_center_to - possible_stems[0].center )
- + <= one_pixel * 2 )
- + {
- + possible_stems[0].center = set_center_to;
- + possible_stems[0].count = stem_matches;
- + possible_stems[0].width = set_width_to;
- + possible_stems[0].height = stem_matches;
- + }
- + /* if the stem isn't within the range of this one */
- + else
- + {
- + /* see if within range of next one and swap if so and proceed */
- + /* overwriting it */
- + if ( abs ( set_center_to - possible_stems[1].center )
- + <= one_pixel * 2 )
- + swap_stem ( &possible_stems[0], &possible_stems[1] );
- +
- + /* otherwise see if in range of third one */
- + else if ( abs ( set_center_to - possible_stems[2].center )
- + <= one_pixel * 2 )
- + swap_stem ( &possible_stems[0], &possible_stems[2] );
- +
- + /* otherwise this is the new top dog, so demote everything */
- + else
- + {
- + swap_stem ( &possible_stems[1], &possible_stems[2] );
- + swap_stem ( &possible_stems[0], &possible_stems[1] );
- + valid_possible_stems += 1;
- + }
- + possible_stems[0].center = set_center_to;
- + possible_stems[0].count = stem_matches;
- + possible_stems[0].width = set_width_to;
- + possible_stems[0].height = stem_matches;
- + }
- + }
- + }
-
- + else if ( stem_matches > possible_stems[1].height &&
- + set_center_to != 0 )
- + {
-
- - /* When accumulating the oversampled spans we need to assure that */
- - /* fully covered pixels are equal to 255 and do not overflow. */
- - /* It is important that the SCALE is a power of 2, each subpixel */
- - /* cover can also reach a power of 2 after rounding, and the total */
- - /* is clamped to 255 when it adds up to 256. */
- - for ( ; count--; spans++ )
- + /* make sure it doesn't match the first stem */
- + if ( abs ( set_center_to - possible_stems[0].center ) >= one_pixel * 2 )
- {
- - cover = ( spans->coverage + SCALE * SCALE / 2 ) / ( SCALE * SCALE );
- - for ( x = 0; x < spans->len; x++ )
- +
- + /* if this is the second stem */
- + if ( valid_possible_stems == 1 )
- + valid_possible_stems = 2;
- +
- + /* otherwise if there is already a stem here */
- + else if ( valid_possible_stems >= 2 )
- + {
- + /* if it doesn't match the second stem, proceed to swap out */
- + /* with the third. if it does, replace it */
- + if ( abs ( set_center_to - possible_stems[1].center )
- + >= one_pixel * 2 )
- {
- - sum = dst[( spans->x + x ) / SCALE] + cover;
- - dst[( spans->x + x ) / SCALE] = (unsigned char)( sum - ( sum >> 8 ) );
- + swap_stem ( &possible_stems[1], &possible_stems[2] );
- + valid_possible_stems +=1;
- }
- }
- + possible_stems[1].center = set_center_to;
- + possible_stems[1].count = stem_matches;
- + possible_stems[1].width = set_width_to;
- + possible_stems[1].height = stem_matches;
- + }
- }
-
- + else if ( stem_matches > possible_stems[2].height &&
- + set_center_to != 0 )
- + {
- + /* if it doesn't match the first or second one */
- + if ( abs( set_center_to - possible_stems[0].center) >= one_pixel * 2 &&
- + abs( set_center_to - possible_stems[1].center) >= one_pixel * 2 )
- + {
- + if ( valid_possible_stems == 2 )
- + valid_possible_stems += 1;
-
- - static FT_Error
- - ft_smooth_raster_overlap( FT_Renderer render,
- - FT_Outline* outline,
- - FT_Bitmap* bitmap )
- + possible_stems[2].center = set_center_to;
- + possible_stems[2].count = stem_matches;
- + possible_stems[2].width = set_width_to;
- + possible_stems[1].height = stem_matches;
- + }
- + }
- +
- + if ( valid_possible_stems > 3 )
- + valid_possible_stems = 3;
- +
- + center++;
- + }
- +
- + /* promote to stem */
- + if ( valid_possible_stems > 0 )
- {
- - FT_Error error = FT_Err_Ok;
- - FT_Vector* points = outline->points;
- - FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
- - FT_Vector* vec;
- + stems[0].center = possible_stems[0].center;
- + stems[0].count = possible_stems[0].count;
- + stems[0].width = possible_stems[0].width;
- + stems[0].height = possible_stems[0].height;
- + stems[0].generated = FALSE;
- + valid_stems++;
- + }
-
- - FT_Raster_Params params;
- - TOrigin target;
- + if ( valid_stems == 1 &&
- + valid_possible_stems > 1 )
- + {
- + stems[1].center = possible_stems[1].center;
- + stems[1].count = possible_stems[1].count;
- + stems[1].width = possible_stems[1].width;
- + stems[1].height = possible_stems[1].height;
- + stems[1].generated = FALSE;
- + valid_stems++;
- + }
-
- + if ( valid_stems == 2 &&
- + valid_possible_stems > 2 &&
- + possible_stems[2].center != 0 )
- + {
- + stems[2].center = possible_stems[2].center;
- + stems[2].count = possible_stems[2].count;
- + stems[2].width = possible_stems[2].width;
- + stems[2].height = possible_stems[2].height;
- + stems[2].generated = FALSE;
- + valid_stems++;
- + }
-
- - /* Reject outlines that are too wide for 16-bit FT_Span. */
- - /* Other limits are applied upstream with the same error code. */
- - if ( bitmap->width * SCALE > 0x7FFF )
- - return FT_THROW( Raster_Overflow );
- + /* sort stems in x direction */
- + if ( valid_stems == 3 )
- + {
- + if ( stems[0].center > stems[1].center )
- + swap_stem ( &stems[0], &stems[1] );
-
- - /* Set up direct rendering to average oversampled spans. */
- - params.source = outline;
- - params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
- - params.gray_spans = (FT_SpanFunc)ft_smooth_overlap_spans;
- - params.user = ⌖
- + if ( stems[0].center > stems[2].center )
- + swap_stem ( &stems[1], &stems[2] );
- +
- + if ( stems[1].center > stems[2].center )
- + swap_stem ( &stems[1], &stems[2] );
- +
- + if ( stems[0].center > stems[1].center )
- + swap_stem ( &stems[0], &stems[1] );
- +
- + /* only look at first and last stem for now */
- + swap_stem ( &stems[1], &stems[2] );
- + }
- +
- + /* synthesize stems - Works, but needs work */
- + if ( ( strategy_synthesize_stems ||
- + known_stem_values->synth_stems ) &&
- + valid_stems == 0 &&
- + ppem > 10 )
- + {
- + /* if the leftmost segment's leftmost point is the same as the glyph's */
- + /* leftmost point, and it is of reasonable width, and is not on the */
- + /* top or bottom of the bitmap */
- + if ( leftmost_segment_not_extrema->x1
- + == leftmost_point_not_extrema &&
- + abs ( leftmost_segment_not_extrema->x2
- + - leftmost_segment_not_extrema->x1 )
- + < ( rightmost_point_not_extrema
- + - leftmost_point_not_extrema ) / 3 &&
- + leftmost_segment_not_extrema->y < height &&
- + leftmost_segment_not_extrema->y > 1 )
- + {
- + stems[valid_stems].center = ( leftmost_segment_not_extrema->x2
- + + leftmost_segment_not_extrema->x1 ) / 2;
- + stems[valid_stems].width = leftmost_segment_not_extrema->x2
- + - leftmost_segment_not_extrema->x1;
- + stems[valid_stems].generated = TRUE;
- + valid_stems += 1;
- + }
- +
- +
- + if ( rightmost_segment_not_extrema->x2
- + == rightmost_point_not_extrema &&
- + abs ( rightmost_segment_not_extrema->x2
- + - rightmost_segment_not_extrema->x1 )
- + < ( rightmost_point_not_extrema
- + - leftmost_point_not_extrema ) / 3 &&
- + rightmost_segment_not_extrema->y < height &&
- + rightmost_segment_not_extrema->y > 1 )
- + {
- + stems[valid_stems].center = ( rightmost_segment_not_extrema->x2
- + + rightmost_segment_not_extrema->x1 ) / 2;
- + stems[valid_stems].width = rightmost_segment_not_extrema->x2
- + - rightmost_segment_not_extrema->x1;
- + stems[valid_stems].generated = TRUE;
- + valid_stems += 1;
- + }
- +
- + }
- +
- + /* sort stems in x direction */
- + if ( valid_stems > 1 && stems[0].center > stems[1].center )
- + swap_stem ( &stems[0], &stems[1] );
- +
- + if ( valid_stems == 0 && known_stem_values->stem_translating != 0 )
- + {
- + *translate_value += known_stem_values->stem_translating;
- +
- + if ( strategy_use_strengths )
- + {
- + /* consider 1/2 pixel the max when strength is at 100%,
- + unless translate is already greater than that */
- + FT_Int strength_cutoff = 32;
- +
- +
- + if ( abs ( *translate_value ) > strength_cutoff)
- + strength_cutoff = *translate_value;
- +
- + max_strength = ( strength_cutoff * alignment_strength ) / 100;
- +
- + if ( *translate_value < -max_strength )
- + *translate_value = -max_strength;
- + else if ( *translate_value > max_strength )
- + *translate_value = max_strength;
- + }
- + }
- + else
- + /* Start snapping */
- + {
- + FT_Int center_offset;
- + FT_Int modulus;
- + FT_Int delta, delta2;
- + FT_Long stem_distance = 1, new_distance = 1;
- + FT_Int distance_floor, distance_ceiling;
- + FT_Int translate_value2 = 0;
- + FT_Int main_stem = 0;
- + FT_Int lbearing = m_horiBearingX * 12;
- + FT_Int bitmap_stem_location = stems[0].center;
- + FT_Int advance_stem_location = bitmap_stem_location
- + + lbearing - one_pixel;
- + FT_Int advance_width = m_horiAdvance * 12;
- + FT_Int original_advance_width = 12 * ( slot->linearHoriAdvance >> 10 );
- + FT_Int glyph_width = rightmost_point - leftmost_point;
- + FT_Int stem_width = stems[0].width;
- + FT_Int advance_leftmost_location = leftmost_point
- + + lbearing - one_pixel;
- + FT_Int advance_rightmost_location = rightmost_point
- + + lbearing - one_pixel;
- +
- +#define proposed_transformed_point(point) \
- + point * (float)(new_distance) / (float)(stem_distance) \
- + + *translate_value * 12 - ( stems[main_stem].center * (float)(new_distance) \
- + / (float)(stem_distance) - stems[main_stem].center)
- +
- +#define proposed_translated_point(point) point + *translate_value * 12
-
- - params.clip_box.xMin = 0;
- - params.clip_box.yMin = 0;
- - params.clip_box.xMax = bitmap->width * SCALE;
- - params.clip_box.yMax = bitmap->rows * SCALE;
- + center_offset = one_pixel / 2; /* half pixel */
- + modulus = one_pixel; /* whole pixel */
-
- - if ( bitmap->pitch < 0 )
- - target.origin = bitmap->buffer;
- + /* Determine center_offset via known values */
- + if ( known_stem_values->stem_width >= 0 )
- + {
- + if ( known_stem_values->stem_width % 2 == 0 )
- + center_offset = 0;
- else
- - target.origin = bitmap->buffer
- - + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
- + center_offset = one_pixel / 2;
- + }
- + /* otherwise do intelligent guessing, if set */
- + else if ( strategy_auto_change_center_offset &&
- + ppem >= STEM_WIDTH_2_PPEM &&
- + stems[0].width < one_pixel * 1.45 )
- + center_offset = one_pixel / 2;
- + else if ( strategy_auto_change_center_offset &&
- + ppem >= STEM_WIDTH_2_PPEM &&
- + stems[0].width >= one_pixel * 1.45 &&
- + stems[0].width < one_pixel * 2.6 )
- + center_offset = 0;
- + else if ( strategy_auto_change_center_offset &&
- + ppem >= STEM_WIDTH_2_PPEM &&
- + stems[0].width >= one_pixel * 2.6 &&
- + stems[0].width < one_pixel * 3.6 )
- + center_offset = one_pixel / 2;
- + else if ( strategy_auto_change_center_offset &&
- + ppem >= STEM_WIDTH_2_PPEM )
- + center_offset =
- + ( one_pixel
- + * ( ( ( (int)( stems[0].width + one_pixel / 2 ) )
- + / one_pixel ) % 2 ) ) / 2;
- +
- + /* Snap to closest translate and scale values by default */
- + if ( valid_stems >= 1 )
- + {
- + /* closest snapping point for stem 0 */
- + delta = ( stems[0].center + center_offset ) % modulus;
- +
- + if ( delta < modulus / 2 )
- + /* snap left */
- + *translate_value = -delta / ( columns_per_pixel * 4 );
- + else
- + /* snap right */
- + *translate_value = ( modulus - delta ) / ( columns_per_pixel * 4 );
- + }
-
- - target.pitch = bitmap->pitch;
- + if ( strategy_use_d_correction )
- + {
- + /* if the only stem is in the last 1/3 of glyph width, the advance */
- + /* is 6 pixels, the ppem 11, and doing so doesn't violate bitmap , */
- + /* boundaries force it to snap right */
- + if ( valid_stems == 1 &&
- + advance_stem_location > (advance_width * 2) / 3 &&
- + advance_width == 6 * one_pixel &&
- + rightmost_point + modulus - delta
- + <= ( width - (columns_per_pixel * 2) / 3) * 256 &&
- + ppem == 11 )
- + *translate_value = ( modulus - delta ) / ( columns_per_pixel * 4 );
- + }
-
- - /* inflate outline */
- - for ( vec = points; vec < points_end; vec++ )
- + if ( strategy_use_strengths )
- {
- - vec->x *= SCALE;
- - vec->y *= SCALE;
- + /* consider 1/2 pixel the max when strength is at 100%,
- + unless translate is already greater than that */
- + FT_Int strength_cutoff = 32;
- + if ( abs ( *translate_value ) > strength_cutoff )
- + strength_cutoff = *translate_value;
- +
- + max_strength = ( strength_cutoff * alignment_strength ) / 100;
- +
- + if ( *translate_value < -max_strength )
- + *translate_value = -max_strength;
- + else if ( *translate_value > max_strength )
- + *translate_value = max_strength;
- }
-
- - /* render outline into the bitmap */
- - error = render->raster_render( render->raster, ¶ms );
- + /* If 2 stems is detected, scale distance
- + between in order to land on pixels */
- + if ( valid_stems >= 2 )
- + {
- + stem_distance = abs ( stems[1].center - stems[0].center );
-
- - /* deflate outline */
- - for ( vec = points; vec < points_end; vec++ )
- + delta = stem_distance % modulus;
- + new_distance = stem_distance - delta;
- +
- + distance_floor = stem_distance - delta;
- + distance_ceiling = stem_distance + ( modulus - delta );
- +
- + if ( delta < modulus / 2 )
- + new_distance = distance_floor;
- + else
- + new_distance = distance_ceiling;
- +
- + if ( columns_per_pixel == 3 &&
- + valid_stems == 3 &&
- + strategy_use_m_control &&
- + ( width - 2 * columns_per_pixel ) > 6 * columns_per_pixel &&
- + ppem > 8 &&
- + ( advance_stem_location - advance_leftmost_location )
- + < stems[main_stem].width * 2 )
- + {
- + /* Possibly use 2 only when compatible widths is on? */
- + FT_Int mod_factor = 2;
- +
- + if ( verbose )
- + printf ( "USING M CONTROL ");
- +
- + distance_floor = stem_distance
- + - stem_distance % ( modulus * mod_factor ) ;
- + distance_ceiling = distance_floor + modulus * mod_factor;
- +
- + new_distance = distance_ceiling;
- +
- + /* force certain ideal situations */
- + /* these 2 are mostly safe to do */
- + if ( distance_ceiling
- + + one_pixel * columns_per_pixel == advance_width &&
- + stem_width < one_pixel * 1.25 )
- + new_distance = distance_ceiling;
- + /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER
- + THAT NUDGE IS UP OR DOWN */
- + else if ( stem_distance + one_pixel * 2.6 >= advance_width &&
- + stem_width < one_pixel * 1.25 )
- + new_distance = distance_ceiling;
- +
- + if ( proposed_transformed_point ( leftmost_point )
- + < one_third_pixel * 2 ||
- + proposed_transformed_point ( rightmost_point )
- + > ( width -2 ) * one_third_pixel )
- + new_distance = distance_floor;
- +
- + /* NEED TO IGNORE SERIF Ms HERE */
- + /* perhaps check bitmap boundaries instead??? */
- + if ( strategy_bearing_correction && new_distance == distance_ceiling )
- + {
- + /* Correct if bearings are made substantially worse
- + (more than 1/3 a pixel beyond advance) */
- + if ( proposed_transformed_point( advance_rightmost_location )
- + > advance_width + one_third_pixel &&
- + proposed_transformed_point( advance_rightmost_location )
- + > advance_rightmost_location &&
- + -proposed_transformed_point( advance_leftmost_location )
- + < advance_rightmost_location - advance_width )
- + new_distance = distance_floor;
- + }
- +
- + if ( known_stem_values->m >= 0 )
- {
- - vec->x /= SCALE;
- - vec->y /= SCALE;
- + if ( known_stem_values->m == 0 )
- + new_distance = distance_floor;
- + else
- + new_distance = distance_ceiling;
- }
-
- - return error;
- + if ( ( rightmost_point - leftmost_point) -
- + ( ( rightmost_point * *scale_value)
- + - ( leftmost_point * *scale_value ) ) >= one_pixel * 1.5 )
- + {
- + *scale_value = 1.0;
- + *translate_value = 0;
- + goto Exit;
- + }
- +
- + }
- + else if ( columns_per_pixel == 1 &&
- + valid_stems == 3 &&
- + strategy_use_m_control && valid_stems == 3 &&
- + width >= 6 * columns_per_pixel &&
- + ppem > 8 &&
- + ( advance_stem_location - advance_leftmost_location )
- + < stems[main_stem].width * 2 )
- + {
- + /* Possibly use 2 only when compatible widths is on? */
- + FT_Int mod_factor = 2;
- +
- + if ( verbose )
- + printf ("USING M CONTROL ");
- + distance_floor = stem_distance - stem_distance
- + % ( modulus * mod_factor) ;
- + distance_ceiling = distance_floor + modulus * mod_factor;
- +
- + new_distance = distance_ceiling;
- +
- + /* force certain ideal situations */
- + /* these 2 are mostly safe to do */
- + if ( distance_ceiling
- + + one_pixel * columns_per_pixel == advance_width &&
- + stem_width < one_pixel * 1.25 )
- + new_distance = distance_ceiling;
- + /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER
- + THAT NUDGE IS UP OR DOWN */
- + else if ( stem_distance + one_pixel * 2.6 >= advance_width &&
- + stem_width < one_pixel * 1.25 )
- + new_distance = distance_ceiling;
- +
- + if ( proposed_transformed_point( leftmost_point ) < 0 ||
- + proposed_transformed_point( rightmost_point )
- + > width * one_pixel - 2 * one_third_pixel )
- + new_distance = distance_floor;
- +
- + /* NEED TO IGNORE SERIF Ms HERE */
- + /* perhaps check bitmap boundaries instead??? */
- + if ( strategy_bearing_correction && new_distance == distance_ceiling )
- + {
- + /* Correct if bearings are made substantially worse
- + (more than 1/3 a pixel beyond advance) */
- + if ( proposed_transformed_point( advance_rightmost_location )
- + > advance_width + one_third_pixel &&
- + proposed_transformed_point( advance_rightmost_location )
- + > advance_rightmost_location &&
- + -proposed_transformed_point( advance_leftmost_location )
- + < advance_rightmost_location - advance_width )
- + new_distance = distance_floor;
- + }
- +
- + if ( known_stem_values->m >= 0 )
- + {
- + if ( known_stem_values->m == 0 )
- + new_distance = distance_floor;
- + else
- + new_distance = distance_ceiling;
- + }
- +
- +
- + if ( ( rightmost_point - leftmost_point )
- + - ( ( rightmost_point * *scale_value )
- + - ( leftmost_point * *scale_value ) ) >= one_pixel * 1.5 )
- + {
- + *scale_value = 1.0;
- + *translate_value = 0;
- + goto Exit;
- + }
- +
- + }
- + else
- + {
- + if ( strategy_fit_to_width )
- + new_distance = advance_width - 3 * one_pixel;
- + else if ( known_stem_values->stem_scaling >= 0 )
- + {
- + if ( known_stem_values->stem_scaling > 0 )
- + new_distance = distance_ceiling;
- + else
- + new_distance = distance_floor;
- +
- + /* enforce advance width boundaries */
- + /* TOO RESTRICTIVE ON SERIF FONTS */
- + if ( proposed_transformed_point( advance_rightmost_location )
- + >= advance_width ||
- + proposed_transformed_point( advance_leftmost_location )
- + <= 0 )
- + new_distance = distance_floor;
- +
- + /* enforce literal bitmap boundaries if no translate room */
- + if ( ( proposed_transformed_point(rightmost_point) >= width * 256
- + || proposed_transformed_point(leftmost_point ) <= one_pixel )
- + && new_distance + one_pixel * 3 > advance_width )
- + new_distance = distance_floor;
- +
- + }
- + else if ( strategy_translate_using_closest_stem )
- + {
- + /* closest snapping point for stem 1 */
- + delta2 = ( stems[1].center + center_offset ) % modulus;
- +
- + if ( delta2 < modulus / 2 )
- + /* snap left */
- + translate_value2 = -delta2 / ( columns_per_pixel * 4 );
- + else
- + /* snap right */
- + translate_value2 = ( modulus - delta2 )
- + / ( columns_per_pixel * 4 );
- +
- + if ( abs ( translate_value2 ) < abs ( *translate_value ) )
- + {
- + *translate_value = translate_value2;
- + main_stem = 1;
- + }
- +
- + }
- + else if ( strategy_scale_to_closest_centers )
- + {
- + /* closest snapping point for stem 0 */
- + delta = ( stems[0].center + center_offset ) % modulus;
- + delta2 = ( stems[1].center + center_offset ) % modulus;
- +
- + if ( delta < modulus / 2 )
- + /* stretch left */
- + new_distance = delta + stem_distance;
- + else
- + /* stretch right */
- + new_distance = delta - modulus + stem_distance;
- +
- + if ( delta2 < modulus / 2 )
- + new_distance -= delta2; /* stretch left */
- + else
- + new_distance += modulus - delta2; /* stretch right */
- +
- + }
- + else if ( strategy_scale_to_closest_centers_up_only )
- + {
- + FT_Int net_change = 0;
- +
- + /* closest snapping point for stem 0 */
- + delta = ( stems[0].center + center_offset ) % modulus;
- + delta2 = ( stems[1].center + center_offset ) % modulus;
- +
- + if ( delta < modulus / 2 )
- + net_change = delta; /* stretch left */
- + else
- + net_change = -( modulus - delta ); /* stretch right */
- +
- + if ( delta2 < modulus / 2 )
- + net_change -= delta2; /* stretch left */
- + else
- + net_change += modulus - delta2; /* stretch right */
- +
- + if ( net_change > 0 &&
- + proposed_transformed_point( advance_rightmost_location )
- + < advance_width &&
- + proposed_transformed_point( advance_leftmost_location ) > 0 )
- + new_distance = distance_ceiling;
- + }
- +
- + else if ( strategy_always_use_distance_ceiling )
- + {
- + if ( proposed_transformed_point( advance_rightmost_location )
- + < advance_width &&
- + proposed_transformed_point( advance_leftmost_location ) > 0 )
- + new_distance = distance_ceiling;
- + }
- + }
- +
- + if ( strategy_use_strengths )
- + {
- + FT_Int strength_cutoff = center_offset;
- +
- +
- + delta2 = new_distance - stem_distance;
- +
- + if ( abs ( delta2 ) > strength_cutoff )
- + strength_cutoff = delta2;
- +
- + max_strength = ( strength_cutoff * fitting_strength ) / 100;
- +
- + if ( delta2 < -max_strength )
- + new_distance = stem_distance - max_strength;
- + else if ( delta2 > max_strength )
- + new_distance = stem_distance + max_strength;
- + }
- +
- + *scale_value = (float)( new_distance ) / (float)( stem_distance );
- + *translate_value = *translate_value
- + - ( (float)( stems[main_stem].center * (float)new_distance )
- + / (float)stem_distance - stems[main_stem].center ) / 12;
- +
- + if ( valid_stems == 2 )
- + *embolden_value = ( 64.0 / *scale_value - 64.0 );
- +
- + if ( valid_stems == 3 )
- + *embolden_value = ( 64.0 / *scale_value - 64.0 ) / 1.5;
- + }
- +
- + if ( verbose )
- + printf ( "%lu stems:", valid_stems );
- +
- + if ( valid_stems == 1 && verbose )
- + printf ( "1 stem: bitmapwidth:%d glyphwidth:%f glyph_width:%f center:%f bearing:%f advance:%f lhadvance:%f stemwidth:%f %d %d",
- + (width - 6) / columns_per_pixel,
- + (float)m_width / 64.0,
- + (float)glyph_width / (float)one_pixel,
- + (float)( (float)advance_stem_location ) / (float)one_pixel,
- + (float)m_horiBearingX / 64.0,
- + (float)m_horiAdvance / 64.0,
- + (float)linearHoriAdvance / 64.0,
- + (float)stems[0].width / (float)one_pixel,
- + advance_width, original_advance_width );
- + else if ( valid_stems >= 2 && verbose )
- + printf ( "%lu stems: bitmapwidth:%d center1:%f center2:%f difference:%f bearing:%f advance:%f advstemloc:%f ",
- + valid_stems,
- + (width - 6) / columns_per_pixel,
- + ( (float)advance_stem_location ) / (float)one_pixel,
- + ( (float)advance_stem_location
- + + (float)abs ( stems[1].center
- + - stems[0].center) ) / (float)one_pixel,
- + ( (float)abs ( stems[1].center
- + - stems[0].center ) ) / (float)one_pixel,
- + (float)m_horiBearingX / 64.0,
- + (float)m_horiAdvance / 64.0,
- + (float)advance_stem_location / (float)one_pixel );
- +
- + if ( strategy_bearing_correction )
- + {
- + /* Correct if negative bearings are made substantially worse */
- + /* (more than 1/3 a pixel) */
- + if ( proposed_transformed_point( advance_rightmost_location )
- + > advance_width &&
- + proposed_transformed_point( advance_rightmost_location )
- + > advance_rightmost_location &&
- + -proposed_transformed_point( advance_leftmost_location )
- + < advance_rightmost_location - advance_width &&
- + *translate_value
- + > one_third_pixel / ( columns_per_pixel * 4 ) )
- + {
- + *translate_value -=64 ;
- + if ( verbose )
- + printf ( "TRANSLATING -64 " );
- + }
- + }
- + goto Exit;
- + }
- +
- + Exit:
- +
- +#define transformed_point( point ) point * *scale_value + *translate_value * 12
- +
- + if ( strategy_correct_out_of_bounds_outlines )
- + {
- + /* Correct if outside bitmap */
- + if ( transformed_point( rightmost_point )
- + >= width * 256 - 2 * one_third_pixel &&
- + transformed_point( leftmost_point )
- + > one_pixel + 2 * one_third_pixel )
- + *translate_value -=64 ;
- + else if ( transformed_point( leftmost_point )
- + <= one_pixel / 2 &&
- + transformed_point( rightmost_point )
- + <= width * 256 - ( one_pixel + one_pixel / 2 ) )
- + *translate_value += 64;
- + }
- +
- + STVALUES
- + free ( centers );
- + free ( segments );
- + free ( stem_centers );
- + free ( stems );
- + free ( leftmost_segment );
- }
-
- -#undef SCALE
-
- + /* Gamma correction */
- + static void
- + _ft_lcd_gamma_correction_correction ( FT_Bitmap* bitmap,
- + FT_Render_Mode mode,
- + FT_GlyphSlot slot,
- + float gamma_correction_lt,
- + float gamma_correction_value )
- + {
- + if ( gamma_correction_value != 1.0 )
- + {
- + FT_UInt width = (FT_UInt)bitmap->width;
- + FT_UInt height = (FT_UInt)bitmap->rows;
- + FT_Byte* line = bitmap->buffer;
- + float ppem = (float)slot->face->size->metrics.x_ppem;
- +
- +
- + if ( !slot->face || !slot->face->size ) return;
- +
- + if ( ppem >= 5 )
- + for ( height = (FT_UInt)bitmap->rows;
- + height > 0;
- + height--, line += bitmap->pitch )
- + {
- + FT_UInt xx;
- +
- +
- + for ( xx = 0; xx < width; xx += 1 )
- + {
- + /*normal*/
- + /*line[xx] = pseudo_gamma ( line[xx], gamma_correction_value );*/
- +
- + /* sloped */
- + /*line[xx] = pseudo_gamma ( line[xx], gamma_correction_value - 5
- + * (1-gamma_correction_value)/(gamma_correction_lt -5)
- + + ((1-gamma_correction_value)/(gamma_correction_lt -5)) * ppem );*/
- +
- + /* 1/3-sloped */
- + line[xx] = pseudo_gamma ( line[xx], gamma_correction_value - 5
- + * ( ( 1 - gamma_correction_value )
- + / ( 3 * ( gamma_correction_lt -5 ) ) )
- + + ( ( 1 - gamma_correction_value )
- + / ( 3 * ( gamma_correction_lt -5) ) ) * ppem );
- + }
- + }
- + }
- + }
- +
- +#endif
- +
- + /* convert a slot's glyph image into a bitmap */
- static FT_Error
- - ft_smooth_render( FT_Renderer render,
- + ft_smooth_render_generic( FT_Renderer render,
- FT_GlyphSlot slot,
- FT_Render_Mode mode,
- - const FT_Vector* origin )
- + const FT_Vector* origin,
- + FT_Render_Mode required_mode )
- {
- - FT_Error error = FT_Err_Ok;
- - FT_Outline* outline = &slot->outline;
- + FT_Error error;
- + FT_Outline* outline = NULL;
- + FT_Outline* outline_orig = NULL;
- + FT_BBox cbox;
- + FT_Pos width, height, pitch, ppem;
- +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- + FT_Pos height_org, width_org;
- +#endif
- FT_Bitmap* bitmap = &slot->bitmap;
- FT_Memory memory = render->root.memory;
- + FT_Int hmul = ( mode == FT_RENDER_MODE_LCD );
- + FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V );
- FT_Pos x_shift = 0;
- FT_Pos y_shift = 0;
- + FT_Pos x_left, y_top;
- +
- + FT_Raster_Params params;
- +
- + FT_Bool have_translated_origin = FALSE;
- + FT_Bool have_outline_shifted = FALSE;
- + FT_Bool have_buffer = FALSE;
- +
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + FT_Matrix scaleMat;
- + FT_Long translate_value = 0;
- + float scale_value = 1.0;
- + FT_Int align_called = 0;
- +
- +
- + int chromeos_style_sharpening_strength = 0;
- + int alignment_strength = 0;
- + int fitting_strength = 0;
- + int fringe_filter_strength = 0;
- + int grayscale_filter_strength = 0;
- +
- + int autohint_horizontal_stem_darken_strength = 0;
- + int autohint_vertical_stem_darken_strength = 0;
- +
- + int windows_style_sharpening_strength = 0;
- + float gamma_correction_value = 1;
- + float gamma_correction_lt = 0;
- +
- + FT_Int brightness_value = 0.0;
- + FT_Int contrast_value = 0.0;
- +
- + FT_Int snapping_sliding_scale_value = 0;
- +
- + FT_Int global_embolden_x_value = 0;
- + FT_Int global_embolden_y_value = 0;
- +
- + FT_Int bold_embolden_x_value = 0;
- + FT_Int bold_embolden_y_value = 0;
- +
- + FT_Byte chromeos_cutoff;
- + double chromeos_gamma_value;
- +
- + float embolden_value = 0.0;
- + FT_Bool autohinted = FALSE;
- + FT_Bool use_various_tweaks = FALSE;
- + FT_Pos cur_width = infinality_cur_width;
- +
- + const FT_Int MIN_PPEM = 1;
- + /*const FT_Int MAX_PPEM = 100; */
- +
- + FT_Bool use_known_settings_on_selected_fonts;
- +
- + if ( slot->face &&
- + slot->face->size &&
- + slot->face->size->metrics.x_ppem )
- + ppem = slot->face->size->metrics.x_ppem;
- + else
- + ppem = 0;
- +
- + if ( cur_width )
- + {
- + autohinted = TRUE;
- + }
- + if( ftinf ){
- + const float *f=ftinf->gamma_correction;
- +
- + use_known_settings_on_selected_fonts=ftinf->use_known_settings_on_selected_fonts;
- + use_various_tweaks=ftinf->use_various_tweaks;
- + snapping_sliding_scale_value=ftinf->stem_snapping_sliding_scale;
- +
- + alignment_strength=ftinf->stem_alignment_strength;
- + if ( snapping_sliding_scale_value != 0 )
- + alignment_strength = sliding_scale(10, snapping_sliding_scale_value, alignment_strength, 100, ppem);
- +
- + fitting_strength=ftinf->stem_fitting_strength;
- + if ( snapping_sliding_scale_value != 0 )
- + fitting_strength = sliding_scale(10, snapping_sliding_scale_value, fitting_strength, 100, ppem);
- +
- + chromeos_style_sharpening_strength=ftinf->chromeos_style_sharpening_strength;
- +
- + if ( ppem > 10 )
- + chromeos_style_sharpening_strength =
- + ( chromeos_style_sharpening_strength * ppem ) / 10;
- +
- + if ( chromeos_style_sharpening_strength > 100 )
- + chromeos_style_sharpening_strength = 100;
- +
- + brightness_value=ftinf->brightness;
- + contrast_value=ftinf->contrast;
- +
- + windows_style_sharpening_strength=ftinf->windows_style_sharpening_strength;
- +
- + /* Decrease effect slightly to have a more linear increase in sharpness */
- + windows_style_sharpening_strength =
- + ( ( windows_style_sharpening_strength
- + * windows_style_sharpening_strength ) / 100
- + + windows_style_sharpening_strength ) / 2;
-
- + gamma_correction_lt = f[0];
- + gamma_correction_value = f[1] / 100.0f;
- +
- + fringe_filter_strength=ftinf->fringe_filter_strength;
- + grayscale_filter_strength=ftinf->grayscale_filter_strength;
- +
- + autohint_horizontal_stem_darken_strength=ftinf->autohint_horizontal_stem_darken_strength;
- + autohint_vertical_stem_darken_strength=ftinf->autohint_vertical_stem_darken_strength;
- +
- + global_embolden_x_value=ftinf->global_embolden_x_value;
- + global_embolden_y_value=ftinf->global_embolden_y_value;
- +
- + bold_embolden_x_value=ftinf->bold_embolden_x_value;
- + bold_embolden_y_value=ftinf->bold_embolden_y_value;
- + } else {
- + use_known_settings_on_selected_fonts=FALSE;
- + }
- +
- + /* set gamma value to 1 if out of range */
- + if ( slot->face &&
- + slot->face->size &&
- + slot->face->size->metrics.x_ppem )
- + {
- + if ( slot->face->size->metrics.x_ppem >= gamma_correction_lt )
- + gamma_correction_value = 1;
- + }
- + else
- + gamma_correction_value = 1;
- +
- + if( use_various_tweaks &&
- + slot->face &&
- + slot->face->style_name )
- + {
- + /* needs to also check for artifical italics */
- + if ( strcasestr(slot->face->style_name, "Italic" ) ||
- + strcasestr(slot->face->style_name, "Oblique" ) )
- + {
- + windows_style_sharpening_strength = 0;
- + chromeos_style_sharpening_strength = 0;
- + }
- + }
- +
- + /*if (fitting_strength == 100) scale_value = 1.1;*/
- +
- +#endif
- +
- +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- +
- + FT_Int lcd_extra = 0;
- + FT_LcdFiveTapFilter lcd_weights = { 0 };
- + FT_Bool have_custom_weight = FALSE;
- + FT_Bitmap_LcdFilterFunc lcd_filter_func = NULL;
- +
- +
- + if ( slot->face )
- + {
- + FT_Char i;
- +
- +
- + for ( i = 0; i < FT_LCD_FILTER_FIVE_TAPS; i++ )
- + if ( slot->face->internal->lcd_weights[i] != 0 )
- + {
- + have_custom_weight = TRUE;
- + break;
- + }
- + }
- +
- + /*
- + * The LCD filter can be set library-wide and per-face. Face overrides
- + * library. If the face filter weights are all zero (the default), it
- + * means that the library default should be used.
- + */
- + if ( have_custom_weight )
- + {
- + /*
- + * A per-font filter is set. It always uses the default 5-tap
- + * in-place FIR filter that needs 2 extra pixels.
- + */
- + ft_memcpy( lcd_weights,
- + slot->face->internal->lcd_weights,
- + FT_LCD_FILTER_FIVE_TAPS );
- + lcd_filter_func = ft_lcd_filter_fir;
- + lcd_extra = 2;
- + }
- + else
- + {
- + /*
- + * The face's lcd_weights is {0, 0, 0, 0, 0}, meaning `use library
- + * default'. If the library is set to use no LCD filtering
- + * (lcd_filter_func == NULL), `lcd_filter_func' here is also set to
- + * NULL and the tests further below pass over the filtering process.
- + */
- + ft_memcpy( lcd_weights,
- + slot->library->lcd_weights,
- + FT_LCD_FILTER_FIVE_TAPS );
- + lcd_filter_func = slot->library->lcd_filter_func;
- + lcd_extra = slot->library->lcd_extra;
- + }
- +
- +#endif /*FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
- /* check glyph image format */
- if ( slot->format != render->glyph_format )
- @@ -446,15 +2541,134 @@
- }
-
- /* check mode */
- - if ( mode != FT_RENDER_MODE_NORMAL &&
- - mode != FT_RENDER_MODE_LIGHT &&
- - mode != FT_RENDER_MODE_LCD &&
- - mode != FT_RENDER_MODE_LCD_V )
- + if ( mode != required_mode )
- {
- error = FT_THROW( Cannot_Render_Glyph );
- goto Exit;
- }
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- +RERENDER:
- + if ( align_called == 1 )
- + {
- + scaleMat.xx = FT_FixedFromFloat(scale_value);
- + scaleMat.xy = 0;
- + scaleMat.yx = 0;
- + scaleMat.yy = ( 1 << 16 );
- +
- + FT_Outline_Copy(outline_orig, outline);
- +
- + if ( scale_value != 1.0 )
- + FT_Outline_Transform( outline, &scaleMat );
- +
- + FT_Outline_Translate( outline, translate_value, 0 );
- +
- + FT_Outline_EmboldenXY( outline, embolden_value, 0 );
- + }
- + else
- + {
- +#endif
- + outline = &slot->outline;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + /* Need to get this PRIOR to embolden, otherwise bad things happen */
- + FT_Outline_Get_CBox( outline, &cbox );
- +
- + /* Various hacks that need to be turned into a new rule set */
- + /*if ( !autohinted
- + && use_known_settings_on_selected_fonts
- + && mode == FT_RENDER_MODE_LCD
- + && slot->face->family_name
- + && slot->face->style_name
- + && ( strcasestr(slot->face->family_name, "Courier New" )
- + && ( strcasestr(slot->face->style_name, "Regular" )
- + || strcasestr(slot->face->style_name, "Italic" ) ) ) )
- + FT_Outline_Embolden( outline, 24 );*/
- +
- + if ( slot->face )
- + {
- + if ( !autohinted &&
- + use_known_settings_on_selected_fonts &&
- + mode == FT_RENDER_MODE_LCD &&
- + slot->face->family_name &&
- + slot->face->style_name &&
- + strcasestr( slot->face->family_name, "Times New Roman" ) &&
- + strcasestr( slot->face->style_name, "Italic" ) )
- + FT_Outline_EmboldenXY( outline, 12, 0 );
- +
- + if ( use_known_settings_on_selected_fonts &&
- + autohinted &&
- + mode == FT_RENDER_MODE_LCD &&
- + slot->face->family_name &&
- + slot->face->style_name &&
- + strcasestr(slot->face->family_name, "FreeSerif" ) &&
- + strcasestr(slot->face->style_name, "Italic" ) )
- + FT_Outline_EmboldenXY( outline, 8, 0 );
- +
- + if ( global_embolden_x_value != 0 || global_embolden_y_value != 0 )
- + FT_Outline_EmboldenXY( outline,
- + global_embolden_x_value,
- + global_embolden_y_value );
- +
- + if ( ( bold_embolden_x_value != 0 || bold_embolden_y_value != 0 ) &&
- + ( slot->face->style_name &&
- + ( strcasestr(slot->face->style_name, "Bold" ) ||
- + strcasestr(slot->face->style_name, "Black" ) ||
- + ( slot->face->style_flags &&
- + slot->face->style_flags & FT_STYLE_FLAG_BOLD ) ) ) )
- + FT_Outline_EmboldenXY( outline,
- + bold_embolden_x_value,
- + bold_embolden_y_value );
- + }
- +
- + FT_Outline_Copy( outline, outline_orig );
- + }
- +
- + /* translate the outline to the new origin if needed */
- + if ( align_called == 0 )
- + {
- + FT_Pos enlarge_cbox = 0;
- +
- + /* enlarge for grayscale rendering */
- + if ( mode == FT_RENDER_MODE_NORMAL )
- + enlarge_cbox = 64;
- +
- + if ( origin )
- + {
- + FT_Outline_Translate( outline, origin->x, origin->y );
- + have_translated_origin = TRUE;
- + }
- +
- + /* compute the control box, and grid fit it */
- + /*FT_Outline_Get_CBox( outline, &cbox );*/
- +
- + cbox.xMin = FT_PIX_FLOOR( cbox.xMin - enlarge_cbox );
- + cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
- + cbox.xMax = FT_PIX_CEIL( cbox.xMax + enlarge_cbox );
- + cbox.yMax = FT_PIX_CEIL( cbox.yMax );
- +#else
- + if ( origin )
- + {
- + FT_Outline_Translate( outline, origin->x, origin->y );
- + have_translated_origin = TRUE;
- + }
- +
- + /* compute the control box, and grid fit it */
- + FT_Outline_Get_CBox( outline, &cbox );
- +
- + cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
- + cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
- + cbox.xMax = FT_PIX_CEIL( cbox.xMax );
- + cbox.yMax = FT_PIX_CEIL( cbox.yMax );
- +#endif
- +
- + width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6;
- + height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6;
- +
- +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- + width_org = width;
- + height_org = height;
- +#endif
- +
- /* release old bitmap buffer */
- if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
- {
- @@ -462,109 +2676,427 @@
- slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
- }
-
- - if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
- + /* allocate new one */
- + pitch = width;
- + if ( hmul )
- {
- - error = FT_THROW( Raster_Overflow );
- - goto Exit;
- + width = width * 3;
- + pitch = FT_PAD_CEIL( width, 4 );
- }
-
- - if ( !bitmap->rows || !bitmap->pitch )
- - goto Exit;
- + if ( vmul )
- + height *= 3;
-
- - /* allocate new one */
- - if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
- - goto Exit;
- + x_shift = cbox.xMin;
- + y_shift = cbox.yMin;
- + x_left = cbox.xMin >> 6;
- + y_top = cbox.yMax >> 6;
-
- - slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
- +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- + if ( lcd_filter_func )
- + {
- + if ( hmul )
- + {
- + x_shift -= 64 * ( lcd_extra >> 1 );
- + x_left -= lcd_extra >> 1;
- + width += 3 * lcd_extra;
- + pitch = FT_PAD_CEIL( width, 4 );
- + }
-
- - x_shift = 64 * -slot->bitmap_left;
- - y_shift = 64 * -slot->bitmap_top;
- - if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
- - y_shift += 64 * (FT_Int)bitmap->rows / 3;
- - else
- - y_shift += 64 * (FT_Int)bitmap->rows;
- + if ( vmul )
- + {
- + y_shift -= 64 * ( lcd_extra >> 1 );
- + y_top += lcd_extra >> 1;
- + height += 3 * lcd_extra;
- + }
- + }
- +#endif
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + }
- +#endif
-
- - if ( origin )
- +
- + /* Required check is (pitch * height < FT_ULONG_MAX), */
- + /* but we care realistic cases only. Always pitch <= width. */
- + if ( width > 0x7FFF || height > 0x7FFF )
- {
- - x_shift += origin->x;
- - y_shift += origin->y;
- + FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n",
- + width, height ));
- + error = FT_THROW( Raster_Overflow );
- + goto Exit;
- }
-
- - /* translate outline to render it into the bitmap */
- - if ( x_shift || y_shift )
- - FT_Outline_Translate( outline, x_shift, y_shift );
- + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
- + bitmap->num_grays = 256;
- + bitmap->width = (unsigned int)width;
- + bitmap->rows = (unsigned int)height;
- + bitmap->pitch = pitch;
-
- - if ( mode == FT_RENDER_MODE_NORMAL ||
- - mode == FT_RENDER_MODE_LIGHT )
- + /* translate outline to render it into the bitmap */
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( align_called == 0 )
- {
- - if ( outline->flags & FT_OUTLINE_OVERLAP )
- - error = ft_smooth_raster_overlap( render, outline, bitmap );
- - else
- +#endif
- + FT_Outline_Translate( outline, -x_shift, -y_shift );
- + have_outline_shifted = TRUE;
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + }
- +#endif
- + /* release old bitmap buffer */
- + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
- {
- - FT_Raster_Params params;
- + FT_FREE( bitmap->buffer );
- + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
- + }
-
- + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) )
- + goto Exit;
- + else
- + have_buffer = TRUE;
-
- + slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
- +
- + /* set up parameters */
- params.target = bitmap;
- params.source = outline;
- params.flags = FT_RASTER_FLAG_AA;
-
- - error = render->raster_render( render->raster, ¶ms );
- - }
- - }
- - else
- +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- +
- + /* implode outline if needed */
- {
- - if ( mode == FT_RENDER_MODE_LCD )
- - error = ft_smooth_raster_lcd ( render, outline, bitmap );
- - else if ( mode == FT_RENDER_MODE_LCD_V )
- - error = ft_smooth_raster_lcdv( render, outline, bitmap );
- + FT_Vector* points = outline->points;
- + FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
- + FT_Vector* vec;
-
- -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
-
- - /* finally apply filtering */
- + if ( hmul )
- + for ( vec = points; vec < points_end; vec++ )
- + vec->x *= 3;
- +
- + if ( vmul )
- + for ( vec = points; vec < points_end; vec++ )
- + vec->y *= 3;
- + }
- +
- + /* render outline into the bitmap */
- + error = render->raster_render( render->raster, ¶ms );
- +
- + /* deflate outline if needed */
- {
- - FT_Byte* lcd_weights;
- - FT_Bitmap_LcdFilterFunc lcd_filter_func;
- + FT_Vector* points = outline->points;
- + FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
- + FT_Vector* vec;
- +
- +
- + if ( hmul )
- + for ( vec = points; vec < points_end; vec++ )
- + vec->x /= 3;
- +
- + if ( vmul )
- + for ( vec = points; vec < points_end; vec++ )
- + vec->y /= 3;
- + }
- +
- + if ( error )
- + goto Exit;
-
- +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
- + if ( ppem <= MAX_PPEM && ppem >= MIN_PPEM )
- + {
- + if ( align_called == 0 && cur_width / ppem < 10 &&
- + ( alignment_strength > 0 || fitting_strength > 0 ) )
- + _lcd_stem_align ( bitmap,
- + mode,
- + slot,
- + &translate_value,
- + &scale_value,
- + alignment_strength,
- + fitting_strength,
- + &embolden_value );
-
- - /* Per-face LCD filtering takes priority if set up. */
- - if ( slot->face && slot->face->internal->lcd_filter_func )
- + if ( align_called == 0 &&
- + ( translate_value != 0 || scale_value != 1.0 ) )
- {
- - lcd_weights = slot->face->internal->lcd_weights;
- - lcd_filter_func = slot->face->internal->lcd_filter_func;
- + align_called = 1;
- + goto RERENDER;
- }
- - else
- +
- + if ( mode == FT_RENDER_MODE_LCD )
- {
- - lcd_weights = slot->library->lcd_weights;
- - lcd_filter_func = slot->library->lcd_filter_func;
- +
- + if ( fringe_filter_strength > 0 /*&& autohinted*/ )
- + _ft_lcd_fringe_filter( bitmap,
- + mode,
- + fringe_filter_strength,
- + slot->library );
- +
- + /*if ( autohinted)
- + _ft_lcd_stem_end_filter( bitmap, mode, 100, slot->library );*/
- +
- + if ( gamma_correction_lt > 0 && gamma_correction_value != 1.0 )
- + _ft_lcd_gamma_correction_correction( bitmap,
- + mode,
- + slot,
- + gamma_correction_lt,
- + gamma_correction_value );
- +
- + chromeos_cutoff = (FT_Byte)( 0.5 * 255.0 )
- + * ( chromeos_style_sharpening_strength / 100.0 );
- + chromeos_gamma_value = 1;
- +
- + if ( chromeos_style_sharpening_strength > 0 )
- + _ft_lcd_chromeos_sharpen( bitmap,
- + mode,
- + chromeos_cutoff,
- + chromeos_gamma_value );
- +
- + if ( ppem > 8 )
- + if ( windows_style_sharpening_strength > 0 )
- + _ft_lcd_windows_sharpen( bitmap,
- + mode,
- + windows_style_sharpening_strength,
- + slot->library );
- +
- + if ( autohinted &&
- + ( cur_width * 100 ) / 64
- + > autohint_horizontal_stem_darken_strength &&
- + autohint_horizontal_stem_darken_strength != 0 )
- + autohint_horizontal_stem_darken_strength = ( cur_width * 100 ) / 64;
- +
- + if ( autohint_horizontal_stem_darken_strength > 100)
- + autohint_horizontal_stem_darken_strength = 100;
- +
- + /* only do on autohinted fonts */
- + /* Necessary to do on some non-thin fonts, which is why it is outside */
- + /* of the below conditional */
- + if ( autohint_horizontal_stem_darken_strength > 0 && autohinted )
- + _ft_lcd_darken_x ( bitmap,
- + mode,
- + autohint_horizontal_stem_darken_strength,
- + slot->library );
- +
- + /* Enhance thin fonts */
- + if ( autohinted )
- + {
- + /* if forcibly set use that, otherwise make a good estimate */
- + float contrast, brightness;
- + ftinf_get_bc( slot->face->family_name, ppem, &brightness, &contrast);
- + if ( slot->face && !_ft_bitmap_bc ( bitmap, brightness, contrast ) )
- + {
- + FT_Bool is_fixed_name = FALSE;
- +
- + if ( slot->face->family_name &&
- + strcasestr(slot->face->family_name, "Mono" ) )
- + is_fixed_name = TRUE;
- +
- + /* Darken vertical stems */
- + _ft_lcd_darken_y ( bitmap,
- + mode,
- + autohint_vertical_stem_darken_strength,
- + slot->library );
- +
- + /* Adjust brightness / contrast automatically based on stem width */
- + if ( cur_width != 0 && cur_width < 30 )
- + cur_width = 30;
- +
- + if ( cur_width >= 30 && cur_width <= 60 )
- + {
- + float ppem_factor = sliding_scale ( 5, 11, 0.0, 1.0, ppem );
- + float brightness_factor = sliding_scale ( 30, 52, -.3, 0.0,
- + cur_width );
- + float contrast_factor = sliding_scale ( 30, 52, .45, 0.0,
- + cur_width );
- + _ft_bitmap_bc ( bitmap,
- + ppem_factor * brightness_factor,
- + ppem_factor * contrast_factor );
- +
- + /* Only cap variable width thin-stemmed fonts */
- + if ( !FT_IS_FIXED_WIDTH( slot->face ) && !is_fixed_name )
- + _ft_bitmap_cap ( bitmap,
- + ( cur_width * 150 ) / 64,
- + slot->library );
- }
- + }
- + }
- +
-
- if ( lcd_filter_func )
- - lcd_filter_func( bitmap, lcd_weights );
- + lcd_filter_func( bitmap, mode, lcd_weights );
- +
- + if ( grayscale_filter_strength > 0 )
- + _ft_lcd_grayscale_filter( bitmap,
- + mode,
- + grayscale_filter_strength,
- + slot->library );
- +
- }
-
- -#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
- + /* Global values */
- + if ( brightness_value != 0 || contrast_value != 0 )
- + _ft_bitmap_bc ( bitmap,
- + (float)brightness_value / 300.0,
- + (float)contrast_value / 300.0);
-
- + FT_Outline_Done( slot->library, outline_orig );
- }
- + else if ( mode == FT_RENDER_MODE_LCD &&
- + lcd_filter_func )
- + lcd_filter_func( bitmap, mode, lcd_weights );
- +#else
- + if ( lcd_filter_func )
- + lcd_filter_func( bitmap, mode, lcd_weights );
- +#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
-
- - Exit:
- - if ( !error )
- +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
- +
- + /* render outline into bitmap */
- + error = render->raster_render( render->raster, ¶ms );
- + if ( error )
- + goto Exit;
- +
- + /* expand it horizontally */
- + if ( hmul )
- {
- - /* everything is fine; the glyph is now officially a bitmap */
- - slot->format = FT_GLYPH_FORMAT_BITMAP;
- + FT_Byte* line = bitmap->buffer;
- + FT_UInt hh;
- +
- +
- + for ( hh = height_org; hh > 0; hh--, line += pitch )
- + {
- + FT_UInt xx;
- + FT_Byte* end = line + width;
- +
- +
- + for ( xx = width_org; xx > 0; xx-- )
- + {
- + FT_UInt pixel = line[xx-1];
- +
- +
- + end[-3] = (FT_Byte)pixel;
- + end[-2] = (FT_Byte)pixel;
- + end[-1] = (FT_Byte)pixel;
- + end -= 3;
- + }
- + }
- + }
- +
- + /* expand it vertically */
- + if ( vmul )
- + {
- + FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch;
- + FT_Byte* write = bitmap->buffer;
- + FT_UInt hh;
- +
- +
- + for ( hh = height_org; hh > 0; hh-- )
- + {
- + ft_memcpy( write, read, pitch );
- + write += pitch;
- +
- + ft_memcpy( write, read, pitch );
- + write += pitch;
- +
- + ft_memcpy( write, read, pitch );
- + write += pitch;
- + read += pitch;
- + }
- }
- - else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
- +
- +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
- +
- + /*
- + * XXX: on 16bit system, we return an error for huge bitmap
- + * to prevent an overflow.
- + */
- + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
- + {
- + error = FT_THROW( Invalid_Pixel_Size );
- + goto Exit;
- + }
- +
- + slot->format = FT_GLYPH_FORMAT_BITMAP;
- + slot->bitmap_left = (FT_Int)x_left;
- + slot->bitmap_top = (FT_Int)y_top;
- +
- + /* everything is fine; don't deallocate buffer */
- + have_buffer = FALSE;
- +
- + error = FT_Err_Ok;
- +
- + Exit:
- + if ( have_outline_shifted )
- + FT_Outline_Translate( outline, x_shift, y_shift );
- + if ( have_translated_origin )
- + FT_Outline_Translate( outline, -origin->x, -origin->y );
- + if ( have_buffer )
- {
- FT_FREE( bitmap->buffer );
- slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
- }
-
- - if ( x_shift || y_shift )
- - FT_Outline_Translate( outline, -x_shift, -y_shift );
- + return error;
- + }
- +
- +
- +
- + /* convert a slot's glyph image into a horizontal LCD bitmap */
- + static FT_Error
- + ft_smooth_render_lcd( FT_Renderer render,
- + FT_GlyphSlot slot,
- + FT_Render_Mode mode,
- + const FT_Vector* origin )
- + {
- + FT_Error error;
- +
- + error = ft_smooth_render_generic( render, slot, mode, origin,
- + FT_RENDER_MODE_LCD );
- + if ( !error )
- + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD;
-
- return error;
- }
-
-
- + /* convert a slot's glyph image into a vertical LCD bitmap */
- + static FT_Error
- + ft_smooth_render_lcd_v( FT_Renderer render,
- + FT_GlyphSlot slot,
- + FT_Render_Mode mode,
- + const FT_Vector* origin )
- + {
- + FT_Error error;
- +
- + error = ft_smooth_render_generic( render, slot, mode, origin,
- + FT_RENDER_MODE_LCD_V );
- + if ( !error )
- + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;
- +
- + return error;
- + }
- +
- +
- +
- + /* convert a slot's glyph image into a bitmap */
- + static FT_Error
- + ft_smooth_render( FT_Renderer render,
- + FT_GlyphSlot slot,
- + FT_Render_Mode mode,
- + const FT_Vector* origin )
- + {
- + switch (mode) {
- + case FT_RENDER_MODE_LIGHT:
- + case FT_RENDER_MODE_NORMAL:
- + return ft_smooth_render_generic( render, slot, mode, origin,
- + FT_RENDER_MODE_NORMAL );
- + case FT_RENDER_MODE_LCD:
- + return ft_smooth_render_lcd( render, slot, mode, origin);
- + case FT_RENDER_MODE_LCD_V:
- + return ft_smooth_render_lcd_v( render, slot, mode, origin);
- + }
- + }
- +
- +
- FT_DEFINE_RENDERER(
- ft_smooth_renderer_class,
-
|