summaryrefslogtreecommitdiffstats
path: root/src/livarot/AlphaLigne.h
blob: a192e1cb3b0fd89c79ecee88fd13c1014e1087a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
 * TODO: insert short description here
 *//*
 * Authors:
 * see git history
 * Fred
 *
 * Copyright (C) 2018 Authors
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#ifndef my_alpha_ligne
#define my_alpha_ligne

#include "LivarotDefs.h"

/*
 * pixel coverage of a line, libart style: each pixel coverage is obtained from the coverage of the previous one by
 * adding a delta given by a step. the goal is to have only a limited number of positions where the delta != 0, so that
 * you only have to store a limited number of steps.
 */

// a step
struct alpha_step {
	int           x;     // position
	float         delta; // increase or decrease in pixel coverage with respect to the coverage of the previous pixel
};


class AlphaLigne {
public:
  // bounds of the line
  // necessary since the visible portion of the canvas is bounded, and you need to compute
  // the value of the pixel "just before the visible portion of the line"
	int          min,max;
	int          length;

  // before is the step containing the delta relative to a pixel infinitely far on the left of the line
  // thus the initial pixel coverage is before.delta
	alpha_step   before,after;
  // array of steps
	int          nbStep,maxStep;
	alpha_step*  steps;
	
  // bounds of the portion of the line that has received some coverage
	int          curMin,curMax;

  // iMin and iMax are the bounds of the visible portion of the line
	AlphaLigne(int iMin,int iMax);
    virtual ~AlphaLigne();

  // empties the line
	void             Reset();
  
  // add some coverage.
  // pente is (eval-sval)/(epos-spos), because you can compute it once per edge, and thus spare the
  // CPU some potentially costly divisions
	int              AddBord(float spos,float sval,float epos,float eval,float iPente);
  // version where you don't have the pente parameter
	int              AddBord(float spos,float sval,float epos,float eval);

  // sorts the steps in increasing order. needed before you raster the line
	void             Flatten();
	
  // debug dump of the steps
	void						 Affiche();

  // private
	void             AddRun(int st,float pente);

  // raster the line in the buffer given in "dest", with the rasterization primitive worker
  // worker() is given the color parameter each time it is called. the type of the function is 
  // defined in LivarotDefs.h
	void             Raster(raster_info &dest,void* color,RasterInRunFunc worker);
	
  // also private. that's the comparison function given to qsort()
	static int       CmpStep(const void * p1, const void * p2) {
		alpha_step* d1=(alpha_step*)p1;
		alpha_step* d2=(alpha_step*)p2;
		return  d1->x - d2->x ;
	};
};


#endif