draw-paint.c 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include "draw-imp.h"
  24. #include "glyph-imp.h"
  25. #include "pixmap-imp.h"
  26. #include <string.h>
  27. #include <assert.h>
  28. /*
  29. The functions in this file implement various flavours of Porter-Duff blending.
  30. We take the following as definitions:
  31. Cx = Color (from plane x)
  32. ax = Alpha (from plane x)
  33. cx = Cx.ax = Premultiplied color (from plane x)
  34. The general PorterDuff blending equation is:
  35. Blend Z = X op Y cz = Fx.cx + Fy.cy where Fx and Fy depend on op
  36. The two operations we use in this file are: '(X in Y) over Z' and
  37. 'S over Z'. The definitions of the 'over' and 'in' operations are as
  38. follows:
  39. For S over Z, Fs = 1, Fz = 1-as
  40. For X in Y, Fx = ay, Fy = 0
  41. We have 2 choices; we can either work with premultiplied data, or non
  42. premultiplied data. Our
  43. First the premultiplied case:
  44. Let S = (X in Y)
  45. Let R = (X in Y) over Z = S over Z
  46. cs = cx.Fx + cy.Fy (where Fx = ay, Fy = 0)
  47. = cx.ay
  48. as = ax.Fx + ay.Fy
  49. = ax.ay
  50. cr = cs.Fs + cz.Fz (where Fs = 1, Fz = 1-as)
  51. = cs + cz.(1-as)
  52. = cx.ay + cz.(1-ax.ay)
  53. ar = as.Fs + az.Fz
  54. = as + az.(1-as)
  55. = ax.ay + az.(1-ax.ay)
  56. This has various nice properties, like not needing any divisions, and
  57. being symmetric in color and alpha, so this is what we use. Because we
  58. went through the pain of deriving the non premultiplied forms, we list
  59. them here too, though they are not used.
  60. Non Pre-multiplied case:
  61. Cs.as = Fx.Cx.ax + Fy.Cy.ay (where Fx = ay, Fy = 0)
  62. = Cx.ay.ax
  63. Cs = (Cx.ay.ax)/(ay.ax)
  64. = Cx
  65. Cr.ar = Fs.Cs.as + Fz.Cz.az (where Fs = 1, Fz = 1-as)
  66. = Cs.as + (1-as).Cz.az
  67. = Cx.ax.ay + Cz.az.(1-ax.ay)
  68. Cr = (Cx.ax.ay + Cz.az.(1-ax.ay))/(ax.ay + az.(1-ax.ay))
  69. Much more complex, it seems. However, if we could restrict ourselves to
  70. the case where we were always plotting onto an opaque background (i.e.
  71. az = 1), then:
  72. Cr = Cx.(ax.ay) + Cz.(1-ax.ay)
  73. = (Cx-Cz)*(1-ax.ay) + Cz (a single MLA operation)
  74. ar = 1
  75. Sadly, this is not true in the general case, so we abandon this effort
  76. and stick to using the premultiplied form.
  77. */
  78. typedef unsigned char byte;
  79. /* These are used by the non-aa scan converter */
  80. static fz_forceinline void
  81. template_solid_color_1_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
  82. {
  83. int sa = FZ_EXPAND(color[1]);
  84. TRACK_FN();
  85. if (sa == 0)
  86. return;
  87. if (sa == 256)
  88. {
  89. do
  90. {
  91. dp[0] = color[0];
  92. dp[1] = 255;
  93. dp += 2;
  94. }
  95. while (--w);
  96. }
  97. else
  98. {
  99. do
  100. {
  101. dp[0] = FZ_BLEND(color[0], dp[0], sa);
  102. dp[1] = FZ_BLEND(255, dp[1], sa);
  103. dp += 2;
  104. }
  105. while (--w);
  106. }
  107. }
  108. static inline int isbigendian(void)
  109. {
  110. union { int i; char c[sizeof(int)]; } u = {1};
  111. return u.c[0] != 1;
  112. }
  113. static fz_forceinline void
  114. template_solid_color_3_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
  115. {
  116. unsigned int rgba = *(int *)color;
  117. int sa = FZ_EXPAND(color[3]);
  118. TRACK_FN();
  119. if (sa == 0)
  120. return;
  121. if (isbigendian())
  122. rgba |= 0x000000FF;
  123. else
  124. rgba |= 0xFF000000;
  125. if (sa == 256)
  126. {
  127. do
  128. {
  129. *(unsigned int *)dp = rgba;
  130. dp += 4;
  131. }
  132. while (--w);
  133. }
  134. else
  135. {
  136. unsigned int mask = 0xFF00FF00;
  137. unsigned int rb = rgba & (mask>>8);
  138. unsigned int ga = (rgba & mask)>>8;
  139. do
  140. {
  141. unsigned int RGBA = *(unsigned int *)dp;
  142. unsigned int RB = (RGBA<<8) & mask;
  143. unsigned int GA = RGBA & mask;
  144. RB += (rb-(RB>>8))*sa;
  145. GA += (ga-(GA>>8))*sa;
  146. RB &= mask;
  147. GA &= mask;
  148. *(unsigned int *)dp = (RB>>8) | GA;
  149. dp += 4;
  150. }
  151. while (--w);
  152. }
  153. }
  154. static fz_forceinline void
  155. template_solid_color_4_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
  156. {
  157. int sa = FZ_EXPAND(color[4]);
  158. TRACK_FN();
  159. if (sa == 0)
  160. return;
  161. if (sa == 256)
  162. {
  163. #ifdef ARCH_UNALIGNED_OK
  164. if (w > 4)
  165. {
  166. if (isbigendian())
  167. {
  168. const uint32_t a = *(uint32_t*)color;
  169. const uint32_t b = 0xFF000000|(a>>8);
  170. const uint32_t c = 0x00FF0000|(a>>16)|(a<<24);
  171. const uint32_t d = 0x0000FF00|(a>>24)|(a<<16);
  172. const uint32_t e = 0x000000FF|(a<<8);
  173. w -= 3;
  174. do
  175. {
  176. ((uint32_t *)(void *)dp)[0] = a;
  177. ((uint32_t *)(void *)dp)[1] = b;
  178. ((uint32_t *)(void *)dp)[2] = c;
  179. ((uint32_t *)(void *)dp)[3] = d;
  180. ((uint32_t *)(void *)dp)[4] = e;
  181. dp += 20;
  182. w -= 4;
  183. }
  184. while (w > 0);
  185. }
  186. else
  187. {
  188. const uint32_t a = *(uint32_t*)color;
  189. const uint32_t b = 0x000000FF|(a<<8);
  190. const uint32_t c = 0x0000FF00|(a<<16)|(a>>24);
  191. const uint32_t d = 0x00FF0000|(a<<24)|(a>>16);
  192. const uint32_t e = 0xFF000000|(a>>8);
  193. w -= 3;
  194. do
  195. {
  196. ((uint32_t *)(void *)dp)[0] = a;
  197. ((uint32_t *)(void *)dp)[1] = b;
  198. ((uint32_t *)(void *)dp)[2] = c;
  199. ((uint32_t *)(void *)dp)[3] = d;
  200. ((uint32_t *)(void *)dp)[4] = e;
  201. dp += 20;
  202. w -= 4;
  203. }
  204. while (w > 0);
  205. }
  206. w += 3;
  207. if (w == 0)
  208. return;
  209. }
  210. #endif
  211. do
  212. {
  213. dp[0] = color[0];
  214. dp[1] = color[1];
  215. dp[2] = color[2];
  216. dp[3] = color[3];
  217. dp[4] = 255;
  218. dp += 5;
  219. }
  220. while (--w);
  221. }
  222. else
  223. {
  224. do
  225. {
  226. dp[0] = FZ_BLEND(color[0], dp[0], sa);
  227. dp[1] = FZ_BLEND(color[1], dp[1], sa);
  228. dp[2] = FZ_BLEND(color[2], dp[2], sa);
  229. dp[3] = FZ_BLEND(color[3], dp[3], sa);
  230. dp[4] = FZ_BLEND(255, dp[5], sa);
  231. dp += 5;
  232. }
  233. while (--w);
  234. }
  235. }
  236. static fz_forceinline void
  237. template_solid_color_N_256(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
  238. {
  239. int k;
  240. int n1 = n - da;
  241. if (n == 3 && da == 0 && w >= 7)
  242. {
  243. union {uint32_t w[3]; byte b[12];} u;
  244. u.b[0] = u.b[3] = u.b[6] = u.b[9] = color[0];
  245. u.b[1] = u.b[4] = u.b[7] = u.b[10] = color[1];
  246. u.b[2] = u.b[5] = u.b[8] = u.b[11] = color[2];
  247. switch (((intptr_t)dp) & 3)
  248. {
  249. case 3:
  250. *dp++ = color[0];
  251. *(uint32_t *)dp = u.w[1];
  252. dp += 4;
  253. *(uint32_t *)dp = u.w[2];
  254. dp += 4;
  255. w -= 3;
  256. break;
  257. case 2:
  258. *dp++ = color[0];
  259. *dp++ = color[1];
  260. *(uint32_t *)dp = u.w[2];
  261. dp += 4;
  262. w -= 2;
  263. break;
  264. case 1:
  265. *dp++ = color[0];
  266. *dp++ = color[1];
  267. *dp++ = color[2];
  268. w -= 1;
  269. break;
  270. }
  271. w -= 4;
  272. do
  273. {
  274. *(uint32_t *)dp = u.w[0];
  275. dp += 4;
  276. *(uint32_t *)dp = u.w[1];
  277. dp += 4;
  278. *(uint32_t *)dp = u.w[2];
  279. dp += 4;
  280. w -= 4;
  281. }
  282. while (w > 0);
  283. w += 4;
  284. if (w == 0)
  285. return;
  286. }
  287. do
  288. {
  289. dp[0] = color[0];
  290. if (n1 > 1)
  291. dp[1] = color[1];
  292. if (n1 > 2)
  293. dp[2] = color[2];
  294. for (k = 3; k < n1; k++)
  295. dp[k] = color[k];
  296. if (da)
  297. dp[n1] = 255;
  298. dp += n;
  299. }
  300. while (--w);
  301. }
  302. static fz_forceinline void
  303. template_solid_color_N_256_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  304. {
  305. int k;
  306. int n1 = n - da;
  307. do
  308. {
  309. if (fz_overprint_component(eop, 0))
  310. dp[0] = color[0];
  311. if (n1 > 1)
  312. if (fz_overprint_component(eop, 1))
  313. dp[1] = color[1];
  314. if (n1 > 2)
  315. if (fz_overprint_component(eop, 2))
  316. dp[2] = color[2];
  317. for (k = 3; k < n1; k++)
  318. if (fz_overprint_component(eop, k))
  319. dp[k] = color[k];
  320. if (da)
  321. dp[n1] = 255;
  322. dp += n;
  323. }
  324. while (--w);
  325. }
  326. static fz_forceinline void
  327. template_solid_color_N_sa(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa)
  328. {
  329. int k;
  330. int n1 = n - da;
  331. do
  332. {
  333. for (k = 0; k < n1; k++)
  334. dp[k] = FZ_BLEND(color[k], dp[k], sa);
  335. if (da)
  336. dp[k] = FZ_BLEND(255, dp[k], sa);
  337. dp += n;
  338. }
  339. while (--w);
  340. }
  341. static fz_forceinline void
  342. template_solid_color_N_sa_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa, const fz_overprint * FZ_RESTRICT eop)
  343. {
  344. int k;
  345. int n1 = n - da;
  346. do
  347. {
  348. for (k = 0; k < n1; k++)
  349. if (fz_overprint_component(eop, k))
  350. dp[k] = FZ_BLEND(color[k], dp[k], sa);
  351. if (da)
  352. dp[k] = FZ_BLEND(255, dp[k], sa);
  353. dp += n;
  354. }
  355. while (--w);
  356. }
  357. #if FZ_PLOTTERS_N
  358. static fz_forceinline void
  359. template_solid_color_N_general(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa)
  360. {
  361. int k;
  362. int n1 = n - da;
  363. if (sa == 256)
  364. {
  365. do
  366. {
  367. dp[0] = color[0];
  368. if (n1 > 1)
  369. dp[1] = color[1];
  370. if (n1 > 2)
  371. dp[2] = color[2];
  372. for (k = 3; k < n1; k++)
  373. dp[k] = color[k];
  374. if (da)
  375. dp[n1] = 255;
  376. dp += n;
  377. }
  378. while (--w);
  379. }
  380. else
  381. {
  382. do
  383. {
  384. for (k = 0; k < n1; k++)
  385. dp[k] = FZ_BLEND(color[k], dp[k], sa);
  386. if (da)
  387. dp[k] = FZ_BLEND(255, dp[k], sa);
  388. dp += n;
  389. }
  390. while (--w);
  391. }
  392. }
  393. static fz_forceinline void
  394. template_solid_color_N_general_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa, const fz_overprint * FZ_RESTRICT eop)
  395. {
  396. int k;
  397. int n1 = n - da;
  398. if (sa == 256)
  399. {
  400. do
  401. {
  402. if (fz_overprint_component(eop, 0))
  403. dp[0] = color[0];
  404. if (n1 > 1)
  405. if (fz_overprint_component(eop, 1))
  406. dp[1] = color[1];
  407. if (n1 > 2)
  408. if (fz_overprint_component(eop, 2))
  409. dp[2] = color[2];
  410. for (k = 3; k < n1; k++)
  411. if (fz_overprint_component(eop, k))
  412. dp[k] = color[k];
  413. if (da)
  414. dp[n1] = 255;
  415. dp += n;
  416. }
  417. while (--w);
  418. }
  419. else
  420. {
  421. do
  422. {
  423. for (k = 0; k < n1; k++)
  424. if (fz_overprint_component(eop, k))
  425. dp[k] = FZ_BLEND(color[k], dp[k], sa);
  426. if (da)
  427. dp[k] = FZ_BLEND(255, dp[k], sa);
  428. dp += n;
  429. }
  430. while (--w);
  431. }
  432. }
  433. #endif
  434. static fz_forceinline void
  435. template_solid_color_0_da(byte * FZ_RESTRICT dp, int w, int sa)
  436. {
  437. if (sa == 256)
  438. {
  439. memset(dp, 255, w);
  440. }
  441. else
  442. {
  443. do
  444. {
  445. *dp = FZ_BLEND(255, *dp, sa);
  446. dp++;
  447. }
  448. while (--w);
  449. }
  450. }
  451. #if FZ_PLOTTERS_G
  452. static void paint_solid_color_1_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  453. {
  454. TRACK_FN();
  455. template_solid_color_N_sa(dp, 1, w, color, 0, FZ_EXPAND(color[1]));
  456. }
  457. static void paint_solid_color_1(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  458. {
  459. TRACK_FN();
  460. template_solid_color_N_256(dp, 1, w, color, 0);
  461. }
  462. static void paint_solid_color_1_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  463. {
  464. TRACK_FN();
  465. template_solid_color_1_da(dp, 2, w, color, 1);
  466. }
  467. #endif /* FZ_PLOTTERS_G */
  468. static void paint_solid_color_0_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  469. {
  470. TRACK_FN();
  471. template_solid_color_0_da(dp, w, 256);
  472. }
  473. #if FZ_PLOTTERS_RGB
  474. static void paint_solid_color_3_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  475. {
  476. TRACK_FN();
  477. template_solid_color_N_sa(dp, 3, w, color, 0, FZ_EXPAND(color[3]));
  478. }
  479. static void paint_solid_color_3(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  480. {
  481. TRACK_FN();
  482. template_solid_color_N_256(dp, 3, w, color, 0);
  483. }
  484. static void paint_solid_color_3_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  485. {
  486. TRACK_FN();
  487. template_solid_color_3_da(dp, 4, w, color, 1);
  488. }
  489. #endif /* FZ_PLOTTERS_RGB */
  490. #if FZ_PLOTTERS_CMYK
  491. static void paint_solid_color_4_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  492. {
  493. TRACK_FN();
  494. template_solid_color_N_sa(dp, 4, w, color, 0, FZ_EXPAND(color[4]));
  495. }
  496. static void paint_solid_color_4(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  497. {
  498. TRACK_FN();
  499. template_solid_color_N_256(dp, 4, w, color, 0);
  500. }
  501. static void paint_solid_color_4_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  502. {
  503. TRACK_FN();
  504. template_solid_color_4_da(dp, 5, w, color, 1);
  505. }
  506. #endif /* FZ_PLOTTERS_CMYK */
  507. #if FZ_PLOTTERS_N
  508. static void paint_solid_color_N_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  509. {
  510. TRACK_FN();
  511. template_solid_color_N_sa(dp, n, w, color, 0, FZ_EXPAND(color[n]));
  512. }
  513. static void paint_solid_color_N(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  514. {
  515. TRACK_FN();
  516. template_solid_color_N_256(dp, n, w, color, 0);
  517. }
  518. static void paint_solid_color_N_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  519. {
  520. TRACK_FN();
  521. template_solid_color_N_general(dp, n, w, color, 1, FZ_EXPAND(color[n-1]));
  522. }
  523. #endif /* FZ_PLOTTERS_N */
  524. #if FZ_ENABLE_SPOT_RENDERING
  525. static void paint_solid_color_N_alpha_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  526. {
  527. TRACK_FN();
  528. template_solid_color_N_sa_op(dp, n, w, color, 0, FZ_EXPAND(color[n]), eop);
  529. }
  530. static void paint_solid_color_N_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  531. {
  532. TRACK_FN();
  533. template_solid_color_N_256_op(dp, n, w, color, 0, eop);
  534. }
  535. static void paint_solid_color_N_da_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  536. {
  537. TRACK_FN();
  538. template_solid_color_N_general_op(dp, n, w, color, 1, FZ_EXPAND(color[n-1]), eop);
  539. }
  540. #endif /* FZ_ENABLE_SPOT_RENDERING */
  541. fz_solid_color_painter_t *
  542. fz_get_solid_color_painter(int n, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  543. {
  544. #if FZ_ENABLE_SPOT_RENDERING
  545. if (fz_overprint_required(eop))
  546. {
  547. if (da)
  548. return paint_solid_color_N_da_op;
  549. else if (color[n] == 255)
  550. return paint_solid_color_N_op;
  551. else
  552. return paint_solid_color_N_alpha_op;
  553. }
  554. #endif /* FZ_ENABLE_SPOT_RENDERING */
  555. switch (n-da)
  556. {
  557. case 0:
  558. return paint_solid_color_0_da;
  559. #if FZ_PLOTTERS_G
  560. case 1:
  561. if (da)
  562. return paint_solid_color_1_da;
  563. else if (color[1] == 255)
  564. return paint_solid_color_1;
  565. else
  566. return paint_solid_color_1_alpha;
  567. #endif /* FZ_PLOTTERS_G */
  568. #if FZ_PLOTTERS_RGB
  569. case 3:
  570. if (da)
  571. return paint_solid_color_3_da;
  572. else if (color[3] == 255)
  573. return paint_solid_color_3;
  574. else
  575. return paint_solid_color_3_alpha;
  576. #endif /* FZ_PLOTTERS_RGB */
  577. #if FZ_PLOTTERS_CMYK
  578. case 4:
  579. if (da)
  580. return paint_solid_color_4_da;
  581. else if (color[4] == 255)
  582. return paint_solid_color_4;
  583. else
  584. return paint_solid_color_4_alpha;
  585. #endif /* FZ_PLOTTERS_CMYK */
  586. default:
  587. #if FZ_PLOTTERS_N
  588. if (da)
  589. return paint_solid_color_N_da;
  590. else if (color[n] == 255)
  591. return paint_solid_color_N;
  592. else
  593. return paint_solid_color_N_alpha;
  594. #else
  595. return NULL;
  596. #endif /* FZ_PLOTTERS_N */
  597. }
  598. }
  599. /* Blend a non-premultiplied color in mask over destination */
  600. static fz_forceinline void
  601. template_span_with_color_1_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  602. {
  603. int g = color[0];
  604. do
  605. {
  606. int ma = *mp++;
  607. ma = FZ_EXPAND(ma);
  608. if (ma == 256)
  609. {
  610. dp[0] = g;
  611. dp[1] = 255;
  612. }
  613. else if (ma != 0)
  614. {
  615. dp[0] = FZ_BLEND(g, dp[0], ma);
  616. dp[1] = FZ_BLEND(255, dp[1], ma);
  617. }
  618. dp += 2;
  619. }
  620. while (--w);
  621. }
  622. static fz_forceinline void
  623. template_span_with_color_1_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  624. {
  625. int sa = FZ_EXPAND(color[1]);
  626. int g = color[0];
  627. do
  628. {
  629. int ma = *mp++;
  630. ma = FZ_EXPAND(ma);
  631. if (ma != 0)
  632. {
  633. ma = FZ_COMBINE(ma, sa);
  634. dp[0] = FZ_BLEND(g, dp[0], ma);
  635. dp[1] = FZ_BLEND(255, dp[1], ma);
  636. }
  637. dp += 2;
  638. }
  639. while (--w);
  640. }
  641. static fz_forceinline void
  642. template_span_with_color_3_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  643. {
  644. unsigned int rgba = *((const unsigned int *)color);
  645. unsigned int mask, rb, ga;
  646. if (isbigendian())
  647. rgba |= 0x000000FF;
  648. else
  649. rgba |= 0xFF000000;
  650. mask = 0xFF00FF00;
  651. rb = rgba & (mask>>8);
  652. ga = (rgba & mask)>>8;
  653. do
  654. {
  655. unsigned int ma = *mp++;
  656. dp += 4;
  657. ma = FZ_EXPAND(ma);
  658. if (ma == 256)
  659. {
  660. ((unsigned int *)dp)[-1] = rgba;
  661. }
  662. else if (ma != 0)
  663. {
  664. unsigned int RGBA = ((unsigned int *)dp)[-1];
  665. unsigned int RB = (RGBA<<8) & mask;
  666. unsigned int GA = RGBA & mask;
  667. RB += (rb-(RB>>8))*ma;
  668. GA += (ga-(GA>>8))*ma;
  669. RB &= mask;
  670. GA &= mask;
  671. ((unsigned int *)dp)[-1] = (RB>>8) | GA;
  672. }
  673. }
  674. while (--w);
  675. }
  676. static fz_forceinline void
  677. template_span_with_color_3_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  678. {
  679. unsigned int rgba = *((const unsigned int *)color);
  680. unsigned int mask, rb, ga;
  681. int sa = FZ_EXPAND(color[3]);
  682. if (isbigendian())
  683. rgba |= 0x000000FF;
  684. else
  685. rgba |= 0xFF000000;
  686. mask = 0xFF00FF00;
  687. rb = rgba & (mask>>8);
  688. ga = (rgba & mask)>>8;
  689. do
  690. {
  691. unsigned int ma = *mp++;
  692. ma = FZ_COMBINE(FZ_EXPAND(ma), sa);
  693. dp += 4;
  694. if (ma != 0)
  695. {
  696. unsigned int RGBA = ((unsigned int*)dp)[-1];
  697. unsigned int RB = (RGBA<<8) & mask;
  698. unsigned int GA = RGBA & mask;
  699. RB += (rb-(RB>>8))*ma;
  700. GA += (ga-(GA>>8))*ma;
  701. RB &= mask;
  702. GA &= mask;
  703. ((unsigned int *)dp)[-1] = (RB>>8) | GA;
  704. }
  705. }
  706. while (--w);
  707. }
  708. static fz_forceinline void
  709. template_span_with_color_4_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  710. {
  711. int c = color[0];
  712. int m = color[1];
  713. int y = color[2];
  714. int k = color[3];
  715. TRACK_FN();
  716. do
  717. {
  718. int ma = *mp++;
  719. ma = FZ_EXPAND(ma);
  720. if (ma == 256)
  721. {
  722. dp[0] = c;
  723. dp[1] = m;
  724. dp[2] = y;
  725. dp[3] = k;
  726. dp[4] = 255;
  727. }
  728. else if (ma != 0)
  729. {
  730. dp[0] = FZ_BLEND(c, dp[0], ma);
  731. dp[1] = FZ_BLEND(m, dp[1], ma);
  732. dp[2] = FZ_BLEND(y, dp[2], ma);
  733. dp[3] = FZ_BLEND(k, dp[3], ma);
  734. dp[4] = FZ_BLEND(255, dp[4], ma);
  735. }
  736. dp += 5;
  737. }
  738. while (--w);
  739. }
  740. static fz_forceinline void
  741. template_span_with_color_4_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  742. {
  743. int sa = FZ_EXPAND(color[4]);
  744. int c = color[0];
  745. int m = color[1];
  746. int y = color[2];
  747. int k = color[3];
  748. TRACK_FN();
  749. do
  750. {
  751. int ma = *mp++;
  752. ma = FZ_EXPAND(ma);
  753. if (ma != 0)
  754. {
  755. ma = FZ_COMBINE(ma, sa);
  756. dp[0] = FZ_BLEND(c, dp[0], ma);
  757. dp[1] = FZ_BLEND(m, dp[1], ma);
  758. dp[2] = FZ_BLEND(y, dp[2], ma);
  759. dp[3] = FZ_BLEND(k, dp[3], ma);
  760. dp[4] = FZ_BLEND(255, dp[4], ma);
  761. }
  762. dp += 5;
  763. }
  764. while (--w);
  765. }
  766. static fz_forceinline void
  767. template_span_with_color_N_general_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  768. {
  769. int k;
  770. int n1 = n - da;
  771. do
  772. {
  773. int ma = *mp++;
  774. ma = FZ_EXPAND(ma);
  775. if (ma == 256)
  776. {
  777. if (n1 > 0)
  778. dp[0] = color[0];
  779. if (n1 > 1)
  780. dp[1] = color[1];
  781. if (n1 > 2)
  782. dp[2] = color[2];
  783. for (k = 3; k < n1; k++)
  784. dp[k] = color[k];
  785. if (da)
  786. dp[n1] = 255;
  787. }
  788. else if (ma != 0)
  789. {
  790. if (n1 > 0)
  791. dp[0] = FZ_BLEND(color[0], dp[0], ma);
  792. if (n1 > 1)
  793. dp[1] = FZ_BLEND(color[1], dp[1], ma);
  794. if (n1 > 2)
  795. dp[2] = FZ_BLEND(color[2], dp[2], ma);
  796. for (k = 3; k < n1; k++)
  797. dp[k] = FZ_BLEND(color[k], dp[k], ma);
  798. if (da)
  799. dp[n1] = FZ_BLEND(255, dp[n1], ma);
  800. }
  801. dp += n;
  802. }
  803. while (--w);
  804. }
  805. static fz_forceinline void
  806. template_span_with_color_N_general_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
  807. {
  808. int k;
  809. int n1 = n - da;
  810. int sa = FZ_EXPAND(color[n1]);
  811. do
  812. {
  813. int ma = *mp++;
  814. ma = FZ_COMBINE(FZ_EXPAND(ma), sa);
  815. if (n1 > 0)
  816. dp[0] = FZ_BLEND(color[0], dp[0], ma);
  817. if (n1 > 1)
  818. dp[1] = FZ_BLEND(color[1], dp[1], ma);
  819. if (n1 > 2)
  820. dp[2] = FZ_BLEND(color[2], dp[2], ma);
  821. for (k = 3; k < n1; k++)
  822. dp[k] = FZ_BLEND(color[k], dp[k], ma);
  823. if (da)
  824. dp[n1] = FZ_BLEND(255, dp[n1], ma);
  825. dp += n;
  826. }
  827. while (--w);
  828. }
  829. static fz_forceinline void
  830. template_span_with_color_N_general_op_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  831. {
  832. int k;
  833. int n1 = n - da;
  834. do
  835. {
  836. int ma = *mp++;
  837. ma = FZ_EXPAND(ma);
  838. if (ma == 256)
  839. {
  840. if (n1 > 0)
  841. if (fz_overprint_component(eop, 0))
  842. dp[0] = color[0];
  843. if (n1 > 1)
  844. if (fz_overprint_component(eop, 1))
  845. dp[1] = color[1];
  846. if (n1 > 2)
  847. if (fz_overprint_component(eop, 2))
  848. dp[2] = color[2];
  849. for (k = 3; k < n1; k++)
  850. if (fz_overprint_component(eop, k))
  851. dp[k] = color[k];
  852. if (da)
  853. dp[n1] = 255;
  854. }
  855. else if (ma != 0)
  856. {
  857. for (k = 0; k < n1; k++)
  858. if (fz_overprint_component(eop, k))
  859. dp[k] = FZ_BLEND(color[k], dp[k], ma);
  860. if (da)
  861. dp[n1] = FZ_BLEND(255, dp[k], ma);
  862. }
  863. dp += n;
  864. }
  865. while (--w);
  866. }
  867. static fz_forceinline void
  868. template_span_with_color_N_general_op_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  869. {
  870. int k;
  871. int n1 = n - da;
  872. int sa = FZ_EXPAND(color[n1]);
  873. do
  874. {
  875. int ma = *mp++;
  876. ma = FZ_COMBINE(FZ_EXPAND(ma), sa);
  877. for (k = 0; k < n1; k++)
  878. if (fz_overprint_component(eop, k))
  879. dp[k] = FZ_BLEND(color[k], dp[k], ma);
  880. if (da)
  881. dp[k] = FZ_BLEND(255, dp[k], ma);
  882. dp += n;
  883. }
  884. while (--w);
  885. }
  886. static void
  887. paint_span_with_color_0_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  888. {
  889. TRACK_FN();
  890. template_span_with_color_N_general_solid(dp, mp, 1, w, color, 1);
  891. }
  892. static void
  893. paint_span_with_color_0_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  894. {
  895. TRACK_FN();
  896. template_span_with_color_N_general_alpha(dp, mp, 1, w, color, 1);
  897. }
  898. static void
  899. paint_span_with_color_1_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  900. {
  901. TRACK_FN();
  902. template_span_with_color_N_general_solid(dp, mp, 1, w, color, 0);
  903. }
  904. static void
  905. paint_span_with_color_1_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  906. {
  907. TRACK_FN();
  908. template_span_with_color_N_general_alpha(dp, mp, 1, w, color, 0);
  909. }
  910. static void
  911. paint_span_with_color_1_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  912. {
  913. TRACK_FN();
  914. template_span_with_color_1_da_solid(dp, mp, 2, w, color, 1);
  915. }
  916. static void
  917. paint_span_with_color_1_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  918. {
  919. TRACK_FN();
  920. template_span_with_color_1_da_alpha(dp, mp, 2, w, color, 1);
  921. }
  922. #if FZ_PLOTTERS_RGB
  923. static void
  924. paint_span_with_color_3_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  925. {
  926. TRACK_FN();
  927. template_span_with_color_N_general_solid(dp, mp, 3, w, color, 0);
  928. }
  929. static void
  930. paint_span_with_color_3_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  931. {
  932. TRACK_FN();
  933. template_span_with_color_3_da_solid(dp, mp, 4, w, color, 1);
  934. }
  935. static void
  936. paint_span_with_color_3_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  937. {
  938. TRACK_FN();
  939. template_span_with_color_N_general_alpha(dp, mp, 3, w, color, 0);
  940. }
  941. static void
  942. paint_span_with_color_3_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  943. {
  944. TRACK_FN();
  945. template_span_with_color_3_da_alpha(dp, mp, 4, w, color, 1);
  946. }
  947. #endif /* FZ_PLOTTERS_RGB */
  948. #if FZ_PLOTTERS_CMYK
  949. static void
  950. paint_span_with_color_4_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  951. {
  952. TRACK_FN();
  953. template_span_with_color_N_general_solid(dp, mp, 4, w, color, 0);
  954. }
  955. static void
  956. paint_span_with_color_4_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  957. {
  958. TRACK_FN();
  959. template_span_with_color_N_general_alpha(dp, mp, 4, w, color, 0);
  960. }
  961. static void
  962. paint_span_with_color_4_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  963. {
  964. TRACK_FN();
  965. template_span_with_color_4_da_solid(dp, mp, 5, w, color, 1);
  966. }
  967. static void
  968. paint_span_with_color_4_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  969. {
  970. TRACK_FN();
  971. template_span_with_color_4_da_alpha(dp, mp, 5, w, color, 1);
  972. }
  973. #endif /* FZ_PLOTTERS_CMYK */
  974. #if FZ_PLOTTERS_N
  975. static void
  976. paint_span_with_color_N_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  977. {
  978. TRACK_FN();
  979. template_span_with_color_N_general_solid(dp, mp, n, w, color, 0);
  980. }
  981. static void
  982. paint_span_with_color_N_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  983. {
  984. TRACK_FN();
  985. template_span_with_color_N_general_alpha(dp, mp, n, w, color, 0);
  986. }
  987. static void
  988. paint_span_with_color_N_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  989. {
  990. TRACK_FN();
  991. template_span_with_color_N_general_solid(dp, mp, n, w, color, 1);
  992. }
  993. static void
  994. paint_span_with_color_N_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  995. {
  996. TRACK_FN();
  997. template_span_with_color_N_general_alpha(dp, mp, n, w, color, 1);
  998. }
  999. #endif /* FZ_PLOTTERS_N */
  1000. #if FZ_ENABLE_SPOT_RENDERING
  1001. static void
  1002. paint_span_with_color_N_op_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  1003. {
  1004. TRACK_FN();
  1005. template_span_with_color_N_general_op_solid(dp, mp, n, w, color, 0, eop);
  1006. }
  1007. static void
  1008. paint_span_with_color_N_op_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  1009. {
  1010. TRACK_FN();
  1011. template_span_with_color_N_general_op_alpha(dp, mp, n, w, color, 0, eop);
  1012. }
  1013. static void
  1014. paint_span_with_color_N_da_op_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  1015. {
  1016. TRACK_FN();
  1017. template_span_with_color_N_general_op_solid(dp, mp, n, w, color, 1, eop);
  1018. }
  1019. static void
  1020. paint_span_with_color_N_da_op_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
  1021. {
  1022. TRACK_FN();
  1023. template_span_with_color_N_general_op_alpha(dp, mp, n, w, color, 1, eop);
  1024. }
  1025. #endif /* FZ_ENABLE_SPOT_RENDERING */
  1026. fz_span_color_painter_t *
  1027. fz_get_span_color_painter(int n, int da, const byte * FZ_RESTRICT color, const fz_overprint * FZ_RESTRICT eop)
  1028. {
  1029. byte alpha = color[n-da];
  1030. if (alpha == 0)
  1031. return NULL;
  1032. #if FZ_ENABLE_SPOT_RENDERING
  1033. if (fz_overprint_required(eop))
  1034. {
  1035. if (alpha == 255)
  1036. return da ? paint_span_with_color_N_da_op_solid : paint_span_with_color_N_op_solid;
  1037. else
  1038. return da ? paint_span_with_color_N_da_op_alpha : paint_span_with_color_N_op_alpha;
  1039. }
  1040. #endif /* FZ_ENABLE_SPOT_RENDERING */
  1041. switch(n-da)
  1042. {
  1043. case 0:
  1044. if (alpha == 255)
  1045. return da ? paint_span_with_color_0_da_solid : NULL;
  1046. else
  1047. return da ? paint_span_with_color_0_da_alpha : NULL;
  1048. case 1:
  1049. if (alpha == 255)
  1050. return da ? paint_span_with_color_1_da_solid : paint_span_with_color_1_solid;
  1051. else
  1052. return da ? paint_span_with_color_1_da_alpha : paint_span_with_color_1_alpha;
  1053. #if FZ_PLOTTERS_RGB
  1054. case 3:
  1055. if (alpha == 255)
  1056. return da ? paint_span_with_color_3_da_solid : paint_span_with_color_3_solid;
  1057. else
  1058. return da ? paint_span_with_color_3_da_alpha : paint_span_with_color_3_alpha;
  1059. #endif/* FZ_PLOTTERS_RGB */
  1060. #if FZ_PLOTTERS_CMYK
  1061. case 4:
  1062. if (alpha == 255)
  1063. return da ? paint_span_with_color_4_da_solid : paint_span_with_color_4_solid;
  1064. else
  1065. return da ? paint_span_with_color_4_da_alpha : paint_span_with_color_4_alpha;
  1066. #endif/* FZ_PLOTTERS_CMYK */
  1067. #if FZ_PLOTTERS_N
  1068. default:
  1069. if (alpha == 255)
  1070. return da ? paint_span_with_color_N_da_solid : paint_span_with_color_N_solid;
  1071. else
  1072. return da ? paint_span_with_color_N_da_alpha : paint_span_with_color_N_alpha;
  1073. #else
  1074. default: return NULL;
  1075. #endif /* FZ_PLOTTERS_N */
  1076. }
  1077. }
  1078. /* Blend source in mask over destination */
  1079. /* FIXME: There is potential for SWAR optimisation here */
  1080. static fz_forceinline void
  1081. template_span_with_mask_1_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w)
  1082. {
  1083. do
  1084. {
  1085. int ma = *mp++;
  1086. ma = FZ_EXPAND(ma);
  1087. if (ma == 0 || (a && sp[1] == 0))
  1088. {
  1089. dp += 1 + a;
  1090. sp += 1 + a;
  1091. }
  1092. else if (ma == 256)
  1093. {
  1094. *dp++ = *sp++;
  1095. if (a)
  1096. *dp++ = *sp++;
  1097. }
  1098. else
  1099. {
  1100. *dp = FZ_BLEND(*sp, *dp, ma);
  1101. sp++; dp++;
  1102. if (a)
  1103. {
  1104. *dp = FZ_BLEND(*sp, *dp, ma);
  1105. sp++; dp++;
  1106. }
  1107. }
  1108. }
  1109. while (--w);
  1110. }
  1111. static fz_forceinline void
  1112. template_span_with_mask_3_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w)
  1113. {
  1114. do
  1115. {
  1116. int ma = *mp++;
  1117. ma = FZ_EXPAND(ma);
  1118. if (ma == 0 || (a && sp[3] == 0))
  1119. {
  1120. dp += 3 + a;
  1121. sp += 3 + a;
  1122. }
  1123. else if (ma == 256)
  1124. {
  1125. if (a)
  1126. {
  1127. *(int32_t *)dp = *(int32_t *)sp;
  1128. sp += 4; dp += 4;
  1129. }
  1130. else
  1131. {
  1132. *dp++ = *sp++;
  1133. *dp++ = *sp++;
  1134. *dp++ = *sp++;
  1135. }
  1136. }
  1137. else if (a)
  1138. {
  1139. const uint32_t mask = 0x00ff00ff;
  1140. uint32_t d0 = *(uint32_t *)dp;
  1141. uint32_t d1 = d0>>8;
  1142. uint32_t s0 = *(uint32_t *)sp;
  1143. uint32_t s1 = s0>>8;
  1144. d0 &= mask;
  1145. d1 &= mask;
  1146. s0 &= mask;
  1147. s1 &= mask;
  1148. d0 = (((d0<<8) + (s0-d0)*ma)>>8) & mask;
  1149. d1 = ((d1<<8) + (s1-d1)*ma) & ~mask;
  1150. d0 |= d1;
  1151. #ifndef NDEBUG
  1152. if (isbigendian())
  1153. {
  1154. assert((d0 & 0xff) >= (d0>>24));
  1155. assert((d0 & 0xff) >= ((d0>>16) & 0xff));
  1156. assert((d0 & 0xff) >= ((d0>>8) & 0xff));
  1157. }
  1158. else
  1159. {
  1160. assert((d0>>24) >= (d0 & 0xff));
  1161. assert((d0>>24) >= ((d0>>8) & 0xff));
  1162. assert((d0>>24) >= ((d0>>16) & 0xff));
  1163. }
  1164. #endif
  1165. *(uint32_t *)dp = d0;
  1166. sp += 4;
  1167. dp += 4;
  1168. }
  1169. else
  1170. {
  1171. *dp = FZ_BLEND(*sp, *dp, ma);
  1172. sp++; dp++;
  1173. *dp = FZ_BLEND(*sp, *dp, ma);
  1174. sp++; dp++;
  1175. *dp = FZ_BLEND(*sp, *dp, ma);
  1176. sp++; dp++;
  1177. }
  1178. }
  1179. while (--w);
  1180. }
  1181. static fz_forceinline void
  1182. template_span_with_mask_4_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w)
  1183. {
  1184. do
  1185. {
  1186. int ma = *mp++;
  1187. ma = FZ_EXPAND(ma);
  1188. if (ma == 0 || (a && sp[4] == 0))
  1189. {
  1190. dp += 4 + a;
  1191. sp += 4 + a;
  1192. }
  1193. else if (ma == 256)
  1194. {
  1195. if (!a)
  1196. {
  1197. *(uint32_t *)dp = *(uint32_t *)sp;
  1198. dp += 4;
  1199. sp += 4;
  1200. }
  1201. else
  1202. {
  1203. *dp++ = *sp++;
  1204. *dp++ = *sp++;
  1205. *dp++ = *sp++;
  1206. *dp++ = *sp++;
  1207. *dp++ = *sp++;
  1208. }
  1209. }
  1210. else if (a)
  1211. {
  1212. *dp = FZ_BLEND(*sp, *dp, ma);
  1213. sp++; dp++;
  1214. *dp = FZ_BLEND(*sp, *dp, ma);
  1215. sp++; dp++;
  1216. *dp = FZ_BLEND(*sp, *dp, ma);
  1217. sp++; dp++;
  1218. *dp = FZ_BLEND(*sp, *dp, ma);
  1219. sp++; dp++;
  1220. *dp = FZ_BLEND(*sp, *dp, ma);
  1221. sp++; dp++;
  1222. }
  1223. else
  1224. {
  1225. const uint32_t mask = 0x00ff00ff;
  1226. uint32_t d0 = *(uint32_t *)dp;
  1227. uint32_t d1 = d0>>8;
  1228. uint32_t s0 = *(uint32_t *)sp;
  1229. uint32_t s1 = s0>>8;
  1230. sp += 4;
  1231. d0 &= mask;
  1232. d1 &= mask;
  1233. s0 &= mask;
  1234. s1 &= mask;
  1235. d0 = (((d0<<8) + (s0-d0)*ma)>>8) & mask;
  1236. d1 = ((d1<<8) + (s1-d1)*ma) & ~mask;
  1237. d0 |= d1;
  1238. *(uint32_t *)dp = d0;
  1239. dp += 4;
  1240. }
  1241. }
  1242. while (--w);
  1243. }
  1244. static fz_forceinline void
  1245. template_span_with_mask_N_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int n, int w)
  1246. {
  1247. do
  1248. {
  1249. int ma = *mp++;
  1250. ma = FZ_EXPAND(ma);
  1251. if (ma == 0 || (a && sp[n] == 0))
  1252. {
  1253. dp += n + a;
  1254. sp += n + a;
  1255. }
  1256. else if (ma == 256)
  1257. {
  1258. int k;
  1259. for (k = 0; k < n; k++)
  1260. *dp++ = *sp++;
  1261. if (a)
  1262. *dp++ = *sp++;
  1263. }
  1264. else
  1265. {
  1266. int k;
  1267. for (k = 0; k < n; k++)
  1268. {
  1269. *dp = FZ_BLEND(*sp, *dp, ma);
  1270. sp++; dp++;
  1271. }
  1272. if (a)
  1273. {
  1274. *dp = FZ_BLEND(*sp, *dp, ma);
  1275. sp++; dp++;
  1276. }
  1277. }
  1278. }
  1279. while (--w);
  1280. }
  1281. static void
  1282. paint_span_with_mask_0_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1283. {
  1284. TRACK_FN();
  1285. template_span_with_mask_N_general(dp, sp, 1, mp, 0, w);
  1286. }
  1287. static void
  1288. paint_span_with_mask_1_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1289. {
  1290. TRACK_FN();
  1291. template_span_with_mask_1_general(dp, sp, 1, mp, w);
  1292. }
  1293. static void
  1294. paint_span_with_mask_1(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1295. {
  1296. TRACK_FN();
  1297. template_span_with_mask_1_general(dp, sp, 0, mp, w);
  1298. }
  1299. #if FZ_PLOTTERS_RGB
  1300. static void
  1301. paint_span_with_mask_3_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1302. {
  1303. TRACK_FN();
  1304. template_span_with_mask_3_general(dp, sp, 1, mp, w);
  1305. }
  1306. static void
  1307. paint_span_with_mask_3(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1308. {
  1309. TRACK_FN();
  1310. template_span_with_mask_3_general(dp, sp, 0, mp, w);
  1311. }
  1312. #endif /* FZ_PLOTTERS_RGB */
  1313. #if FZ_PLOTTERS_CMYK
  1314. static void
  1315. paint_span_with_mask_4_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1316. {
  1317. TRACK_FN();
  1318. template_span_with_mask_4_general(dp, sp, 1, mp, w);
  1319. }
  1320. static void
  1321. paint_span_with_mask_4(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1322. {
  1323. TRACK_FN();
  1324. template_span_with_mask_4_general(dp, sp, 0, mp, w);
  1325. }
  1326. #endif /* FZ_PLOTTERS_CMYK */
  1327. #if FZ_PLOTTERS_N
  1328. static void
  1329. paint_span_with_mask_N_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1330. {
  1331. TRACK_FN();
  1332. template_span_with_mask_N_general(dp, sp, 1, mp, n, w);
  1333. }
  1334. static void
  1335. paint_span_with_mask_N(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
  1336. {
  1337. TRACK_FN();
  1338. template_span_with_mask_N_general(dp, sp, 0, mp, n, w);
  1339. }
  1340. #endif /* FZ_PLOTTERS_N */
  1341. typedef void (fz_span_mask_painter_t)(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop);
  1342. static fz_span_mask_painter_t *
  1343. fz_get_span_mask_painter(int a, int n)
  1344. {
  1345. switch(n)
  1346. {
  1347. case 0:
  1348. /* assert(a); */
  1349. return paint_span_with_mask_0_a;
  1350. case 1:
  1351. if (a)
  1352. return paint_span_with_mask_1_a;
  1353. else
  1354. return paint_span_with_mask_1;
  1355. #if FZ_PLOTTERS_RGB
  1356. case 3:
  1357. if (a)
  1358. return paint_span_with_mask_3_a;
  1359. else
  1360. return paint_span_with_mask_3;
  1361. #endif /* FZ_PLOTTERS_RGB */
  1362. #if FZ_PLOTTERS_CMYK
  1363. case 4:
  1364. if (a)
  1365. return paint_span_with_mask_4_a;
  1366. else
  1367. return paint_span_with_mask_4;
  1368. #endif /* FZ_PLOTTERS_CMYK */
  1369. default:
  1370. {
  1371. #if FZ_PLOTTERS_N
  1372. if (a)
  1373. return paint_span_with_mask_N_a;
  1374. else
  1375. return paint_span_with_mask_N;
  1376. #else
  1377. return NULL;
  1378. #endif /* FZ_PLOTTERS_N */
  1379. }
  1380. }
  1381. }
  1382. /* Blend source in constant alpha over destination */
  1383. static fz_forceinline void
  1384. template_span_1_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha)
  1385. {
  1386. if (sa)
  1387. alpha = FZ_EXPAND(alpha);
  1388. do
  1389. {
  1390. int masa = (sa ? FZ_COMBINE(sp[1], alpha) : alpha);
  1391. int t = FZ_EXPAND(255-masa);
  1392. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1393. dp++; sp++;
  1394. if (da)
  1395. {
  1396. *dp = masa + FZ_COMBINE(*dp, t);
  1397. dp++;
  1398. }
  1399. if (sa)
  1400. sp++;
  1401. }
  1402. while (--w);
  1403. }
  1404. static fz_forceinline void
  1405. template_span_3_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha)
  1406. {
  1407. if (sa)
  1408. alpha = FZ_EXPAND(alpha);
  1409. do
  1410. {
  1411. int masa = (sa ? FZ_COMBINE(sp[3], alpha) : alpha);
  1412. int t = FZ_EXPAND(255-masa);
  1413. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1414. sp++; dp++;
  1415. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1416. sp++; dp++;
  1417. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1418. sp++; dp++;
  1419. if (da)
  1420. {
  1421. *dp = masa + FZ_COMBINE(*dp, t);
  1422. dp++;
  1423. }
  1424. if (sa)
  1425. sp++;
  1426. }
  1427. while (--w);
  1428. }
  1429. static fz_forceinline void
  1430. template_span_4_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha)
  1431. {
  1432. if (sa)
  1433. alpha = FZ_EXPAND(alpha);
  1434. do
  1435. {
  1436. int masa = (sa ? FZ_COMBINE(sp[4], alpha) : alpha);
  1437. int t = FZ_EXPAND(255-masa);
  1438. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1439. sp++; dp++;
  1440. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1441. sp++; dp++;
  1442. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1443. sp++; dp++;
  1444. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1445. sp++; dp++;
  1446. if (da)
  1447. {
  1448. *dp = masa + FZ_COMBINE(*dp, t);
  1449. dp++;
  1450. }
  1451. if (sa)
  1452. sp++;
  1453. }
  1454. while (--w);
  1455. }
  1456. #if FZ_PLOTTERS_N
  1457. static fz_forceinline void
  1458. template_span_N_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, int alpha)
  1459. {
  1460. if (sa)
  1461. alpha = FZ_EXPAND(alpha);
  1462. do
  1463. {
  1464. int masa = (sa ? FZ_COMBINE(sp[n1], alpha) : alpha);
  1465. int t = FZ_EXPAND(255-masa);
  1466. int k;
  1467. for (k = 0; k < n1; k++)
  1468. {
  1469. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1470. sp++; dp++;
  1471. }
  1472. if (da)
  1473. {
  1474. *dp = masa + FZ_COMBINE(*dp, t);
  1475. dp++;
  1476. }
  1477. if (sa)
  1478. sp++;
  1479. }
  1480. while (--w);
  1481. }
  1482. static fz_forceinline void
  1483. template_span_N_with_alpha_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1484. {
  1485. if (sa)
  1486. alpha = FZ_EXPAND(alpha);
  1487. do
  1488. {
  1489. int masa = (sa ? FZ_COMBINE(sp[n1], alpha) : alpha);
  1490. int t = FZ_EXPAND(255-masa);
  1491. int k;
  1492. for (k = 0; k < n1; k++)
  1493. {
  1494. if (fz_overprint_component(eop, k))
  1495. *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
  1496. sp++;
  1497. dp++;
  1498. }
  1499. if (da)
  1500. {
  1501. *dp = masa + FZ_COMBINE(*dp, t);
  1502. dp++;
  1503. }
  1504. if (sa)
  1505. sp++;
  1506. }
  1507. while (--w);
  1508. }
  1509. #endif
  1510. /* Blend source over destination */
  1511. static fz_forceinline void
  1512. template_span_1_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w)
  1513. {
  1514. do
  1515. {
  1516. int t = (sa ? FZ_EXPAND(sp[1]): 256);
  1517. if (t == 0)
  1518. {
  1519. dp += 1 + da; sp += 1 + sa;
  1520. }
  1521. else
  1522. {
  1523. t = 256 - t;
  1524. if (t == 0)
  1525. {
  1526. *dp++ = *sp++;
  1527. if (da)
  1528. *dp++ = (sa ? *sp : 255);
  1529. if (sa)
  1530. sp++;
  1531. }
  1532. else
  1533. {
  1534. *dp = *sp + FZ_COMBINE(*dp, t);
  1535. sp++;
  1536. dp++;
  1537. if (da)
  1538. {
  1539. *dp = *sp + FZ_COMBINE(*dp, t);
  1540. dp++;
  1541. }
  1542. sp++;
  1543. }
  1544. }
  1545. }
  1546. while (--w);
  1547. }
  1548. static fz_forceinline void
  1549. template_span_3_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w)
  1550. {
  1551. do
  1552. {
  1553. int t = (sa ? FZ_EXPAND(sp[3]) : 256);
  1554. if (t == 0)
  1555. {
  1556. dp += 3 + da; sp += 3 + sa;
  1557. }
  1558. else
  1559. {
  1560. t = 256 - t;
  1561. if (t == 0)
  1562. {
  1563. if (da && sa)
  1564. *(int32_t *)dp = *(const int32_t *)sp;
  1565. else
  1566. {
  1567. dp[0] = sp[0];
  1568. dp[1] = sp[1];
  1569. dp[2] = sp[2];
  1570. if (da)
  1571. dp[3] = 255;
  1572. }
  1573. dp += 3+da; sp += 3+sa;
  1574. }
  1575. else
  1576. {
  1577. /* sa != 0 as t != 0 */
  1578. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1579. dp++;
  1580. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1581. dp++;
  1582. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1583. dp++;
  1584. if (da)
  1585. {
  1586. *dp = *sp + FZ_COMBINE(*dp, t);
  1587. dp++;
  1588. }
  1589. sp++;
  1590. }
  1591. }
  1592. }
  1593. while (--w);
  1594. }
  1595. static fz_forceinline void
  1596. template_span_4_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w)
  1597. {
  1598. do
  1599. {
  1600. int t = (sa ? FZ_EXPAND(sp[4]) : 256);
  1601. if (t == 0)
  1602. {
  1603. dp += 4+da; sp += 4+sa;
  1604. }
  1605. else
  1606. {
  1607. t = 256 - t;
  1608. if (t == 0)
  1609. {
  1610. dp[0] = sp[0];
  1611. dp[1] = sp[1];
  1612. dp[2] = sp[2];
  1613. dp[3] = sp[3];
  1614. if (da)
  1615. dp[4] = (sa ? sp[4] : 255);
  1616. dp += 4+da; sp += 4 + sa;
  1617. }
  1618. else
  1619. {
  1620. /* sa != 0 as t != 0 */
  1621. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1622. dp++;
  1623. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1624. dp++;
  1625. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1626. dp++;
  1627. *dp = *sp++ + FZ_COMBINE(*dp, t);
  1628. dp++;
  1629. if (da)
  1630. {
  1631. *dp = *sp + FZ_COMBINE(*dp, t);
  1632. dp++;
  1633. }
  1634. sp++;
  1635. }
  1636. }
  1637. }
  1638. while (--w);
  1639. }
  1640. #if FZ_PLOTTERS_N
  1641. static fz_forceinline void
  1642. template_span_N_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w)
  1643. {
  1644. do
  1645. {
  1646. int t = (sa ? FZ_EXPAND(sp[n1]) : 256);
  1647. if (t == 0)
  1648. {
  1649. dp += n1 + da; sp += n1 + sa;
  1650. }
  1651. else
  1652. {
  1653. t = 256 - t;
  1654. if (t == 0)
  1655. {
  1656. int k;
  1657. for (k = 0; k < n1; k++)
  1658. *dp++ = *sp++;
  1659. if (da)
  1660. *dp++ = (sa ? *sp : 255);
  1661. if (sa)
  1662. sp++;
  1663. }
  1664. else
  1665. {
  1666. /* sa != 0, as t != 0 */
  1667. int k;
  1668. for (k = 0; k < n1; k++)
  1669. {
  1670. *dp = *sp + FZ_COMBINE(*dp, t);
  1671. sp++;
  1672. dp++;
  1673. }
  1674. if (da)
  1675. {
  1676. *dp = *sp + FZ_COMBINE(*dp, t);
  1677. dp++;
  1678. }
  1679. sp++;
  1680. }
  1681. }
  1682. }
  1683. while (--w);
  1684. }
  1685. static fz_forceinline void
  1686. template_span_N_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, const fz_overprint * FZ_RESTRICT eop)
  1687. {
  1688. do
  1689. {
  1690. int t = (sa ? FZ_EXPAND(sp[n1]) : 256);
  1691. if (t == 0)
  1692. {
  1693. dp += n1 + da; sp += n1 + sa;
  1694. }
  1695. else
  1696. {
  1697. t = 256 - t;
  1698. if (t == 0)
  1699. {
  1700. int k;
  1701. for (k = 0; k < n1; k++)
  1702. {
  1703. if (fz_overprint_component(eop, k))
  1704. *dp = *sp;
  1705. dp++;
  1706. sp++;
  1707. }
  1708. if (da)
  1709. *dp++ = (sa ? *sp : 255);
  1710. if (sa)
  1711. sp++;
  1712. }
  1713. else
  1714. {
  1715. int k;
  1716. /* sa can never be 0 here, as t != 0. */
  1717. for (k = 0; k < n1; k++)
  1718. {
  1719. if (fz_overprint_component(eop, k))
  1720. *dp = *sp + FZ_COMBINE(*dp, t);
  1721. sp++;
  1722. dp++;
  1723. }
  1724. if (da)
  1725. {
  1726. *dp = *sp + FZ_COMBINE(*dp, t);
  1727. dp++;
  1728. }
  1729. sp++;
  1730. }
  1731. }
  1732. }
  1733. while (--w);
  1734. }
  1735. #endif
  1736. static void
  1737. paint_span_0_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1738. {
  1739. TRACK_FN();
  1740. do
  1741. {
  1742. int s = *sp++;
  1743. int t = FZ_EXPAND(255 - s);
  1744. *dp = s + FZ_COMBINE(*dp, t);
  1745. dp ++;
  1746. }
  1747. while (--w);
  1748. }
  1749. static void
  1750. paint_span_0_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1751. {
  1752. TRACK_FN();
  1753. alpha = FZ_EXPAND(alpha);
  1754. do
  1755. {
  1756. int masa = FZ_COMBINE(sp[0], alpha);
  1757. int t = FZ_EXPAND(255-masa);
  1758. *dp = masa + FZ_COMBINE(*dp, t);
  1759. dp++;
  1760. sp++;
  1761. }
  1762. while (--w);
  1763. }
  1764. static void
  1765. paint_span_1_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1766. {
  1767. TRACK_FN();
  1768. template_span_1_general(dp, 0, sp, 1, w);
  1769. }
  1770. static void
  1771. paint_span_1_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1772. {
  1773. TRACK_FN();
  1774. template_span_1_with_alpha_general(dp, 0, sp, 1, w, alpha);
  1775. }
  1776. static void
  1777. paint_span_1_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1778. {
  1779. TRACK_FN();
  1780. template_span_1_general(dp, 1, sp, 1, w);
  1781. }
  1782. static void
  1783. paint_span_1_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1784. {
  1785. TRACK_FN();
  1786. template_span_1_with_alpha_general(dp, 1, sp, 1, w, alpha);
  1787. }
  1788. #if FZ_PLOTTERS_G
  1789. static void
  1790. paint_span_1_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1791. {
  1792. TRACK_FN();
  1793. template_span_1_general(dp, 1, sp, 0, w);
  1794. }
  1795. static void
  1796. paint_span_1_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1797. {
  1798. TRACK_FN();
  1799. template_span_1_with_alpha_general(dp, 1, sp, 0, w, alpha);
  1800. }
  1801. static void
  1802. paint_span_1(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1803. {
  1804. TRACK_FN();
  1805. template_span_1_general(dp, 0, sp, 0, w);
  1806. }
  1807. static void
  1808. paint_span_1_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1809. {
  1810. TRACK_FN();
  1811. template_span_1_with_alpha_general(dp, 0, sp, 0, w, alpha);
  1812. }
  1813. #endif /* FZ_PLOTTERS_G */
  1814. #if FZ_PLOTTERS_RGB
  1815. static void
  1816. paint_span_3_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1817. {
  1818. TRACK_FN();
  1819. template_span_3_general(dp, 1, sp, 1, w);
  1820. }
  1821. static void
  1822. paint_span_3_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1823. {
  1824. TRACK_FN();
  1825. template_span_3_with_alpha_general(dp, 1, sp, 1, w, alpha);
  1826. }
  1827. static void
  1828. paint_span_3_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1829. {
  1830. TRACK_FN();
  1831. template_span_3_general(dp, 1, sp, 0, w);
  1832. }
  1833. static void
  1834. paint_span_3_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1835. {
  1836. TRACK_FN();
  1837. template_span_3_with_alpha_general(dp, 1, sp, 0, w, alpha);
  1838. }
  1839. static void
  1840. paint_span_3_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1841. {
  1842. TRACK_FN();
  1843. template_span_3_general(dp, 0, sp, 1, w);
  1844. }
  1845. static void
  1846. paint_span_3_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1847. {
  1848. TRACK_FN();
  1849. template_span_3_with_alpha_general(dp, 0, sp, 1, w, alpha);
  1850. }
  1851. static void
  1852. paint_span_3(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1853. {
  1854. TRACK_FN();
  1855. template_span_3_general(dp, 0, sp, 0, w);
  1856. }
  1857. static void
  1858. paint_span_3_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1859. {
  1860. TRACK_FN();
  1861. template_span_3_with_alpha_general(dp, 0, sp, 0, w, alpha);
  1862. }
  1863. #endif /* FZ_PLOTTERS_RGB */
  1864. #if FZ_PLOTTERS_CMYK
  1865. static void
  1866. paint_span_4_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1867. {
  1868. TRACK_FN();
  1869. template_span_4_general(dp, 1, sp, 1, w);
  1870. }
  1871. static void
  1872. paint_span_4_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1873. {
  1874. TRACK_FN();
  1875. template_span_4_with_alpha_general(dp, 1, sp, 1, w, alpha);
  1876. }
  1877. static void
  1878. paint_span_4_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1879. {
  1880. TRACK_FN();
  1881. template_span_4_general(dp, 1, sp, 0, w);
  1882. }
  1883. static void
  1884. paint_span_4_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1885. {
  1886. TRACK_FN();
  1887. template_span_4_with_alpha_general(dp, 1, sp, 0, w, alpha);
  1888. }
  1889. static void
  1890. paint_span_4_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1891. {
  1892. TRACK_FN();
  1893. template_span_4_general(dp, 0, sp, 1, w);
  1894. }
  1895. static void
  1896. paint_span_4_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1897. {
  1898. TRACK_FN();
  1899. template_span_4_with_alpha_general(dp, 0, sp, 1, w, alpha);
  1900. }
  1901. static void
  1902. paint_span_4(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1903. {
  1904. TRACK_FN();
  1905. template_span_4_general(dp, 0, sp, 0, w);
  1906. }
  1907. static void
  1908. paint_span_4_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1909. {
  1910. TRACK_FN();
  1911. template_span_4_with_alpha_general(dp, 0, sp, 0, w, alpha);
  1912. }
  1913. #endif /* FZ_PLOTTERS_CMYK */
  1914. #if FZ_PLOTTERS_N
  1915. static void
  1916. paint_span_N_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1917. {
  1918. TRACK_FN();
  1919. template_span_N_general(dp, 1, sp, 1, n, w);
  1920. }
  1921. static void
  1922. paint_span_N_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1923. {
  1924. TRACK_FN();
  1925. template_span_N_with_alpha_general(dp, 1, sp, 1, n, w, alpha);
  1926. }
  1927. static void
  1928. paint_span_N_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1929. {
  1930. TRACK_FN();
  1931. template_span_N_general(dp, 1, sp, 0, n, w);
  1932. }
  1933. static void
  1934. paint_span_N_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1935. {
  1936. TRACK_FN();
  1937. template_span_N_with_alpha_general(dp, 1, sp, 0, n, w, alpha);
  1938. }
  1939. static void
  1940. paint_span_N_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1941. {
  1942. TRACK_FN();
  1943. template_span_N_general(dp, 0, sp, 1, n, w);
  1944. }
  1945. static void
  1946. paint_span_N_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1947. {
  1948. TRACK_FN();
  1949. template_span_N_with_alpha_general(dp, 0, sp, 1, n, w, alpha);
  1950. }
  1951. static void
  1952. paint_span_N(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1953. {
  1954. TRACK_FN();
  1955. template_span_N_general(dp, 0, sp, 0, n, w);
  1956. }
  1957. static void
  1958. paint_span_N_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1959. {
  1960. TRACK_FN();
  1961. template_span_N_with_alpha_general(dp, 0, sp, 0, n, w, alpha);
  1962. }
  1963. #endif /* FZ_PLOTTERS_N */
  1964. #if FZ_ENABLE_SPOT_RENDERING
  1965. static void
  1966. paint_span_N_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1967. {
  1968. TRACK_FN();
  1969. template_span_N_general_op(dp, da, sp, sa, n, w, eop);
  1970. }
  1971. static void
  1972. paint_span_N_general_alpha_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1973. {
  1974. TRACK_FN();
  1975. template_span_N_with_alpha_general_op(dp, da, sp, sa, n, w, alpha, eop);
  1976. }
  1977. #endif /* FZ_ENABLE_SPOT_RENDERING */
  1978. fz_span_painter_t *
  1979. fz_get_span_painter(int da, int sa, int n, int alpha, const fz_overprint * FZ_RESTRICT eop)
  1980. {
  1981. #if FZ_ENABLE_SPOT_RENDERING
  1982. if (fz_overprint_required(eop))
  1983. {
  1984. if (alpha == 255)
  1985. return paint_span_N_general_op;
  1986. else if (alpha > 0)
  1987. return paint_span_N_general_alpha_op;
  1988. else
  1989. return NULL;
  1990. }
  1991. #endif /* FZ_ENABLE_SPOT_RENDERING */
  1992. switch (n)
  1993. {
  1994. case 0:
  1995. if (alpha == 255)
  1996. return paint_span_0_da_sa;
  1997. else if (alpha > 0)
  1998. return paint_span_0_da_sa_alpha;
  1999. break;
  2000. case 1:
  2001. if (sa)
  2002. if (da)
  2003. {
  2004. if (alpha == 255)
  2005. return paint_span_1_da_sa;
  2006. else if (alpha > 0)
  2007. return paint_span_1_da_sa_alpha;
  2008. }
  2009. else
  2010. {
  2011. if (alpha == 255)
  2012. return paint_span_1_sa;
  2013. else if (alpha > 0)
  2014. return paint_span_1_sa_alpha;
  2015. }
  2016. else
  2017. #if FZ_PLOTTERS_G
  2018. if (da)
  2019. {
  2020. if (alpha == 255)
  2021. return paint_span_1_da;
  2022. else if (alpha > 0)
  2023. return paint_span_1_da_alpha;
  2024. }
  2025. else
  2026. {
  2027. if (alpha == 255)
  2028. return paint_span_1;
  2029. else if (alpha > 0)
  2030. return paint_span_1_alpha;
  2031. }
  2032. #else
  2033. goto fallback;
  2034. #endif /* FZ_PLOTTERS_G */
  2035. break;
  2036. #if FZ_PLOTTERS_RGB
  2037. case 3:
  2038. if (da)
  2039. if (sa)
  2040. {
  2041. if (alpha == 255)
  2042. return paint_span_3_da_sa;
  2043. else if (alpha > 0)
  2044. return paint_span_3_da_sa_alpha;
  2045. }
  2046. else
  2047. {
  2048. if (alpha == 255)
  2049. return paint_span_3_da;
  2050. else if (alpha > 0)
  2051. return paint_span_3_da_alpha;
  2052. }
  2053. else
  2054. if (sa)
  2055. {
  2056. if (alpha == 255)
  2057. return paint_span_3_sa;
  2058. else if (alpha > 0)
  2059. return paint_span_3_sa_alpha;
  2060. }
  2061. else
  2062. {
  2063. if (alpha == 255)
  2064. return paint_span_3;
  2065. else if (alpha > 0)
  2066. return paint_span_3_alpha;
  2067. }
  2068. break;
  2069. #endif /* FZ_PLOTTERS_RGB */
  2070. #if FZ_PLOTTERS_CMYK
  2071. case 4:
  2072. if (da)
  2073. if (sa)
  2074. {
  2075. if (alpha == 255)
  2076. return paint_span_4_da_sa;
  2077. else if (alpha > 0)
  2078. return paint_span_4_da_sa_alpha;
  2079. }
  2080. else
  2081. {
  2082. if (alpha == 255)
  2083. return paint_span_4_da;
  2084. else if (alpha > 0)
  2085. return paint_span_4_da_alpha;
  2086. }
  2087. else
  2088. if (sa)
  2089. {
  2090. if (alpha == 255)
  2091. return paint_span_4_sa;
  2092. else if (alpha > 0)
  2093. return paint_span_4_sa_alpha;
  2094. }
  2095. else
  2096. {
  2097. if (alpha == 255)
  2098. return paint_span_4;
  2099. else if (alpha > 0)
  2100. return paint_span_4_alpha;
  2101. }
  2102. break;
  2103. #endif /* FZ_PLOTTERS_CMYK */
  2104. default:
  2105. {
  2106. #if !FZ_PLOTTERS_G
  2107. fallback:{}
  2108. #endif /* FZ_PLOTTERS_G */
  2109. #if FZ_PLOTTERS_N
  2110. if (da)
  2111. if (sa)
  2112. {
  2113. if (alpha == 255)
  2114. return paint_span_N_da_sa;
  2115. else if (alpha > 0)
  2116. return paint_span_N_da_sa_alpha;
  2117. }
  2118. else
  2119. {
  2120. if (alpha == 255)
  2121. return paint_span_N_da;
  2122. else if (alpha > 0)
  2123. return paint_span_N_da_alpha;
  2124. }
  2125. else
  2126. if (sa)
  2127. {
  2128. if (alpha == 255)
  2129. return paint_span_N_sa;
  2130. else if (alpha > 0)
  2131. return paint_span_N_sa_alpha;
  2132. }
  2133. else
  2134. {
  2135. if (alpha == 255)
  2136. return paint_span_N;
  2137. else if (alpha > 0)
  2138. return paint_span_N_alpha;
  2139. }
  2140. #endif /* FZ_PLOTTERS_N */
  2141. break;
  2142. }
  2143. }
  2144. return NULL;
  2145. }
  2146. /*
  2147. * Pixmap blending functions
  2148. */
  2149. void
  2150. fz_paint_pixmap_with_bbox(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha, fz_irect bbox)
  2151. {
  2152. const unsigned char *sp;
  2153. unsigned char *dp;
  2154. int x, y, w, h, n, da, sa;
  2155. fz_span_painter_t *fn;
  2156. assert(dst->n - dst->alpha == src->n - src->alpha);
  2157. if (alpha == 0)
  2158. return;
  2159. bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(dst));
  2160. bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
  2161. x = bbox.x0;
  2162. y = bbox.y0;
  2163. w = fz_irect_width(bbox);
  2164. h = fz_irect_height(bbox);
  2165. if (w == 0 || h == 0)
  2166. return;
  2167. n = src->n;
  2168. sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n;
  2169. sa = src->alpha;
  2170. dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n;
  2171. da = dst->alpha;
  2172. n -= sa;
  2173. fn = fz_get_span_painter(da, sa, n, alpha, 0);
  2174. if (fn == NULL)
  2175. return;
  2176. while (h--)
  2177. {
  2178. (*fn)(dp, da, sp, sa, n, w, alpha, 0);
  2179. sp += src->stride;
  2180. dp += dst->stride;
  2181. }
  2182. }
  2183. void
  2184. fz_paint_pixmap(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha)
  2185. {
  2186. const unsigned char *sp;
  2187. unsigned char *dp;
  2188. fz_irect bbox;
  2189. int x, y, w, h, n, da, sa;
  2190. fz_span_painter_t *fn;
  2191. if (alpha == 0)
  2192. return;
  2193. if (dst->n - dst->alpha != src->n - src->alpha)
  2194. {
  2195. // fprintf(stderr, "fz_paint_pixmap - FIXME\n");
  2196. return;
  2197. }
  2198. assert(dst->n - dst->alpha == src->n - src->alpha);
  2199. bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst));
  2200. x = bbox.x0;
  2201. y = bbox.y0;
  2202. w = fz_irect_width(bbox);
  2203. h = fz_irect_height(bbox);
  2204. if (w == 0 || h == 0)
  2205. return;
  2206. n = src->n;
  2207. sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n;
  2208. sa = src->alpha;
  2209. dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n;
  2210. da = dst->alpha;
  2211. n -= sa;
  2212. fn = fz_get_span_painter(da, sa, n, alpha, 0);
  2213. if (fn == NULL)
  2214. return;
  2215. while (h--)
  2216. {
  2217. (*fn)(dp, da, sp, sa, n, w, alpha, 0);
  2218. sp += src->stride;
  2219. dp += dst->stride;
  2220. }
  2221. }
  2222. static fz_forceinline void
  2223. paint_span_alpha_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int n, int w)
  2224. {
  2225. TRACK_FN();
  2226. sp += n-1;
  2227. do
  2228. {
  2229. int s = *sp;
  2230. int t = FZ_EXPAND(255 - s);
  2231. sp += n;
  2232. *dp = s + FZ_COMBINE(*dp, t);
  2233. dp ++;
  2234. }
  2235. while (--w);
  2236. }
  2237. static fz_forceinline void
  2238. paint_span_alpha_not_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int n, int w, int alpha)
  2239. {
  2240. TRACK_FN();
  2241. sp += n-1;
  2242. alpha = FZ_EXPAND(alpha);
  2243. do
  2244. {
  2245. int masa = FZ_COMBINE(sp[0], alpha);
  2246. sp += n;
  2247. *dp = FZ_BLEND(*sp, *dp, masa);
  2248. dp++;
  2249. }
  2250. while (--w);
  2251. }
  2252. void
  2253. fz_paint_pixmap_alpha(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha)
  2254. {
  2255. const unsigned char *sp;
  2256. unsigned char *dp;
  2257. fz_irect bbox;
  2258. int x, y, w, h, n;
  2259. if (alpha == 0)
  2260. return;
  2261. assert(dst->n == 1 && dst->alpha == 1 && src->n >= 1 && src->alpha == 1);
  2262. bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst));
  2263. x = bbox.x0;
  2264. y = bbox.y0;
  2265. w = fz_irect_width(bbox);
  2266. h = fz_irect_height(bbox);
  2267. if (w == 0 || h == 0)
  2268. return;
  2269. n = src->n;
  2270. sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n;
  2271. dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n;
  2272. if (alpha == 255)
  2273. {
  2274. while (h--)
  2275. {
  2276. paint_span_alpha_solid(dp, sp, n, w);
  2277. sp += src->stride;
  2278. dp += dst->stride;
  2279. }
  2280. }
  2281. else
  2282. {
  2283. while (h--)
  2284. {
  2285. paint_span_alpha_not_solid(dp, sp, n, w, alpha);
  2286. sp += src->stride;
  2287. dp += dst->stride;
  2288. }
  2289. }
  2290. }
  2291. void
  2292. fz_paint_pixmap_with_overprint(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_overprint * FZ_RESTRICT eop)
  2293. {
  2294. const unsigned char *sp;
  2295. unsigned char *dp;
  2296. fz_irect bbox;
  2297. int x, y, w, h, n, da, sa;
  2298. fz_span_painter_t *fn;
  2299. if (dst->n - dst->alpha != src->n - src->alpha)
  2300. {
  2301. // fprintf(stderr, "fz_paint_pixmap_with_overprint - FIXME\n");
  2302. return;
  2303. }
  2304. assert(dst->n - dst->alpha == src->n - src->alpha);
  2305. bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst));
  2306. x = bbox.x0;
  2307. y = bbox.y0;
  2308. w = fz_irect_width(bbox);
  2309. h = fz_irect_height(bbox);
  2310. if (w == 0 || h == 0)
  2311. return;
  2312. n = src->n;
  2313. sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n;
  2314. sa = src->alpha;
  2315. dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n;
  2316. da = dst->alpha;
  2317. n -= sa;
  2318. fn = fz_get_span_painter(da, sa, n, 255, eop);
  2319. if (fn == NULL)
  2320. return;
  2321. while (h--)
  2322. {
  2323. (*fn)(dp, da, sp, sa, n, w, 255, eop);
  2324. sp += src->stride;
  2325. dp += dst->stride;
  2326. }
  2327. }
  2328. void
  2329. fz_paint_pixmap_with_mask(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_pixmap * FZ_RESTRICT msk)
  2330. {
  2331. const unsigned char *sp, *mp;
  2332. unsigned char *dp;
  2333. fz_irect bbox;
  2334. int x, y, w, h, n, sa, da;
  2335. fz_span_mask_painter_t *fn;
  2336. assert(dst->n == src->n);
  2337. assert(msk->n == 1);
  2338. bbox = fz_pixmap_bbox_no_ctx(dst);
  2339. bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
  2340. bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(msk));
  2341. x = bbox.x0;
  2342. y = bbox.y0;
  2343. w = fz_irect_width(bbox);
  2344. h = fz_irect_height(bbox);
  2345. if (w == 0 || h == 0)
  2346. return;
  2347. n = src->n;
  2348. sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n;
  2349. sa = src->alpha;
  2350. mp = msk->samples + (y - msk->y) * (size_t)msk->stride + (x - msk->x) * (size_t)msk->n;
  2351. dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n;
  2352. da = dst->alpha;
  2353. /* sa == da, or something has gone very wrong! */
  2354. assert(sa == da);
  2355. n -= sa;
  2356. fn = fz_get_span_mask_painter(da, n);
  2357. if (fn == NULL)
  2358. return;
  2359. while (h--)
  2360. {
  2361. (*fn)(dp, sp, mp, w, n, sa, NULL);
  2362. sp += src->stride;
  2363. dp += dst->stride;
  2364. mp += msk->stride;
  2365. }
  2366. }
  2367. static fz_forceinline void
  2368. paint_over_span_with_mask(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w)
  2369. {
  2370. do
  2371. {
  2372. int ma = *mp++;
  2373. ma = FZ_EXPAND(ma);
  2374. if (ma == 0 || *sp == 0)
  2375. {
  2376. dp++;
  2377. sp++;
  2378. }
  2379. else
  2380. {
  2381. int a = *sp++;
  2382. if (ma != 256)
  2383. a = fz_mul255(ma, a);
  2384. *dp = 255 - fz_mul255(255 - a, 255 - *dp);
  2385. dp++;
  2386. }
  2387. }
  2388. while (--w);
  2389. }
  2390. void
  2391. fz_paint_over_pixmap_with_mask(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_pixmap * FZ_RESTRICT msk)
  2392. {
  2393. const unsigned char *sp, *mp;
  2394. unsigned char *dp;
  2395. fz_irect bbox;
  2396. int x, y, w, h;
  2397. assert(dst->n == src->n);
  2398. assert(msk->n == 1);
  2399. bbox = fz_pixmap_bbox_no_ctx(dst);
  2400. bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
  2401. bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(msk));
  2402. x = bbox.x0;
  2403. y = bbox.y0;
  2404. w = fz_irect_width(bbox);
  2405. h = fz_irect_height(bbox);
  2406. if (w == 0 || h == 0)
  2407. return;
  2408. /* sa == da, or something has gone very wrong! */
  2409. assert(src->alpha == dst->alpha && dst->alpha == 1 && src->n == 1);
  2410. sp = src->samples + (y - src->y) * (size_t)src->stride + (size_t)(x - src->x);
  2411. mp = msk->samples + (y - msk->y) * (size_t)msk->stride + (size_t)(x - msk->x);
  2412. dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (size_t)(x - dst->x);
  2413. while (h--)
  2414. {
  2415. paint_over_span_with_mask(dp, sp, mp, w);
  2416. sp += src->stride;
  2417. dp += dst->stride;
  2418. mp += msk->stride;
  2419. }
  2420. }
  2421. static inline void
  2422. fz_paint_glyph_mask(int span, unsigned char *dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y)
  2423. {
  2424. while (h--)
  2425. {
  2426. int skip_xx, ww, len, extend;
  2427. const unsigned char *runp;
  2428. unsigned char *ddp = dp;
  2429. int offset = ((const int *)(glyph->data))[skip_y++];
  2430. if (offset >= 0)
  2431. {
  2432. int eol = 0;
  2433. runp = &glyph->data[offset];
  2434. extend = 0;
  2435. ww = w;
  2436. skip_xx = skip_x;
  2437. while (skip_xx)
  2438. {
  2439. int v = *runp++;
  2440. switch (v & 3)
  2441. {
  2442. case 0: /* Extend */
  2443. extend = v>>2;
  2444. len = 0;
  2445. break;
  2446. case 1: /* Transparent */
  2447. len = (v>>2) + 1 + (extend<<6);
  2448. extend = 0;
  2449. if (len > skip_xx)
  2450. {
  2451. len -= skip_xx;
  2452. goto transparent_run;
  2453. }
  2454. break;
  2455. case 2: /* Solid */
  2456. eol = v & 4;
  2457. len = (v>>3) + 1 + (extend<<5);
  2458. extend = 0;
  2459. if (len > skip_xx)
  2460. {
  2461. len -= skip_xx;
  2462. goto solid_run;
  2463. }
  2464. break;
  2465. default: /* Intermediate */
  2466. eol = v & 4;
  2467. len = (v>>3) + 1 + (extend<<5);
  2468. extend = 0;
  2469. if (len > skip_xx)
  2470. {
  2471. runp += skip_xx;
  2472. len -= skip_xx;
  2473. goto intermediate_run;
  2474. }
  2475. runp += len;
  2476. break;
  2477. }
  2478. if (eol)
  2479. {
  2480. ww = 0;
  2481. break;
  2482. }
  2483. skip_xx -= len;
  2484. }
  2485. while (ww > 0)
  2486. {
  2487. int v = *runp++;
  2488. switch(v & 3)
  2489. {
  2490. case 0: /* Extend */
  2491. extend = v>>2;
  2492. break;
  2493. case 1: /* Transparent */
  2494. len = (v>>2) + 1 + (extend<<6);
  2495. extend = 0;
  2496. transparent_run:
  2497. if (len > ww)
  2498. len = ww;
  2499. ww -= len;
  2500. ddp += len;
  2501. break;
  2502. case 2: /* Solid */
  2503. eol = v & 4;
  2504. len = (v>>3) + 1 + (extend<<5);
  2505. extend = 0;
  2506. solid_run:
  2507. if (len > ww)
  2508. len = ww;
  2509. ww -= len;
  2510. do
  2511. {
  2512. *ddp++ = 0xFF;
  2513. }
  2514. while (--len);
  2515. break;
  2516. default: /* Intermediate */
  2517. eol = v & 4;
  2518. len = (v>>3) + 1 + (extend<<5);
  2519. extend = 0;
  2520. intermediate_run:
  2521. if (len > ww)
  2522. len = ww;
  2523. ww -= len;
  2524. do
  2525. {
  2526. int a = *runp++;
  2527. v = *ddp;
  2528. if (v == 0)
  2529. {
  2530. *ddp++ = a;
  2531. }
  2532. else
  2533. {
  2534. a = FZ_EXPAND(a);
  2535. *ddp = FZ_BLEND(0xFF, v, a);
  2536. ddp++;
  2537. }
  2538. }
  2539. while (--len);
  2540. break;
  2541. }
  2542. if (eol)
  2543. break;
  2544. }
  2545. }
  2546. dp += span;
  2547. }
  2548. }
  2549. static inline void
  2550. fz_paint_glyph_mask_alpha(int span, unsigned char *dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y, unsigned char alpha)
  2551. {
  2552. while (h--)
  2553. {
  2554. int skip_xx, ww, len, extend;
  2555. const unsigned char *runp;
  2556. unsigned char *ddp = dp;
  2557. int offset = ((const int *)(glyph->data))[skip_y++];
  2558. if (offset >= 0)
  2559. {
  2560. int eol = 0;
  2561. runp = &glyph->data[offset];
  2562. extend = 0;
  2563. ww = w;
  2564. skip_xx = skip_x;
  2565. while (skip_xx)
  2566. {
  2567. int v = *runp++;
  2568. switch (v & 3)
  2569. {
  2570. case 0: /* Extend */
  2571. extend = v>>2;
  2572. len = 0;
  2573. break;
  2574. case 1: /* Transparent */
  2575. len = (v>>2) + 1 + (extend<<6);
  2576. extend = 0;
  2577. if (len > skip_xx)
  2578. {
  2579. len -= skip_xx;
  2580. goto transparent_run;
  2581. }
  2582. break;
  2583. case 2: /* Solid */
  2584. eol = v & 4;
  2585. len = (v>>3) + 1 + (extend<<5);
  2586. extend = 0;
  2587. if (len > skip_xx)
  2588. {
  2589. len -= skip_xx;
  2590. goto solid_run;
  2591. }
  2592. break;
  2593. default: /* Intermediate */
  2594. eol = v & 4;
  2595. len = (v>>3) + 1 + (extend<<5);
  2596. extend = 0;
  2597. if (len > skip_xx)
  2598. {
  2599. runp += skip_xx;
  2600. len -= skip_xx;
  2601. goto intermediate_run;
  2602. }
  2603. runp += len;
  2604. break;
  2605. }
  2606. if (eol)
  2607. {
  2608. ww = 0;
  2609. break;
  2610. }
  2611. skip_xx -= len;
  2612. }
  2613. while (ww > 0)
  2614. {
  2615. int v = *runp++;
  2616. switch(v & 3)
  2617. {
  2618. case 0: /* Extend */
  2619. extend = v>>2;
  2620. break;
  2621. case 1: /* Transparent */
  2622. len = (v>>2) + 1 + (extend<<6);
  2623. extend = 0;
  2624. transparent_run:
  2625. if (len > ww)
  2626. len = ww;
  2627. ww -= len;
  2628. ddp += len;
  2629. break;
  2630. case 2: /* Solid */
  2631. eol = v & 4;
  2632. len = (v>>3) + 1 + (extend<<5);
  2633. extend = 0;
  2634. solid_run:
  2635. if (len > ww)
  2636. len = ww;
  2637. ww -= len;
  2638. do
  2639. {
  2640. *ddp++ = alpha;
  2641. }
  2642. while (--len);
  2643. break;
  2644. default: /* Intermediate */
  2645. eol = v & 4;
  2646. len = (v>>3) + 1 + (extend<<5);
  2647. extend = 0;
  2648. intermediate_run:
  2649. if (len > ww)
  2650. len = ww;
  2651. ww -= len;
  2652. do
  2653. {
  2654. int a = *runp++;
  2655. v = *ddp;
  2656. if (v == 0)
  2657. {
  2658. *ddp++ = fz_mul255(a, alpha);
  2659. }
  2660. else
  2661. {
  2662. a = FZ_EXPAND(a);
  2663. *ddp = FZ_BLEND(alpha, v, a);
  2664. ddp++;
  2665. }
  2666. }
  2667. while (--len);
  2668. break;
  2669. }
  2670. if (eol)
  2671. break;
  2672. }
  2673. }
  2674. dp += span;
  2675. }
  2676. }
  2677. #define N 1
  2678. #include "paint-glyph.h"
  2679. #define ALPHA
  2680. #define N 1
  2681. #include "paint-glyph.h"
  2682. #if FZ_PLOTTERS_G
  2683. #define DA
  2684. #define N 1
  2685. #include "paint-glyph.h"
  2686. #define DA
  2687. #define ALPHA
  2688. #define N 1
  2689. #include "paint-glyph.h"
  2690. #endif /* FZ_PLOTTERS_G */
  2691. #if FZ_PLOTTERS_RGB
  2692. #define DA
  2693. #define N 3
  2694. #include "paint-glyph.h"
  2695. #define DA
  2696. #define ALPHA
  2697. #define N 3
  2698. #include "paint-glyph.h"
  2699. #define N 3
  2700. #include "paint-glyph.h"
  2701. #define ALPHA
  2702. #define N 3
  2703. #include "paint-glyph.h"
  2704. #endif /* FZ_PLOTTERS_RGB */
  2705. #if FZ_PLOTTERS_CMYK
  2706. #define DA
  2707. #define N 4
  2708. #include "paint-glyph.h"
  2709. #define DA
  2710. #define ALPHA
  2711. #define N 4
  2712. #include "paint-glyph.h"
  2713. #define ALPHA
  2714. #define N 4
  2715. #include "paint-glyph.h"
  2716. #define N 4
  2717. #include "paint-glyph.h"
  2718. #endif /* FZ_PLOTTERS_CMYK */
  2719. #if FZ_PLOTTERS_N
  2720. #define ALPHA
  2721. #include "paint-glyph.h"
  2722. #define DA
  2723. #include "paint-glyph.h"
  2724. #define DA
  2725. #define ALPHA
  2726. #include "paint-glyph.h"
  2727. #include "paint-glyph.h"
  2728. #endif /* FZ_PLOTTERS_N */
  2729. #if FZ_ENABLE_SPOT_RENDERING
  2730. #define ALPHA
  2731. #define EOP
  2732. #include "paint-glyph.h"
  2733. #define DA
  2734. #define EOP
  2735. #include "paint-glyph.h"
  2736. #define DA
  2737. #define ALPHA
  2738. #define EOP
  2739. #include "paint-glyph.h"
  2740. #define EOP
  2741. #include "paint-glyph.h"
  2742. #endif /* FZ_ENABLE_SPOT_RENDERING */
  2743. static void
  2744. fz_paint_glyph_alpha(const unsigned char * FZ_RESTRICT colorbv, int n, int span, unsigned char * FZ_RESTRICT dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop)
  2745. {
  2746. #if FZ_ENABLE_SPOT_RENDERING
  2747. if (fz_overprint_required(eop))
  2748. {
  2749. if (da)
  2750. fz_paint_glyph_alpha_N_da_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
  2751. else
  2752. fz_paint_glyph_alpha_N_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
  2753. return;
  2754. }
  2755. #endif /* FZ_ENABLE_SPOT_RENDERING */
  2756. switch (n)
  2757. {
  2758. case 1:
  2759. if (da)
  2760. #if FZ_PLOTTERS_G
  2761. fz_paint_glyph_alpha_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2762. #else
  2763. goto fallback;
  2764. #endif /* FZ_PLOTTERS_G */
  2765. else
  2766. fz_paint_glyph_alpha_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2767. break;
  2768. #if FZ_PLOTTERS_RGB
  2769. case 3:
  2770. if (da)
  2771. fz_paint_glyph_alpha_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2772. else
  2773. fz_paint_glyph_alpha_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2774. break;
  2775. #endif /* FZ_PLOTTERS_RGB */
  2776. #if FZ_PLOTTERS_CMYK
  2777. case 4:
  2778. if (da)
  2779. fz_paint_glyph_alpha_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2780. else
  2781. fz_paint_glyph_alpha_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2782. break;
  2783. #endif /* FZ_PLOTTERS_CMYK */
  2784. default:
  2785. {
  2786. #if !FZ_PLOTTERS_G
  2787. fallback:{}
  2788. #endif /* !FZ_PLOTTERS_G */
  2789. #if FZ_PLOTTERS_N
  2790. if (da)
  2791. fz_paint_glyph_alpha_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
  2792. else
  2793. fz_paint_glyph_alpha_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
  2794. #endif /* FZ_PLOTTERS_N */
  2795. break;
  2796. }
  2797. }
  2798. }
  2799. static void
  2800. fz_paint_glyph_solid(const unsigned char * FZ_RESTRICT colorbv, int n, int span, unsigned char * FZ_RESTRICT dp, int da, const fz_glyph * FZ_RESTRICT glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop)
  2801. {
  2802. #if FZ_ENABLE_SPOT_RENDERING
  2803. if (fz_overprint_required(eop))
  2804. {
  2805. if (da)
  2806. fz_paint_glyph_solid_N_da_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
  2807. else
  2808. fz_paint_glyph_solid_N_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
  2809. return;
  2810. }
  2811. #endif /* FZ_ENABLE_SPOT_RENDERING */
  2812. switch (n)
  2813. {
  2814. case 1:
  2815. if (da)
  2816. #if FZ_PLOTTERS_G
  2817. fz_paint_glyph_solid_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2818. #else
  2819. goto fallback;
  2820. #endif /* FZ_PLOTTERS_G */
  2821. else
  2822. fz_paint_glyph_solid_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2823. break;
  2824. #if FZ_PLOTTERS_RGB
  2825. case 3:
  2826. if (da)
  2827. fz_paint_glyph_solid_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2828. else
  2829. fz_paint_glyph_solid_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2830. break;
  2831. #endif /* FZ_PLOTTERS_RGB */
  2832. #if FZ_PLOTTERS_CMYK
  2833. case 4:
  2834. if (da)
  2835. fz_paint_glyph_solid_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2836. else
  2837. fz_paint_glyph_solid_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
  2838. break;
  2839. #endif /* FZ_PLOTTERS_CMYK */
  2840. default:
  2841. {
  2842. #if !FZ_PLOTTERS_G
  2843. fallback:{}
  2844. #endif /* FZ_PLOTTERS_G */
  2845. #if FZ_PLOTTERS_N
  2846. if (da)
  2847. fz_paint_glyph_solid_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
  2848. else
  2849. fz_paint_glyph_solid_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
  2850. break;
  2851. #endif /* FZ_PLOTTERS_N */
  2852. }
  2853. }
  2854. }
  2855. void
  2856. fz_paint_glyph(const unsigned char * FZ_RESTRICT colorbv, fz_pixmap * FZ_RESTRICT dst, unsigned char * FZ_RESTRICT dp, const fz_glyph * FZ_RESTRICT glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop)
  2857. {
  2858. int n = dst->n - dst->alpha;
  2859. if (dst->colorspace)
  2860. {
  2861. assert(n > 0);
  2862. if (colorbv[n] == 255)
  2863. fz_paint_glyph_solid(colorbv, n, dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, eop);
  2864. else if (colorbv[n] != 0)
  2865. fz_paint_glyph_alpha(colorbv, n, dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, eop);
  2866. }
  2867. else
  2868. {
  2869. assert(dst->alpha && dst->n == 1 && dst->colorspace == NULL && !fz_overprint_required(eop));
  2870. if (colorbv == NULL || colorbv[0] == 255)
  2871. fz_paint_glyph_mask(dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y);
  2872. else
  2873. fz_paint_glyph_mask_alpha(dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, colorbv[0]);
  2874. }
  2875. }