fbcompose.c 117 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285
  1. /*
  2. *
  3. * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
  4. * 2005 Lars Knoll & Zack Rusin, Trolltech
  5. *
  6. * Permission to use, copy, modify, distribute, and sell this software and its
  7. * documentation for any purpose is hereby granted without fee, provided that
  8. * the above copyright notice appear in all copies and that both that
  9. * copyright notice and this permission notice appear in supporting
  10. * documentation, and that the name of Keith Packard not be used in
  11. * advertising or publicity pertaining to distribution of the software without
  12. * specific, written prior permission. Keith Packard makes no
  13. * representations about the suitability of this software for any purpose. It
  14. * is provided "as is" without express or implied warranty.
  15. *
  16. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  17. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  18. * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  20. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  21. * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  22. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23. * SOFTWARE.
  24. */
  25. #ifdef HAVE_DIX_CONFIG_H
  26. #include <dix-config.h>
  27. #endif
  28. #include "fb.h"
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <math.h>
  32. #include <assert.h>
  33. #include "picturestr.h"
  34. #include "mipict.h"
  35. #include "fbpict.h"
  36. #define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
  37. #define SCANLINE_BUFFER_LENGTH 2048
  38. typedef FASTCALL void (*fetchProc) (const FbBits * bits, int x, int width,
  39. CARD32 *buffer, miIndexedPtr indexed);
  40. /*
  41. * All of the fetch functions
  42. */
  43. static FASTCALL void
  44. fbFetch_a8r8g8b8(const FbBits * bits, int x, int width, CARD32 *buffer,
  45. miIndexedPtr indexed)
  46. {
  47. memcpy(buffer, (const CARD32 *) bits + x, width * sizeof(CARD32));
  48. }
  49. static FASTCALL void
  50. fbFetch_x8r8g8b8(const FbBits * bits, int x, int width, CARD32 *buffer,
  51. miIndexedPtr indexed)
  52. {
  53. const CARD32 *pixel = (const CARD32 *) bits + x;
  54. const CARD32 *end = pixel + width;
  55. while (pixel < end) {
  56. *buffer++ = *pixel++ | 0xff000000;
  57. }
  58. }
  59. static FASTCALL void
  60. fbFetch_a8b8g8r8(const FbBits * bits, int x, int width, CARD32 *buffer,
  61. miIndexedPtr indexed)
  62. {
  63. const CARD32 *pixel = (CARD32 *) bits + x;
  64. const CARD32 *end = pixel + width;
  65. while (pixel < end) {
  66. *buffer++ = ((*pixel & 0xff00ff00) |
  67. ((*pixel >> 16) & 0xff) | ((*pixel & 0xff) << 16));
  68. ++pixel;
  69. }
  70. }
  71. static FASTCALL void
  72. fbFetch_x8b8g8r8(const FbBits * bits, int x, int width, CARD32 *buffer,
  73. miIndexedPtr indexed)
  74. {
  75. const CARD32 *pixel = (CARD32 *) bits + x;
  76. const CARD32 *end = pixel + width;
  77. while (pixel < end) {
  78. *buffer++ = 0xff000000 |
  79. ((*pixel & 0x0000ff00) |
  80. ((*pixel >> 16) & 0xff) | ((*pixel & 0xff) << 16));
  81. ++pixel;
  82. }
  83. }
  84. static FASTCALL void
  85. fbFetch_r8g8b8(const FbBits * bits, int x, int width, CARD32 *buffer,
  86. miIndexedPtr indexed)
  87. {
  88. const CARD8 *pixel = (const CARD8 *) bits + 3 * x;
  89. const CARD8 *end = pixel + 3 * width;
  90. while (pixel < end) {
  91. CARD32 b = Fetch24(pixel) | 0xff000000;
  92. pixel += 3;
  93. *buffer++ = b;
  94. }
  95. }
  96. static FASTCALL void
  97. fbFetch_b8g8r8(const FbBits * bits, int x, int width, CARD32 *buffer,
  98. miIndexedPtr indexed)
  99. {
  100. const CARD8 *pixel = (const CARD8 *) bits + 3 * x;
  101. const CARD8 *end = pixel + 3 * width;
  102. while (pixel < end) {
  103. CARD32 b = 0xff000000;
  104. #if IMAGE_BYTE_ORDER == MSBFirst
  105. b |= (*pixel++);
  106. b |= (*pixel++ << 8);
  107. b |= (*pixel++ << 16);
  108. #else
  109. b |= (*pixel++ << 16);
  110. b |= (*pixel++ << 8);
  111. b |= (*pixel++);
  112. #endif
  113. *buffer++ = b;
  114. }
  115. }
  116. static FASTCALL void
  117. fbFetch_r5g6b5(const FbBits * bits, int x, int width, CARD32 *buffer,
  118. miIndexedPtr indexed)
  119. {
  120. const CARD16 *pixel = (const CARD16 *) bits + x;
  121. const CARD16 *end = pixel + width;
  122. while (pixel < end) {
  123. CARD32 p = *pixel++;
  124. CARD32 r = (((p) << 3) & 0xf8) |
  125. (((p) << 5) & 0xfc00) | (((p) << 8) & 0xf80000);
  126. r |= (r >> 5) & 0x70007;
  127. r |= (r >> 6) & 0x300;
  128. *buffer++ = 0xff000000 | r;
  129. }
  130. }
  131. static FASTCALL void
  132. fbFetch_b5g6r5(const FbBits * bits, int x, int width, CARD32 *buffer,
  133. miIndexedPtr indexed)
  134. {
  135. const CARD16 *pixel = (const CARD16 *) bits + x;
  136. const CARD16 *end = pixel + width;
  137. while (pixel < end) {
  138. CARD32 p = *pixel++;
  139. CARD32 r, g, b;
  140. b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
  141. g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
  142. r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
  143. *buffer++ = (0xff000000 | r | g | b);
  144. }
  145. }
  146. static FASTCALL void
  147. fbFetch_a1r5g5b5(const FbBits * bits, int x, int width, CARD32 *buffer,
  148. miIndexedPtr indexed)
  149. {
  150. const CARD16 *pixel = (const CARD16 *) bits + x;
  151. const CARD16 *end = pixel + width;
  152. while (pixel < end) {
  153. CARD32 p = *pixel++;
  154. CARD32 r, g, b, a;
  155. a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
  156. r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
  157. g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
  158. b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
  159. *buffer++ = (a | r | g | b);
  160. }
  161. }
  162. static FASTCALL void
  163. fbFetch_x1r5g5b5(const FbBits * bits, int x, int width, CARD32 *buffer,
  164. miIndexedPtr indexed)
  165. {
  166. const CARD16 *pixel = (const CARD16 *) bits + x;
  167. const CARD16 *end = pixel + width;
  168. while (pixel < end) {
  169. CARD32 p = *pixel++;
  170. CARD32 r, g, b;
  171. r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
  172. g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
  173. b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
  174. *buffer++ = (0xff000000 | r | g | b);
  175. }
  176. }
  177. static FASTCALL void
  178. fbFetch_a1b5g5r5(const FbBits * bits, int x, int width, CARD32 *buffer,
  179. miIndexedPtr indexed)
  180. {
  181. const CARD16 *pixel = (const CARD16 *) bits + x;
  182. const CARD16 *end = pixel + width;
  183. while (pixel < end) {
  184. CARD32 p = *pixel++;
  185. CARD32 r, g, b, a;
  186. a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
  187. b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
  188. g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
  189. r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
  190. *buffer++ = (a | r | g | b);
  191. }
  192. }
  193. static FASTCALL void
  194. fbFetch_x1b5g5r5(const FbBits * bits, int x, int width, CARD32 *buffer,
  195. miIndexedPtr indexed)
  196. {
  197. const CARD16 *pixel = (const CARD16 *) bits + x;
  198. const CARD16 *end = pixel + width;
  199. while (pixel < end) {
  200. CARD32 p = *pixel++;
  201. CARD32 r, g, b;
  202. b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
  203. g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
  204. r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
  205. *buffer++ = (0xff000000 | r | g | b);
  206. }
  207. }
  208. static FASTCALL void
  209. fbFetch_a4r4g4b4(const FbBits * bits, int x, int width, CARD32 *buffer,
  210. miIndexedPtr indexed)
  211. {
  212. const CARD16 *pixel = (const CARD16 *) bits + x;
  213. const CARD16 *end = pixel + width;
  214. while (pixel < end) {
  215. CARD32 p = *pixel++;
  216. CARD32 r, g, b, a;
  217. a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
  218. r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
  219. g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
  220. b = ((p & 0x000f) | ((p & 0x000f) << 4));
  221. *buffer++ = (a | r | g | b);
  222. }
  223. }
  224. static FASTCALL void
  225. fbFetch_x4r4g4b4(const FbBits * bits, int x, int width, CARD32 *buffer,
  226. miIndexedPtr indexed)
  227. {
  228. const CARD16 *pixel = (const CARD16 *) bits + x;
  229. const CARD16 *end = pixel + width;
  230. while (pixel < end) {
  231. CARD32 p = *pixel++;
  232. CARD32 r, g, b;
  233. r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
  234. g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
  235. b = ((p & 0x000f) | ((p & 0x000f) << 4));
  236. *buffer++ = (0xff000000 | r | g | b);
  237. }
  238. }
  239. static FASTCALL void
  240. fbFetch_a4b4g4r4(const FbBits * bits, int x, int width, CARD32 *buffer,
  241. miIndexedPtr indexed)
  242. {
  243. const CARD16 *pixel = (const CARD16 *) bits + x;
  244. const CARD16 *end = pixel + width;
  245. while (pixel < end) {
  246. CARD32 p = *pixel++;
  247. CARD32 r, g, b, a;
  248. a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
  249. b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
  250. g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
  251. r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
  252. *buffer++ = (a | r | g | b);
  253. }
  254. }
  255. static FASTCALL void
  256. fbFetch_x4b4g4r4(const FbBits * bits, int x, int width, CARD32 *buffer,
  257. miIndexedPtr indexed)
  258. {
  259. const CARD16 *pixel = (const CARD16 *) bits + x;
  260. const CARD16 *end = pixel + width;
  261. while (pixel < end) {
  262. CARD32 p = *pixel++;
  263. CARD32 r, g, b;
  264. b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
  265. g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
  266. r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
  267. *buffer++ = (0xff000000 | r | g | b);
  268. }
  269. }
  270. static FASTCALL void
  271. fbFetch_a8(const FbBits * bits, int x, int width, CARD32 *buffer,
  272. miIndexedPtr indexed)
  273. {
  274. const CARD8 *pixel = (const CARD8 *) bits + x;
  275. const CARD8 *end = pixel + width;
  276. while (pixel < end) {
  277. *buffer++ = (*pixel++) << 24;
  278. }
  279. }
  280. static FASTCALL void
  281. fbFetch_r3g3b2(const FbBits * bits, int x, int width, CARD32 *buffer,
  282. miIndexedPtr indexed)
  283. {
  284. const CARD8 *pixel = (const CARD8 *) bits + x;
  285. const CARD8 *end = pixel + width;
  286. while (pixel < end) {
  287. CARD32 p = *pixel++;
  288. CARD32 r, g, b;
  289. r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
  290. g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
  291. b = (((p & 0x03)) |
  292. ((p & 0x03) << 2) | ((p & 0x03) << 4) | ((p & 0x03) << 6));
  293. *buffer++ = (0xff000000 | r | g | b);
  294. }
  295. }
  296. static FASTCALL void
  297. fbFetch_b2g3r3(const FbBits * bits, int x, int width, CARD32 *buffer,
  298. miIndexedPtr indexed)
  299. {
  300. const CARD8 *pixel = (const CARD8 *) bits + x;
  301. const CARD8 *end = pixel + width;
  302. while (pixel < end) {
  303. CARD32 p = *pixel++;
  304. CARD32 r, g, b;
  305. b = (((p & 0xc0)) |
  306. ((p & 0xc0) >> 2) | ((p & 0xc0) >> 4) | ((p & 0xc0) >> 6));
  307. g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
  308. r = (((p & 0x07)) | ((p & 0x07) << 3) | ((p & 0x06) << 6)) << 16;
  309. *buffer++ = (0xff000000 | r | g | b);
  310. }
  311. }
  312. static FASTCALL void
  313. fbFetch_a2r2g2b2(const FbBits * bits, int x, int width, CARD32 *buffer,
  314. miIndexedPtr indexed)
  315. {
  316. const CARD8 *pixel = (const CARD8 *) bits + x;
  317. const CARD8 *end = pixel + width;
  318. while (pixel < end) {
  319. CARD32 p = *pixel++;
  320. CARD32 a, r, g, b;
  321. a = ((p & 0xc0) * 0x55) << 18;
  322. r = ((p & 0x30) * 0x55) << 12;
  323. g = ((p & 0x0c) * 0x55) << 6;
  324. b = ((p & 0x03) * 0x55);
  325. *buffer++ = a | r | g | b;
  326. }
  327. }
  328. static FASTCALL void
  329. fbFetch_a2b2g2r2(const FbBits * bits, int x, int width, CARD32 *buffer,
  330. miIndexedPtr indexed)
  331. {
  332. const CARD8 *pixel = (const CARD8 *) bits + x;
  333. const CARD8 *end = pixel + width;
  334. while (pixel < end) {
  335. CARD32 p = *pixel++;
  336. CARD32 a, r, g, b;
  337. a = ((p & 0xc0) * 0x55) << 18;
  338. b = ((p & 0x30) * 0x55) >> 6;
  339. g = ((p & 0x0c) * 0x55) << 6;
  340. r = ((p & 0x03) * 0x55) << 16;
  341. *buffer++ = a | r | g | b;
  342. }
  343. }
  344. static FASTCALL void
  345. fbFetch_c8(const FbBits * bits, int x, int width, CARD32 *buffer,
  346. miIndexedPtr indexed)
  347. {
  348. const CARD8 *pixel = (const CARD8 *) bits + x;
  349. const CARD8 *end = pixel + width;
  350. while (pixel < end) {
  351. CARD32 p = *pixel++;
  352. *buffer++ = indexed->rgba[p];
  353. }
  354. }
  355. static FASTCALL void
  356. fbFetch_x4a4(const FbBits * bits, int x, int width, CARD32 *buffer,
  357. miIndexedPtr indexed)
  358. {
  359. const CARD8 *pixel = (const CARD8 *) bits + x;
  360. const CARD8 *end = pixel + width;
  361. while (pixel < end) {
  362. CARD8 p = (*pixel++) & 0xf;
  363. *buffer++ = (p | (p << 4)) << 24;
  364. }
  365. }
  366. #define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2])
  367. #if IMAGE_BYTE_ORDER == MSBFirst
  368. #define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
  369. #else
  370. #define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
  371. #endif
  372. static FASTCALL void
  373. fbFetch_a4(const FbBits * bits, int x, int width, CARD32 *buffer,
  374. miIndexedPtr indexed)
  375. {
  376. int i;
  377. for (i = 0; i < width; ++i) {
  378. CARD32 p = Fetch4(bits, i + x);
  379. p |= p << 4;
  380. *buffer++ = p << 24;
  381. }
  382. }
  383. static FASTCALL void
  384. fbFetch_r1g2b1(const FbBits * bits, int x, int width, CARD32 *buffer,
  385. miIndexedPtr indexed)
  386. {
  387. int i;
  388. for (i = 0; i < width; ++i) {
  389. CARD32 p = Fetch4(bits, i + x);
  390. CARD32 r, g, b;
  391. r = ((p & 0x8) * 0xff) << 13;
  392. g = ((p & 0x6) * 0x55) << 7;
  393. b = ((p & 0x1) * 0xff);
  394. *buffer++ = 0xff000000 | r | g | b;
  395. }
  396. }
  397. static FASTCALL void
  398. fbFetch_b1g2r1(const FbBits * bits, int x, int width, CARD32 *buffer,
  399. miIndexedPtr indexed)
  400. {
  401. int i;
  402. for (i = 0; i < width; ++i) {
  403. CARD32 p = Fetch4(bits, i + x);
  404. CARD32 r, g, b;
  405. b = ((p & 0x8) * 0xff) >> 3;
  406. g = ((p & 0x6) * 0x55) << 7;
  407. r = ((p & 0x1) * 0xff) << 16;
  408. *buffer++ = 0xff000000 | r | g | b;
  409. }
  410. }
  411. static FASTCALL void
  412. fbFetch_a1r1g1b1(const FbBits * bits, int x, int width, CARD32 *buffer,
  413. miIndexedPtr indexed)
  414. {
  415. int i;
  416. for (i = 0; i < width; ++i) {
  417. CARD32 p = Fetch4(bits, i + x);
  418. CARD32 a, r, g, b;
  419. a = ((p & 0x8) * 0xff) << 21;
  420. r = ((p & 0x4) * 0xff) << 14;
  421. g = ((p & 0x2) * 0xff) << 7;
  422. b = ((p & 0x1) * 0xff);
  423. *buffer++ = a | r | g | b;
  424. }
  425. }
  426. static FASTCALL void
  427. fbFetch_a1b1g1r1(const FbBits * bits, int x, int width, CARD32 *buffer,
  428. miIndexedPtr indexed)
  429. {
  430. int i;
  431. for (i = 0; i < width; ++i) {
  432. CARD32 p = Fetch4(bits, i + x);
  433. CARD32 a, r, g, b;
  434. a = ((p & 0x8) * 0xff) << 21;
  435. r = ((p & 0x4) * 0xff) >> 3;
  436. g = ((p & 0x2) * 0xff) << 7;
  437. b = ((p & 0x1) * 0xff) << 16;
  438. *buffer++ = a | r | g | b;
  439. }
  440. }
  441. static FASTCALL void
  442. fbFetch_c4(const FbBits * bits, int x, int width, CARD32 *buffer,
  443. miIndexedPtr indexed)
  444. {
  445. int i;
  446. for (i = 0; i < width; ++i) {
  447. CARD32 p = Fetch4(bits, i + x);
  448. *buffer++ = indexed->rgba[p];
  449. }
  450. }
  451. static FASTCALL void
  452. fbFetch_a1(const FbBits * bits, int x, int width, CARD32 *buffer,
  453. miIndexedPtr indexed)
  454. {
  455. int i;
  456. for (i = 0; i < width; ++i) {
  457. CARD32 p = ((CARD32 *) bits)[(i + x) >> 5];
  458. CARD32 a;
  459. #if BITMAP_BIT_ORDER == MSBFirst
  460. a = p >> (0x1f - ((i + x) & 0x1f));
  461. #else
  462. a = p >> ((i + x) & 0x1f);
  463. #endif
  464. a = a & 1;
  465. a |= a << 1;
  466. a |= a << 2;
  467. a |= a << 4;
  468. *buffer++ = a << 24;
  469. }
  470. }
  471. static FASTCALL void
  472. fbFetch_g1(const FbBits * bits, int x, int width, CARD32 *buffer,
  473. miIndexedPtr indexed)
  474. {
  475. int i;
  476. for (i = 0; i < width; ++i) {
  477. CARD32 p = ((CARD32 *) bits)[(i + x) >> 5];
  478. CARD32 a;
  479. #if BITMAP_BIT_ORDER == MSBFirst
  480. a = p >> (0x1f - ((i + x) & 0x1f));
  481. #else
  482. a = p >> ((i + x) & 0x1f);
  483. #endif
  484. a = a & 1;
  485. *buffer++ = indexed->rgba[a];
  486. }
  487. }
  488. static fetchProc
  489. fetchProcForPicture(PicturePtr pict)
  490. {
  491. switch (pict->format) {
  492. case PICT_a8r8g8b8:
  493. return fbFetch_a8r8g8b8;
  494. case PICT_x8r8g8b8:
  495. return fbFetch_x8r8g8b8;
  496. case PICT_a8b8g8r8:
  497. return fbFetch_a8b8g8r8;
  498. case PICT_x8b8g8r8:
  499. return fbFetch_x8b8g8r8;
  500. /* 24bpp formats */
  501. case PICT_r8g8b8:
  502. return fbFetch_r8g8b8;
  503. case PICT_b8g8r8:
  504. return fbFetch_b8g8r8;
  505. /* 16bpp formats */
  506. case PICT_r5g6b5:
  507. return fbFetch_r5g6b5;
  508. case PICT_b5g6r5:
  509. return fbFetch_b5g6r5;
  510. case PICT_a1r5g5b5:
  511. return fbFetch_a1r5g5b5;
  512. case PICT_x1r5g5b5:
  513. return fbFetch_x1r5g5b5;
  514. case PICT_a1b5g5r5:
  515. return fbFetch_a1b5g5r5;
  516. case PICT_x1b5g5r5:
  517. return fbFetch_x1b5g5r5;
  518. case PICT_a4r4g4b4:
  519. return fbFetch_a4r4g4b4;
  520. case PICT_x4r4g4b4:
  521. return fbFetch_x4r4g4b4;
  522. case PICT_a4b4g4r4:
  523. return fbFetch_a4b4g4r4;
  524. case PICT_x4b4g4r4:
  525. return fbFetch_x4b4g4r4;
  526. /* 8bpp formats */
  527. case PICT_a8:
  528. return fbFetch_a8;
  529. case PICT_r3g3b2:
  530. return fbFetch_r3g3b2;
  531. case PICT_b2g3r3:
  532. return fbFetch_b2g3r3;
  533. case PICT_a2r2g2b2:
  534. return fbFetch_a2r2g2b2;
  535. case PICT_a2b2g2r2:
  536. return fbFetch_a2b2g2r2;
  537. case PICT_c8:
  538. return fbFetch_c8;
  539. case PICT_g8:
  540. return fbFetch_c8;
  541. case PICT_x4a4:
  542. return fbFetch_x4a4;
  543. /* 4bpp formats */
  544. case PICT_a4:
  545. return fbFetch_a4;
  546. case PICT_r1g2b1:
  547. return fbFetch_r1g2b1;
  548. case PICT_b1g2r1:
  549. return fbFetch_b1g2r1;
  550. case PICT_a1r1g1b1:
  551. return fbFetch_a1r1g1b1;
  552. case PICT_a1b1g1r1:
  553. return fbFetch_a1b1g1r1;
  554. case PICT_c4:
  555. return fbFetch_c4;
  556. case PICT_g4:
  557. return fbFetch_c4;
  558. /* 1bpp formats */
  559. case PICT_a1:
  560. return fbFetch_a1;
  561. case PICT_g1:
  562. return fbFetch_g1;
  563. }
  564. return NULL;
  565. }
  566. /*
  567. * Pixel wise fetching
  568. */
  569. typedef FASTCALL CARD32 (*fetchPixelProc) (const FbBits * bits, int offset,
  570. miIndexedPtr indexed);
  571. static FASTCALL CARD32
  572. fbFetchPixel_a8r8g8b8(const FbBits * bits, int offset, miIndexedPtr indexed)
  573. {
  574. return ((CARD32 *) bits)[offset];
  575. }
  576. static FASTCALL CARD32
  577. fbFetchPixel_x8r8g8b8(const FbBits * bits, int offset, miIndexedPtr indexed)
  578. {
  579. return ((CARD32 *) bits)[offset] | 0xff000000;
  580. }
  581. static FASTCALL CARD32
  582. fbFetchPixel_a8b8g8r8(const FbBits * bits, int offset, miIndexedPtr indexed)
  583. {
  584. CARD32 pixel = ((CARD32 *) bits)[offset];
  585. return ((pixel & 0xff000000) |
  586. ((pixel >> 16) & 0xff) |
  587. (pixel & 0x0000ff00) | ((pixel & 0xff) << 16));
  588. }
  589. static FASTCALL CARD32
  590. fbFetchPixel_x8b8g8r8(const FbBits * bits, int offset, miIndexedPtr indexed)
  591. {
  592. CARD32 pixel = ((CARD32 *) bits)[offset];
  593. return ((0xff000000) |
  594. ((pixel >> 16) & 0xff) |
  595. (pixel & 0x0000ff00) | ((pixel & 0xff) << 16));
  596. }
  597. static FASTCALL CARD32
  598. fbFetchPixel_r8g8b8(const FbBits * bits, int offset, miIndexedPtr indexed)
  599. {
  600. CARD8 *pixel = ((CARD8 *) bits) + (offset * 3);
  601. #if IMAGE_BYTE_ORDER == MSBFirst
  602. return (0xff000000 | (pixel[0] << 16) | (pixel[1] << 8) | (pixel[2]));
  603. #else
  604. return (0xff000000 | (pixel[2] << 16) | (pixel[1] << 8) | (pixel[0]));
  605. #endif
  606. }
  607. static FASTCALL CARD32
  608. fbFetchPixel_b8g8r8(const FbBits * bits, int offset, miIndexedPtr indexed)
  609. {
  610. CARD8 *pixel = ((CARD8 *) bits) + (offset * 3);
  611. #if IMAGE_BYTE_ORDER == MSBFirst
  612. return (0xff000000 | (pixel[2] << 16) | (pixel[1] << 8) | (pixel[0]));
  613. #else
  614. return (0xff000000 | (pixel[0] << 16) | (pixel[1] << 8) | (pixel[2]));
  615. #endif
  616. }
  617. static FASTCALL CARD32
  618. fbFetchPixel_r5g6b5(const FbBits * bits, int offset, miIndexedPtr indexed)
  619. {
  620. CARD32 pixel = ((CARD16 *) bits)[offset];
  621. CARD32 r, g, b;
  622. r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
  623. g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
  624. b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
  625. return (0xff000000 | r | g | b);
  626. }
  627. static FASTCALL CARD32
  628. fbFetchPixel_b5g6r5(const FbBits * bits, int offset, miIndexedPtr indexed)
  629. {
  630. CARD32 pixel = ((CARD16 *) bits)[offset];
  631. CARD32 r, g, b;
  632. b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
  633. g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
  634. r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
  635. return (0xff000000 | r | g | b);
  636. }
  637. static FASTCALL CARD32
  638. fbFetchPixel_a1r5g5b5(const FbBits * bits, int offset, miIndexedPtr indexed)
  639. {
  640. CARD32 pixel = ((CARD16 *) bits)[offset];
  641. CARD32 a, r, g, b;
  642. a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
  643. r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
  644. g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
  645. b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
  646. return (a | r | g | b);
  647. }
  648. static FASTCALL CARD32
  649. fbFetchPixel_x1r5g5b5(const FbBits * bits, int offset, miIndexedPtr indexed)
  650. {
  651. CARD32 pixel = ((CARD16 *) bits)[offset];
  652. CARD32 r, g, b;
  653. r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
  654. g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
  655. b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
  656. return (0xff000000 | r | g | b);
  657. }
  658. static FASTCALL CARD32
  659. fbFetchPixel_a1b5g5r5(const FbBits * bits, int offset, miIndexedPtr indexed)
  660. {
  661. CARD32 pixel = ((CARD16 *) bits)[offset];
  662. CARD32 a, r, g, b;
  663. a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
  664. b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
  665. g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
  666. r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
  667. return (a | r | g | b);
  668. }
  669. static FASTCALL CARD32
  670. fbFetchPixel_x1b5g5r5(const FbBits * bits, int offset, miIndexedPtr indexed)
  671. {
  672. CARD32 pixel = ((CARD16 *) bits)[offset];
  673. CARD32 r, g, b;
  674. b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
  675. g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
  676. r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
  677. return (0xff000000 | r | g | b);
  678. }
  679. static FASTCALL CARD32
  680. fbFetchPixel_a4r4g4b4(const FbBits * bits, int offset, miIndexedPtr indexed)
  681. {
  682. CARD32 pixel = ((CARD16 *) bits)[offset];
  683. CARD32 a, r, g, b;
  684. a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
  685. r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
  686. g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
  687. b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
  688. return (a | r | g | b);
  689. }
  690. static FASTCALL CARD32
  691. fbFetchPixel_x4r4g4b4(const FbBits * bits, int offset, miIndexedPtr indexed)
  692. {
  693. CARD32 pixel = ((CARD16 *) bits)[offset];
  694. CARD32 r, g, b;
  695. r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
  696. g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
  697. b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
  698. return (0xff000000 | r | g | b);
  699. }
  700. static FASTCALL CARD32
  701. fbFetchPixel_a4b4g4r4(const FbBits * bits, int offset, miIndexedPtr indexed)
  702. {
  703. CARD32 pixel = ((CARD16 *) bits)[offset];
  704. CARD32 a, r, g, b;
  705. a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
  706. b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
  707. g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
  708. r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
  709. return (a | r | g | b);
  710. }
  711. static FASTCALL CARD32
  712. fbFetchPixel_x4b4g4r4(const FbBits * bits, int offset, miIndexedPtr indexed)
  713. {
  714. CARD32 pixel = ((CARD16 *) bits)[offset];
  715. CARD32 r, g, b;
  716. b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
  717. g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
  718. r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
  719. return (0xff000000 | r | g | b);
  720. }
  721. static FASTCALL CARD32
  722. fbFetchPixel_a8(const FbBits * bits, int offset, miIndexedPtr indexed)
  723. {
  724. CARD32 pixel = ((CARD8 *) bits)[offset];
  725. return pixel << 24;
  726. }
  727. static FASTCALL CARD32
  728. fbFetchPixel_r3g3b2(const FbBits * bits, int offset, miIndexedPtr indexed)
  729. {
  730. CARD32 pixel = ((CARD8 *) bits)[offset];
  731. CARD32 r, g, b;
  732. r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
  733. g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
  734. b = (((pixel & 0x03)) |
  735. ((pixel & 0x03) << 2) | ((pixel & 0x03) << 4) | ((pixel & 0x03) << 6));
  736. return (0xff000000 | r | g | b);
  737. }
  738. static FASTCALL CARD32
  739. fbFetchPixel_b2g3r3(const FbBits * bits, int offset, miIndexedPtr indexed)
  740. {
  741. CARD32 pixel = ((CARD8 *) bits)[offset];
  742. CARD32 r, g, b;
  743. b = (((pixel & 0xc0)) |
  744. ((pixel & 0xc0) >> 2) | ((pixel & 0xc0) >> 4) | ((pixel & 0xc0) >> 6));
  745. g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
  746. r = (((pixel & 0x07)) |
  747. ((pixel & 0x07) << 3) | ((pixel & 0x06) << 6)) << 16;
  748. return (0xff000000 | r | g | b);
  749. }
  750. static FASTCALL CARD32
  751. fbFetchPixel_a2r2g2b2(const FbBits * bits, int offset, miIndexedPtr indexed)
  752. {
  753. CARD32 pixel = ((CARD8 *) bits)[offset];
  754. CARD32 a, r, g, b;
  755. a = ((pixel & 0xc0) * 0x55) << 18;
  756. r = ((pixel & 0x30) * 0x55) << 12;
  757. g = ((pixel & 0x0c) * 0x55) << 6;
  758. b = ((pixel & 0x03) * 0x55);
  759. return a | r | g | b;
  760. }
  761. static FASTCALL CARD32
  762. fbFetchPixel_a2b2g2r2(const FbBits * bits, int offset, miIndexedPtr indexed)
  763. {
  764. CARD32 pixel = ((CARD8 *) bits)[offset];
  765. CARD32 a, r, g, b;
  766. a = ((pixel & 0xc0) * 0x55) << 18;
  767. b = ((pixel & 0x30) * 0x55) >> 6;
  768. g = ((pixel & 0x0c) * 0x55) << 6;
  769. r = ((pixel & 0x03) * 0x55) << 16;
  770. return a | r | g | b;
  771. }
  772. static FASTCALL CARD32
  773. fbFetchPixel_c8(const FbBits * bits, int offset, miIndexedPtr indexed)
  774. {
  775. CARD32 pixel = ((CARD8 *) bits)[offset];
  776. return indexed->rgba[pixel];
  777. }
  778. static FASTCALL CARD32
  779. fbFetchPixel_x4a4(const FbBits * bits, int offset, miIndexedPtr indexed)
  780. {
  781. CARD32 pixel = ((CARD8 *) bits)[offset];
  782. return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
  783. }
  784. #define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2])
  785. #if IMAGE_BYTE_ORDER == MSBFirst
  786. #define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
  787. #else
  788. #define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
  789. #endif
  790. static FASTCALL CARD32
  791. fbFetchPixel_a4(const FbBits * bits, int offset, miIndexedPtr indexed)
  792. {
  793. CARD32 pixel = Fetch4(bits, offset);
  794. pixel |= pixel << 4;
  795. return pixel << 24;
  796. }
  797. static FASTCALL CARD32
  798. fbFetchPixel_r1g2b1(const FbBits * bits, int offset, miIndexedPtr indexed)
  799. {
  800. CARD32 pixel = Fetch4(bits, offset);
  801. CARD32 r, g, b;
  802. r = ((pixel & 0x8) * 0xff) << 13;
  803. g = ((pixel & 0x6) * 0x55) << 7;
  804. b = ((pixel & 0x1) * 0xff);
  805. return 0xff000000 | r | g | b;
  806. }
  807. static FASTCALL CARD32
  808. fbFetchPixel_b1g2r1(const FbBits * bits, int offset, miIndexedPtr indexed)
  809. {
  810. CARD32 pixel = Fetch4(bits, offset);
  811. CARD32 r, g, b;
  812. b = ((pixel & 0x8) * 0xff) >> 3;
  813. g = ((pixel & 0x6) * 0x55) << 7;
  814. r = ((pixel & 0x1) * 0xff) << 16;
  815. return 0xff000000 | r | g | b;
  816. }
  817. static FASTCALL CARD32
  818. fbFetchPixel_a1r1g1b1(const FbBits * bits, int offset, miIndexedPtr indexed)
  819. {
  820. CARD32 pixel = Fetch4(bits, offset);
  821. CARD32 a, r, g, b;
  822. a = ((pixel & 0x8) * 0xff) << 21;
  823. r = ((pixel & 0x4) * 0xff) << 14;
  824. g = ((pixel & 0x2) * 0xff) << 7;
  825. b = ((pixel & 0x1) * 0xff);
  826. return a | r | g | b;
  827. }
  828. static FASTCALL CARD32
  829. fbFetchPixel_a1b1g1r1(const FbBits * bits, int offset, miIndexedPtr indexed)
  830. {
  831. CARD32 pixel = Fetch4(bits, offset);
  832. CARD32 a, r, g, b;
  833. a = ((pixel & 0x8) * 0xff) << 21;
  834. r = ((pixel & 0x4) * 0xff) >> 3;
  835. g = ((pixel & 0x2) * 0xff) << 7;
  836. b = ((pixel & 0x1) * 0xff) << 16;
  837. return a | r | g | b;
  838. }
  839. static FASTCALL CARD32
  840. fbFetchPixel_c4(const FbBits * bits, int offset, miIndexedPtr indexed)
  841. {
  842. CARD32 pixel = Fetch4(bits, offset);
  843. return indexed->rgba[pixel];
  844. }
  845. static FASTCALL CARD32
  846. fbFetchPixel_a1(const FbBits * bits, int offset, miIndexedPtr indexed)
  847. {
  848. CARD32 pixel = ((CARD32 *) bits)[offset >> 5];
  849. CARD32 a;
  850. #if BITMAP_BIT_ORDER == MSBFirst
  851. a = pixel >> (0x1f - (offset & 0x1f));
  852. #else
  853. a = pixel >> (offset & 0x1f);
  854. #endif
  855. a = a & 1;
  856. a |= a << 1;
  857. a |= a << 2;
  858. a |= a << 4;
  859. return a << 24;
  860. }
  861. static FASTCALL CARD32
  862. fbFetchPixel_g1(const FbBits * bits, int offset, miIndexedPtr indexed)
  863. {
  864. CARD32 pixel = ((CARD32 *) bits)[offset >> 5];
  865. CARD32 a;
  866. #if BITMAP_BIT_ORDER == MSBFirst
  867. a = pixel >> (0x1f - (offset & 0x1f));
  868. #else
  869. a = pixel >> (offset & 0x1f);
  870. #endif
  871. a = a & 1;
  872. return indexed->rgba[a];
  873. }
  874. static fetchPixelProc
  875. fetchPixelProcForPicture(PicturePtr pict)
  876. {
  877. switch (pict->format) {
  878. case PICT_a8r8g8b8:
  879. return fbFetchPixel_a8r8g8b8;
  880. case PICT_x8r8g8b8:
  881. return fbFetchPixel_x8r8g8b8;
  882. case PICT_a8b8g8r8:
  883. return fbFetchPixel_a8b8g8r8;
  884. case PICT_x8b8g8r8:
  885. return fbFetchPixel_x8b8g8r8;
  886. /* 24bpp formats */
  887. case PICT_r8g8b8:
  888. return fbFetchPixel_r8g8b8;
  889. case PICT_b8g8r8:
  890. return fbFetchPixel_b8g8r8;
  891. /* 16bpp formats */
  892. case PICT_r5g6b5:
  893. return fbFetchPixel_r5g6b5;
  894. case PICT_b5g6r5:
  895. return fbFetchPixel_b5g6r5;
  896. case PICT_a1r5g5b5:
  897. return fbFetchPixel_a1r5g5b5;
  898. case PICT_x1r5g5b5:
  899. return fbFetchPixel_x1r5g5b5;
  900. case PICT_a1b5g5r5:
  901. return fbFetchPixel_a1b5g5r5;
  902. case PICT_x1b5g5r5:
  903. return fbFetchPixel_x1b5g5r5;
  904. case PICT_a4r4g4b4:
  905. return fbFetchPixel_a4r4g4b4;
  906. case PICT_x4r4g4b4:
  907. return fbFetchPixel_x4r4g4b4;
  908. case PICT_a4b4g4r4:
  909. return fbFetchPixel_a4b4g4r4;
  910. case PICT_x4b4g4r4:
  911. return fbFetchPixel_x4b4g4r4;
  912. /* 8bpp formats */
  913. case PICT_a8:
  914. return fbFetchPixel_a8;
  915. case PICT_r3g3b2:
  916. return fbFetchPixel_r3g3b2;
  917. case PICT_b2g3r3:
  918. return fbFetchPixel_b2g3r3;
  919. case PICT_a2r2g2b2:
  920. return fbFetchPixel_a2r2g2b2;
  921. case PICT_a2b2g2r2:
  922. return fbFetchPixel_a2b2g2r2;
  923. case PICT_c8:
  924. return fbFetchPixel_c8;
  925. case PICT_g8:
  926. return fbFetchPixel_c8;
  927. case PICT_x4a4:
  928. return fbFetchPixel_x4a4;
  929. /* 4bpp formats */
  930. case PICT_a4:
  931. return fbFetchPixel_a4;
  932. case PICT_r1g2b1:
  933. return fbFetchPixel_r1g2b1;
  934. case PICT_b1g2r1:
  935. return fbFetchPixel_b1g2r1;
  936. case PICT_a1r1g1b1:
  937. return fbFetchPixel_a1r1g1b1;
  938. case PICT_a1b1g1r1:
  939. return fbFetchPixel_a1b1g1r1;
  940. case PICT_c4:
  941. return fbFetchPixel_c4;
  942. case PICT_g4:
  943. return fbFetchPixel_c4;
  944. /* 1bpp formats */
  945. case PICT_a1:
  946. return fbFetchPixel_a1;
  947. case PICT_g1:
  948. return fbFetchPixel_g1;
  949. }
  950. return NULL;
  951. }
  952. /*
  953. * All the store functions
  954. */
  955. typedef FASTCALL void (*storeProc) (FbBits * bits, const CARD32 *values, int x,
  956. int width, miIndexedPtr indexed);
  957. #define Splita(v) CARD32 a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
  958. #define Split(v) CARD32 r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
  959. static FASTCALL void
  960. fbStore_a8r8g8b8(FbBits * bits, const CARD32 *values, int x, int width,
  961. miIndexedPtr indexed)
  962. {
  963. memcpy(((CARD32 *) bits) + x, values, width * sizeof(CARD32));
  964. }
  965. static FASTCALL void
  966. fbStore_x8r8g8b8(FbBits * bits, const CARD32 *values, int x, int width,
  967. miIndexedPtr indexed)
  968. {
  969. int i;
  970. CARD32 *pixel = (CARD32 *) bits + x;
  971. for (i = 0; i < width; ++i)
  972. *pixel++ = values[i] & 0xffffff;
  973. }
  974. static FASTCALL void
  975. fbStore_a8b8g8r8(FbBits * bits, const CARD32 *values, int x, int width,
  976. miIndexedPtr indexed)
  977. {
  978. int i;
  979. CARD32 *pixel = (CARD32 *) bits + x;
  980. for (i = 0; i < width; ++i)
  981. *pixel++ =
  982. (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) |
  983. ((values[i] & 0xff) << 16);
  984. }
  985. static FASTCALL void
  986. fbStore_x8b8g8r8(FbBits * bits, const CARD32 *values, int x, int width,
  987. miIndexedPtr indexed)
  988. {
  989. int i;
  990. CARD32 *pixel = (CARD32 *) bits + x;
  991. for (i = 0; i < width; ++i)
  992. *pixel++ =
  993. (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) |
  994. ((values[i] & 0xff) << 16);
  995. }
  996. static FASTCALL void
  997. fbStore_r8g8b8(FbBits * bits, const CARD32 *values, int x, int width,
  998. miIndexedPtr indexed)
  999. {
  1000. int i;
  1001. CARD8 *pixel = ((CARD8 *) bits) + 3 * x;
  1002. for (i = 0; i < width; ++i) {
  1003. Store24(pixel, values[i]);
  1004. pixel += 3;
  1005. }
  1006. }
  1007. static FASTCALL void
  1008. fbStore_b8g8r8(FbBits * bits, const CARD32 *values, int x, int width,
  1009. miIndexedPtr indexed)
  1010. {
  1011. int i;
  1012. CARD8 *pixel = ((CARD8 *) bits) + 3 * x;
  1013. for (i = 0; i < width; ++i) {
  1014. #if IMAGE_BYTE_ORDER == MSBFirst
  1015. *pixel++ = Blue(values[i]);
  1016. *pixel++ = Green(values[i]);
  1017. *pixel++ = Red(values[i]);
  1018. #else
  1019. *pixel++ = Red(values[i]);
  1020. *pixel++ = Green(values[i]);
  1021. *pixel++ = Blue(values[i]);
  1022. #endif
  1023. }
  1024. }
  1025. static FASTCALL void
  1026. fbStore_r5g6b5(FbBits * bits, const CARD32 *values, int x, int width,
  1027. miIndexedPtr indexed)
  1028. {
  1029. int i;
  1030. CARD16 *pixel = ((CARD16 *) bits) + x;
  1031. for (i = 0; i < width; ++i) {
  1032. CARD32 s = values[i];
  1033. *pixel++ = ((s >> 3) & 0x001f) |
  1034. ((s >> 5) & 0x07e0) | ((s >> 8) & 0xf800);
  1035. }
  1036. }
  1037. static FASTCALL void
  1038. fbStore_b5g6r5(FbBits * bits, const CARD32 *values, int x, int width,
  1039. miIndexedPtr indexed)
  1040. {
  1041. int i;
  1042. CARD16 *pixel = ((CARD16 *) bits) + x;
  1043. for (i = 0; i < width; ++i) {
  1044. Split(values[i]);
  1045. *pixel++ = (((b << 8) & 0xf800) | ((g << 3) & 0x07e0) | ((r >> 3)));
  1046. }
  1047. }
  1048. static FASTCALL void
  1049. fbStore_a1r5g5b5(FbBits * bits, const CARD32 *values, int x, int width,
  1050. miIndexedPtr indexed)
  1051. {
  1052. int i;
  1053. CARD16 *pixel = ((CARD16 *) bits) + x;
  1054. for (i = 0; i < width; ++i) {
  1055. Splita(values[i]);
  1056. *pixel++ = (((a << 8) & 0x8000) |
  1057. ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3)));
  1058. }
  1059. }
  1060. static FASTCALL void
  1061. fbStore_x1r5g5b5(FbBits * bits, const CARD32 *values, int x, int width,
  1062. miIndexedPtr indexed)
  1063. {
  1064. int i;
  1065. CARD16 *pixel = ((CARD16 *) bits) + x;
  1066. for (i = 0; i < width; ++i) {
  1067. Split(values[i]);
  1068. *pixel++ = (((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3)));
  1069. }
  1070. }
  1071. static FASTCALL void
  1072. fbStore_a1b5g5r5(FbBits * bits, const CARD32 *values, int x, int width,
  1073. miIndexedPtr indexed)
  1074. {
  1075. int i;
  1076. CARD16 *pixel = ((CARD16 *) bits) + x;
  1077. for (i = 0; i < width; ++i) {
  1078. Splita(values[i]);
  1079. *pixel++ = (((a << 8) & 0x8000) |
  1080. ((b << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((r >> 3)));
  1081. }
  1082. }
  1083. static FASTCALL void
  1084. fbStore_x1b5g5r5(FbBits * bits, const CARD32 *values, int x, int width,
  1085. miIndexedPtr indexed)
  1086. {
  1087. int i;
  1088. CARD16 *pixel = ((CARD16 *) bits) + x;
  1089. for (i = 0; i < width; ++i) {
  1090. Split(values[i]);
  1091. *pixel++ = (((b << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((r >> 3)));
  1092. }
  1093. }
  1094. static FASTCALL void
  1095. fbStore_a4r4g4b4(FbBits * bits, const CARD32 *values, int x, int width,
  1096. miIndexedPtr indexed)
  1097. {
  1098. int i;
  1099. CARD16 *pixel = ((CARD16 *) bits) + x;
  1100. for (i = 0; i < width; ++i) {
  1101. Splita(values[i]);
  1102. *pixel++ = (((a << 8) & 0xf000) |
  1103. ((r << 4) & 0x0f00) | ((g) & 0x00f0) | ((b >> 4)));
  1104. }
  1105. }
  1106. static FASTCALL void
  1107. fbStore_x4r4g4b4(FbBits * bits, const CARD32 *values, int x, int width,
  1108. miIndexedPtr indexed)
  1109. {
  1110. int i;
  1111. CARD16 *pixel = ((CARD16 *) bits) + x;
  1112. for (i = 0; i < width; ++i) {
  1113. Split(values[i]);
  1114. *pixel++ = (((r << 4) & 0x0f00) | ((g) & 0x00f0) | ((b >> 4)));
  1115. }
  1116. }
  1117. static FASTCALL void
  1118. fbStore_a4b4g4r4(FbBits * bits, const CARD32 *values, int x, int width,
  1119. miIndexedPtr indexed)
  1120. {
  1121. int i;
  1122. CARD16 *pixel = ((CARD16 *) bits) + x;
  1123. for (i = 0; i < width; ++i) {
  1124. Splita(values[i]);
  1125. *pixel++ = (((a << 8) & 0xf000) |
  1126. ((b << 4) & 0x0f00) | ((g) & 0x00f0) | ((r >> 4)));
  1127. }
  1128. }
  1129. static FASTCALL void
  1130. fbStore_x4b4g4r4(FbBits * bits, const CARD32 *values, int x, int width,
  1131. miIndexedPtr indexed)
  1132. {
  1133. int i;
  1134. CARD16 *pixel = ((CARD16 *) bits) + x;
  1135. for (i = 0; i < width; ++i) {
  1136. Split(values[i]);
  1137. *pixel++ = (((b << 4) & 0x0f00) | ((g) & 0x00f0) | ((r >> 4)));
  1138. }
  1139. }
  1140. static FASTCALL void
  1141. fbStore_a8(FbBits * bits, const CARD32 *values, int x, int width,
  1142. miIndexedPtr indexed)
  1143. {
  1144. int i;
  1145. CARD8 *pixel = ((CARD8 *) bits) + x;
  1146. for (i = 0; i < width; ++i) {
  1147. *pixel++ = values[i] >> 24;
  1148. }
  1149. }
  1150. static FASTCALL void
  1151. fbStore_r3g3b2(FbBits * bits, const CARD32 *values, int x, int width,
  1152. miIndexedPtr indexed)
  1153. {
  1154. int i;
  1155. CARD8 *pixel = ((CARD8 *) bits) + x;
  1156. for (i = 0; i < width; ++i) {
  1157. Split(values[i]);
  1158. *pixel++ = (((r) & 0xe0) | ((g >> 3) & 0x1c) | ((b >> 6)));
  1159. }
  1160. }
  1161. static FASTCALL void
  1162. fbStore_b2g3r3(FbBits * bits, const CARD32 *values, int x, int width,
  1163. miIndexedPtr indexed)
  1164. {
  1165. int i;
  1166. CARD8 *pixel = ((CARD8 *) bits) + x;
  1167. for (i = 0; i < width; ++i) {
  1168. Split(values[i]);
  1169. *pixel++ = (((b) & 0xe0) | ((g >> 3) & 0x1c) | ((r >> 6)));
  1170. }
  1171. }
  1172. static FASTCALL void
  1173. fbStore_a2r2g2b2(FbBits * bits, const CARD32 *values, int x, int width,
  1174. miIndexedPtr indexed)
  1175. {
  1176. int i;
  1177. CARD8 *pixel = ((CARD8 *) bits) + x;
  1178. for (i = 0; i < width; ++i) {
  1179. Splita(values[i]);
  1180. *pixel++ = (((a) & 0xc0) |
  1181. ((r >> 2) & 0x30) | ((g >> 4) & 0x0c) | ((b >> 6)));
  1182. }
  1183. }
  1184. static FASTCALL void
  1185. fbStore_c8(FbBits * bits, const CARD32 *values, int x, int width,
  1186. miIndexedPtr indexed)
  1187. {
  1188. int i;
  1189. CARD8 *pixel = ((CARD8 *) bits) + x;
  1190. for (i = 0; i < width; ++i) {
  1191. *pixel++ = miIndexToEnt24(indexed, values[i]);
  1192. }
  1193. }
  1194. static FASTCALL void
  1195. fbStore_x4a4(FbBits * bits, const CARD32 *values, int x, int width,
  1196. miIndexedPtr indexed)
  1197. {
  1198. int i;
  1199. CARD8 *pixel = ((CARD8 *) bits) + x;
  1200. for (i = 0; i < width; ++i) {
  1201. *pixel++ = values[i] >> 28;
  1202. }
  1203. }
  1204. #define Store8(l,o,v) (((CARD8 *) l)[(o) >> 3] = (v))
  1205. #if IMAGE_BYTE_ORDER == MSBFirst
  1206. #define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
  1207. (Fetch8(l,o) & 0xf0) | (v) : \
  1208. (Fetch8(l,o) & 0x0f) | ((v) << 4)))
  1209. #else
  1210. #define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
  1211. (Fetch8(l,o) & 0x0f) | ((v) << 4) : \
  1212. (Fetch8(l,o) & 0xf0) | (v)))
  1213. #endif
  1214. static FASTCALL void
  1215. fbStore_a4(FbBits * bits, const CARD32 *values, int x, int width,
  1216. miIndexedPtr indexed)
  1217. {
  1218. int i;
  1219. for (i = 0; i < width; ++i) {
  1220. Store4(bits, i + x, values[i] >> 28);
  1221. }
  1222. }
  1223. static FASTCALL void
  1224. fbStore_r1g2b1(FbBits * bits, const CARD32 *values, int x, int width,
  1225. miIndexedPtr indexed)
  1226. {
  1227. int i;
  1228. for (i = 0; i < width; ++i) {
  1229. CARD32 pixel;
  1230. Split(values[i]);
  1231. pixel = (((r >> 4) & 0x8) | ((g >> 5) & 0x6) | ((b >> 7)));
  1232. Store4(bits, i + x, pixel);
  1233. }
  1234. }
  1235. static FASTCALL void
  1236. fbStore_b1g2r1(FbBits * bits, const CARD32 *values, int x, int width,
  1237. miIndexedPtr indexed)
  1238. {
  1239. int i;
  1240. for (i = 0; i < width; ++i) {
  1241. CARD32 pixel;
  1242. Split(values[i]);
  1243. pixel = (((b >> 4) & 0x8) | ((g >> 5) & 0x6) | ((r >> 7)));
  1244. Store4(bits, i + x, pixel);
  1245. }
  1246. }
  1247. static FASTCALL void
  1248. fbStore_a1r1g1b1(FbBits * bits, const CARD32 *values, int x, int width,
  1249. miIndexedPtr indexed)
  1250. {
  1251. int i;
  1252. for (i = 0; i < width; ++i) {
  1253. CARD32 pixel;
  1254. Splita(values[i]);
  1255. pixel = (((a >> 4) & 0x8) |
  1256. ((r >> 5) & 0x4) | ((g >> 6) & 0x2) | ((b >> 7)));
  1257. Store4(bits, i + x, pixel);
  1258. }
  1259. }
  1260. static FASTCALL void
  1261. fbStore_a1b1g1r1(FbBits * bits, const CARD32 *values, int x, int width,
  1262. miIndexedPtr indexed)
  1263. {
  1264. int i;
  1265. for (i = 0; i < width; ++i) {
  1266. CARD32 pixel;
  1267. Splita(values[i]);
  1268. pixel = (((a >> 4) & 0x8) |
  1269. ((b >> 5) & 0x4) | ((g >> 6) & 0x2) | ((r >> 7)));
  1270. Store4(bits, i + x, pixel);
  1271. }
  1272. }
  1273. static FASTCALL void
  1274. fbStore_c4(FbBits * bits, const CARD32 *values, int x, int width,
  1275. miIndexedPtr indexed)
  1276. {
  1277. int i;
  1278. for (i = 0; i < width; ++i) {
  1279. CARD32 pixel;
  1280. pixel = miIndexToEnt24(indexed, values[i]);
  1281. Store4(bits, i + x, pixel);
  1282. }
  1283. }
  1284. static FASTCALL void
  1285. fbStore_a1(FbBits * bits, const CARD32 *values, int x, int width,
  1286. miIndexedPtr indexed)
  1287. {
  1288. int i;
  1289. for (i = 0; i < width; ++i) {
  1290. CARD32 *pixel = ((CARD32 *) bits) + ((i + x) >> 5);
  1291. CARD32 mask = FbStipMask((i + x) & 0x1f, 1);
  1292. CARD32 v = values[i] & 0x80000000 ? mask : 0;
  1293. *pixel = (*pixel & ~mask) | v;
  1294. }
  1295. }
  1296. static FASTCALL void
  1297. fbStore_g1(FbBits * bits, const CARD32 *values, int x, int width,
  1298. miIndexedPtr indexed)
  1299. {
  1300. int i;
  1301. for (i = 0; i < width; ++i) {
  1302. CARD32 *pixel = ((CARD32 *) bits) + ((i + x) >> 5);
  1303. CARD32 mask = FbStipMask((i + x) & 0x1f, 1);
  1304. CARD32 v = miIndexToEntY24(indexed, values[i]) ? mask : 0;
  1305. *pixel = (*pixel & ~mask) | v;
  1306. }
  1307. }
  1308. static storeProc
  1309. storeProcForPicture(PicturePtr pict)
  1310. {
  1311. switch (pict->format) {
  1312. case PICT_a8r8g8b8:
  1313. return fbStore_a8r8g8b8;
  1314. case PICT_x8r8g8b8:
  1315. return fbStore_x8r8g8b8;
  1316. case PICT_a8b8g8r8:
  1317. return fbStore_a8b8g8r8;
  1318. case PICT_x8b8g8r8:
  1319. return fbStore_x8b8g8r8;
  1320. /* 24bpp formats */
  1321. case PICT_r8g8b8:
  1322. return fbStore_r8g8b8;
  1323. case PICT_b8g8r8:
  1324. return fbStore_b8g8r8;
  1325. /* 16bpp formats */
  1326. case PICT_r5g6b5:
  1327. return fbStore_r5g6b5;
  1328. case PICT_b5g6r5:
  1329. return fbStore_b5g6r5;
  1330. case PICT_a1r5g5b5:
  1331. return fbStore_a1r5g5b5;
  1332. case PICT_x1r5g5b5:
  1333. return fbStore_x1r5g5b5;
  1334. case PICT_a1b5g5r5:
  1335. return fbStore_a1b5g5r5;
  1336. case PICT_x1b5g5r5:
  1337. return fbStore_x1b5g5r5;
  1338. case PICT_a4r4g4b4:
  1339. return fbStore_a4r4g4b4;
  1340. case PICT_x4r4g4b4:
  1341. return fbStore_x4r4g4b4;
  1342. case PICT_a4b4g4r4:
  1343. return fbStore_a4b4g4r4;
  1344. case PICT_x4b4g4r4:
  1345. return fbStore_x4b4g4r4;
  1346. /* 8bpp formats */
  1347. case PICT_a8:
  1348. return fbStore_a8;
  1349. case PICT_r3g3b2:
  1350. return fbStore_r3g3b2;
  1351. case PICT_b2g3r3:
  1352. return fbStore_b2g3r3;
  1353. case PICT_a2r2g2b2:
  1354. return fbStore_a2r2g2b2;
  1355. case PICT_c8:
  1356. return fbStore_c8;
  1357. case PICT_g8:
  1358. return fbStore_c8;
  1359. case PICT_x4a4:
  1360. return fbStore_x4a4;
  1361. /* 4bpp formats */
  1362. case PICT_a4:
  1363. return fbStore_a4;
  1364. case PICT_r1g2b1:
  1365. return fbStore_r1g2b1;
  1366. case PICT_b1g2r1:
  1367. return fbStore_b1g2r1;
  1368. case PICT_a1r1g1b1:
  1369. return fbStore_a1r1g1b1;
  1370. case PICT_a1b1g1r1:
  1371. return fbStore_a1b1g1r1;
  1372. case PICT_c4:
  1373. return fbStore_c4;
  1374. case PICT_g4:
  1375. return fbStore_c4;
  1376. /* 1bpp formats */
  1377. case PICT_a1:
  1378. return fbStore_a1;
  1379. case PICT_g1:
  1380. return fbStore_g1;
  1381. default:
  1382. return NULL;
  1383. }
  1384. }
  1385. /*
  1386. * Combine src and mask
  1387. */
  1388. static FASTCALL void
  1389. fbCombineMaskU(CARD32 *src, const CARD32 *mask, int width)
  1390. {
  1391. int i;
  1392. for (i = 0; i < width; ++i) {
  1393. CARD32 a = mask[i] >> 24;
  1394. CARD32 s = src[i];
  1395. FbByteMul(s, a);
  1396. src[i] = s;
  1397. }
  1398. }
  1399. /*
  1400. * All of the composing functions
  1401. */
  1402. static FASTCALL void
  1403. fbCombineClear(CARD32 *dest, const CARD32 *src, int width)
  1404. {
  1405. memset(dest, 0, width * sizeof(CARD32));
  1406. }
  1407. static FASTCALL void
  1408. fbCombineSrcU(CARD32 *dest, const CARD32 *src, int width)
  1409. {
  1410. memcpy(dest, src, width * sizeof(CARD32));
  1411. }
  1412. static FASTCALL void
  1413. fbCombineOverU(CARD32 *dest, const CARD32 *src, int width)
  1414. {
  1415. int i;
  1416. for (i = 0; i < width; ++i) {
  1417. CARD32 s = src[i];
  1418. CARD32 d = dest[i];
  1419. CARD32 ia = Alpha(~s);
  1420. FbByteMulAdd(d, ia, s);
  1421. dest[i] = d;
  1422. }
  1423. }
  1424. static FASTCALL void
  1425. fbCombineOverReverseU(CARD32 *dest, const CARD32 *src, int width)
  1426. {
  1427. int i;
  1428. for (i = 0; i < width; ++i) {
  1429. CARD32 s = src[i];
  1430. CARD32 d = dest[i];
  1431. CARD32 ia = Alpha(~dest[i]);
  1432. FbByteMulAdd(s, ia, d);
  1433. dest[i] = s;
  1434. }
  1435. }
  1436. static FASTCALL void
  1437. fbCombineInU(CARD32 *dest, const CARD32 *src, int width)
  1438. {
  1439. int i;
  1440. for (i = 0; i < width; ++i) {
  1441. CARD32 s = src[i];
  1442. CARD32 a = Alpha(dest[i]);
  1443. FbByteMul(s, a);
  1444. dest[i] = s;
  1445. }
  1446. }
  1447. static FASTCALL void
  1448. fbCombineInReverseU(CARD32 *dest, const CARD32 *src, int width)
  1449. {
  1450. int i;
  1451. for (i = 0; i < width; ++i) {
  1452. CARD32 d = dest[i];
  1453. CARD32 a = Alpha(src[i]);
  1454. FbByteMul(d, a);
  1455. dest[i] = d;
  1456. }
  1457. }
  1458. static FASTCALL void
  1459. fbCombineOutU(CARD32 *dest, const CARD32 *src, int width)
  1460. {
  1461. int i;
  1462. for (i = 0; i < width; ++i) {
  1463. CARD32 s = src[i];
  1464. CARD32 a = Alpha(~dest[i]);
  1465. FbByteMul(s, a);
  1466. dest[i] = s;
  1467. }
  1468. }
  1469. static FASTCALL void
  1470. fbCombineOutReverseU(CARD32 *dest, const CARD32 *src, int width)
  1471. {
  1472. int i;
  1473. for (i = 0; i < width; ++i) {
  1474. CARD32 d = dest[i];
  1475. CARD32 a = Alpha(~src[i]);
  1476. FbByteMul(d, a);
  1477. dest[i] = d;
  1478. }
  1479. }
  1480. static FASTCALL void
  1481. fbCombineAtopU(CARD32 *dest, const CARD32 *src, int width)
  1482. {
  1483. int i;
  1484. for (i = 0; i < width; ++i) {
  1485. CARD32 s = src[i];
  1486. CARD32 d = dest[i];
  1487. CARD32 dest_a = Alpha(d);
  1488. CARD32 src_ia = Alpha(~s);
  1489. FbByteAddMul(s, dest_a, d, src_ia);
  1490. dest[i] = s;
  1491. }
  1492. }
  1493. static FASTCALL void
  1494. fbCombineAtopReverseU(CARD32 *dest, const CARD32 *src, int width)
  1495. {
  1496. int i;
  1497. for (i = 0; i < width; ++i) {
  1498. CARD32 s = src[i];
  1499. CARD32 d = dest[i];
  1500. CARD32 src_a = Alpha(s);
  1501. CARD32 dest_ia = Alpha(~d);
  1502. FbByteAddMul(s, dest_ia, d, src_a);
  1503. dest[i] = s;
  1504. }
  1505. }
  1506. static FASTCALL void
  1507. fbCombineXorU(CARD32 *dest, const CARD32 *src, int width)
  1508. {
  1509. int i;
  1510. for (i = 0; i < width; ++i) {
  1511. CARD32 s = src[i];
  1512. CARD32 d = dest[i];
  1513. CARD32 src_ia = Alpha(~s);
  1514. CARD32 dest_ia = Alpha(~d);
  1515. FbByteAddMul(s, dest_ia, d, src_ia);
  1516. dest[i] = s;
  1517. }
  1518. }
  1519. static FASTCALL void
  1520. fbCombineAddU(CARD32 *dest, const CARD32 *src, int width)
  1521. {
  1522. int i;
  1523. for (i = 0; i < width; ++i) {
  1524. CARD32 s = src[i];
  1525. CARD32 d = dest[i];
  1526. FbByteAdd(d, s);
  1527. dest[i] = d;
  1528. }
  1529. }
  1530. static FASTCALL void
  1531. fbCombineSaturateU(CARD32 *dest, const CARD32 *src, int width)
  1532. {
  1533. int i;
  1534. for (i = 0; i < width; ++i) {
  1535. CARD32 s = src[i];
  1536. CARD32 d = dest[i];
  1537. CARD16 sa, da;
  1538. sa = s >> 24;
  1539. da = ~d >> 24;
  1540. if (sa > da) {
  1541. sa = FbIntDiv(da, sa);
  1542. FbByteMul(s, sa);
  1543. }
  1544. FbByteAdd(d, s);
  1545. dest[i] = d;
  1546. }
  1547. }
  1548. /*
  1549. * All of the disjoint composing functions
  1550. The four entries in the first column indicate what source contributions
  1551. come from each of the four areas of the picture -- areas covered by neither
  1552. A nor B, areas covered only by A, areas covered only by B and finally
  1553. areas covered by both A and B.
  1554. Disjoint Conjoint
  1555. Fa Fb Fa Fb
  1556. (0,0,0,0) 0 0 0 0
  1557. (0,A,0,A) 1 0 1 0
  1558. (0,0,B,B) 0 1 0 1
  1559. (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
  1560. (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
  1561. (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
  1562. (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
  1563. (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
  1564. (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
  1565. (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
  1566. (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
  1567. (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
  1568. */
  1569. #define CombineAOut 1
  1570. #define CombineAIn 2
  1571. #define CombineBOut 4
  1572. #define CombineBIn 8
  1573. #define CombineClear 0
  1574. #define CombineA (CombineAOut|CombineAIn)
  1575. #define CombineB (CombineBOut|CombineBIn)
  1576. #define CombineAOver (CombineAOut|CombineBOut|CombineAIn)
  1577. #define CombineBOver (CombineAOut|CombineBOut|CombineBIn)
  1578. #define CombineAAtop (CombineBOut|CombineAIn)
  1579. #define CombineBAtop (CombineAOut|CombineBIn)
  1580. #define CombineXor (CombineAOut|CombineBOut)
  1581. /* portion covered by a but not b */
  1582. static INLINE CARD8
  1583. fbCombineDisjointOutPart(CARD8 a, CARD8 b)
  1584. {
  1585. /* min (1, (1-b) / a) */
  1586. b = ~b; /* 1 - b */
  1587. if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
  1588. return 0xff; /* 1 */
  1589. return FbIntDiv(b, a); /* (1-b) / a */
  1590. }
  1591. /* portion covered by both a and b */
  1592. static INLINE CARD8
  1593. fbCombineDisjointInPart(CARD8 a, CARD8 b)
  1594. {
  1595. /* max (1-(1-b)/a,0) */
  1596. /* = - min ((1-b)/a - 1, 0) */
  1597. /* = 1 - min (1, (1-b)/a) */
  1598. b = ~b; /* 1 - b */
  1599. if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
  1600. return 0; /* 1 - 1 */
  1601. return ~FbIntDiv(b, a); /* 1 - (1-b) / a */
  1602. }
  1603. static FASTCALL void
  1604. fbCombineDisjointGeneralU(CARD32 *dest, const CARD32 *src, int width,
  1605. CARD8 combine)
  1606. {
  1607. int i;
  1608. for (i = 0; i < width; ++i) {
  1609. CARD32 s = src[i];
  1610. CARD32 d = dest[i];
  1611. CARD32 m, n, o, p;
  1612. CARD16 Fa, Fb, t, u, v;
  1613. CARD8 sa = s >> 24;
  1614. CARD8 da = d >> 24;
  1615. switch (combine & CombineA) {
  1616. default:
  1617. Fa = 0;
  1618. break;
  1619. case CombineAOut:
  1620. Fa = fbCombineDisjointOutPart(sa, da);
  1621. break;
  1622. case CombineAIn:
  1623. Fa = fbCombineDisjointInPart(sa, da);
  1624. break;
  1625. case CombineA:
  1626. Fa = 0xff;
  1627. break;
  1628. }
  1629. switch (combine & CombineB) {
  1630. default:
  1631. Fb = 0;
  1632. break;
  1633. case CombineBOut:
  1634. Fb = fbCombineDisjointOutPart(da, sa);
  1635. break;
  1636. case CombineBIn:
  1637. Fb = fbCombineDisjointInPart(da, sa);
  1638. break;
  1639. case CombineB:
  1640. Fb = 0xff;
  1641. break;
  1642. }
  1643. m = FbGen(s, d, 0, Fa, Fb, t, u, v);
  1644. n = FbGen(s, d, 8, Fa, Fb, t, u, v);
  1645. o = FbGen(s, d, 16, Fa, Fb, t, u, v);
  1646. p = FbGen(s, d, 24, Fa, Fb, t, u, v);
  1647. s = m | n | o | p;
  1648. dest[i] = s;
  1649. }
  1650. }
  1651. static FASTCALL void
  1652. fbCombineDisjointOverU(CARD32 *dest, const CARD32 *src, int width)
  1653. {
  1654. int i;
  1655. for (i = 0; i < width; ++i) {
  1656. CARD32 s = src[i];
  1657. CARD16 a = s >> 24;
  1658. if (a != 0x00) {
  1659. if (a != 0xff) {
  1660. CARD32 d = dest[i];
  1661. a = fbCombineDisjointOutPart(d >> 24, a);
  1662. FbByteMulAdd(d, a, s);
  1663. s = d;
  1664. }
  1665. dest[i] = s;
  1666. }
  1667. }
  1668. }
  1669. static FASTCALL void
  1670. fbCombineDisjointInU(CARD32 *dest, const CARD32 *src, int width)
  1671. {
  1672. fbCombineDisjointGeneralU(dest, src, width, CombineAIn);
  1673. }
  1674. static FASTCALL void
  1675. fbCombineDisjointInReverseU(CARD32 *dest, const CARD32 *src, int width)
  1676. {
  1677. fbCombineDisjointGeneralU(dest, src, width, CombineBIn);
  1678. }
  1679. static FASTCALL void
  1680. fbCombineDisjointOutU(CARD32 *dest, const CARD32 *src, int width)
  1681. {
  1682. fbCombineDisjointGeneralU(dest, src, width, CombineAOut);
  1683. }
  1684. static FASTCALL void
  1685. fbCombineDisjointOutReverseU(CARD32 *dest, const CARD32 *src, int width)
  1686. {
  1687. fbCombineDisjointGeneralU(dest, src, width, CombineBOut);
  1688. }
  1689. static FASTCALL void
  1690. fbCombineDisjointAtopU(CARD32 *dest, const CARD32 *src, int width)
  1691. {
  1692. fbCombineDisjointGeneralU(dest, src, width, CombineAAtop);
  1693. }
  1694. static FASTCALL void
  1695. fbCombineDisjointAtopReverseU(CARD32 *dest, const CARD32 *src, int width)
  1696. {
  1697. fbCombineDisjointGeneralU(dest, src, width, CombineBAtop);
  1698. }
  1699. static FASTCALL void
  1700. fbCombineDisjointXorU(CARD32 *dest, const CARD32 *src, int width)
  1701. {
  1702. fbCombineDisjointGeneralU(dest, src, width, CombineXor);
  1703. }
  1704. /* portion covered by a but not b */
  1705. static INLINE CARD8
  1706. fbCombineConjointOutPart(CARD8 a, CARD8 b)
  1707. {
  1708. /* max (1-b/a,0) */
  1709. /* = 1-min(b/a,1) */
  1710. /* min (1, (1-b) / a) */
  1711. if (b >= a) /* b >= a -> b/a >= 1 */
  1712. return 0x00; /* 0 */
  1713. return ~FbIntDiv(b, a); /* 1 - b/a */
  1714. }
  1715. /* portion covered by both a and b */
  1716. static INLINE CARD8
  1717. fbCombineConjointInPart(CARD8 a, CARD8 b)
  1718. {
  1719. /* min (1,b/a) */
  1720. if (b >= a) /* b >= a -> b/a >= 1 */
  1721. return 0xff; /* 1 */
  1722. return FbIntDiv(b, a); /* b/a */
  1723. }
  1724. static FASTCALL void
  1725. fbCombineConjointGeneralU(CARD32 *dest, const CARD32 *src, int width,
  1726. CARD8 combine)
  1727. {
  1728. int i;
  1729. for (i = 0; i < width; ++i) {
  1730. CARD32 s = src[i];
  1731. CARD32 d = dest[i];
  1732. CARD32 m, n, o, p;
  1733. CARD16 Fa, Fb, t, u, v;
  1734. CARD8 sa = s >> 24;
  1735. CARD8 da = d >> 24;
  1736. switch (combine & CombineA) {
  1737. default:
  1738. Fa = 0;
  1739. break;
  1740. case CombineAOut:
  1741. Fa = fbCombineConjointOutPart(sa, da);
  1742. break;
  1743. case CombineAIn:
  1744. Fa = fbCombineConjointInPart(sa, da);
  1745. break;
  1746. case CombineA:
  1747. Fa = 0xff;
  1748. break;
  1749. }
  1750. switch (combine & CombineB) {
  1751. default:
  1752. Fb = 0;
  1753. break;
  1754. case CombineBOut:
  1755. Fb = fbCombineConjointOutPart(da, sa);
  1756. break;
  1757. case CombineBIn:
  1758. Fb = fbCombineConjointInPart(da, sa);
  1759. break;
  1760. case CombineB:
  1761. Fb = 0xff;
  1762. break;
  1763. }
  1764. m = FbGen(s, d, 0, Fa, Fb, t, u, v);
  1765. n = FbGen(s, d, 8, Fa, Fb, t, u, v);
  1766. o = FbGen(s, d, 16, Fa, Fb, t, u, v);
  1767. p = FbGen(s, d, 24, Fa, Fb, t, u, v);
  1768. s = m | n | o | p;
  1769. dest[i] = s;
  1770. }
  1771. }
  1772. static FASTCALL void
  1773. fbCombineConjointOverU(CARD32 *dest, const CARD32 *src, int width)
  1774. {
  1775. fbCombineConjointGeneralU(dest, src, width, CombineAOver);
  1776. }
  1777. static FASTCALL void
  1778. fbCombineConjointOverReverseU(CARD32 *dest, const CARD32 *src, int width)
  1779. {
  1780. fbCombineConjointGeneralU(dest, src, width, CombineBOver);
  1781. }
  1782. static FASTCALL void
  1783. fbCombineConjointInU(CARD32 *dest, const CARD32 *src, int width)
  1784. {
  1785. fbCombineConjointGeneralU(dest, src, width, CombineAIn);
  1786. }
  1787. static FASTCALL void
  1788. fbCombineConjointInReverseU(CARD32 *dest, const CARD32 *src, int width)
  1789. {
  1790. fbCombineConjointGeneralU(dest, src, width, CombineBIn);
  1791. }
  1792. static FASTCALL void
  1793. fbCombineConjointOutU(CARD32 *dest, const CARD32 *src, int width)
  1794. {
  1795. fbCombineConjointGeneralU(dest, src, width, CombineAOut);
  1796. }
  1797. static FASTCALL void
  1798. fbCombineConjointOutReverseU(CARD32 *dest, const CARD32 *src, int width)
  1799. {
  1800. fbCombineConjointGeneralU(dest, src, width, CombineBOut);
  1801. }
  1802. static FASTCALL void
  1803. fbCombineConjointAtopU(CARD32 *dest, const CARD32 *src, int width)
  1804. {
  1805. fbCombineConjointGeneralU(dest, src, width, CombineAAtop);
  1806. }
  1807. static FASTCALL void
  1808. fbCombineConjointAtopReverseU(CARD32 *dest, const CARD32 *src, int width)
  1809. {
  1810. fbCombineConjointGeneralU(dest, src, width, CombineBAtop);
  1811. }
  1812. static FASTCALL void
  1813. fbCombineConjointXorU(CARD32 *dest, const CARD32 *src, int width)
  1814. {
  1815. fbCombineConjointGeneralU(dest, src, width, CombineXor);
  1816. }
  1817. static const CombineFuncU fbCombineFuncU[] = {
  1818. fbCombineClear,
  1819. fbCombineSrcU,
  1820. NULL, /* CombineDst */
  1821. fbCombineOverU,
  1822. fbCombineOverReverseU,
  1823. fbCombineInU,
  1824. fbCombineInReverseU,
  1825. fbCombineOutU,
  1826. fbCombineOutReverseU,
  1827. fbCombineAtopU,
  1828. fbCombineAtopReverseU,
  1829. fbCombineXorU,
  1830. fbCombineAddU,
  1831. fbCombineSaturateU,
  1832. NULL,
  1833. NULL,
  1834. fbCombineClear,
  1835. fbCombineSrcU,
  1836. NULL, /* CombineDst */
  1837. fbCombineDisjointOverU,
  1838. fbCombineSaturateU, /* DisjointOverReverse */
  1839. fbCombineDisjointInU,
  1840. fbCombineDisjointInReverseU,
  1841. fbCombineDisjointOutU,
  1842. fbCombineDisjointOutReverseU,
  1843. fbCombineDisjointAtopU,
  1844. fbCombineDisjointAtopReverseU,
  1845. fbCombineDisjointXorU,
  1846. NULL,
  1847. NULL,
  1848. NULL,
  1849. NULL,
  1850. fbCombineClear,
  1851. fbCombineSrcU,
  1852. NULL, /* CombineDst */
  1853. fbCombineConjointOverU,
  1854. fbCombineConjointOverReverseU,
  1855. fbCombineConjointInU,
  1856. fbCombineConjointInReverseU,
  1857. fbCombineConjointOutU,
  1858. fbCombineConjointOutReverseU,
  1859. fbCombineConjointAtopU,
  1860. fbCombineConjointAtopReverseU,
  1861. fbCombineConjointXorU,
  1862. };
  1863. static FASTCALL void
  1864. fbCombineMaskC(CARD32 *src, CARD32 *mask, int width)
  1865. {
  1866. int i;
  1867. for (i = 0; i < width; ++i) {
  1868. CARD32 a = mask[i];
  1869. CARD32 x;
  1870. CARD16 xa;
  1871. if (!a) {
  1872. src[i] = 0;
  1873. continue;
  1874. }
  1875. x = src[i];
  1876. if (a == 0xffffffff) {
  1877. x = x >> 24;
  1878. x |= x << 8;
  1879. x |= x << 16;
  1880. mask[i] = x;
  1881. continue;
  1882. }
  1883. xa = x >> 24;
  1884. FbByteMulC(x, a);
  1885. src[i] = x;
  1886. FbByteMul(a, xa);
  1887. mask[i] = a;
  1888. }
  1889. }
  1890. static FASTCALL void
  1891. fbCombineMaskValueC(CARD32 *src, const CARD32 *mask, int width)
  1892. {
  1893. int i;
  1894. for (i = 0; i < width; ++i) {
  1895. CARD32 a = mask[i];
  1896. CARD32 x;
  1897. if (!a) {
  1898. src[i] = 0;
  1899. continue;
  1900. }
  1901. if (a == 0xffffffff)
  1902. continue;
  1903. x = src[i];
  1904. FbByteMulC(x, a);
  1905. src[i] = x;
  1906. }
  1907. }
  1908. static FASTCALL void
  1909. fbCombineMaskAlphaC(const CARD32 *src, CARD32 *mask, int width)
  1910. {
  1911. int i;
  1912. for (i = 0; i < width; ++i) {
  1913. CARD32 a = mask[i];
  1914. CARD32 x;
  1915. if (!a)
  1916. continue;
  1917. x = src[i] >> 24;
  1918. if (x == 0xff)
  1919. continue;
  1920. if (a == 0xffffffff) {
  1921. x = x >> 24;
  1922. x |= x << 8;
  1923. x |= x << 16;
  1924. mask[i] = x;
  1925. continue;
  1926. }
  1927. FbByteMul(a, x);
  1928. mask[i] = a;
  1929. }
  1930. }
  1931. static FASTCALL void
  1932. fbCombineClearC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  1933. {
  1934. memset(dest, 0, width * sizeof(CARD32));
  1935. }
  1936. static FASTCALL void
  1937. fbCombineSrcC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  1938. {
  1939. fbCombineMaskValueC(src, mask, width);
  1940. memcpy(dest, src, width * sizeof(CARD32));
  1941. }
  1942. static FASTCALL void
  1943. fbCombineOverC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  1944. {
  1945. int i;
  1946. fbCombineMaskC(src, mask, width);
  1947. for (i = 0; i < width; ++i) {
  1948. CARD32 s = src[i];
  1949. CARD32 a = ~mask[i];
  1950. if (a != 0xffffffff) {
  1951. if (a) {
  1952. CARD32 d = dest[i];
  1953. FbByteMulAddC(d, a, s);
  1954. s = d;
  1955. }
  1956. dest[i] = s;
  1957. }
  1958. }
  1959. }
  1960. static FASTCALL void
  1961. fbCombineOverReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  1962. {
  1963. int i;
  1964. fbCombineMaskValueC(src, mask, width);
  1965. for (i = 0; i < width; ++i) {
  1966. CARD32 d = dest[i];
  1967. CARD32 a = ~d >> 24;
  1968. if (a) {
  1969. CARD32 s = src[i];
  1970. if (a != 0xff) {
  1971. FbByteMulAdd(s, a, d);
  1972. }
  1973. dest[i] = s;
  1974. }
  1975. }
  1976. }
  1977. static FASTCALL void
  1978. fbCombineInC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  1979. {
  1980. int i;
  1981. fbCombineMaskValueC(src, mask, width);
  1982. for (i = 0; i < width; ++i) {
  1983. CARD32 d = dest[i];
  1984. CARD16 a = d >> 24;
  1985. CARD32 s = 0;
  1986. if (a) {
  1987. s = src[i];
  1988. if (a != 0xff) {
  1989. FbByteMul(s, a);
  1990. }
  1991. }
  1992. dest[i] = s;
  1993. }
  1994. }
  1995. static FASTCALL void
  1996. fbCombineInReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  1997. {
  1998. int i;
  1999. fbCombineMaskAlphaC(src, mask, width);
  2000. for (i = 0; i < width; ++i) {
  2001. CARD32 a = mask[i];
  2002. if (a != 0xffffffff) {
  2003. CARD32 d = 0;
  2004. if (a) {
  2005. d = dest[i];
  2006. FbByteMulC(d, a);
  2007. }
  2008. dest[i] = d;
  2009. }
  2010. }
  2011. }
  2012. static FASTCALL void
  2013. fbCombineOutC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2014. {
  2015. int i;
  2016. fbCombineMaskValueC(src, mask, width);
  2017. for (i = 0; i < width; ++i) {
  2018. CARD32 d = dest[i];
  2019. CARD16 a = ~d >> 24;
  2020. CARD32 s = 0;
  2021. if (a) {
  2022. s = src[i];
  2023. if (a != 0xff) {
  2024. FbByteMul(s, a);
  2025. }
  2026. }
  2027. dest[i] = s;
  2028. }
  2029. }
  2030. static FASTCALL void
  2031. fbCombineOutReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2032. {
  2033. int i;
  2034. fbCombineMaskAlphaC(src, mask, width);
  2035. for (i = 0; i < width; ++i) {
  2036. CARD32 a = ~mask[i];
  2037. if (a != 0xffffffff) {
  2038. CARD32 d = 0;
  2039. if (a) {
  2040. d = dest[i];
  2041. FbByteMulC(d, a);
  2042. }
  2043. dest[i] = d;
  2044. }
  2045. }
  2046. }
  2047. static FASTCALL void
  2048. fbCombineAtopC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2049. {
  2050. int i;
  2051. fbCombineMaskC(src, mask, width);
  2052. for (i = 0; i < width; ++i) {
  2053. CARD32 d = dest[i];
  2054. CARD32 s = src[i];
  2055. CARD32 ad = ~mask[i];
  2056. CARD16 as = d >> 24;
  2057. FbByteAddMulC(d, ad, s, as);
  2058. dest[i] = d;
  2059. }
  2060. }
  2061. static FASTCALL void
  2062. fbCombineAtopReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2063. {
  2064. int i;
  2065. fbCombineMaskC(src, mask, width);
  2066. for (i = 0; i < width; ++i) {
  2067. CARD32 d = dest[i];
  2068. CARD32 s = src[i];
  2069. CARD32 ad = mask[i];
  2070. CARD16 as = ~d >> 24;
  2071. FbByteAddMulC(d, ad, s, as);
  2072. dest[i] = d;
  2073. }
  2074. }
  2075. static FASTCALL void
  2076. fbCombineXorC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2077. {
  2078. int i;
  2079. fbCombineMaskC(src, mask, width);
  2080. for (i = 0; i < width; ++i) {
  2081. CARD32 d = dest[i];
  2082. CARD32 s = src[i];
  2083. CARD32 ad = ~mask[i];
  2084. CARD16 as = ~d >> 24;
  2085. FbByteAddMulC(d, ad, s, as);
  2086. dest[i] = d;
  2087. }
  2088. }
  2089. static FASTCALL void
  2090. fbCombineAddC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2091. {
  2092. int i;
  2093. fbCombineMaskValueC(src, mask, width);
  2094. for (i = 0; i < width; ++i) {
  2095. CARD32 s = src[i];
  2096. CARD32 d = dest[i];
  2097. FbByteAdd(d, s);
  2098. dest[i] = d;
  2099. }
  2100. }
  2101. static FASTCALL void
  2102. fbCombineSaturateC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2103. {
  2104. int i;
  2105. fbCombineMaskC(src, mask, width);
  2106. for (i = 0; i < width; ++i) {
  2107. CARD32 s, d;
  2108. CARD16 sa, sr, sg, sb, da;
  2109. CARD16 t, u, v;
  2110. CARD32 m, n, o, p;
  2111. d = dest[i];
  2112. s = src[i];
  2113. sa = (mask[i] >> 24);
  2114. sr = (mask[i] >> 16) & 0xff;
  2115. sg = (mask[i] >> 8) & 0xff;
  2116. sb = (mask[i]) & 0xff;
  2117. da = ~d >> 24;
  2118. if (sb <= da)
  2119. m = FbAdd(s, d, 0, t);
  2120. else
  2121. m = FbGen(s, d, 0, (da << 8) / sb, 0xff, t, u, v);
  2122. if (sg <= da)
  2123. n = FbAdd(s, d, 8, t);
  2124. else
  2125. n = FbGen(s, d, 8, (da << 8) / sg, 0xff, t, u, v);
  2126. if (sr <= da)
  2127. o = FbAdd(s, d, 16, t);
  2128. else
  2129. o = FbGen(s, d, 16, (da << 8) / sr, 0xff, t, u, v);
  2130. if (sa <= da)
  2131. p = FbAdd(s, d, 24, t);
  2132. else
  2133. p = FbGen(s, d, 24, (da << 8) / sa, 0xff, t, u, v);
  2134. dest[i] = m | n | o | p;
  2135. }
  2136. }
  2137. static FASTCALL void
  2138. fbCombineDisjointGeneralC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width,
  2139. CARD8 combine)
  2140. {
  2141. int i;
  2142. fbCombineMaskC(src, mask, width);
  2143. for (i = 0; i < width; ++i) {
  2144. CARD32 s, d;
  2145. CARD32 m, n, o, p;
  2146. CARD32 Fa, Fb;
  2147. CARD16 t, u, v;
  2148. CARD32 sa;
  2149. CARD8 da;
  2150. s = src[i];
  2151. sa = mask[i];
  2152. d = dest[i];
  2153. da = d >> 24;
  2154. switch (combine & CombineA) {
  2155. default:
  2156. Fa = 0;
  2157. break;
  2158. case CombineAOut:
  2159. m = fbCombineDisjointOutPart((CARD8) (sa >> 0), da);
  2160. n = fbCombineDisjointOutPart((CARD8) (sa >> 8), da) << 8;
  2161. o = fbCombineDisjointOutPart((CARD8) (sa >> 16), da) << 16;
  2162. p = fbCombineDisjointOutPart((CARD8) (sa >> 24), da) << 24;
  2163. Fa = m | n | o | p;
  2164. break;
  2165. case CombineAIn:
  2166. m = fbCombineDisjointInPart((CARD8) (sa >> 0), da);
  2167. n = fbCombineDisjointInPart((CARD8) (sa >> 8), da) << 8;
  2168. o = fbCombineDisjointInPart((CARD8) (sa >> 16), da) << 16;
  2169. p = fbCombineDisjointInPart((CARD8) (sa >> 24), da) << 24;
  2170. Fa = m | n | o | p;
  2171. break;
  2172. case CombineA:
  2173. Fa = 0xffffffff;
  2174. break;
  2175. }
  2176. switch (combine & CombineB) {
  2177. default:
  2178. Fb = 0;
  2179. break;
  2180. case CombineBOut:
  2181. m = fbCombineDisjointOutPart(da, (CARD8) (sa >> 0));
  2182. n = fbCombineDisjointOutPart(da, (CARD8) (sa >> 8)) << 8;
  2183. o = fbCombineDisjointOutPart(da, (CARD8) (sa >> 16)) << 16;
  2184. p = fbCombineDisjointOutPart(da, (CARD8) (sa >> 24)) << 24;
  2185. Fb = m | n | o | p;
  2186. break;
  2187. case CombineBIn:
  2188. m = fbCombineDisjointInPart(da, (CARD8) (sa >> 0));
  2189. n = fbCombineDisjointInPart(da, (CARD8) (sa >> 8)) << 8;
  2190. o = fbCombineDisjointInPart(da, (CARD8) (sa >> 16)) << 16;
  2191. p = fbCombineDisjointInPart(da, (CARD8) (sa >> 24)) << 24;
  2192. Fb = m | n | o | p;
  2193. break;
  2194. case CombineB:
  2195. Fb = 0xffffffff;
  2196. break;
  2197. }
  2198. m = FbGen(s, d, 0, FbGet8(Fa, 0), FbGet8(Fb, 0), t, u, v);
  2199. n = FbGen(s, d, 8, FbGet8(Fa, 8), FbGet8(Fb, 8), t, u, v);
  2200. o = FbGen(s, d, 16, FbGet8(Fa, 16), FbGet8(Fb, 16), t, u, v);
  2201. p = FbGen(s, d, 24, FbGet8(Fa, 24), FbGet8(Fb, 24), t, u, v);
  2202. s = m | n | o | p;
  2203. dest[i] = s;
  2204. }
  2205. }
  2206. static FASTCALL void
  2207. fbCombineDisjointOverC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2208. {
  2209. fbCombineDisjointGeneralC(dest, src, mask, width, CombineAOver);
  2210. }
  2211. static FASTCALL void
  2212. fbCombineDisjointInC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2213. {
  2214. fbCombineDisjointGeneralC(dest, src, mask, width, CombineAIn);
  2215. }
  2216. static FASTCALL void
  2217. fbCombineDisjointInReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2218. {
  2219. fbCombineDisjointGeneralC(dest, src, mask, width, CombineBIn);
  2220. }
  2221. static FASTCALL void
  2222. fbCombineDisjointOutC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2223. {
  2224. fbCombineDisjointGeneralC(dest, src, mask, width, CombineAOut);
  2225. }
  2226. static FASTCALL void
  2227. fbCombineDisjointOutReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2228. {
  2229. fbCombineDisjointGeneralC(dest, src, mask, width, CombineBOut);
  2230. }
  2231. static FASTCALL void
  2232. fbCombineDisjointAtopC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2233. {
  2234. fbCombineDisjointGeneralC(dest, src, mask, width, CombineAAtop);
  2235. }
  2236. static FASTCALL void
  2237. fbCombineDisjointAtopReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask,
  2238. int width)
  2239. {
  2240. fbCombineDisjointGeneralC(dest, src, mask, width, CombineBAtop);
  2241. }
  2242. static FASTCALL void
  2243. fbCombineDisjointXorC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2244. {
  2245. fbCombineDisjointGeneralC(dest, src, mask, width, CombineXor);
  2246. }
  2247. static FASTCALL void
  2248. fbCombineConjointGeneralC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width,
  2249. CARD8 combine)
  2250. {
  2251. int i;
  2252. fbCombineMaskC(src, mask, width);
  2253. for (i = 0; i < width; ++i) {
  2254. CARD32 s, d;
  2255. CARD32 m, n, o, p;
  2256. CARD32 Fa, Fb;
  2257. CARD16 t, u, v;
  2258. CARD32 sa;
  2259. CARD8 da;
  2260. s = src[i];
  2261. sa = mask[i];
  2262. d = dest[i];
  2263. da = d >> 24;
  2264. switch (combine & CombineA) {
  2265. default:
  2266. Fa = 0;
  2267. break;
  2268. case CombineAOut:
  2269. m = fbCombineConjointOutPart((CARD8) (sa >> 0), da);
  2270. n = fbCombineConjointOutPart((CARD8) (sa >> 8), da) << 8;
  2271. o = fbCombineConjointOutPart((CARD8) (sa >> 16), da) << 16;
  2272. p = fbCombineConjointOutPart((CARD8) (sa >> 24), da) << 24;
  2273. Fa = m | n | o | p;
  2274. break;
  2275. case CombineAIn:
  2276. m = fbCombineConjointInPart((CARD8) (sa >> 0), da);
  2277. n = fbCombineConjointInPart((CARD8) (sa >> 8), da) << 8;
  2278. o = fbCombineConjointInPart((CARD8) (sa >> 16), da) << 16;
  2279. p = fbCombineConjointInPart((CARD8) (sa >> 24), da) << 24;
  2280. Fa = m | n | o | p;
  2281. break;
  2282. case CombineA:
  2283. Fa = 0xffffffff;
  2284. break;
  2285. }
  2286. switch (combine & CombineB) {
  2287. default:
  2288. Fb = 0;
  2289. break;
  2290. case CombineBOut:
  2291. m = fbCombineConjointOutPart(da, (CARD8) (sa >> 0));
  2292. n = fbCombineConjointOutPart(da, (CARD8) (sa >> 8)) << 8;
  2293. o = fbCombineConjointOutPart(da, (CARD8) (sa >> 16)) << 16;
  2294. p = fbCombineConjointOutPart(da, (CARD8) (sa >> 24)) << 24;
  2295. Fb = m | n | o | p;
  2296. break;
  2297. case CombineBIn:
  2298. m = fbCombineConjointInPart(da, (CARD8) (sa >> 0));
  2299. n = fbCombineConjointInPart(da, (CARD8) (sa >> 8)) << 8;
  2300. o = fbCombineConjointInPart(da, (CARD8) (sa >> 16)) << 16;
  2301. p = fbCombineConjointInPart(da, (CARD8) (sa >> 24)) << 24;
  2302. Fb = m | n | o | p;
  2303. break;
  2304. case CombineB:
  2305. Fb = 0xffffffff;
  2306. break;
  2307. }
  2308. m = FbGen(s, d, 0, FbGet8(Fa, 0), FbGet8(Fb, 0), t, u, v);
  2309. n = FbGen(s, d, 8, FbGet8(Fa, 8), FbGet8(Fb, 8), t, u, v);
  2310. o = FbGen(s, d, 16, FbGet8(Fa, 16), FbGet8(Fb, 16), t, u, v);
  2311. p = FbGen(s, d, 24, FbGet8(Fa, 24), FbGet8(Fb, 24), t, u, v);
  2312. s = m | n | o | p;
  2313. dest[i] = s;
  2314. }
  2315. }
  2316. static FASTCALL void
  2317. fbCombineConjointOverC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2318. {
  2319. fbCombineConjointGeneralC(dest, src, mask, width, CombineAOver);
  2320. }
  2321. static FASTCALL void
  2322. fbCombineConjointOverReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask,
  2323. int width)
  2324. {
  2325. fbCombineConjointGeneralC(dest, src, mask, width, CombineBOver);
  2326. }
  2327. static FASTCALL void
  2328. fbCombineConjointInC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2329. {
  2330. fbCombineConjointGeneralC(dest, src, mask, width, CombineAIn);
  2331. }
  2332. static FASTCALL void
  2333. fbCombineConjointInReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2334. {
  2335. fbCombineConjointGeneralC(dest, src, mask, width, CombineBIn);
  2336. }
  2337. static FASTCALL void
  2338. fbCombineConjointOutC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2339. {
  2340. fbCombineConjointGeneralC(dest, src, mask, width, CombineAOut);
  2341. }
  2342. static FASTCALL void
  2343. fbCombineConjointOutReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2344. {
  2345. fbCombineConjointGeneralC(dest, src, mask, width, CombineBOut);
  2346. }
  2347. static FASTCALL void
  2348. fbCombineConjointAtopC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2349. {
  2350. fbCombineConjointGeneralC(dest, src, mask, width, CombineAAtop);
  2351. }
  2352. static FASTCALL void
  2353. fbCombineConjointAtopReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask,
  2354. int width)
  2355. {
  2356. fbCombineConjointGeneralC(dest, src, mask, width, CombineBAtop);
  2357. }
  2358. static FASTCALL void
  2359. fbCombineConjointXorC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
  2360. {
  2361. fbCombineConjointGeneralC(dest, src, mask, width, CombineXor);
  2362. }
  2363. static const CombineFuncC fbCombineFuncC[] = {
  2364. fbCombineClearC,
  2365. fbCombineSrcC,
  2366. NULL, /* Dest */
  2367. fbCombineOverC,
  2368. fbCombineOverReverseC,
  2369. fbCombineInC,
  2370. fbCombineInReverseC,
  2371. fbCombineOutC,
  2372. fbCombineOutReverseC,
  2373. fbCombineAtopC,
  2374. fbCombineAtopReverseC,
  2375. fbCombineXorC,
  2376. fbCombineAddC,
  2377. fbCombineSaturateC,
  2378. NULL,
  2379. NULL,
  2380. fbCombineClearC, /* 0x10 */
  2381. fbCombineSrcC,
  2382. NULL, /* Dest */
  2383. fbCombineDisjointOverC,
  2384. fbCombineSaturateC, /* DisjointOverReverse */
  2385. fbCombineDisjointInC,
  2386. fbCombineDisjointInReverseC,
  2387. fbCombineDisjointOutC,
  2388. fbCombineDisjointOutReverseC,
  2389. fbCombineDisjointAtopC,
  2390. fbCombineDisjointAtopReverseC,
  2391. fbCombineDisjointXorC, /* 0x1b */
  2392. NULL,
  2393. NULL,
  2394. NULL,
  2395. NULL,
  2396. fbCombineClearC,
  2397. fbCombineSrcC,
  2398. NULL, /* Dest */
  2399. fbCombineConjointOverC,
  2400. fbCombineConjointOverReverseC,
  2401. fbCombineConjointInC,
  2402. fbCombineConjointInReverseC,
  2403. fbCombineConjointOutC,
  2404. fbCombineConjointOutReverseC,
  2405. fbCombineConjointAtopC,
  2406. fbCombineConjointAtopReverseC,
  2407. fbCombineConjointXorC,
  2408. };
  2409. static const FbComposeFunctions composeFunctions = {
  2410. fbCombineFuncU,
  2411. fbCombineFuncC,
  2412. fbCombineMaskU
  2413. };
  2414. static void
  2415. fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  2416. {
  2417. FbBits *bits;
  2418. FbStride stride;
  2419. int bpp;
  2420. int xoff, yoff;
  2421. CARD32 color;
  2422. CARD32 *end;
  2423. fetchPixelProc fetch = fetchPixelProcForPicture(pict);
  2424. miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
  2425. fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
  2426. bits += yoff * stride + (xoff * bpp >> FB_SHIFT);
  2427. color = fetch(bits, 0, indexed);
  2428. end = buffer + width;
  2429. while (buffer < end)
  2430. *buffer++ = color;
  2431. }
  2432. static void
  2433. fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  2434. {
  2435. FbBits *bits;
  2436. FbStride stride;
  2437. int bpp;
  2438. int xoff, yoff;
  2439. fetchProc fetch = fetchProcForPicture(pict);
  2440. miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
  2441. fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
  2442. x += xoff;
  2443. y += yoff;
  2444. bits += y * stride;
  2445. fetch(bits, x, width, buffer, indexed);
  2446. }
  2447. #define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
  2448. #define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :\
  2449. ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
  2450. static CARD32
  2451. gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos,
  2452. unsigned int spread)
  2453. {
  2454. int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
  2455. /* calculate the actual offset. */
  2456. if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) {
  2457. if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) {
  2458. ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE;
  2459. ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos;
  2460. }
  2461. else if (spread == RepeatReflect) {
  2462. const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1;
  2463. ipos = ipos % limit;
  2464. ipos = ipos < 0 ? limit + ipos : ipos;
  2465. ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos;
  2466. }
  2467. else if (spread == RepeatPad) {
  2468. if (ipos < 0)
  2469. ipos = 0;
  2470. else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE)
  2471. ipos = PICT_GRADIENT_STOPTABLE_SIZE - 1;
  2472. }
  2473. else { /* RepeatNone */
  2474. return 0;
  2475. }
  2476. }
  2477. assert(ipos >= 0);
  2478. assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE);
  2479. return pGradient->linear.colorTable[ipos];
  2480. }
  2481. static void
  2482. fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  2483. {
  2484. SourcePictPtr pGradient = pict->pSourcePict;
  2485. CARD32 *end = buffer + width;
  2486. if (pGradient->type == SourcePictTypeSolidFill) {
  2487. CARD32 color = pGradient->solidFill.color;
  2488. while (buffer < end) {
  2489. *buffer++ = color;
  2490. }
  2491. }
  2492. else if (pGradient->type == SourcePictTypeLinear) {
  2493. PictVector v, unit;
  2494. xFixed_32_32 l;
  2495. xFixed_48_16 dx, dy, a, b, off;
  2496. /* reference point is the center of the pixel */
  2497. v.vector[0] = IntToxFixed(x) + xFixed1 / 2;
  2498. v.vector[1] = IntToxFixed(y) + xFixed1 / 2;
  2499. v.vector[2] = xFixed1;
  2500. if (pict->transform) {
  2501. if (!PictureTransformPoint3d(pict->transform, &v))
  2502. return;
  2503. unit.vector[0] = pict->transform->matrix[0][0];
  2504. unit.vector[1] = pict->transform->matrix[1][0];
  2505. unit.vector[2] = pict->transform->matrix[2][0];
  2506. }
  2507. else {
  2508. unit.vector[0] = xFixed1;
  2509. unit.vector[1] = 0;
  2510. unit.vector[2] = 0;
  2511. }
  2512. dx = pGradient->linear.p2.x - pGradient->linear.p1.x;
  2513. dy = pGradient->linear.p2.y - pGradient->linear.p1.y;
  2514. l = dx * dx + dy * dy;
  2515. if (l != 0) {
  2516. a = (dx << 32) / l;
  2517. b = (dy << 32) / l;
  2518. off =
  2519. (-a * pGradient->linear.p1.x -
  2520. b * pGradient->linear.p1.y) >> 16;
  2521. }
  2522. if (l == 0 || (unit.vector[2] == 0 && v.vector[2] == xFixed1)) {
  2523. xFixed_48_16 inc, t;
  2524. /* affine transformation only */
  2525. if (l == 0) {
  2526. t = 0;
  2527. inc = 0;
  2528. }
  2529. else {
  2530. t = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
  2531. inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
  2532. }
  2533. while (buffer < end) {
  2534. *buffer++ = gradientPixel(pGradient, t, pict->repeatType);
  2535. t += inc;
  2536. }
  2537. }
  2538. else {
  2539. /* projective transformation */
  2540. while (buffer < end) {
  2541. xFixed_48_16 t;
  2542. if (v.vector[2] == 0) {
  2543. t = 0;
  2544. }
  2545. else {
  2546. xFixed_48_16 x, y;
  2547. x = ((xFixed_48_16) v.vector[0] << 16) / v.vector[2];
  2548. y = ((xFixed_48_16) v.vector[1] << 16) / v.vector[2];
  2549. t = ((a * x + b * y) >> 16) + off;
  2550. }
  2551. *buffer++ = gradientPixel(pGradient, t, pict->repeatType);
  2552. v.vector[0] += unit.vector[0];
  2553. v.vector[1] += unit.vector[1];
  2554. v.vector[2] += unit.vector[2];
  2555. }
  2556. }
  2557. }
  2558. else {
  2559. /* radial or conical */
  2560. Bool affine = TRUE;
  2561. double cx = 1.;
  2562. double cy = 0.;
  2563. double cz = 0.;
  2564. double rx = x;
  2565. double ry = y;
  2566. double rz = 1.;
  2567. if (pict->transform) {
  2568. PictVector v;
  2569. /* reference point is the center of the pixel */
  2570. v.vector[0] = IntToxFixed(x) + xFixed1 / 2;
  2571. v.vector[1] = IntToxFixed(y) + xFixed1 / 2;
  2572. v.vector[2] = xFixed1;
  2573. if (!PictureTransformPoint3d(pict->transform, &v))
  2574. return;
  2575. cx = pict->transform->matrix[0][0] / 65536.;
  2576. cy = pict->transform->matrix[1][0] / 65536.;
  2577. cz = pict->transform->matrix[2][0] / 65536.;
  2578. rx = v.vector[0] / 65536.;
  2579. ry = v.vector[1] / 65536.;
  2580. rz = v.vector[2] / 65536.;
  2581. affine = pict->transform->matrix[2][0] == 0 &&
  2582. v.vector[2] == xFixed1;
  2583. }
  2584. if (pGradient->type == SourcePictTypeRadial) {
  2585. if (affine) {
  2586. rx -= pGradient->radial.fx;
  2587. ry -= pGradient->radial.fy;
  2588. while (buffer < end) {
  2589. double b =
  2590. 2 * (rx * pGradient->radial.dx +
  2591. ry * pGradient->radial.dy);
  2592. double c = -(rx * rx + ry * ry);
  2593. double det = (b * b) - (4 * pGradient->radial.a * c);
  2594. double s = (-b + sqrt(det)) / (2. * pGradient->radial.a);
  2595. *buffer = gradientPixel(pGradient,
  2596. (xFixed_48_16) ((s *
  2597. pGradient->radial.
  2598. m +
  2599. pGradient->radial.
  2600. b) * 65536),
  2601. pict->repeatType);
  2602. ++buffer;
  2603. rx += cx;
  2604. ry += cy;
  2605. }
  2606. }
  2607. else {
  2608. while (buffer < end) {
  2609. double x, y;
  2610. double b, c, det, s;
  2611. if (rz != 0) {
  2612. x = rx / rz;
  2613. y = ry / rz;
  2614. }
  2615. else {
  2616. x = y = 0.;
  2617. }
  2618. x -= pGradient->radial.fx;
  2619. y -= pGradient->radial.fy;
  2620. b = 2 * (x * pGradient->radial.dx +
  2621. y * pGradient->radial.dy);
  2622. c = -(x * x + y * y);
  2623. det = (b * b) - (4 * pGradient->radial.a * c);
  2624. s = (-b + sqrt(det)) / (2. * pGradient->radial.a);
  2625. *buffer = gradientPixel(pGradient,
  2626. (xFixed_48_16) ((s *
  2627. pGradient->radial.
  2628. m +
  2629. pGradient->radial.
  2630. b) * 65536),
  2631. pict->repeatType);
  2632. ++buffer;
  2633. rx += cx;
  2634. ry += cy;
  2635. rz += cz;
  2636. }
  2637. }
  2638. }
  2639. else { /* SourcePictTypeConical */
  2640. double a = pGradient->conical.angle / (180. * 65536);
  2641. if (affine) {
  2642. rx -= pGradient->conical.center.x / 65536.;
  2643. ry -= pGradient->conical.center.y / 65536.;
  2644. while (buffer < end) {
  2645. double angle = atan2(ry, rx) + a;
  2646. *buffer =
  2647. gradientPixel(pGradient,
  2648. (xFixed_48_16) (angle *
  2649. (65536. / (2 * M_PI))),
  2650. pict->repeatType);
  2651. ++buffer;
  2652. rx += cx;
  2653. ry += cy;
  2654. }
  2655. }
  2656. else {
  2657. while (buffer < end) {
  2658. double x, y, angle;
  2659. if (rz != 0) {
  2660. x = rx / rz;
  2661. y = ry / rz;
  2662. }
  2663. else {
  2664. x = y = 0.;
  2665. }
  2666. x -= pGradient->conical.center.x / 65536.;
  2667. y -= pGradient->conical.center.y / 65536.;
  2668. angle = atan2(y, x) + a;
  2669. *buffer =
  2670. gradientPixel(pGradient,
  2671. (xFixed_48_16) (angle *
  2672. (65536. / (2 * M_PI))),
  2673. pict->repeatType);
  2674. ++buffer;
  2675. rx += cx;
  2676. ry += cy;
  2677. rz += cz;
  2678. }
  2679. }
  2680. }
  2681. }
  2682. }
  2683. static void
  2684. fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  2685. {
  2686. FbBits *bits;
  2687. FbStride stride;
  2688. int bpp;
  2689. int xoff, yoff, dx, dy;
  2690. fetchPixelProc fetch;
  2691. PictVector v;
  2692. PictVector unit;
  2693. int i;
  2694. BoxRec box;
  2695. miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
  2696. Bool affine = TRUE;
  2697. fetch = fetchPixelProcForPicture(pict);
  2698. fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
  2699. x += xoff;
  2700. y += yoff;
  2701. dx = pict->pDrawable->x;
  2702. dy = pict->pDrawable->y;
  2703. /* reference point is the center of the pixel */
  2704. v.vector[0] = IntToxFixed(x - dx) + xFixed1 / 2;
  2705. v.vector[1] = IntToxFixed(y - dy) + xFixed1 / 2;
  2706. v.vector[2] = xFixed1;
  2707. /* when using convolution filters one might get here without a transform */
  2708. if (pict->transform) {
  2709. if (!PictureTransformPoint3d(pict->transform, &v))
  2710. return;
  2711. unit.vector[0] = pict->transform->matrix[0][0];
  2712. unit.vector[1] = pict->transform->matrix[1][0];
  2713. unit.vector[2] = pict->transform->matrix[2][0];
  2714. affine = v.vector[2] == xFixed1 && unit.vector[2] == 0;
  2715. }
  2716. else {
  2717. unit.vector[0] = xFixed1;
  2718. unit.vector[1] = 0;
  2719. unit.vector[2] = 0;
  2720. }
  2721. if (pict->filter == PictFilterNearest) {
  2722. if (pict->repeatType == RepeatNormal) {
  2723. if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
  2724. for (i = 0; i < width; ++i) {
  2725. if (!v.vector[2]) {
  2726. buffer[i] = 0;
  2727. }
  2728. else {
  2729. if (!affine) {
  2730. y = MOD(DIV(v.vector[1], v.vector[2]),
  2731. pict->pDrawable->height);
  2732. x = MOD(DIV(v.vector[0], v.vector[2]),
  2733. pict->pDrawable->width);
  2734. }
  2735. else {
  2736. y = MOD(v.vector[1] >> 16, pict->pDrawable->height);
  2737. x = MOD(v.vector[0] >> 16, pict->pDrawable->width);
  2738. }
  2739. buffer[i] =
  2740. fetch(bits + (y + dy) * stride, x + dx, indexed);
  2741. }
  2742. v.vector[0] += unit.vector[0];
  2743. v.vector[1] += unit.vector[1];
  2744. v.vector[2] += unit.vector[2];
  2745. }
  2746. }
  2747. else {
  2748. for (i = 0; i < width; ++i) {
  2749. if (!v.vector[2]) {
  2750. buffer[i] = 0;
  2751. }
  2752. else {
  2753. if (!affine) {
  2754. y = MOD(DIV(v.vector[1], v.vector[2]),
  2755. pict->pDrawable->height);
  2756. x = MOD(DIV(v.vector[0], v.vector[2]),
  2757. pict->pDrawable->width);
  2758. }
  2759. else {
  2760. y = MOD(v.vector[1] >> 16, pict->pDrawable->height);
  2761. x = MOD(v.vector[0] >> 16, pict->pDrawable->width);
  2762. }
  2763. if (POINT_IN_REGION(pict->pCompositeClip, x + dx, y + dy, &box))
  2764. buffer[i] =
  2765. fetch(bits + (y + dy) * stride, x + dx,
  2766. indexed);
  2767. else
  2768. buffer[i] = 0;
  2769. }
  2770. v.vector[0] += unit.vector[0];
  2771. v.vector[1] += unit.vector[1];
  2772. v.vector[2] += unit.vector[2];
  2773. }
  2774. }
  2775. }
  2776. else {
  2777. if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
  2778. box = pict->pCompositeClip->extents;
  2779. for (i = 0; i < width; ++i) {
  2780. if (!v.vector[2]) {
  2781. buffer[i] = 0;
  2782. }
  2783. else {
  2784. if (!affine) {
  2785. y = DIV(v.vector[1], v.vector[2]);
  2786. x = DIV(v.vector[0], v.vector[2]);
  2787. }
  2788. else {
  2789. y = v.vector[1] >> 16;
  2790. x = v.vector[0] >> 16;
  2791. }
  2792. buffer[i] =
  2793. ((x < box.x1 - dx) | (x >= box.x2 - dx) | (y <
  2794. box.y1 -
  2795. dy) | (y
  2796. >=
  2797. box.
  2798. y2
  2799. -
  2800. dy))
  2801. ? 0 : fetch(bits + (y + dy) * stride, x + dx,
  2802. indexed);
  2803. }
  2804. v.vector[0] += unit.vector[0];
  2805. v.vector[1] += unit.vector[1];
  2806. v.vector[2] += unit.vector[2];
  2807. }
  2808. }
  2809. else {
  2810. for (i = 0; i < width; ++i) {
  2811. if (!v.vector[2]) {
  2812. buffer[i] = 0;
  2813. }
  2814. else {
  2815. if (!affine) {
  2816. y = DIV(v.vector[1], v.vector[2]);
  2817. x = DIV(v.vector[0], v.vector[2]);
  2818. }
  2819. else {
  2820. y = v.vector[1] >> 16;
  2821. x = v.vector[0] >> 16;
  2822. }
  2823. if (POINT_IN_REGION(pict->pCompositeClip, x + dx, y + dy, &box))
  2824. buffer[i] =
  2825. fetch(bits + (y + dy) * stride, x + dx,
  2826. indexed);
  2827. else
  2828. buffer[i] = 0;
  2829. }
  2830. v.vector[0] += unit.vector[0];
  2831. v.vector[1] += unit.vector[1];
  2832. v.vector[2] += unit.vector[2];
  2833. }
  2834. }
  2835. }
  2836. }
  2837. else if (pict->filter == PictFilterBilinear) {
  2838. /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */
  2839. v.vector[0] -= v.vector[2] / 2;
  2840. v.vector[1] -= v.vector[2] / 2;
  2841. unit.vector[0] -= unit.vector[2] / 2;
  2842. unit.vector[1] -= unit.vector[2] / 2;
  2843. if (pict->repeatType == RepeatNormal) {
  2844. if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
  2845. for (i = 0; i < width; ++i) {
  2846. if (!v.vector[2]) {
  2847. buffer[i] = 0;
  2848. }
  2849. else {
  2850. int x1, x2, y1, y2, distx, idistx, disty, idisty;
  2851. FbBits *b;
  2852. CARD32 tl, tr, bl, br, r;
  2853. CARD32 ft, fb;
  2854. if (!affine) {
  2855. xFixed_48_16 div;
  2856. div =
  2857. ((xFixed_48_16) v.vector[0] << 16) /
  2858. v.vector[2];
  2859. x1 = div >> 16;
  2860. distx = ((xFixed) div >> 8) & 0xff;
  2861. div =
  2862. ((xFixed_48_16) v.vector[1] << 16) /
  2863. v.vector[2];
  2864. y1 = div >> 16;
  2865. disty = ((xFixed) div >> 8) & 0xff;
  2866. }
  2867. else {
  2868. x1 = v.vector[0] >> 16;
  2869. distx = (v.vector[0] >> 8) & 0xff;
  2870. y1 = v.vector[1] >> 16;
  2871. disty = (v.vector[1] >> 8) & 0xff;
  2872. }
  2873. x2 = x1 + 1;
  2874. y2 = y1 + 1;
  2875. idistx = 256 - distx;
  2876. idisty = 256 - disty;
  2877. x1 = MOD(x1, pict->pDrawable->width);
  2878. x2 = MOD(x2, pict->pDrawable->width);
  2879. y1 = MOD(y1, pict->pDrawable->height);
  2880. y2 = MOD(y2, pict->pDrawable->height);
  2881. b = bits + (y1 + dy) * stride;
  2882. tl = fetch(b, x1 + dx, indexed);
  2883. tr = fetch(b, x2 + dx, indexed);
  2884. b = bits + (y2 + dy) * stride;
  2885. bl = fetch(b, x1 + dx, indexed);
  2886. br = fetch(b, x2 + dx, indexed);
  2887. ft = FbGet8(tl, 0) * idistx + FbGet8(tr, 0) * distx;
  2888. fb = FbGet8(bl, 0) * idistx + FbGet8(br, 0) * distx;
  2889. r = (((ft * idisty + fb * disty) >> 16) & 0xff);
  2890. ft = FbGet8(tl, 8) * idistx + FbGet8(tr, 8) * distx;
  2891. fb = FbGet8(bl, 8) * idistx + FbGet8(br, 8) * distx;
  2892. r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
  2893. ft = FbGet8(tl, 16) * idistx + FbGet8(tr, 16) * distx;
  2894. fb = FbGet8(bl, 16) * idistx + FbGet8(br, 16) * distx;
  2895. r |= (((ft * idisty + fb * disty)) & 0xff0000);
  2896. ft = FbGet8(tl, 24) * idistx + FbGet8(tr, 24) * distx;
  2897. fb = FbGet8(bl, 24) * idistx + FbGet8(br, 24) * distx;
  2898. r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
  2899. buffer[i] = r;
  2900. }
  2901. v.vector[0] += unit.vector[0];
  2902. v.vector[1] += unit.vector[1];
  2903. v.vector[2] += unit.vector[2];
  2904. }
  2905. }
  2906. else {
  2907. for (i = 0; i < width; ++i) {
  2908. if (!v.vector[2]) {
  2909. buffer[i] = 0;
  2910. }
  2911. else {
  2912. int x1, x2, y1, y2, distx, idistx, disty, idisty;
  2913. FbBits *b;
  2914. CARD32 tl, tr, bl, br, r;
  2915. CARD32 ft, fb;
  2916. if (!affine) {
  2917. xFixed_48_16 div;
  2918. div =
  2919. ((xFixed_48_16) v.vector[0] << 16) /
  2920. v.vector[2];
  2921. x1 = div >> 16;
  2922. distx = ((xFixed) div >> 8) & 0xff;
  2923. div =
  2924. ((xFixed_48_16) v.vector[1] << 16) /
  2925. v.vector[2];
  2926. y1 = div >> 16;
  2927. disty = ((xFixed) div >> 8) & 0xff;
  2928. }
  2929. else {
  2930. x1 = v.vector[0] >> 16;
  2931. distx = (v.vector[0] >> 8) & 0xff;
  2932. y1 = v.vector[1] >> 16;
  2933. disty = (v.vector[1] >> 8) & 0xff;
  2934. }
  2935. x2 = x1 + 1;
  2936. y2 = y1 + 1;
  2937. idistx = 256 - distx;
  2938. idisty = 256 - disty;
  2939. x1 = MOD(x1, pict->pDrawable->width);
  2940. x2 = MOD(x2, pict->pDrawable->width);
  2941. y1 = MOD(y1, pict->pDrawable->height);
  2942. y2 = MOD(y2, pict->pDrawable->height);
  2943. b = bits + (y1 + dy) * stride;
  2944. tl = POINT_IN_REGION(pict->pCompositeClip, x1 + dx,
  2945. y1 + dy, &box)
  2946. ? fetch(b, x1 + dx, indexed) : 0;
  2947. tr = POINT_IN_REGION(pict->pCompositeClip, x2 + dx,
  2948. y1 + dy, &box)
  2949. ? fetch(b, x2 + dx, indexed) : 0;
  2950. b = bits + (y2 + dy) * stride;
  2951. bl = POINT_IN_REGION(pict->pCompositeClip, x1 + dx,
  2952. y2 + dy, &box)
  2953. ? fetch(b, x1 + dx, indexed) : 0;
  2954. br = POINT_IN_REGION(pict->pCompositeClip, x2 + dx,
  2955. y2 + dy, &box)
  2956. ? fetch(b, x2 + dx, indexed) : 0;
  2957. ft = FbGet8(tl, 0) * idistx + FbGet8(tr, 0) * distx;
  2958. fb = FbGet8(bl, 0) * idistx + FbGet8(br, 0) * distx;
  2959. r = (((ft * idisty + fb * disty) >> 16) & 0xff);
  2960. ft = FbGet8(tl, 8) * idistx + FbGet8(tr, 8) * distx;
  2961. fb = FbGet8(bl, 8) * idistx + FbGet8(br, 8) * distx;
  2962. r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
  2963. ft = FbGet8(tl, 16) * idistx + FbGet8(tr, 16) * distx;
  2964. fb = FbGet8(bl, 16) * idistx + FbGet8(br, 16) * distx;
  2965. r |= (((ft * idisty + fb * disty)) & 0xff0000);
  2966. ft = FbGet8(tl, 24) * idistx + FbGet8(tr, 24) * distx;
  2967. fb = FbGet8(bl, 24) * idistx + FbGet8(br, 24) * distx;
  2968. r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
  2969. buffer[i] = r;
  2970. }
  2971. v.vector[0] += unit.vector[0];
  2972. v.vector[1] += unit.vector[1];
  2973. v.vector[2] += unit.vector[2];
  2974. }
  2975. }
  2976. }
  2977. else {
  2978. if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
  2979. box = pict->pCompositeClip->extents;
  2980. for (i = 0; i < width; ++i) {
  2981. if (!v.vector[2]) {
  2982. buffer[i] = 0;
  2983. }
  2984. else {
  2985. int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
  2986. FbBits *b;
  2987. CARD32 tl, tr, bl, br, r;
  2988. Bool x1_out, x2_out, y1_out, y2_out;
  2989. CARD32 ft, fb;
  2990. if (!affine) {
  2991. xFixed_48_16 div;
  2992. div =
  2993. ((xFixed_48_16) v.vector[0] << 16) /
  2994. v.vector[2];
  2995. x1 = div >> 16;
  2996. distx = ((xFixed) div >> 8) & 0xff;
  2997. div =
  2998. ((xFixed_48_16) v.vector[1] << 16) /
  2999. v.vector[2];
  3000. y1 = div >> 16;
  3001. disty = ((xFixed) div >> 8) & 0xff;
  3002. }
  3003. else {
  3004. x1 = v.vector[0] >> 16;
  3005. distx = (v.vector[0] >> 8) & 0xff;
  3006. y1 = v.vector[1] >> 16;
  3007. disty = (v.vector[1] >> 8) & 0xff;
  3008. }
  3009. x2 = x1 + 1;
  3010. y2 = y1 + 1;
  3011. idistx = 256 - distx;
  3012. idisty = 256 - disty;
  3013. b = bits + (y1 + dy) * stride;
  3014. x_off = x1 + dx;
  3015. x1_out = (x1 < box.x1 - dx) | (x1 >= box.x2 - dx);
  3016. x2_out = (x2 < box.x1 - dx) | (x2 >= box.x2 - dx);
  3017. y1_out = (y1 < box.y1 - dy) | (y1 >= box.y2 - dy);
  3018. y2_out = (y2 < box.y1 - dy) | (y2 >= box.y2 - dy);
  3019. tl = x1_out | y1_out ? 0 : fetch(b, x_off, indexed);
  3020. tr = x2_out | y1_out ? 0 : fetch(b, x_off + 1, indexed);
  3021. b += stride;
  3022. bl = x1_out | y2_out ? 0 : fetch(b, x_off, indexed);
  3023. br = x2_out | y2_out ? 0 : fetch(b, x_off + 1, indexed);
  3024. ft = FbGet8(tl, 0) * idistx + FbGet8(tr, 0) * distx;
  3025. fb = FbGet8(bl, 0) * idistx + FbGet8(br, 0) * distx;
  3026. r = (((ft * idisty + fb * disty) >> 16) & 0xff);
  3027. ft = FbGet8(tl, 8) * idistx + FbGet8(tr, 8) * distx;
  3028. fb = FbGet8(bl, 8) * idistx + FbGet8(br, 8) * distx;
  3029. r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
  3030. ft = FbGet8(tl, 16) * idistx + FbGet8(tr, 16) * distx;
  3031. fb = FbGet8(bl, 16) * idistx + FbGet8(br, 16) * distx;
  3032. r |= (((ft * idisty + fb * disty)) & 0xff0000);
  3033. ft = FbGet8(tl, 24) * idistx + FbGet8(tr, 24) * distx;
  3034. fb = FbGet8(bl, 24) * idistx + FbGet8(br, 24) * distx;
  3035. r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
  3036. buffer[i] = r;
  3037. }
  3038. v.vector[0] += unit.vector[0];
  3039. v.vector[1] += unit.vector[1];
  3040. v.vector[2] += unit.vector[2];
  3041. }
  3042. }
  3043. else {
  3044. for (i = 0; i < width; ++i) {
  3045. if (!v.vector[2]) {
  3046. buffer[i] = 0;
  3047. }
  3048. else {
  3049. int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
  3050. FbBits *b;
  3051. CARD32 tl, tr, bl, br, r;
  3052. CARD32 ft, fb;
  3053. if (!affine) {
  3054. xFixed_48_16 div;
  3055. div =
  3056. ((xFixed_48_16) v.vector[0] << 16) /
  3057. v.vector[2];
  3058. x1 = div >> 16;
  3059. distx = ((xFixed) div >> 8) & 0xff;
  3060. div =
  3061. ((xFixed_48_16) v.vector[1] << 16) /
  3062. v.vector[2];
  3063. y1 = div >> 16;
  3064. disty = ((xFixed) div >> 8) & 0xff;
  3065. }
  3066. else {
  3067. x1 = v.vector[0] >> 16;
  3068. distx = (v.vector[0] >> 8) & 0xff;
  3069. y1 = v.vector[1] >> 16;
  3070. disty = (v.vector[1] >> 8) & 0xff;
  3071. }
  3072. x2 = x1 + 1;
  3073. y2 = y1 + 1;
  3074. idistx = 256 - distx;
  3075. idisty = 256 - disty;
  3076. b = bits + (y1 + dy) * stride;
  3077. x_off = x1 + dx;
  3078. tl = POINT_IN_REGION(pict->pCompositeClip, x1 + dx,
  3079. y1 + dy, &box)
  3080. ? fetch(b, x_off, indexed) : 0;
  3081. tr = POINT_IN_REGION(pict->pCompositeClip, x2 + dx,
  3082. y1 + dy, &box)
  3083. ? fetch(b, x_off + 1, indexed) : 0;
  3084. b += stride;
  3085. bl = POINT_IN_REGION(pict->pCompositeClip, x1 + dx,
  3086. y2 + dy, &box)
  3087. ? fetch(b, x_off, indexed) : 0;
  3088. br = POINT_IN_REGION(pict->pCompositeClip, x2 + dx,
  3089. y2 + dy, &box)
  3090. ? fetch(b, x_off + 1, indexed) : 0;
  3091. ft = FbGet8(tl, 0) * idistx + FbGet8(tr, 0) * distx;
  3092. fb = FbGet8(bl, 0) * idistx + FbGet8(br, 0) * distx;
  3093. r = (((ft * idisty + fb * disty) >> 16) & 0xff);
  3094. ft = FbGet8(tl, 8) * idistx + FbGet8(tr, 8) * distx;
  3095. fb = FbGet8(bl, 8) * idistx + FbGet8(br, 8) * distx;
  3096. r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
  3097. ft = FbGet8(tl, 16) * idistx + FbGet8(tr, 16) * distx;
  3098. fb = FbGet8(bl, 16) * idistx + FbGet8(br, 16) * distx;
  3099. r |= (((ft * idisty + fb * disty)) & 0xff0000);
  3100. ft = FbGet8(tl, 24) * idistx + FbGet8(tr, 24) * distx;
  3101. fb = FbGet8(bl, 24) * idistx + FbGet8(br, 24) * distx;
  3102. r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
  3103. buffer[i] = r;
  3104. }
  3105. v.vector[0] += unit.vector[0];
  3106. v.vector[1] += unit.vector[1];
  3107. v.vector[2] += unit.vector[2];
  3108. }
  3109. }
  3110. }
  3111. }
  3112. else if (pict->filter == PictFilterConvolution) {
  3113. xFixed *params = pict->filter_params;
  3114. INT32 cwidth = xFixedToInt(params[0]);
  3115. INT32 cheight = xFixedToInt(params[1]);
  3116. int xoff = (params[0] - xFixed1) >> 1;
  3117. int yoff = (params[1] - xFixed1) >> 1;
  3118. params += 2;
  3119. for (i = 0; i < width; ++i) {
  3120. if (!v.vector[2]) {
  3121. buffer[i] = 0;
  3122. }
  3123. else {
  3124. int x1, x2, y1, y2, x, y;
  3125. INT32 srtot, sgtot, sbtot, satot;
  3126. xFixed *p = params;
  3127. if (!affine) {
  3128. xFixed_48_16 tmp;
  3129. tmp =
  3130. ((xFixed_48_16) v.vector[0] << 16) / v.vector[2] - xoff;
  3131. x1 = xFixedToInt(tmp);
  3132. tmp =
  3133. ((xFixed_48_16) v.vector[1] << 16) / v.vector[2] - yoff;
  3134. y1 = xFixedToInt(tmp);
  3135. }
  3136. else {
  3137. x1 = xFixedToInt(v.vector[0] - xoff);
  3138. y1 = xFixedToInt(v.vector[1] - yoff);
  3139. }
  3140. x2 = x1 + cwidth;
  3141. y2 = y1 + cheight;
  3142. srtot = sgtot = sbtot = satot = 0;
  3143. for (y = y1; y < y2; y++) {
  3144. int ty =
  3145. (pict->repeatType == RepeatNormal) ? MOD(y,
  3146. pict->
  3147. pDrawable->
  3148. height) : y;
  3149. for (x = x1; x < x2; x++) {
  3150. if (*p) {
  3151. int tx =
  3152. (pict->repeatType == RepeatNormal) ? MOD(x,
  3153. pict->
  3154. pDrawable->
  3155. width)
  3156. : x;
  3157. if (POINT_IN_REGION(pict->pCompositeClip, tx + dx, ty + dy,
  3158. &box)) {
  3159. FbBits *b = bits + (ty + dy) * stride;
  3160. CARD32 c = fetch(b, tx + dx, indexed);
  3161. srtot += Red(c) * *p;
  3162. sgtot += Green(c) * *p;
  3163. sbtot += Blue(c) * *p;
  3164. satot += Alpha(c) * *p;
  3165. }
  3166. }
  3167. p++;
  3168. }
  3169. }
  3170. satot >>= 16;
  3171. srtot >>= 16;
  3172. sgtot >>= 16;
  3173. sbtot >>= 16;
  3174. if (satot < 0)
  3175. satot = 0;
  3176. else if (satot > 0xff)
  3177. satot = 0xff;
  3178. if (srtot < 0)
  3179. srtot = 0;
  3180. else if (srtot > 0xff)
  3181. srtot = 0xff;
  3182. if (sgtot < 0)
  3183. sgtot = 0;
  3184. else if (sgtot > 0xff)
  3185. sgtot = 0xff;
  3186. if (sbtot < 0)
  3187. sbtot = 0;
  3188. else if (sbtot > 0xff)
  3189. sbtot = 0xff;
  3190. buffer[i] = ((satot << 24) |
  3191. (srtot << 16) | (sgtot << 8) | (sbtot));
  3192. }
  3193. v.vector[0] += unit.vector[0];
  3194. v.vector[1] += unit.vector[1];
  3195. v.vector[2] += unit.vector[2];
  3196. }
  3197. }
  3198. }
  3199. static void
  3200. fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  3201. {
  3202. int i;
  3203. CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
  3204. CARD32 *alpha_buffer = _alpha_buffer;
  3205. if (!pict->alphaMap) {
  3206. fbFetchTransformed(pict, x, y, width, buffer);
  3207. return;
  3208. }
  3209. if (width > SCANLINE_BUFFER_LENGTH)
  3210. alpha_buffer = malloc(width * sizeof(CARD32));
  3211. fbFetchTransformed(pict, x, y, width, buffer);
  3212. fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
  3213. y - pict->alphaOrigin.y, width, alpha_buffer);
  3214. for (i = 0; i < width; ++i) {
  3215. int a = alpha_buffer[i] >> 24;
  3216. buffer[i] = (a << 24)
  3217. | (div_255(Red(buffer[i]) * a) << 16)
  3218. | (div_255(Green(buffer[i]) * a) << 8)
  3219. | (div_255(Blue(buffer[i]) * a));
  3220. }
  3221. if (alpha_buffer != _alpha_buffer)
  3222. free(alpha_buffer);
  3223. }
  3224. static void
  3225. fbStore(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  3226. {
  3227. FbBits *bits;
  3228. FbStride stride;
  3229. int bpp;
  3230. int xoff, yoff;
  3231. storeProc store = storeProcForPicture(pict);
  3232. miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
  3233. fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
  3234. x += xoff;
  3235. y += yoff;
  3236. bits += y * stride;
  3237. store(bits, buffer, x, width, indexed);
  3238. }
  3239. static void
  3240. fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
  3241. {
  3242. FbBits *bits, *alpha_bits;
  3243. FbStride stride, astride;
  3244. int bpp, abpp;
  3245. int xoff, yoff;
  3246. int ax, ay;
  3247. storeProc store;
  3248. storeProc astore;
  3249. miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
  3250. miIndexedPtr aindexed;
  3251. if (!pict->alphaMap) {
  3252. fbStore(pict, x, y, width, buffer);
  3253. return;
  3254. }
  3255. store = storeProcForPicture(pict);
  3256. astore = storeProcForPicture(pict->alphaMap);
  3257. aindexed = (miIndexedPtr) pict->alphaMap->pFormat->index.devPrivate;
  3258. ax = x;
  3259. ay = y;
  3260. fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
  3261. x += xoff;
  3262. y += yoff;
  3263. fbGetDrawable(pict->alphaMap->pDrawable, alpha_bits, astride, abpp, xoff,
  3264. yoff);
  3265. ax += xoff;
  3266. ay += yoff;
  3267. bits += y * stride;
  3268. alpha_bits += (ay - pict->alphaOrigin.y) * astride;
  3269. store(bits, buffer, x, width, indexed);
  3270. astore(alpha_bits, buffer, ax - pict->alphaOrigin.x, width, aindexed);
  3271. }
  3272. typedef void (*scanStoreProc) (PicturePtr, int, int, int, CARD32 *);
  3273. typedef void (*scanFetchProc) (PicturePtr, int, int, int, CARD32 *);
  3274. static void
  3275. fbCompositeRect(const FbComposeData * data, CARD32 *scanline_buffer)
  3276. {
  3277. CARD32 *src_buffer = scanline_buffer;
  3278. CARD32 *dest_buffer = src_buffer + data->width;
  3279. int i;
  3280. scanStoreProc store;
  3281. scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
  3282. if (data->op == PictOpClear)
  3283. fetchSrc = NULL;
  3284. else if (!data->src->pDrawable) {
  3285. if (data->src->pSourcePict)
  3286. fetchSrc = fbFetchSourcePict;
  3287. }
  3288. else if (data->src->alphaMap)
  3289. fetchSrc = fbFetchExternalAlpha;
  3290. else if (data->src->repeatType == RepeatNormal &&
  3291. data->src->pDrawable->width == 1 &&
  3292. data->src->pDrawable->height == 1)
  3293. fetchSrc = fbFetchSolid;
  3294. else if (!data->src->transform &&
  3295. data->src->filter != PictFilterConvolution)
  3296. fetchSrc = fbFetch;
  3297. else
  3298. fetchSrc = fbFetchTransformed;
  3299. if (data->mask && data->op != PictOpClear) {
  3300. if (!data->mask->pDrawable) {
  3301. if (data->mask->pSourcePict)
  3302. fetchMask = fbFetchSourcePict;
  3303. }
  3304. else if (data->mask->alphaMap)
  3305. fetchMask = fbFetchExternalAlpha;
  3306. else if (data->mask->repeatType == RepeatNormal
  3307. && data->mask->pDrawable->width == 1 &&
  3308. data->mask->pDrawable->height == 1)
  3309. fetchMask = fbFetchSolid;
  3310. else if (!data->mask->transform &&
  3311. data->mask->filter != PictFilterConvolution)
  3312. fetchMask = fbFetch;
  3313. else
  3314. fetchMask = fbFetchTransformed;
  3315. }
  3316. else {
  3317. fetchMask = NULL;
  3318. }
  3319. if (data->dest->alphaMap) {
  3320. fetchDest = fbFetchExternalAlpha;
  3321. store = fbStoreExternalAlpha;
  3322. }
  3323. else {
  3324. fetchDest = fbFetch;
  3325. store = fbStore;
  3326. }
  3327. if (data->op == PictOpClear || data->op == PictOpSrc)
  3328. fetchDest = NULL;
  3329. if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha &&
  3330. PICT_FORMAT_RGB(data->mask->format)) {
  3331. CARD32 *mask_buffer = dest_buffer + data->width;
  3332. CombineFuncC compose = composeFunctions.combineC[data->op];
  3333. if (!compose)
  3334. return;
  3335. for (i = 0; i < data->height; ++i) {
  3336. /* fill first half of scanline with source */
  3337. fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width,
  3338. src_buffer);
  3339. fetchMask(data->mask, data->xMask, data->yMask + i, data->width,
  3340. mask_buffer);
  3341. /* fill dest into second half of scanline */
  3342. if (fetchDest)
  3343. fetchDest(data->dest, data->xDest, data->yDest + i, data->width,
  3344. dest_buffer);
  3345. /* blend */
  3346. compose(dest_buffer, src_buffer, mask_buffer, data->width);
  3347. /* write back */
  3348. store(data->dest, data->xDest, data->yDest + i, data->width,
  3349. dest_buffer);
  3350. }
  3351. }
  3352. else {
  3353. CombineFuncU compose = composeFunctions.combineU[data->op];
  3354. if (!compose)
  3355. return;
  3356. if (fetchSrc == fbFetchSolid &&
  3357. (!fetchMask || fetchMask == fbFetchSolid)) {
  3358. fetchSrc(data->src, data->xSrc, data->ySrc, data->width,
  3359. src_buffer);
  3360. if (fetchMask) {
  3361. fetchMask(data->mask, data->xMask, data->yMask, data->width,
  3362. dest_buffer);
  3363. composeFunctions.combineMaskU(src_buffer, dest_buffer,
  3364. data->width);
  3365. }
  3366. fetchSrc = NULL;
  3367. fetchMask = NULL;
  3368. }
  3369. for (i = 0; i < data->height; ++i) {
  3370. /* fill first half of scanline with source */
  3371. if (fetchSrc) {
  3372. fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width,
  3373. src_buffer);
  3374. /* add in mask */
  3375. if (fetchMask) {
  3376. fetchMask(data->mask, data->xMask, data->yMask + i,
  3377. data->width, dest_buffer);
  3378. composeFunctions.combineMaskU(src_buffer, dest_buffer,
  3379. data->width);
  3380. }
  3381. }
  3382. /* fill dest into second half of scanline */
  3383. if (fetchDest)
  3384. fetchDest(data->dest, data->xDest, data->yDest + i, data->width,
  3385. dest_buffer);
  3386. /* blend */
  3387. compose(dest_buffer, src_buffer, data->width);
  3388. /* write back */
  3389. store(data->dest, data->xDest, data->yDest + i, data->width,
  3390. dest_buffer);
  3391. }
  3392. }
  3393. }
  3394. void
  3395. fbCompositeGeneral(CARD8 op,
  3396. PicturePtr pSrc,
  3397. PicturePtr pMask,
  3398. PicturePtr pDst,
  3399. INT16 xSrc,
  3400. INT16 ySrc,
  3401. INT16 xMask,
  3402. INT16 yMask,
  3403. INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
  3404. {
  3405. RegionRec region;
  3406. int n;
  3407. BoxPtr pbox;
  3408. Bool srcRepeat = FALSE;
  3409. Bool maskRepeat = FALSE;
  3410. int w, h;
  3411. CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH * 3];
  3412. CARD32 *scanline_buffer = _scanline_buffer;
  3413. FbComposeData compose_data;
  3414. if (pSrc->pDrawable)
  3415. srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform
  3416. && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
  3417. if (pMask && pMask->pDrawable)
  3418. maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform
  3419. && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
  3420. if (op == PictOpOver && !pMask && !pSrc->transform &&
  3421. !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
  3422. op = PictOpSrc;
  3423. if (!miComputeCompositeRegion(&region,
  3424. pSrc,
  3425. pMask,
  3426. pDst,
  3427. xSrc,
  3428. ySrc,
  3429. xMask, yMask, xDst, yDst, width, height))
  3430. return;
  3431. compose_data.op = op;
  3432. compose_data.src = pSrc;
  3433. compose_data.mask = pMask;
  3434. compose_data.dest = pDst;
  3435. if (width > SCANLINE_BUFFER_LENGTH)
  3436. scanline_buffer = malloc(width * 3 * sizeof(CARD32));
  3437. n = REGION_NUM_RECTS(&region);
  3438. pbox = REGION_RECTS(&region);
  3439. while (n--) {
  3440. h = pbox->y2 - pbox->y1;
  3441. compose_data.ySrc = pbox->y1 - yDst + ySrc;
  3442. compose_data.yMask = pbox->y1 - yDst + yMask;
  3443. compose_data.yDest = pbox->y1;
  3444. while (h) {
  3445. compose_data.height = h;
  3446. w = pbox->x2 - pbox->x1;
  3447. compose_data.xSrc = pbox->x1 - xDst + xSrc;
  3448. compose_data.xMask = pbox->x1 - xDst + xMask;
  3449. compose_data.xDest = pbox->x1;
  3450. if (maskRepeat) {
  3451. compose_data.yMask =
  3452. mod(compose_data.yMask, pMask->pDrawable->height);
  3453. if (compose_data.height >
  3454. pMask->pDrawable->height - compose_data.yMask)
  3455. compose_data.height =
  3456. pMask->pDrawable->height - compose_data.yMask;
  3457. }
  3458. if (srcRepeat) {
  3459. compose_data.ySrc =
  3460. mod(compose_data.ySrc, pSrc->pDrawable->height);
  3461. if (compose_data.height >
  3462. pSrc->pDrawable->height - compose_data.ySrc)
  3463. compose_data.height =
  3464. pSrc->pDrawable->height - compose_data.ySrc;
  3465. }
  3466. while (w) {
  3467. compose_data.width = w;
  3468. if (maskRepeat) {
  3469. compose_data.xMask =
  3470. mod(compose_data.xMask, pMask->pDrawable->width);
  3471. if (compose_data.width >
  3472. pMask->pDrawable->width - compose_data.xMask)
  3473. compose_data.width =
  3474. pMask->pDrawable->width - compose_data.xMask;
  3475. }
  3476. if (srcRepeat) {
  3477. compose_data.xSrc =
  3478. mod(compose_data.xSrc, pSrc->pDrawable->width);
  3479. if (compose_data.width >
  3480. pSrc->pDrawable->width - compose_data.xSrc)
  3481. compose_data.width =
  3482. pSrc->pDrawable->width - compose_data.xSrc;
  3483. }
  3484. fbCompositeRect(&compose_data, scanline_buffer);
  3485. w -= compose_data.width;
  3486. compose_data.xSrc += compose_data.width;
  3487. compose_data.xMask += compose_data.width;
  3488. compose_data.xDest += compose_data.width;
  3489. }
  3490. h -= compose_data.height;
  3491. compose_data.ySrc += compose_data.height;
  3492. compose_data.yMask += compose_data.height;
  3493. compose_data.yDest += compose_data.height;
  3494. }
  3495. pbox++;
  3496. }
  3497. REGION_UNINIT(&region);
  3498. if (scanline_buffer != _scanline_buffer)
  3499. free(scanline_buffer);
  3500. }