/// <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 }
/// <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 }