コード例 #1
0
        /// <summary>
        /// Filling using radial gradient for circle gradient only
        /// </summary>
        /// <param name="radial">radial</param>
        /// <param name="rows">rows</param>
        /// <param name="startRowIndex">start y index</param>
        /// <param name="endRowIndex">end y index</param>
        /// <param name="gammaLutRed">gamma look up table for red</param>
        /// <param name="gammaLutGreen">gamma look up table for green</param>
        /// <param name="gammaLutBlue">gamma look up table for blue</param>
        void FillingRadialEvenOdd(RadialGradient radial, uint opacity, RowData[] rows, int startRowIndex, int endRowIndex, byte[] gammaLutRed, byte[] gammaLutGreen, byte[] gammaLutBlue)
        {
            // now not need to check null or not
            uint[] builtColors = radial.GetLinearColors(opacity);
            #region private variable for filling
            int currentCoverage, scLastCoverage, scLastX = 0;
            int tempCover = 0;
            int currentArea = 0;
            int lastXPosition = 0;
            int startXPosition = 0;
            byte calculatedCoverage = 0;

            double centerX = radial.CenterX;
            double centerY = radial.CenterY;
            // in this case radius x = radius y
            double radius = radial.RadiusX;

            // saving precompute value for rows
            /* Normal calculation to get the color index
             * currentColorIndexValue =
                (int)(Math.Sqrt(
                    (startRowIndex - centerY) * (startRowIndex - centerY) +
                    (currentXPosition - centerX) * (currentXPosition - centerX)) * ColorIndexScale / radius );
             * but
             *  preComputeForRow= (startRowIndex - centerY) * (startRowIndex - centerY)
             *  so that
             *    currentColorIndexValue = 
             *    (int)(Math.Sqrt(
                    (preComputeForRow) +
                    (currentXPosition - centerX) * (currentXPosition - centerX)) * ColorIndexScale / radius );
             */
            double preComputeForRow = 0;

            // this is precompute value so that (* ColorIndexScale / radius) now just ( * preComputeRadiusLookup )
            double preComputeRadiusLookup = ColorIndexScale / radius;

            CellData currentCellData = null;
            uint colorData = 0;
            //uint colorG = 0;
            //uint colorRB = 0;


            int currentColorIndexValue = 0;
            int currentXPosition = 0;

            uint dst, dstRB, dstG;
            #endregion

            #region FILLING
            if (radial.Ramp.NoBlendingColor)
            {
                // when no need to blending, when draw a horizontal line
                // do not need check the back color, alway setup
                if (radial.Style != GradientStyle.Pad)
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY);
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            // get current color index value
                                            //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex;
                                            currentXPosition = scLastX + 1;
                                            if (scLastCoverage >= 255)
                                            {
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)(Math.Sqrt(
                                                            preComputeForRow +
                                                            (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                                    #endregion
                                                    BufferData[startXPosition] = builtColors[currentColorIndexValue & ColorIndexDoubleMask];
                                                    startXPosition++;
                                                    currentXPosition++;
                                                }
                                            }
                                            else
                                            {
                                                calculatedCoverage = (byte)scLastCoverage;
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)(Math.Sqrt(
                                                            preComputeForRow +
                                                            (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                                    #endregion

                                                    colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];
                                                    //calculatedCoverage = (byte)((colorData >> 24));
                                                    //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                    if (calculatedCoverage >= 254)
                                                    {
                                                        BufferData[startXPosition] = colorData;
                                                    }
                                                    else
                                                    {
                                                        #region gamma apply
                                                        dst = BufferData[startXPosition];
                                                        dstG = (dst >> 8) & 0xFF;
                                                        dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                                        BufferData[startXPosition] =
                                                            (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                            | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                                            | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                                            | (gammaLutBlue[(dstRB & 0x00FF)]))
                                                            ;
                                                        #endregion
                                                    }
                                                    startXPosition++;
                                                    currentXPosition++;
                                                }
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region calculate color index
                                        currentXPosition = currentCellData.X;
                                        currentColorIndexValue =
                                            (int)(Math.Sqrt(preComputeForRow +
                                                (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex];
                                        //calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        //tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        //dst = BufferData[startXPosition];
                                        //dstRB = dst & 0x00FF00FF;
                                        //dstG = (dst >> 8) & 0xFF;
                                        //BufferData[startXPosition] =
                                        //    (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                        //    | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                        //    | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        if (calculatedCoverage >= 254)
                                        {
                                            BufferData[startXPosition] = colorData;
                                        }
                                        else
                                        {
                                            #region gamma apply
                                            dst = BufferData[startXPosition];
                                            dstG = (dst >> 8) & 0xFF;
                                            dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                            BufferData[startXPosition] =
                                                (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                                | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                                | (gammaLutBlue[(dstRB & 0x00FF)]))
                                                ;
                                            #endregion
                                        }
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY);
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            // get current color index value
                                            //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex;
                                            currentXPosition = scLastX + 1;
                                            if (scLastCoverage >= 255)
                                            {
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)(Math.Sqrt(
                                                            preComputeForRow +
                                                            (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                                    #endregion
                                                    BufferData[startXPosition] = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                                    startXPosition++;
                                                    currentXPosition++;
                                                }
                                            }
                                            else
                                            {
                                                calculatedCoverage = (byte)(scLastCoverage);
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)(Math.Sqrt(
                                                            preComputeForRow +
                                                            (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                                    #endregion

                                                    colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                                    //calculatedCoverage = (byte)((colorData >> 24));
                                                    //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                    if (calculatedCoverage >= 254)
                                                    {
                                                        BufferData[startXPosition] = colorData;
                                                    }
                                                    else
                                                    {
                                                        //// blend here
                                                        //dst = BufferData[startXPosition];
                                                        //dstRB = dst & 0x00FF00FF;
                                                        //dstG = (dst >> 8) & 0xFF;

                                                        //BufferData[startXPosition] =
                                                        //    (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                        //    | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                                        //    | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                                        #region gamma apply
                                                        dst = BufferData[startXPosition];
                                                        dstG = (dst >> 8) & 0xFF;
                                                        dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                                        BufferData[startXPosition] =
                                                            (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                            | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                                            | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                                            | (gammaLutBlue[(dstRB & 0x00FF)]))
                                                            ;
                                                        #endregion
                                                    }
                                                    startXPosition++;
                                                    currentXPosition++;
                                                }
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region calculate color index
                                        currentXPosition = currentCellData.X;
                                        currentColorIndexValue =
                                            (int)(Math.Sqrt(preComputeForRow +
                                                (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];//fixedColor[currentCellData.X - CurrentStartXIndex];
                                        //calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        //tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        //dst = BufferData[startXPosition];
                                        //dstRB = dst & 0x00FF00FF;
                                        //dstG = (dst >> 8) & 0xFF;
                                        //BufferData[startXPosition] =
                                        //    (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                        //    | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                        //    | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        if (calculatedCoverage >= 254)
                                        {
                                            BufferData[startXPosition] = colorData;
                                        }
                                        else
                                        {
                                            #region gamma apply
                                            dst = BufferData[startXPosition];
                                            dstG = (dst >> 8) & 0xFF;
                                            dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                            BufferData[startXPosition] =
                                                (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                                | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                                | (gammaLutBlue[(dstRB & 0x00FF)]))
                                                ;
                                            #endregion
                                        }
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
            }
            else
            {
                // when no need to blending, when draw a horizontal line
                // do not need check the back color, alway setup
                if (radial.Style != GradientStyle.Pad)
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY);
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            // get current color index value
                                            //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex;
                                            currentXPosition = scLastX + 1;

                                            while (startXPosition < lastXPosition)
                                            {
                                                #region calculate color index
                                                currentColorIndexValue =
                                                    (int)(Math.Sqrt(
                                                        preComputeForRow +
                                                        (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                                #endregion

                                                colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];
                                                calculatedCoverage = (byte)((colorData >> 24));
                                                calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                if (calculatedCoverage >= 254)
                                                {
                                                    BufferData[startXPosition] = colorData;
                                                }
                                                else
                                                {
                                                    #region gamma apply
                                                    dst = BufferData[startXPosition];
                                                    dstG = (dst >> 8) & 0xFF;
                                                    dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                                    BufferData[startXPosition] =
                                                        (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                        | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                                        | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                                        | (gammaLutBlue[(dstRB & 0x00FF)]))
                                                        ;
                                                    #endregion
                                                }
                                                startXPosition++;
                                                currentXPosition++;
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region calculate color index
                                        currentXPosition = currentCellData.X;
                                        currentColorIndexValue =
                                            (int)(Math.Sqrt(preComputeForRow +
                                                (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex];
                                        calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        //if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        //dst = BufferData[startXPosition];
                                        //dstRB = dst & 0x00FF00FF;
                                        //dstG = (dst >> 8) & 0xFF;
                                        //BufferData[startXPosition] =
                                        //    (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                        //    | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                        //    | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        #region gamma apply
                                        dst = BufferData[startXPosition];
                                        dstG = (dst >> 8) & 0xFF;
                                        dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                        BufferData[startXPosition] =
                                            (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                            | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                            | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                            | (gammaLutBlue[(dstRB & 0x00FF)]))
                                            ;
                                        #endregion
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY);
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            // get current color index value
                                            //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex;
                                            currentXPosition = scLastX + 1;

                                            while (startXPosition < lastXPosition)
                                            {
                                                #region calculate color index
                                                currentColorIndexValue =
                                                    (int)(Math.Sqrt(
                                                        preComputeForRow +
                                                        (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                                #endregion

                                                colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                                calculatedCoverage = (byte)((colorData >> 24));
                                                calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                if (calculatedCoverage >= 254)
                                                {
                                                    BufferData[startXPosition] = colorData;
                                                }
                                                else
                                                {
                                                    //// blend here
                                                    //dst = BufferData[startXPosition];
                                                    //dstRB = dst & 0x00FF00FF;
                                                    //dstG = (dst >> 8) & 0xFF;

                                                    //BufferData[startXPosition] =
                                                    //    (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                    //    | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                                    //    | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);

                                                    #region gamma apply
                                                    dst = BufferData[startXPosition];
                                                    dstG = (dst >> 8) & 0xFF;
                                                    dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                                    BufferData[startXPosition] =
                                                        (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                        | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                                        | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                                        | (gammaLutBlue[(dstRB & 0x00FF)]))
                                                        ;
                                                    #endregion
                                                }
                                                startXPosition++;
                                                currentXPosition++;
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region calculate color index
                                        currentXPosition = currentCellData.X;
                                        currentColorIndexValue =
                                            (int)(Math.Sqrt(preComputeForRow +
                                                (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];//fixedColor[currentCellData.X - CurrentStartXIndex];
                                        calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        //if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;
                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        //dst = BufferData[startXPosition];
                                        //dstRB = dst & 0x00FF00FF;
                                        //dstG = (dst >> 8) & 0xFF;
                                        //BufferData[startXPosition] =
                                        //    (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                        //    | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                        //    | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        #region gamma apply
                                        dst = BufferData[startXPosition];
                                        dstG = (dst >> 8) & 0xFF;
                                        dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF));

                                        BufferData[startXPosition] =
                                            (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                            | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8))
                                            | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16)
                                            | (gammaLutBlue[(dstRB & 0x00FF)]))
                                            ;
                                        #endregion
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
            }

            #endregion
        }
コード例 #2
0
        /// <summary>
        /// Filling using radial gradient for circle gradient only
        /// </summary>
        /// <param name="radial">radial</param>
        /// <param name="rows">rows</param>
        /// <param name="startRowIndex">start y index</param>
        /// <param name="endRowIndex">end y index</param>
        void FillingEllipseFocalEvenOdd(RadialGradient radial, uint opacity, RowData[] rows, int startRowIndex, int endRowIndex)
        {
            // now not need to check null or not
            uint[] builtColors = radial.GetLinearColors(opacity);
            #region private variable for filling
            int currentCoverage, scLastCoverage, scLastX = 0;
            int tempCover = 0;
            int currentArea = 0;
            int lastXPosition = 0;
            int startXPosition = 0;
            byte calculatedCoverage = 0;


            double centerX = radial.CenterX;
            double centerY = radial.CenterY;
            // in this case radius x = radius y
            double radius = radial.RadiusX;
            double radiusYForX = radial.RadiusY / radial.RadiusX;


            // this is precompute value so that (* ColorIndexScale / radius) now just ( * preComputeRadiusLookup )
            double preComputeRadiusLookup = ColorIndexScale / radius;

            CellData currentCellData = null;
            uint colorData = 0;

            double dx = 0, dy = 0;

            double dySquared = 0; // saving dy * dy
            // focus is changed to relative from the center
            double absoluteFocusX = radial.FocusX;
            double absoluteFocusY = radial.FocusY;

            double focusX = radial.FocusX - centerX;
            double focusY = radial.FocusY - centerY;
            focusY = focusY / radiusYForX;

            // note that dx,dy need to move center
            /*
             *  dx = (currentXPosition - absoluteFocusX);
             *  dy = (startRowIndex - absoluteFocusY);
             *  currentColorIndexValue =
                    (int)
                    (
                        (
                            (
                            (dx * focusX) + (dy * focusY)
                            + Math.Sqrt
                            (
                                Math.Abs
                                (
                                    radius * radius * (dx * dx + dy * dy) - (dx * focusY - dy * focusX) * (dx * focusY - dy * focusX)      
                                )
                            )
                        ) * (radius /
                        ((radius * radius) - ((focusX * focusX )+ (focusY * focusY))))
                    ) * 256 /radius
                );
             */

            //note that  ( radius / (( radius * radius) - ((focusX * focusX) + (focusY * focusY))) is const
            // so that need to pre compute
            double preComputeMultiply = radius / ((radius * radius) - ((focusX * focusX) + (focusY * focusY)));

            #region modify when pre compute for multiply is zero
            if (preComputeMultiply == 0)
            {
                if (focusX != 0)
                {
                    if (focusX < 0)
                    {
                        focusX += GradientAdjustment;
                    }
                    else
                    {
                        focusX -= GradientAdjustment;
                    }
                }
                if (focusY != 0)
                {
                    if (focusY < 0)
                    {
                        focusY += GradientAdjustment;
                    }
                    else
                    {
                        focusY -= GradientAdjustment;
                    }
                }
                preComputeMultiply = radius / ((radius * radius) - ((focusX * focusX) + (focusY * focusY)));
            }
            #endregion

            double preComputeMultiplyIncludeLookup = preComputeRadiusLookup * preComputeMultiply;

            // saving dy * focusY
            double dyFocusY = 0;
            double dyFocusX = 0;
            double dxFocusYIncrement = 0; // saving dx * focusY - dyFocusX
            double radiusSquared = radius * radius;


            int currentColorIndexValue = 0;
            //int currentXPosition = 0;
            uint dst, dstRB, dstG;
            #endregion

            #region FILLING
            if (radial.Ramp.NoBlendingColor)
            {
                // when no need to blending, when draw a horizontal line
                // do not need check the back color, alway setup
                if (radial.Style != GradientStyle.Pad)
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;

                        #region cumpute value for row
                        //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY);
                        dy = ((startRowIndex - centerY) / radiusYForX) - focusY;
                        dySquared = dy * dy;
                        dyFocusX = dy * focusX;
                        dyFocusY = dy * focusY;
                        #endregion
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;

                                            #region prepare for row color index calculation
                                            // get current color index value
                                            //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex;
                                            //currentXPosition = scLastX + 1;
                                            dx = (scLastX + 1 - absoluteFocusX);
                                            dxFocusYIncrement = (dx * focusY - dyFocusX);
                                            #endregion
                                            if (scLastCoverage >= 255)
                                            {
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)
                                                        ((((dx * focusX) + dyFocusY +
                                                            Math.Sqrt(Math.Abs(
                                                                radiusSquared *
                                                                (dx * dx + dySquared) -
                                                                dxFocusYIncrement * dxFocusYIncrement))
                                                                ) * preComputeMultiplyIncludeLookup)
                                                        );

                                                    //currentColorIndexValue =
                                                    //    (int)
                                                    //    (
                                                    //        (
                                                    //            (
                                                    //            (dx * focusX) + (dy * focusY)
                                                    //            + Math.Sqrt
                                                    //            (
                                                    //                Math.Abs
                                                    //                (
                                                    //                    radius * radius 
                                                    //                    * (dx * dx + dy * dy) 
                                                    //                    - (dx * focusY - dy * focusX) 
                                                    //                    * (dx * focusY - dy * focusX)
                                                    //                )
                                                    //            )
                                                    //        ) * (radius /
                                                    //        ((radius * radius) - ((focusX * focusX) + (focusY * focusY))))
                                                    //        ) * 256 / radius
                                                    //    );

                                                    // change for color index calculation
                                                    dx++;
                                                    dxFocusYIncrement += focusY;
                                                    #endregion
                                                    BufferData[startXPosition] = builtColors[currentColorIndexValue & ColorIndexDoubleMask];
                                                    startXPosition++;
                                                }
                                            }
                                            else
                                            {
                                                calculatedCoverage = (byte)scLastCoverage;
                                                while (startXPosition < lastXPosition)
                                                {

                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)
                                                        ((((dx * focusX) + dyFocusY +
                                                            Math.Sqrt(Math.Abs(
                                                                radiusSquared *
                                                                (dx * dx + dySquared) -
                                                                dxFocusYIncrement * dxFocusYIncrement))
                                                                ) * preComputeMultiplyIncludeLookup)
                                                        );

                                                    // change for color index calculation
                                                    dx++;
                                                    dxFocusYIncrement += focusY;
                                                    #endregion

                                                    colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];
                                                    //calculatedCoverage = (byte)((colorData >> 24));
                                                    //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                    if (calculatedCoverage >= 254)
                                                    {
                                                        BufferData[startXPosition] = colorData;
                                                    }
                                                    else
                                                    {
                                                        // blend here
                                                        dst = BufferData[startXPosition];
                                                        dstRB = dst & 0x00FF00FF;
                                                        dstG = (dst >> 8) & 0xFF;

                                                        BufferData[startXPosition] =
                                                            (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                            | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                                            | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                                    }
                                                    startXPosition++;

                                                }
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region calculate color index
                                        //currentXPosition = currentCellData.X;
                                        //currentColorIndexValue =
                                        //    (int)(Math.Sqrt(dyFocusY +
                                        //        (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup);
                                        #region prepare for row color index calculation
                                        // get current color index value
                                        dx = (currentCellData.X - absoluteFocusX);
                                        dxFocusYIncrement = (dx * focusY - dyFocusX);
                                        #endregion

                                        #region calculate color index
                                        currentColorIndexValue =
                                            (int)
                                            ((((dx * focusX) + dyFocusY +
                                                Math.Sqrt(Math.Abs(
                                                    radiusSquared *
                                                    (dx * dx + dySquared) -
                                                    dxFocusYIncrement * dxFocusYIncrement))
                                                    ) * preComputeMultiplyIncludeLookup)
                                            );
                                        #endregion
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex];
                                        //calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        //tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        dst = BufferData[startXPosition];
                                        dstRB = dst & 0x00FF00FF;
                                        dstG = (dst >> 8) & 0xFF;
                                        BufferData[startXPosition] =
                                            (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                            | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                            | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        #region cumpute value for row
                        //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY);
                        dy = ((startRowIndex - centerY) / radiusYForX) - focusY;
                        dySquared = dy * dy;
                        dyFocusX = dy * focusX;
                        dyFocusY = dy * focusY;
                        #endregion
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            #region prepare for row color index calculation
                                            // get current color index value
                                            dx = (scLastX + 1 - absoluteFocusX);
                                            dxFocusYIncrement = (dx * focusY - dyFocusX);
                                            #endregion

                                            if (scLastCoverage >= 255)
                                            {
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)
                                                        ((((dx * focusX) + dyFocusY +
                                                            Math.Sqrt(Math.Abs(
                                                                radiusSquared *
                                                                (dx * dx + dySquared) -
                                                                dxFocusYIncrement * dxFocusYIncrement))
                                                                ) * preComputeMultiplyIncludeLookup)
                                                        );

                                                    // change for color index calculation
                                                    dx++;
                                                    dxFocusYIncrement += focusY;
                                                    #endregion

                                                    BufferData[startXPosition] = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                                    startXPosition++;
                                                }
                                            }
                                            else
                                            {
                                                calculatedCoverage = (byte)(scLastCoverage);
                                                while (startXPosition < lastXPosition)
                                                {
                                                    #region calculate color index
                                                    currentColorIndexValue =
                                                        (int)
                                                        ((((dx * focusX) + dyFocusY +
                                                            Math.Sqrt(Math.Abs(
                                                                radiusSquared *
                                                                (dx * dx + dySquared) -
                                                                dxFocusYIncrement * dxFocusYIncrement))
                                                                ) * preComputeMultiplyIncludeLookup)
                                                        );

                                                    // change for color index calculation
                                                    dx++;
                                                    dxFocusYIncrement += focusY;
                                                    #endregion
                                                    colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                                    //calculatedCoverage = (byte)((colorData >> 24));
                                                    //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                    if (calculatedCoverage >= 254)
                                                    {
                                                        BufferData[startXPosition] = colorData;
                                                    }
                                                    else
                                                    {
                                                        // blend here
                                                        dst = BufferData[startXPosition];
                                                        dstRB = dst & 0x00FF00FF;
                                                        dstG = (dst >> 8) & 0xFF;

                                                        BufferData[startXPosition] =
                                                            (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                            | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                                            | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                                    }
                                                    startXPosition++;
                                                }
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region calculate color index
                                        #region prepare for row color index calculation
                                        // get current color index value
                                        dx = (currentCellData.X - absoluteFocusX);
                                        dxFocusYIncrement = (dx * focusY - dyFocusX);
                                        #endregion

                                        #region calculate color index
                                        currentColorIndexValue =
                                            (int)
                                            ((((dx * focusX) + dyFocusY +
                                                Math.Sqrt(Math.Abs(
                                                    radiusSquared *
                                                    (dx * dx + dySquared) -
                                                    dxFocusYIncrement * dxFocusYIncrement))
                                                    ) * preComputeMultiplyIncludeLookup)
                                            );
                                        #endregion
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                        //calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        //tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        dst = BufferData[startXPosition];
                                        dstRB = dst & 0x00FF00FF;
                                        dstG = (dst >> 8) & 0xFF;
                                        BufferData[startXPosition] =
                                            (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                            | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                            | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
            }
            else
            {
                // when no need to blending, when draw a horizontal line
                // do not need check the back color, alway setup
                if (radial.Style != GradientStyle.Pad)
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        #region cumpute value for row
                        //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY);
                        dy = ((startRowIndex - centerY) / radiusYForX) - focusY;
                        dySquared = dy * dy;
                        dyFocusX = dy * focusX;
                        dyFocusY = dy * focusY;
                        #endregion
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            #region prepare for row color index calculation
                                            // get current color index value
                                            dx = (scLastX + 1 - absoluteFocusX);
                                            dxFocusYIncrement = (dx * focusY - dyFocusX);
                                            #endregion


                                            while (startXPosition < lastXPosition)
                                            {
                                                #region calculate color index
                                                currentColorIndexValue =
                                                    (int)
                                                    ((((dx * focusX) + dyFocusY +
                                                        Math.Sqrt(Math.Abs(
                                                            radiusSquared *
                                                            (dx * dx + dySquared) -
                                                            dxFocusYIncrement * dxFocusYIncrement))
                                                            ) * preComputeMultiplyIncludeLookup)
                                                    );

                                                // change for color index calculation
                                                dx++;
                                                dxFocusYIncrement += focusY;
                                                #endregion
                                                colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];
                                                calculatedCoverage = (byte)((colorData >> 24));
                                                calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                if (calculatedCoverage >= 254)
                                                {
                                                    BufferData[startXPosition] = colorData;
                                                }
                                                else
                                                {
                                                    // blend here
                                                    dst = BufferData[startXPosition];
                                                    dstRB = dst & 0x00FF00FF;
                                                    dstG = (dst >> 8) & 0xFF;

                                                    BufferData[startXPosition] =
                                                        (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                        | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                                        | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                                }
                                                startXPosition++;
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region prepare for row color index calculation
                                        // get current color index value
                                        dx = (currentCellData.X - absoluteFocusX);
                                        dxFocusYIncrement = (dx * focusY - dyFocusX);
                                        #endregion

                                        #region calculate color index
                                        currentColorIndexValue =
                                            (int)
                                            ((((dx * focusX) + dyFocusY +
                                                Math.Sqrt(Math.Abs(
                                                    radiusSquared *
                                                    (dx * dx + dySquared) -
                                                    dxFocusYIncrement * dxFocusYIncrement))
                                                    ) * preComputeMultiplyIncludeLookup)
                                            );
                                        #endregion

                                        colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex];
                                        calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        //if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        dst = BufferData[startXPosition];
                                        dstRB = dst & 0x00FF00FF;
                                        dstG = (dst >> 8) & 0xFF;
                                        BufferData[startXPosition] =
                                            (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                            | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                            | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    #region filling without blend for horizontal lines
                    startRowIndex--;
                    while (++startRowIndex <= endRowIndex)
                    {
                        currentCoverage = scLastCoverage = scLastX = 0;
                        #region cumpute value for row
                        //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY);
                        dy = ((startRowIndex - centerY) / radiusYForX) - focusY;
                        dySquared = dy * dy;
                        dyFocusX = dy * focusX;
                        dyFocusY = dy * focusY;
                        #endregion
                        if (rows[startRowIndex] != null)
                        {
                            // get first cell in current row
                            currentCellData = rows[startRowIndex].First;
                            if (currentCellData != null)
                            {
                                #region fill current row
                                do
                                {
                                    currentArea = currentCellData.Area;
                                    #region blend horizontal line
                                    if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0))
                                    {
                                        // fast bit absolute
                                        scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31);
                                        #region even odd change
                                        scLastCoverage &= 511;
                                        if (scLastCoverage >= 256)
                                        {
                                            scLastCoverage = 512 - scLastCoverage - 1;
                                        }
                                        #endregion
                                        if (scLastCoverage != 0)
                                        {
                                            #region BLEND HORIZONTAL LINE
                                            // calculate start and end position
                                            startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1;
                                            lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                            #region prepare for row color index calculation
                                            // get current color index value
                                            dx = (scLastX + 1 - absoluteFocusX);
                                            dxFocusYIncrement = (dx * focusY - dyFocusX);
                                            #endregion


                                            while (startXPosition < lastXPosition)
                                            {
                                                #region calculate color index
                                                currentColorIndexValue =
                                                    (int)
                                                    ((((dx * focusX) + dyFocusY +
                                                        Math.Sqrt(Math.Abs(
                                                            radiusSquared *
                                                            (dx * dx + dySquared) -
                                                            dxFocusYIncrement * dxFocusYIncrement))
                                                            ) * preComputeMultiplyIncludeLookup)
                                                    );

                                                // change for color index calculation
                                                dx++;
                                                dxFocusYIncrement += focusY;
                                                #endregion

                                                colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                                calculatedCoverage = (byte)((colorData >> 24));
                                                calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8);
                                                if (calculatedCoverage >= 254)
                                                {
                                                    BufferData[startXPosition] = colorData;
                                                }
                                                else
                                                {
                                                    // blend here
                                                    dst = BufferData[startXPosition];
                                                    dstRB = dst & 0x00FF00FF;
                                                    dstG = (dst >> 8) & 0xFF;

                                                    BufferData[startXPosition] =
                                                        (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                                        | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                                        | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                                }
                                                startXPosition++;
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    currentCoverage += currentCellData.Coverage;

                                    #region blend the current cell
                                    // fast absolute
                                    tempCover = ((currentCoverage << 9) - currentArea) >> 9;
                                    if (tempCover != 0)
                                    {
                                        // fast bit absolute
                                        tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31);

                                        #region even odd change
                                        tempCover &= 511;
                                        if (tempCover >= 256)
                                        {
                                            tempCover = 512 - tempCover - 1;
                                        }
                                        #endregion
                                        // get current color data
                                        #region prepare for row color index calculation
                                        // get current color index value
                                        dx = (currentCellData.X - absoluteFocusX);
                                        dxFocusYIncrement = (dx * focusY - dyFocusX);
                                        #endregion

                                        #region calculate color index
                                        currentColorIndexValue =
                                            (int)
                                            ((((dx * focusX) + dyFocusY +
                                                Math.Sqrt(Math.Abs(
                                                    radiusSquared *
                                                    (dx * dx + dySquared) -
                                                    dxFocusYIncrement * dxFocusYIncrement))
                                                    ) * preComputeMultiplyIncludeLookup)
                                            );
                                        #endregion
                                        colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue];
                                        calculatedCoverage = (byte)(colorData >> 24);

                                        #region blend pixel
                                        tempCover = (int)((tempCover * calculatedCoverage) >> 8);
                                        //if (tempCover > 255) tempCover = 255;
                                        calculatedCoverage = (byte)tempCover;

                                        startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X;
                                        #region blend here
                                        dst = BufferData[startXPosition];
                                        dstRB = dst & 0x00FF00FF;
                                        dstG = (dst >> 8) & 0xFF;
                                        BufferData[startXPosition] =
                                            (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage])
                                            | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00)
                                            | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF);
                                        #endregion
                                        #endregion
                                    }
                                    #endregion

                                    scLastCoverage = currentCoverage;
                                    scLastX = currentCellData.X;

                                    // move to next cell
                                    currentCellData = currentCellData.Next;
                                } while (currentCellData != null);
                                #endregion
                            }
                        }
                    }
                    #endregion
                }
            }

            #endregion
        }