draw-mesh.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. // Copyright (C) 2004-2021 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 "color-imp.h"
  24. #include "draw-imp.h"
  25. #include "pixmap-imp.h"
  26. #include <assert.h>
  27. #include <math.h>
  28. enum { MAXN = 2 + FZ_MAX_COLORS };
  29. static void paint_scan(fz_pixmap *FZ_RESTRICT pix, int y, int fx0, int fx1, int cx0, int cx1, const int *FZ_RESTRICT v0, const int *FZ_RESTRICT v1, int n)
  30. {
  31. unsigned char *p;
  32. int c[MAXN], dc[MAXN];
  33. int k, w;
  34. float div, mul;
  35. int x0, x1, pa;
  36. /* Ensure that fx0 is left edge, and fx1 is right */
  37. if (fx0 > fx1)
  38. {
  39. const int *v;
  40. int t = fx0; fx0 = fx1; fx1 = t;
  41. v = v0; v0 = v1; v1 = v;
  42. }
  43. else if (fx0 == fx1)
  44. return;
  45. /* Clip fx0, fx1 to range */
  46. if (fx0 >= cx1)
  47. return;
  48. if (fx1 <= cx0)
  49. return;
  50. x0 = (fx0 > cx0 ? fx0 : cx0);
  51. x1 = (fx1 < cx1 ? fx1 : cx1);
  52. w = x1 - x0;
  53. if (w == 0)
  54. return;
  55. div = 1.0f / (fx1 - fx0);
  56. mul = (x0 - fx0);
  57. for (k = 0; k < n; k++)
  58. {
  59. dc[k] = (v1[k] - v0[k]) * div;
  60. c[k] = v0[k] + dc[k] * mul;
  61. }
  62. p = pix->samples + ((x0 - pix->x) * pix->n) + ((y - pix->y) * pix->stride);
  63. pa = pix->alpha;
  64. do
  65. {
  66. for (k = 0; k < n; k++)
  67. {
  68. *p++ = c[k]>>16;
  69. c[k] += dc[k];
  70. }
  71. if (pa)
  72. *p++ = 255;
  73. }
  74. while (--w);
  75. }
  76. typedef struct
  77. {
  78. float x;
  79. float dx;
  80. int v[2*MAXN];
  81. } edge_data;
  82. static inline void prepare_edge(const float *FZ_RESTRICT vtop, const float *FZ_RESTRICT vbot, edge_data *FZ_RESTRICT edge, float y, int n)
  83. {
  84. float r = 1.0f / (vbot[1] - vtop[1]);
  85. float t = (y - vtop[1]) * r;
  86. float diff = vbot[0] - vtop[0];
  87. int i;
  88. edge->x = vtop[0] + diff * t;
  89. edge->dx = diff * r;
  90. for (i = 0; i < n; i++)
  91. {
  92. diff = vbot[i+2] - vtop[i+2];
  93. edge->v[i] = (int)(65536.0f * (vtop[i+2] + diff * t));
  94. edge->v[i+MAXN] = (int)(65536.0f * diff * r);
  95. }
  96. }
  97. static inline void step_edge(edge_data *edge, int n)
  98. {
  99. int i;
  100. edge->x += edge->dx;
  101. for (i = 0; i < n; i++)
  102. {
  103. edge->v[i] += edge->v[i + MAXN];
  104. }
  105. }
  106. static void
  107. fz_paint_triangle(fz_pixmap *pix, float *v[3], int n, fz_irect bbox)
  108. {
  109. edge_data e0, e1;
  110. int top, mid, bot;
  111. float y, y1;
  112. int minx, maxx;
  113. top = bot = 0;
  114. if (v[1][1] < v[0][1]) top = 1; else bot = 1;
  115. if (v[2][1] < v[top][1]) top = 2;
  116. else if (v[2][1] > v[bot][1]) bot = 2;
  117. if (v[top][1] == v[bot][1]) return;
  118. /* Test if the triangle is completely outside the scissor rect */
  119. if (v[bot][1] < bbox.y0) return;
  120. if (v[top][1] > bbox.y1) return;
  121. /* Magic! Ensure that mid/top/bot are all different */
  122. mid = 3^top^bot;
  123. assert(top != bot && top != mid && mid != bot);
  124. minx = fz_maxi(bbox.x0, pix->x);
  125. maxx = fz_mini(bbox.x1, pix->x + pix->w);
  126. y = ceilf(fz_max(bbox.y0, v[top][1]));
  127. y1 = ceilf(fz_min(bbox.y1, v[mid][1]));
  128. n -= 2;
  129. prepare_edge(v[top], v[bot], &e0, y, n);
  130. if (y < y1)
  131. {
  132. prepare_edge(v[top], v[mid], &e1, y, n);
  133. do
  134. {
  135. paint_scan(pix, y, (int)e0.x, (int)e1.x, minx, maxx, &e0.v[0], &e1.v[0], n);
  136. step_edge(&e0, n);
  137. step_edge(&e1, n);
  138. y ++;
  139. }
  140. while (y < y1);
  141. }
  142. y1 = ceilf(fz_min(bbox.y1, v[bot][1]));
  143. if (y < y1)
  144. {
  145. prepare_edge(v[mid], v[bot], &e1, y, n);
  146. do
  147. {
  148. paint_scan(pix, y, (int)e0.x, (int)e1.x, minx, maxx, &e0.v[0], &e1.v[0], n);
  149. y ++;
  150. if (y >= y1)
  151. break;
  152. step_edge(&e0, n);
  153. step_edge(&e1, n);
  154. }
  155. while (1);
  156. }
  157. }
  158. struct paint_tri_data
  159. {
  160. const fz_shade *shade;
  161. fz_pixmap *dest;
  162. fz_irect bbox;
  163. fz_color_converter cc;
  164. };
  165. static void
  166. prepare_mesh_vertex(fz_context *ctx, void *arg, fz_vertex *v, const float *input)
  167. {
  168. struct paint_tri_data *ptd = (struct paint_tri_data *)arg;
  169. const fz_shade *shade = ptd->shade;
  170. fz_pixmap *dest = ptd->dest;
  171. float *output = v->c;
  172. int i;
  173. if (shade->function_stride)
  174. {
  175. float f = input[0];
  176. if (shade->type >= 4 && shade->type <= 7)
  177. f = (f - shade->u.m.c0[0]) / (shade->u.m.c1[0] - shade->u.m.c0[0]);
  178. output[0] = f * 255;
  179. }
  180. else
  181. {
  182. int n = fz_colorspace_n(ctx, dest->colorspace);
  183. int a = dest->alpha;
  184. int m = dest->n - a;
  185. for (i = n; i < m; i++)
  186. output[i] = 0;
  187. if (ptd->cc.convert)
  188. ptd->cc.convert(ctx, &ptd->cc, input, output);
  189. for (i = 0; i < m; i++)
  190. output[i] *= 255;
  191. if (a)
  192. output[m] = 255;
  193. }
  194. }
  195. static void
  196. do_paint_tri(fz_context *ctx, void *arg, fz_vertex *av, fz_vertex *bv, fz_vertex *cv)
  197. {
  198. struct paint_tri_data *ptd = (struct paint_tri_data *)arg;
  199. float *vertices[3];
  200. fz_pixmap *dest;
  201. vertices[0] = (float *)av;
  202. vertices[1] = (float *)bv;
  203. vertices[2] = (float *)cv;
  204. dest = ptd->dest;
  205. fz_paint_triangle(dest, vertices, 2 + dest->n - dest->alpha, ptd->bbox);
  206. }
  207. struct fz_shade_color_cache
  208. {
  209. fz_colorspace *src;
  210. fz_colorspace *dst;
  211. fz_color_params params;
  212. int full;
  213. fz_color_converter cached;
  214. fz_colorspace *src2;
  215. fz_colorspace *dst2;
  216. fz_color_params params2;
  217. int full2;
  218. fz_color_converter cached2;
  219. };
  220. void
  221. fz_drop_shade_color_cache(fz_context *ctx, fz_shade_color_cache *cache)
  222. {
  223. if (cache == NULL)
  224. return;
  225. fz_drop_colorspace(ctx, cache->src);
  226. fz_drop_colorspace(ctx, cache->dst);
  227. if (cache->full)
  228. fz_fin_cached_color_converter(ctx, &cache->cached);
  229. fz_drop_colorspace(ctx, cache->src2);
  230. fz_drop_colorspace(ctx, cache->dst2);
  231. if (cache->full2)
  232. fz_drop_color_converter(ctx, &cache->cached2);
  233. fz_free(ctx, cache);
  234. }
  235. void
  236. fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_colorspace *colorspace, fz_matrix ctm, fz_pixmap *dest, fz_color_params color_params, fz_irect bbox, const fz_overprint *eop, fz_shade_color_cache **color_cache)
  237. {
  238. unsigned char clut[256][FZ_MAX_COLORS];
  239. fz_pixmap *temp = NULL;
  240. fz_pixmap *conv = NULL;
  241. fz_color_converter cc = { 0 };
  242. float color[FZ_MAX_COLORS];
  243. struct paint_tri_data ptd = { 0 };
  244. int i, k;
  245. fz_matrix local_ctm;
  246. fz_shade_color_cache *cache = NULL;
  247. int recache = 0;
  248. int recache2 = 0;
  249. int stride = shade->function_stride;
  250. fz_var(temp);
  251. fz_var(conv);
  252. fz_var(recache);
  253. fz_var(recache2);
  254. fz_var(cc);
  255. if (colorspace == NULL)
  256. colorspace = shade->colorspace;
  257. if (color_cache)
  258. {
  259. cache = *color_cache;
  260. if (cache == NULL)
  261. *color_cache = cache = fz_malloc_struct(ctx, fz_shade_color_cache);
  262. }
  263. fz_try(ctx)
  264. {
  265. local_ctm = fz_concat(shade->matrix, ctm);
  266. if (stride)
  267. {
  268. /* We need to use alpha = 1 here, because the shade might not fill the bbox. */
  269. temp = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), bbox, NULL, 1);
  270. fz_clear_pixmap(ctx, temp);
  271. }
  272. else
  273. {
  274. temp = dest;
  275. }
  276. ptd.dest = temp;
  277. ptd.shade = shade;
  278. ptd.bbox = bbox;
  279. if (temp->colorspace)
  280. {
  281. if (cache && cache->full && cache->src == colorspace && cache->dst == temp->colorspace &&
  282. cache->params.op == color_params.op &&
  283. cache->params.opm == color_params.opm &&
  284. cache->params.ri == color_params.ri)
  285. {
  286. ptd.cc = cache->cached;
  287. cache->full = 0;
  288. }
  289. else
  290. fz_init_cached_color_converter(ctx, &ptd.cc, colorspace, temp->colorspace, temp->seps, NULL, color_params);
  291. /* Drop the existing contents of the cache. */
  292. if (cache)
  293. {
  294. fz_drop_colorspace(ctx, cache->src);
  295. cache->src = NULL;
  296. fz_drop_colorspace(ctx, cache->dst);
  297. cache->dst = NULL;
  298. if (cache->full)
  299. fz_fin_cached_color_converter(ctx, &cache->cached);
  300. cache->full = 0;
  301. /* Remember that we can put stuff back into the cache. */
  302. recache = 1;
  303. }
  304. }
  305. fz_process_shade(ctx, shade, local_ctm, fz_rect_from_irect(bbox), prepare_mesh_vertex, &do_paint_tri, &ptd);
  306. if (stride)
  307. {
  308. /* If the shade is defined in a deviceN (or separation,
  309. * which is the same internally to MuPDF) space, then
  310. * we need to render it in deviceN before painting it
  311. * to the destination. If not, we are free to render it
  312. * direct to the target. */
  313. if (fz_colorspace_is_device_n(ctx, colorspace))
  314. {
  315. /* We've drawn it as greyscale, with the values being
  316. * the input to the function. Now make DevN version
  317. * by mapping that greyscale through the function.
  318. * This seems inefficient, but it's actually required,
  319. * because we need to apply the function lookup POST
  320. * interpolation in the do_paint_tri routines, not
  321. * before it to avoid problems with some test files
  322. * (tests/GhentV3.0/061_Shading_x1a.pdf for example).
  323. */
  324. unsigned char *s = temp->samples;
  325. unsigned char *d;
  326. int hh = temp->h;
  327. int n = fz_colorspace_n(ctx, colorspace);
  328. /* alpha = 1 here for the same reason as earlier */
  329. conv = fz_new_pixmap_with_bbox(ctx, colorspace, bbox, NULL, 1);
  330. d = conv->samples;
  331. while (hh--)
  332. {
  333. int len = temp->w;
  334. while (len--)
  335. {
  336. int v = *s++;
  337. int a = *s++;
  338. const float *f = &shade->function[v*stride];
  339. for (k = 0; k < n; k++)
  340. *d++ = fz_clampi(255 * f[k], 0, 255);
  341. *d++ = a;
  342. }
  343. d += conv->stride - conv->w * (size_t)conv->n;
  344. s += temp->stride - temp->w * (size_t)temp->n;
  345. }
  346. fz_drop_pixmap(ctx, temp);
  347. temp = conv;
  348. conv = NULL;
  349. /* Now Change from our device_n colorspace into the target colorspace/spots. */
  350. conv = fz_clone_pixmap_area_with_different_seps(ctx, temp, NULL, dest->colorspace, dest->seps, color_params, NULL);
  351. }
  352. else
  353. {
  354. unsigned char *s = temp->samples;
  355. unsigned char *d;
  356. int da;
  357. int sa = temp->alpha;
  358. int hh = temp->h;
  359. int cn = fz_colorspace_n(ctx, colorspace);
  360. int m = dest->n - dest->alpha;
  361. int n = fz_colorspace_n(ctx, dest->colorspace);
  362. if (dest->colorspace)
  363. {
  364. if (cache && cache->full2 && cache->src2 == colorspace && cache->dst2 == dest->colorspace &&
  365. cache->params2.op == color_params.op &&
  366. cache->params2.opm == color_params.opm &&
  367. cache->params2.ri == color_params.ri)
  368. {
  369. cc = cache->cached2;
  370. cache->full2 = 0;
  371. }
  372. else
  373. fz_find_color_converter(ctx, &cc, colorspace, dest->colorspace, dest->seps, NULL, color_params);
  374. /* Drop the existing contents of the cache */
  375. if (cache)
  376. {
  377. fz_drop_colorspace(ctx, cache->src2);
  378. cache->src2 = NULL;
  379. fz_drop_colorspace(ctx, cache->dst2);
  380. cache->dst2 = NULL;
  381. if (cache->full2)
  382. fz_drop_color_converter(ctx, &cache->cached2);
  383. cache->full2 = 0;
  384. /* Remember that we can put stuff back into the cache. */
  385. recache2 = 1;
  386. }
  387. for (i = 0; i < 256; i++)
  388. {
  389. cc.convert(ctx, &cc, &shade->function[i*stride], color);
  390. for (k = 0; k < n; k++)
  391. clut[i][k] = color[k] * 255;
  392. for (; k < m; k++)
  393. clut[i][k] = 0;
  394. clut[i][k] = shade->function[i*stride + cn] * 255;
  395. }
  396. }
  397. else
  398. {
  399. for (i = 0; i < 256; i++)
  400. {
  401. for (k = 0; k < m; k++)
  402. clut[i][k] = 0;
  403. clut[i][k] = shade->function[i*stride + cn] * 255;
  404. }
  405. }
  406. conv = fz_new_pixmap_with_bbox(ctx, dest->colorspace, bbox, dest->seps, 1);
  407. d = conv->samples;
  408. da = conv->alpha;
  409. while (hh--)
  410. {
  411. int len = temp->w;
  412. while (len--)
  413. {
  414. int v = *s++;
  415. int a = (da ? clut[v][conv->n - 1] : 255);
  416. if (sa)
  417. a = fz_mul255(*s++, a);
  418. for (k = 0; k < conv->n - da; k++)
  419. *d++ = fz_mul255(clut[v][k], a);
  420. if (da)
  421. *d++ = a;
  422. }
  423. d += conv->stride - conv->w * (size_t)conv->n;
  424. s += temp->stride - temp->w * (size_t)temp->n;
  425. }
  426. }
  427. fz_paint_pixmap_with_overprint(dest, conv, eop);
  428. }
  429. }
  430. fz_always(ctx)
  431. {
  432. if (recache)
  433. {
  434. cache->src = fz_keep_colorspace(ctx, colorspace);
  435. cache->dst = fz_keep_colorspace(ctx, temp->colorspace);
  436. cache->params = color_params;
  437. cache->cached = ptd.cc;
  438. cache->full = 1;
  439. }
  440. else
  441. fz_fin_cached_color_converter(ctx, &ptd.cc);
  442. if (stride)
  443. {
  444. if (recache2)
  445. {
  446. cache->src2 = fz_keep_colorspace(ctx, colorspace);
  447. cache->dst2 = fz_keep_colorspace(ctx, dest->colorspace);
  448. cache->params2 = color_params;
  449. cache->cached2 = cc;
  450. cache->full2 = 1;
  451. }
  452. else
  453. fz_drop_color_converter(ctx, &cc);
  454. fz_drop_pixmap(ctx, temp);
  455. fz_drop_pixmap(ctx, conv);
  456. }
  457. }
  458. fz_catch(ctx)
  459. fz_rethrow(ctx);
  460. }