agg_renderer_scanline.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. //----------------------------------------------------------------------------
  2. // Anti-Grain Geometry - Version 2.4
  3. // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  4. //
  5. // Permission to copy, use, modify, sell and distribute this software
  6. // is granted provided this copyright notice appears in all copies.
  7. // This software is provided "as is" without express or implied
  8. // warranty, and with no claim as to its suitability for any purpose.
  9. //
  10. //----------------------------------------------------------------------------
  11. // Contact: mcseem@antigrain.com
  12. // mcseemagg@yahoo.com
  13. // http://www.antigrain.com
  14. //----------------------------------------------------------------------------
  15. #ifndef AGG_RENDERER_SCANLINE_INCLUDED
  16. #define AGG_RENDERER_SCANLINE_INCLUDED
  17. #include "agg_basics.h"
  18. #include "agg_renderer_base.h"
  19. namespace agg
  20. {
  21. //================================================render_scanline_aa_solid
  22. template<class Scanline, class BaseRenderer, class ColorT>
  23. void render_scanline_aa_solid(const Scanline& sl,
  24. BaseRenderer& ren,
  25. const ColorT& color)
  26. {
  27. int y = sl.y();
  28. unsigned num_spans = sl.num_spans();
  29. typename Scanline::const_iterator span = sl.begin();
  30. for(;;)
  31. {
  32. int x = span->x;
  33. if(span->len > 0)
  34. {
  35. ren.blend_solid_hspan(x, y, (unsigned)span->len,
  36. color,
  37. span->covers);
  38. }
  39. else
  40. {
  41. ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
  42. color,
  43. *(span->covers));
  44. }
  45. if(--num_spans == 0) break;
  46. ++span;
  47. }
  48. }
  49. //===============================================render_scanlines_aa_solid
  50. template<class Rasterizer, class Scanline,
  51. class BaseRenderer, class ColorT>
  52. void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
  53. BaseRenderer& ren, const ColorT& color)
  54. {
  55. if(ras.rewind_scanlines())
  56. {
  57. // Explicitly convert "color" to the BaseRenderer color type.
  58. // For example, it can be called with color type "rgba", while
  59. // "rgba8" is needed. Otherwise it will be implicitly
  60. // converted in the loop many times.
  61. //----------------------
  62. typename BaseRenderer::color_type ren_color(color);
  63. sl.reset(ras.min_x(), ras.max_x());
  64. while(ras.sweep_scanline(sl))
  65. {
  66. //render_scanline_aa_solid(sl, ren, ren_color);
  67. // This code is equivalent to the above call (copy/paste).
  68. // It's just a "manual" optimization for old compilers,
  69. // like Microsoft Visual C++ v6.0
  70. //-------------------------------
  71. int y = sl.y();
  72. unsigned num_spans = sl.num_spans();
  73. typename Scanline::const_iterator span = sl.begin();
  74. for(;;)
  75. {
  76. int x = span->x;
  77. if(span->len > 0)
  78. {
  79. ren.blend_solid_hspan(x, y, (unsigned)span->len,
  80. ren_color,
  81. span->covers);
  82. }
  83. else
  84. {
  85. ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
  86. ren_color,
  87. *(span->covers));
  88. }
  89. if(--num_spans == 0) break;
  90. ++span;
  91. }
  92. }
  93. }
  94. }
  95. //==============================================renderer_scanline_aa_solid
  96. template<class BaseRenderer> class renderer_scanline_aa_solid
  97. {
  98. public:
  99. typedef BaseRenderer base_ren_type;
  100. typedef typename base_ren_type::color_type color_type;
  101. //--------------------------------------------------------------------
  102. renderer_scanline_aa_solid() : m_ren(0) {}
  103. explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
  104. void attach(base_ren_type& ren)
  105. {
  106. m_ren = &ren;
  107. }
  108. //--------------------------------------------------------------------
  109. void color(const color_type& c) { m_color = c; }
  110. const color_type& color() const { return m_color; }
  111. //--------------------------------------------------------------------
  112. void prepare() {}
  113. //--------------------------------------------------------------------
  114. template<class Scanline> void render(const Scanline& sl)
  115. {
  116. render_scanline_aa_solid(sl, *m_ren, m_color);
  117. }
  118. private:
  119. base_ren_type* m_ren;
  120. color_type m_color;
  121. };
  122. //======================================================render_scanline_aa
  123. template<class Scanline, class BaseRenderer,
  124. class SpanAllocator, class SpanGenerator>
  125. void render_scanline_aa(const Scanline& sl, BaseRenderer& ren,
  126. SpanAllocator& alloc, SpanGenerator& span_gen)
  127. {
  128. int y = sl.y();
  129. unsigned num_spans = sl.num_spans();
  130. typename Scanline::const_iterator span = sl.begin();
  131. for(;;)
  132. {
  133. int x = span->x;
  134. int len = span->len;
  135. const typename Scanline::cover_type* covers = span->covers;
  136. if(len < 0) len = -len;
  137. typename BaseRenderer::color_type* colors = alloc.allocate(len);
  138. span_gen.generate(colors, x, y, len);
  139. ren.blend_color_hspan(x, y, len, colors,
  140. (span->len < 0) ? 0 : covers, *covers);
  141. if(--num_spans == 0) break;
  142. ++span;
  143. }
  144. }
  145. //=====================================================render_scanlines_aa
  146. template<class Rasterizer, class Scanline, class BaseRenderer,
  147. class SpanAllocator, class SpanGenerator>
  148. void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
  149. SpanAllocator& alloc, SpanGenerator& span_gen)
  150. {
  151. if(ras.rewind_scanlines())
  152. {
  153. sl.reset(ras.min_x(), ras.max_x());
  154. span_gen.prepare();
  155. while(ras.sweep_scanline(sl))
  156. {
  157. render_scanline_aa(sl, ren, alloc, span_gen);
  158. }
  159. }
  160. }
  161. //====================================================renderer_scanline_aa
  162. template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
  163. class renderer_scanline_aa
  164. {
  165. public:
  166. typedef BaseRenderer base_ren_type;
  167. typedef SpanAllocator alloc_type;
  168. typedef SpanGenerator span_gen_type;
  169. //--------------------------------------------------------------------
  170. renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
  171. renderer_scanline_aa(base_ren_type& ren,
  172. alloc_type& alloc,
  173. span_gen_type& span_gen) :
  174. m_ren(&ren),
  175. m_alloc(&alloc),
  176. m_span_gen(&span_gen)
  177. {}
  178. void attach(base_ren_type& ren,
  179. alloc_type& alloc,
  180. span_gen_type& span_gen)
  181. {
  182. m_ren = &ren;
  183. m_alloc = &alloc;
  184. m_span_gen = &span_gen;
  185. }
  186. //--------------------------------------------------------------------
  187. void prepare() { m_span_gen->prepare(); }
  188. //--------------------------------------------------------------------
  189. template<class Scanline> void render(const Scanline& sl)
  190. {
  191. render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
  192. }
  193. private:
  194. base_ren_type* m_ren;
  195. alloc_type* m_alloc;
  196. span_gen_type* m_span_gen;
  197. };
  198. //===============================================render_scanline_bin_solid
  199. template<class Scanline, class BaseRenderer, class ColorT>
  200. void render_scanline_bin_solid(const Scanline& sl,
  201. BaseRenderer& ren,
  202. const ColorT& color)
  203. {
  204. unsigned num_spans = sl.num_spans();
  205. typename Scanline::const_iterator span = sl.begin();
  206. for(;;)
  207. {
  208. ren.blend_hline(span->x,
  209. sl.y(),
  210. span->x - 1 + ((span->len < 0) ?
  211. -span->len :
  212. span->len),
  213. color,
  214. cover_full);
  215. if(--num_spans == 0) break;
  216. ++span;
  217. }
  218. }
  219. //==============================================render_scanlines_bin_solid
  220. template<class Rasterizer, class Scanline,
  221. class BaseRenderer, class ColorT>
  222. void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
  223. BaseRenderer& ren, const ColorT& color)
  224. {
  225. if(ras.rewind_scanlines())
  226. {
  227. // Explicitly convert "color" to the BaseRenderer color type.
  228. // For example, it can be called with color type "rgba", while
  229. // "rgba8" is needed. Otherwise it will be implicitly
  230. // converted in the loop many times.
  231. //----------------------
  232. typename BaseRenderer::color_type ren_color(color);
  233. sl.reset(ras.min_x(), ras.max_x());
  234. while(ras.sweep_scanline(sl))
  235. {
  236. //render_scanline_bin_solid(sl, ren, ren_color);
  237. // This code is equivalent to the above call (copy/paste).
  238. // It's just a "manual" optimization for old compilers,
  239. // like Microsoft Visual C++ v6.0
  240. //-------------------------------
  241. unsigned num_spans = sl.num_spans();
  242. typename Scanline::const_iterator span = sl.begin();
  243. for(;;)
  244. {
  245. ren.blend_hline(span->x,
  246. sl.y(),
  247. span->x - 1 + ((span->len < 0) ?
  248. -span->len :
  249. span->len),
  250. ren_color,
  251. cover_full);
  252. if(--num_spans == 0) break;
  253. ++span;
  254. }
  255. }
  256. }
  257. }
  258. //=============================================renderer_scanline_bin_solid
  259. template<class BaseRenderer> class renderer_scanline_bin_solid
  260. {
  261. public:
  262. typedef BaseRenderer base_ren_type;
  263. typedef typename base_ren_type::color_type color_type;
  264. //--------------------------------------------------------------------
  265. renderer_scanline_bin_solid() : m_ren(0) {}
  266. explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {}
  267. void attach(base_ren_type& ren)
  268. {
  269. m_ren = &ren;
  270. }
  271. //--------------------------------------------------------------------
  272. void color(const color_type& c) { m_color = c; }
  273. const color_type& color() const { return m_color; }
  274. //--------------------------------------------------------------------
  275. void prepare() {}
  276. //--------------------------------------------------------------------
  277. template<class Scanline> void render(const Scanline& sl)
  278. {
  279. render_scanline_bin_solid(sl, *m_ren, m_color);
  280. }
  281. private:
  282. base_ren_type* m_ren;
  283. color_type m_color;
  284. };
  285. //======================================================render_scanline_bin
  286. template<class Scanline, class BaseRenderer,
  287. class SpanAllocator, class SpanGenerator>
  288. void render_scanline_bin(const Scanline& sl, BaseRenderer& ren,
  289. SpanAllocator& alloc, SpanGenerator& span_gen)
  290. {
  291. int y = sl.y();
  292. unsigned num_spans = sl.num_spans();
  293. typename Scanline::const_iterator span = sl.begin();
  294. for(;;)
  295. {
  296. int x = span->x;
  297. int len = span->len;
  298. if(len < 0) len = -len;
  299. typename BaseRenderer::color_type* colors = alloc.allocate(len);
  300. span_gen.generate(colors, x, y, len);
  301. ren.blend_color_hspan(x, y, len, colors, 0, cover_full);
  302. if(--num_spans == 0) break;
  303. ++span;
  304. }
  305. }
  306. //=====================================================render_scanlines_bin
  307. template<class Rasterizer, class Scanline, class BaseRenderer,
  308. class SpanAllocator, class SpanGenerator>
  309. void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
  310. SpanAllocator& alloc, SpanGenerator& span_gen)
  311. {
  312. if(ras.rewind_scanlines())
  313. {
  314. sl.reset(ras.min_x(), ras.max_x());
  315. span_gen.prepare();
  316. while(ras.sweep_scanline(sl))
  317. {
  318. render_scanline_bin(sl, ren, alloc, span_gen);
  319. }
  320. }
  321. }
  322. //====================================================renderer_scanline_bin
  323. template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
  324. class renderer_scanline_bin
  325. {
  326. public:
  327. typedef BaseRenderer base_ren_type;
  328. typedef SpanAllocator alloc_type;
  329. typedef SpanGenerator span_gen_type;
  330. //--------------------------------------------------------------------
  331. renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {}
  332. renderer_scanline_bin(base_ren_type& ren,
  333. alloc_type& alloc,
  334. span_gen_type& span_gen) :
  335. m_ren(&ren),
  336. m_alloc(&alloc),
  337. m_span_gen(&span_gen)
  338. {}
  339. void attach(base_ren_type& ren,
  340. alloc_type& alloc,
  341. span_gen_type& span_gen)
  342. {
  343. m_ren = &ren;
  344. m_alloc = &alloc;
  345. m_span_gen = &span_gen;
  346. }
  347. //--------------------------------------------------------------------
  348. void prepare() { m_span_gen->prepare(); }
  349. //--------------------------------------------------------------------
  350. template<class Scanline> void render(const Scanline& sl)
  351. {
  352. render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
  353. }
  354. private:
  355. base_ren_type* m_ren;
  356. alloc_type* m_alloc;
  357. span_gen_type* m_span_gen;
  358. };
  359. //========================================================render_scanlines
  360. template<class Rasterizer, class Scanline, class Renderer>
  361. void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
  362. {
  363. if(ras.rewind_scanlines())
  364. {
  365. sl.reset(ras.min_x(), ras.max_x());
  366. ren.prepare();
  367. while(ras.sweep_scanline(sl))
  368. {
  369. ren.render(sl);
  370. }
  371. }
  372. }
  373. //========================================================render_all_paths
  374. template<class Rasterizer, class Scanline, class Renderer,
  375. class VertexSource, class ColorStorage, class PathId>
  376. void render_all_paths(Rasterizer& ras,
  377. Scanline& sl,
  378. Renderer& r,
  379. VertexSource& vs,
  380. const ColorStorage& as,
  381. const PathId& path_id,
  382. unsigned num_paths)
  383. {
  384. for(unsigned i = 0; i < num_paths; i++)
  385. {
  386. ras.reset();
  387. ras.add_path(vs, path_id[i]);
  388. r.color(as[i]);
  389. render_scanlines(ras, sl, r);
  390. }
  391. }
  392. //=============================================render_scanlines_compound
  393. template<class Rasterizer,
  394. class ScanlineAA,
  395. class ScanlineBin,
  396. class BaseRenderer,
  397. class SpanAllocator,
  398. class StyleHandler>
  399. void render_scanlines_compound(Rasterizer& ras,
  400. ScanlineAA& sl_aa,
  401. ScanlineBin& sl_bin,
  402. BaseRenderer& ren,
  403. SpanAllocator& alloc,
  404. StyleHandler& sh)
  405. {
  406. if(ras.rewind_scanlines())
  407. {
  408. int min_x = ras.min_x();
  409. int len = ras.max_x() - min_x + 2;
  410. sl_aa.reset(min_x, ras.max_x());
  411. sl_bin.reset(min_x, ras.max_x());
  412. typedef typename BaseRenderer::color_type color_type;
  413. color_type* color_span = alloc.allocate(len * 2);
  414. color_type* mix_buffer = color_span + len;
  415. unsigned num_spans;
  416. unsigned num_styles;
  417. unsigned style;
  418. bool solid;
  419. while((num_styles = ras.sweep_styles()) > 0)
  420. {
  421. typename ScanlineAA::const_iterator span_aa;
  422. if(num_styles == 1)
  423. {
  424. // Optimization for a single style. Happens often
  425. //-------------------------
  426. if(ras.sweep_scanline(sl_aa, 0))
  427. {
  428. style = ras.style(0);
  429. if(sh.is_solid(style))
  430. {
  431. // Just solid fill
  432. //-----------------------
  433. render_scanline_aa_solid(sl_aa, ren, sh.color(style));
  434. }
  435. else
  436. {
  437. // Arbitrary span generator
  438. //-----------------------
  439. span_aa = sl_aa.begin();
  440. num_spans = sl_aa.num_spans();
  441. for(;;)
  442. {
  443. len = span_aa->len;
  444. sh.generate_span(color_span,
  445. span_aa->x,
  446. sl_aa.y(),
  447. len,
  448. style);
  449. ren.blend_color_hspan(span_aa->x,
  450. sl_aa.y(),
  451. span_aa->len,
  452. color_span,
  453. span_aa->covers);
  454. if(--num_spans == 0) break;
  455. ++span_aa;
  456. }
  457. }
  458. }
  459. }
  460. else
  461. {
  462. if(ras.sweep_scanline(sl_bin, -1))
  463. {
  464. // Clear the spans of the mix_buffer
  465. //--------------------
  466. typename ScanlineBin::const_iterator span_bin = sl_bin.begin();
  467. num_spans = sl_bin.num_spans();
  468. for(;;)
  469. {
  470. memset(mix_buffer + span_bin->x - min_x,
  471. 0,
  472. span_bin->len * sizeof(color_type));
  473. if(--num_spans == 0) break;
  474. ++span_bin;
  475. }
  476. unsigned i;
  477. for(i = 0; i < num_styles; i++)
  478. {
  479. style = ras.style(i);
  480. solid = sh.is_solid(style);
  481. if(ras.sweep_scanline(sl_aa, i))
  482. {
  483. color_type* colors;
  484. color_type* cspan;
  485. typename ScanlineAA::cover_type* covers;
  486. span_aa = sl_aa.begin();
  487. num_spans = sl_aa.num_spans();
  488. if(solid)
  489. {
  490. // Just solid fill
  491. //-----------------------
  492. for(;;)
  493. {
  494. color_type c = sh.color(style);
  495. len = span_aa->len;
  496. colors = mix_buffer + span_aa->x - min_x;
  497. covers = span_aa->covers;
  498. do
  499. {
  500. if(*covers == cover_full)
  501. {
  502. *colors = c;
  503. }
  504. else
  505. {
  506. colors->add(c, *covers);
  507. }
  508. ++colors;
  509. ++covers;
  510. }
  511. while(--len);
  512. if(--num_spans == 0) break;
  513. ++span_aa;
  514. }
  515. }
  516. else
  517. {
  518. // Arbitrary span generator
  519. //-----------------------
  520. for(;;)
  521. {
  522. len = span_aa->len;
  523. colors = mix_buffer + span_aa->x - min_x;
  524. cspan = color_span;
  525. sh.generate_span(cspan,
  526. span_aa->x,
  527. sl_aa.y(),
  528. len,
  529. style);
  530. covers = span_aa->covers;
  531. do
  532. {
  533. if(*covers == cover_full)
  534. {
  535. *colors = *cspan;
  536. }
  537. else
  538. {
  539. colors->add(*cspan, *covers);
  540. }
  541. ++cspan;
  542. ++colors;
  543. ++covers;
  544. }
  545. while(--len);
  546. if(--num_spans == 0) break;
  547. ++span_aa;
  548. }
  549. }
  550. }
  551. }
  552. // Emit the blended result as a color hspan
  553. //-------------------------
  554. span_bin = sl_bin.begin();
  555. num_spans = sl_bin.num_spans();
  556. for(;;)
  557. {
  558. ren.blend_color_hspan(span_bin->x,
  559. sl_bin.y(),
  560. span_bin->len,
  561. mix_buffer + span_bin->x - min_x,
  562. 0,
  563. cover_full);
  564. if(--num_spans == 0) break;
  565. ++span_bin;
  566. }
  567. } // if(ras.sweep_scanline(sl_bin, -1))
  568. } // if(num_styles == 1) ... else
  569. } // while((num_styles = ras.sweep_styles()) > 0)
  570. } // if(ras.rewind_scanlines())
  571. }
  572. //=======================================render_scanlines_compound_layered
  573. template<class Rasterizer,
  574. class ScanlineAA,
  575. class BaseRenderer,
  576. class SpanAllocator,
  577. class StyleHandler>
  578. void render_scanlines_compound_layered(Rasterizer& ras,
  579. ScanlineAA& sl_aa,
  580. BaseRenderer& ren,
  581. SpanAllocator& alloc,
  582. StyleHandler& sh)
  583. {
  584. if(ras.rewind_scanlines())
  585. {
  586. int min_x = ras.min_x();
  587. int len = ras.max_x() - min_x + 2;
  588. sl_aa.reset(min_x, ras.max_x());
  589. typedef typename BaseRenderer::color_type color_type;
  590. color_type* color_span = alloc.allocate(len * 2);
  591. color_type* mix_buffer = color_span + len;
  592. cover_type* cover_buffer = ras.allocate_cover_buffer(len);
  593. unsigned num_spans;
  594. unsigned num_styles;
  595. unsigned style;
  596. bool solid;
  597. while((num_styles = ras.sweep_styles()) > 0)
  598. {
  599. typename ScanlineAA::const_iterator span_aa;
  600. if(num_styles == 1)
  601. {
  602. // Optimization for a single style. Happens often
  603. //-------------------------
  604. if(ras.sweep_scanline(sl_aa, 0))
  605. {
  606. style = ras.style(0);
  607. if(sh.is_solid(style))
  608. {
  609. // Just solid fill
  610. //-----------------------
  611. render_scanline_aa_solid(sl_aa, ren, sh.color(style));
  612. }
  613. else
  614. {
  615. // Arbitrary span generator
  616. //-----------------------
  617. span_aa = sl_aa.begin();
  618. num_spans = sl_aa.num_spans();
  619. for(;;)
  620. {
  621. len = span_aa->len;
  622. sh.generate_span(color_span,
  623. span_aa->x,
  624. sl_aa.y(),
  625. len,
  626. style);
  627. ren.blend_color_hspan(span_aa->x,
  628. sl_aa.y(),
  629. span_aa->len,
  630. color_span,
  631. span_aa->covers);
  632. if(--num_spans == 0) break;
  633. ++span_aa;
  634. }
  635. }
  636. }
  637. }
  638. else
  639. {
  640. int sl_start = ras.scanline_start();
  641. unsigned sl_len = ras.scanline_length();
  642. if(sl_len)
  643. {
  644. memset(mix_buffer + sl_start - min_x,
  645. 0,
  646. sl_len * sizeof(color_type));
  647. memset(cover_buffer + sl_start - min_x,
  648. 0,
  649. sl_len * sizeof(cover_type));
  650. int sl_y = 0x7FFFFFFF;
  651. unsigned i;
  652. for(i = 0; i < num_styles; i++)
  653. {
  654. style = ras.style(i);
  655. solid = sh.is_solid(style);
  656. if(ras.sweep_scanline(sl_aa, i))
  657. {
  658. unsigned cover;
  659. color_type* colors;
  660. color_type* cspan;
  661. cover_type* src_covers;
  662. cover_type* dst_covers;
  663. span_aa = sl_aa.begin();
  664. num_spans = sl_aa.num_spans();
  665. sl_y = sl_aa.y();
  666. if(solid)
  667. {
  668. // Just solid fill
  669. //-----------------------
  670. for(;;)
  671. {
  672. color_type c = sh.color(style);
  673. len = span_aa->len;
  674. colors = mix_buffer + span_aa->x - min_x;
  675. src_covers = span_aa->covers;
  676. dst_covers = cover_buffer + span_aa->x - min_x;
  677. do
  678. {
  679. cover = *src_covers;
  680. if(*dst_covers + cover > cover_full)
  681. {
  682. cover = cover_full - *dst_covers;
  683. }
  684. if(cover)
  685. {
  686. colors->add(c, cover);
  687. *dst_covers += cover;
  688. }
  689. ++colors;
  690. ++src_covers;
  691. ++dst_covers;
  692. }
  693. while(--len);
  694. if(--num_spans == 0) break;
  695. ++span_aa;
  696. }
  697. }
  698. else
  699. {
  700. // Arbitrary span generator
  701. //-----------------------
  702. for(;;)
  703. {
  704. len = span_aa->len;
  705. colors = mix_buffer + span_aa->x - min_x;
  706. cspan = color_span;
  707. sh.generate_span(cspan,
  708. span_aa->x,
  709. sl_aa.y(),
  710. len,
  711. style);
  712. src_covers = span_aa->covers;
  713. dst_covers = cover_buffer + span_aa->x - min_x;
  714. do
  715. {
  716. cover = *src_covers;
  717. if(*dst_covers + cover > cover_full)
  718. {
  719. cover = cover_full - *dst_covers;
  720. }
  721. if(cover)
  722. {
  723. colors->add(*cspan, cover);
  724. *dst_covers += cover;
  725. }
  726. ++cspan;
  727. ++colors;
  728. ++src_covers;
  729. ++dst_covers;
  730. }
  731. while(--len);
  732. if(--num_spans == 0) break;
  733. ++span_aa;
  734. }
  735. }
  736. }
  737. }
  738. ren.blend_color_hspan(sl_start,
  739. sl_y,
  740. sl_len,
  741. mix_buffer + sl_start - min_x,
  742. 0,
  743. cover_full);
  744. } //if(sl_len)
  745. } //if(num_styles == 1) ... else
  746. } //while((num_styles = ras.sweep_styles()) > 0)
  747. } //if(ras.rewind_scanlines())
  748. }
  749. }
  750. #endif