public void generate(RGBA_Bytes[] span, int spanIndex, int x, int y, int len)
		{
			m_rgba1.calc(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
			rgba_calc pc1 = m_rgba1;
			rgba_calc pc2 = m_rgba2;

			if (y <= m_y2)
			{
				// Bottom part of the triangle (first subtriangle)
				//-------------------------
				m_rgba2.calc(y + m_rgba2.m_1dy);
			}
			else
			{
				// Upper part (second subtriangle)
				m_rgba3.calc(y - m_rgba3.m_1dy);
				//-------------------------
				pc2 = m_rgba3;
			}

			if (m_swap)
			{
				// It means that the triangle is oriented clockwise,
				// so that we need to swap the controlling structures
				//-------------------------
				rgba_calc t = pc2;
				pc2 = pc1;
				pc1 = t;
			}

			// Get the horizontal length with subpixel accuracy
			// and protect it from division by zero
			//-------------------------
			int nlen = Math.Abs(pc2.m_x - pc1.m_x);
			if (nlen <= 0) nlen = 1;

			dda_line_interpolator r = new dda_line_interpolator(pc1.m_r, pc2.m_r, nlen, 14);
			dda_line_interpolator g = new dda_line_interpolator(pc1.m_g, pc2.m_g, nlen, 14);
			dda_line_interpolator b = new dda_line_interpolator(pc1.m_b, pc2.m_b, nlen, 14);
			dda_line_interpolator a = new dda_line_interpolator(pc1.m_a, pc2.m_a, nlen, 14);

			// Calculate the starting point of the gradient with subpixel
			// accuracy and correct (roll back) the interpolators.
			// This operation will also clip the beginning of the span
			// if necessary.
			//-------------------------
			int start = pc1.m_x - (x << (int)subpixel_scale_e.subpixel_shift);
			r.Prev(start);
			g.Prev(start);
			b.Prev(start);
			a.Prev(start);
			nlen += start;

			int vr, vg, vb, va;
			uint lim = 255;

			// Beginning part of the span. Since we rolled back the
			// interpolators, the color values may have overflowed.
			// So that, we render the beginning part with checking
			// for overflow. It lasts until "start" is positive;
			// typically it's 1-2 pixels, but may be more in some cases.
			//-------------------------
			while (len != 0 && start > 0)
			{
				vr = r.y();
				vg = g.y();
				vb = b.y();
				va = a.y();
				if (vr < 0) vr = 0; if (vr > lim) vr = (int)lim;
				if (vg < 0) vg = 0; if (vg > lim) vg = (int)lim;
				if (vb < 0) vb = 0; if (vb > lim) vb = (int)lim;
				if (va < 0) va = 0; if (va > lim) va = (int)lim;
				span[spanIndex].red = (byte)vr;
				span[spanIndex].green = (byte)vg;
				span[spanIndex].blue = (byte)vb;
				span[spanIndex].alpha = (byte)va;
				r.Next((int)subpixel_scale_e.subpixel_scale);
				g.Next((int)subpixel_scale_e.subpixel_scale);
				b.Next((int)subpixel_scale_e.subpixel_scale);
				a.Next((int)subpixel_scale_e.subpixel_scale);
				nlen -= (int)subpixel_scale_e.subpixel_scale;
				start -= (int)subpixel_scale_e.subpixel_scale;
				++spanIndex;
				--len;
			}

			// Middle part, no checking for overflow.
			// Actual spans can be longer than the calculated length
			// because of anti-aliasing, thus, the interpolators can
			// overflow. But while "nlen" is positive we are safe.
			//-------------------------
			while (len != 0 && nlen > 0)
			{
				span[spanIndex].red = ((byte)r.y());
				span[spanIndex].green = ((byte)g.y());
				span[spanIndex].blue = ((byte)b.y());
				span[spanIndex].alpha = ((byte)a.y());
				r.Next((int)subpixel_scale_e.subpixel_scale);
				g.Next((int)subpixel_scale_e.subpixel_scale);
				b.Next((int)subpixel_scale_e.subpixel_scale);
				a.Next((int)subpixel_scale_e.subpixel_scale);
				nlen -= (int)subpixel_scale_e.subpixel_scale;
				++spanIndex;
				--len;
			}

			// Ending part; checking for overflow.
			// Typically it's 1-2 pixels, but may be more in some cases.
			//-------------------------
			while (len != 0)
			{
				vr = r.y();
				vg = g.y();
				vb = b.y();
				va = a.y();
				if (vr < 0) vr = 0; if (vr > lim) vr = (int)lim;
				if (vg < 0) vg = 0; if (vg > lim) vg = (int)lim;
				if (vb < 0) vb = 0; if (vb > lim) vb = (int)lim;
				if (va < 0) va = 0; if (va > lim) va = (int)lim;
				span[spanIndex].red = ((byte)vr);
				span[spanIndex].green = ((byte)vg);
				span[spanIndex].blue = ((byte)vb);
				span[spanIndex].alpha = ((byte)va);
				r.Next((int)subpixel_scale_e.subpixel_scale);
				g.Next((int)subpixel_scale_e.subpixel_scale);
				b.Next((int)subpixel_scale_e.subpixel_scale);
				a.Next((int)subpixel_scale_e.subpixel_scale);
				++spanIndex;
				--len;
			}
		}
Esempio n. 2
0
        public void generate(Color[] span, int spanIndex, int x, int y, int len)
        {
            m_rgba1.calc(y);            //(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
            rgba_calc pc1 = m_rgba1;
            rgba_calc pc2 = m_rgba2;

            if (y <= m_y2)
            {
                // Bottom part of the triangle (first subtriangle)
                //-------------------------
                m_rgba2.calc(y + m_rgba2.m_1dy);
            }
            else
            {
                // Upper part (second subtriangle)
                m_rgba3.calc(y - m_rgba3.m_1dy);
                //-------------------------
                pc2 = m_rgba3;
            }

            if (m_swap)
            {
                // It means that the triangle is oriented clockwise,
                // so that we need to swap the controlling structures
                //-------------------------
                rgba_calc t = pc2;
                pc2 = pc1;
                pc1 = t;
            }

            // Get the horizontal length with subpixel accuracy
            // and protect it from division by zero
            //-------------------------
            int nlen = Math.Abs(pc2.m_x - pc1.m_x);

            if (nlen <= 0)
            {
                nlen = 1;
            }

            dda_line_interpolator r = new dda_line_interpolator(pc1.m_r, pc2.m_r, nlen, 14);
            dda_line_interpolator g = new dda_line_interpolator(pc1.m_g, pc2.m_g, nlen, 14);
            dda_line_interpolator b = new dda_line_interpolator(pc1.m_b, pc2.m_b, nlen, 14);
            dda_line_interpolator a = new dda_line_interpolator(pc1.m_a, pc2.m_a, nlen, 14);

            // Calculate the starting point of the gradient with subpixel
            // accuracy and correct (roll back) the interpolators.
            // This operation will also clip the beginning of the span
            // if necessary.
            //-------------------------
            int start = pc1.m_x - (x << (int)subpixel_scale_e.subpixel_shift);

            r.Prev(start);
            g.Prev(start);
            b.Prev(start);
            a.Prev(start);
            nlen += start;

            int  vr, vg, vb, va;
            uint lim = 255;

            // Beginning part of the span. Since we rolled back the
            // interpolators, the color values may have overflowed.
            // So that, we render the beginning part with checking
            // for overflow. It lasts until "start" is positive;
            // typically it's 1-2 pixels, but may be more in some cases.
            //-------------------------
            while (len != 0 && start > 0)
            {
                vr = r.y();
                vg = g.y();
                vb = b.y();
                va = a.y();
                if (vr < 0)
                {
                    vr = 0;
                }
                if (vr > lim)
                {
                    vr = (int)lim;
                }
                if (vg < 0)
                {
                    vg = 0;
                }
                if (vg > lim)
                {
                    vg = (int)lim;
                }
                if (vb < 0)
                {
                    vb = 0;
                }
                if (vb > lim)
                {
                    vb = (int)lim;
                }
                if (va < 0)
                {
                    va = 0;
                }
                if (va > lim)
                {
                    va = (int)lim;
                }
                span[spanIndex].red   = (byte)vr;
                span[spanIndex].green = (byte)vg;
                span[spanIndex].blue  = (byte)vb;
                span[spanIndex].alpha = (byte)va;
                r.Next((int)subpixel_scale_e.subpixel_scale);
                g.Next((int)subpixel_scale_e.subpixel_scale);
                b.Next((int)subpixel_scale_e.subpixel_scale);
                a.Next((int)subpixel_scale_e.subpixel_scale);
                nlen  -= (int)subpixel_scale_e.subpixel_scale;
                start -= (int)subpixel_scale_e.subpixel_scale;
                ++spanIndex;
                --len;
            }

            // Middle part, no checking for overflow.
            // Actual spans can be longer than the calculated length
            // because of anti-aliasing, thus, the interpolators can
            // overflow. But while "nlen" is positive we are safe.
            //-------------------------
            while (len != 0 && nlen > 0)
            {
                span[spanIndex].red   = ((byte)r.y());
                span[spanIndex].green = ((byte)g.y());
                span[spanIndex].blue  = ((byte)b.y());
                span[spanIndex].alpha = ((byte)a.y());
                r.Next((int)subpixel_scale_e.subpixel_scale);
                g.Next((int)subpixel_scale_e.subpixel_scale);
                b.Next((int)subpixel_scale_e.subpixel_scale);
                a.Next((int)subpixel_scale_e.subpixel_scale);
                nlen -= (int)subpixel_scale_e.subpixel_scale;
                ++spanIndex;
                --len;
            }

            // Ending part; checking for overflow.
            // Typically it's 1-2 pixels, but may be more in some cases.
            //-------------------------
            while (len != 0)
            {
                vr = r.y();
                vg = g.y();
                vb = b.y();
                va = a.y();
                if (vr < 0)
                {
                    vr = 0;
                }
                if (vr > lim)
                {
                    vr = (int)lim;
                }
                if (vg < 0)
                {
                    vg = 0;
                }
                if (vg > lim)
                {
                    vg = (int)lim;
                }
                if (vb < 0)
                {
                    vb = 0;
                }
                if (vb > lim)
                {
                    vb = (int)lim;
                }
                if (va < 0)
                {
                    va = 0;
                }
                if (va > lim)
                {
                    va = (int)lim;
                }
                span[spanIndex].red   = ((byte)vr);
                span[spanIndex].green = ((byte)vg);
                span[spanIndex].blue  = ((byte)vb);
                span[spanIndex].alpha = ((byte)va);
                r.Next((int)subpixel_scale_e.subpixel_scale);
                g.Next((int)subpixel_scale_e.subpixel_scale);
                b.Next((int)subpixel_scale_e.subpixel_scale);
                a.Next((int)subpixel_scale_e.subpixel_scale);
                ++spanIndex;
                --len;
            }
        }