Esempio n. 1
0
        public void GenerateColors(ColorRGBA[] outputColors, int startIndex, int x, int y, int len)
        {
            m_rgba1.Calculate(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
            RGBA_Calculator pc1 = m_rgba1;
            RGBA_Calculator pc2 = m_rgba2;

            if (y <= m_y2)
            {
                // Bottom part of the triangle (first subtriangle)
                //-------------------------
                m_rgba2.Calculate(y + m_rgba2.m_1dy);
            }
            else
            {
                // Upper part (second subtriangle)
                m_rgba3.Calculate(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_Calculator 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;
            }

            var line_r = new PixelFarm.Agg.Transform.LineInterpolatorDDA(pc1.m_r, pc2.m_r, nlen, 14);
            var line_g = new PixelFarm.Agg.Transform.LineInterpolatorDDA(pc1.m_g, pc2.m_g, nlen, 14);
            var line_b = new PixelFarm.Agg.Transform.LineInterpolatorDDA(pc1.m_b, pc2.m_b, nlen, 14);
            var line_a = new PixelFarm.Agg.Transform.LineInterpolatorDDA(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_SHIFT);

            line_r.Prev(start);
            line_g.Prev(start);
            line_b.Prev(start);
            line_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 = line_r.y();
                vg = line_g.y();
                vb = line_b.y();
                va = line_a.y();
                if (vr < 0)
                {
                    vr = 0;
                }
                else if (vr > lim)
                {
                    vr = (int)lim;
                }
                if (vg < 0)
                {
                    vg = 0;
                }
                else if (vg > lim)
                {
                    vg = (int)lim;
                }
                if (vb < 0)
                {
                    vb = 0;
                }
                else if (vb > lim)
                {
                    vb = (int)lim;
                }
                if (va < 0)
                {
                    va = 0;
                }
                else if (va > lim)
                {
                    va = (int)lim;
                }

                outputColors[startIndex].red   = (byte)vr;
                outputColors[startIndex].green = (byte)vg;
                outputColors[startIndex].blue  = (byte)vb;
                outputColors[startIndex].alpha = (byte)va;

                line_r.Next(SUBPIXEL_SCALE);
                line_g.Next(SUBPIXEL_SCALE);
                line_b.Next(SUBPIXEL_SCALE);
                line_a.Next(SUBPIXEL_SCALE);
                nlen  -= SUBPIXEL_SCALE;
                start -= SUBPIXEL_SCALE;
                ++startIndex;
                --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)
            {
                outputColors[startIndex].red   = ((byte)line_r.y());
                outputColors[startIndex].green = ((byte)line_g.y());
                outputColors[startIndex].blue  = ((byte)line_b.y());
                outputColors[startIndex].alpha = ((byte)line_a.y());

                line_r.Next(SUBPIXEL_SCALE);
                line_g.Next(SUBPIXEL_SCALE);
                line_b.Next(SUBPIXEL_SCALE);
                line_a.Next(SUBPIXEL_SCALE);
                nlen -= SUBPIXEL_SCALE;
                ++startIndex;
                --len;
            }

            // Ending part; checking for overflow.
            // Typically it's 1-2 pixels, but may be more in some cases.
            //-------------------------
            while (len != 0)
            {
                vr = line_r.y();
                vg = line_g.y();
                vb = line_b.y();
                va = line_a.y();

                if (vr < 0)
                {
                    vr = 0;
                }
                else if (vr > lim)
                {
                    vr = (int)lim;
                }
                if (vg < 0)
                {
                    vg = 0;
                }
                else if (vg > lim)
                {
                    vg = (int)lim;
                }
                if (vb < 0)
                {
                    vb = 0;
                }
                else if (vb > lim)
                {
                    vb = (int)lim;
                }
                if (va < 0)
                {
                    va = 0;
                }
                else if (va > lim)
                {
                    va = (int)lim;
                }

                outputColors[startIndex].red   = ((byte)vr);
                outputColors[startIndex].green = ((byte)vg);
                outputColors[startIndex].blue  = ((byte)vb);
                outputColors[startIndex].alpha = ((byte)va);
                line_r.Next(SUBPIXEL_SCALE);
                line_g.Next(SUBPIXEL_SCALE);
                line_b.Next(SUBPIXEL_SCALE);
                line_a.Next(SUBPIXEL_SCALE);
                ++startIndex;
                --len;
            }
        }
        public void GenerateColors(Color[] outputColors, int startIndex, int x, int y, int len)
        {
            m_rgba1.Calculate(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
            RGBA_Calculator pc1 = m_rgba1;
            RGBA_Calculator pc2 = m_rgba2;
            if (y <= m_y2)
            {
                // Bottom part of the triangle (first subtriangle)
                //-------------------------
                m_rgba2.Calculate(y + m_rgba2.m_1dy);
            }
            else
            {
                // Upper part (second subtriangle)
                m_rgba3.Calculate(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_Calculator 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;
            var line_r = new PixelFarm.Agg.Transform.LineInterpolatorDDA(pc1.m_r, pc2.m_r, nlen, 14);
            var line_g = new PixelFarm.Agg.Transform.LineInterpolatorDDA(pc1.m_g, pc2.m_g, nlen, 14);
            var line_b = new PixelFarm.Agg.Transform.LineInterpolatorDDA(pc1.m_b, pc2.m_b, nlen, 14);
            var line_a = new PixelFarm.Agg.Transform.LineInterpolatorDDA(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_SHIFT);
            line_r.Prev(start);
            line_g.Prev(start);
            line_b.Prev(start);
            line_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 = line_r.y();
                vg = line_g.y();
                vb = line_b.y();
                va = line_a.y();
                if (vr < 0) { vr = 0; } else if (vr > lim) { vr = (int)lim; }
                if (vg < 0) { vg = 0; } else if (vg > lim) { vg = (int)lim; }
                if (vb < 0) { vb = 0; } else if (vb > lim) { vb = (int)lim; }
                if (va < 0) { va = 0; } else if (va > lim) { va = (int)lim; }

                outputColors[startIndex].red = (byte)vr;
                outputColors[startIndex].green = (byte)vg;
                outputColors[startIndex].blue = (byte)vb;
                outputColors[startIndex].alpha = (byte)va;
                line_r.Next(SUBPIXEL_SCALE);
                line_g.Next(SUBPIXEL_SCALE);
                line_b.Next(SUBPIXEL_SCALE);
                line_a.Next(SUBPIXEL_SCALE);
                nlen -= SUBPIXEL_SCALE;
                start -= SUBPIXEL_SCALE;
                ++startIndex;
                --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)
            {
                outputColors[startIndex].red = ((byte)line_r.y());
                outputColors[startIndex].green = ((byte)line_g.y());
                outputColors[startIndex].blue = ((byte)line_b.y());
                outputColors[startIndex].alpha = ((byte)line_a.y());
                line_r.Next(SUBPIXEL_SCALE);
                line_g.Next(SUBPIXEL_SCALE);
                line_b.Next(SUBPIXEL_SCALE);
                line_a.Next(SUBPIXEL_SCALE);
                nlen -= SUBPIXEL_SCALE;
                ++startIndex;
                --len;
            }

            // Ending part; checking for overflow.
            // Typically it's 1-2 pixels, but may be more in some cases.
            //-------------------------
            while (len != 0)
            {
                vr = line_r.y();
                vg = line_g.y();
                vb = line_b.y();
                va = line_a.y();
                if (vr < 0) { vr = 0; } else if (vr > lim) { vr = (int)lim; }
                if (vg < 0) { vg = 0; } else if (vg > lim) { vg = (int)lim; }
                if (vb < 0) { vb = 0; } else if (vb > lim) { vb = (int)lim; }
                if (va < 0) { va = 0; } else if (va > lim) { va = (int)lim; }

                outputColors[startIndex].red = ((byte)vr);
                outputColors[startIndex].green = ((byte)vg);
                outputColors[startIndex].blue = ((byte)vb);
                outputColors[startIndex].alpha = ((byte)va);
                line_r.Next(SUBPIXEL_SCALE);
                line_g.Next(SUBPIXEL_SCALE);
                line_b.Next(SUBPIXEL_SCALE);
                line_a.Next(SUBPIXEL_SCALE);
                ++startIndex;
                --len;
            }
        }