public void BlendHL(int x1, int y, int x2, ColorRGBA sourceColor, byte cover) { if (sourceColor.alpha == 0) { return; } //------------------------------------------------- int len = x2 - x1 + 1; byte[] buffer = GetBuffer(); int bufferOffset = GetBufferOffsetXY(x1, y); int alpha = (((int)(sourceColor.alpha) * (cover + 1)) >> 8); if (alpha == BASE_MASK) { //full recieveBlender.CopyPixels(buffer, bufferOffset, sourceColor, len); } else { ColorRGBA c2 = new ColorRGBA(sourceColor, alpha); do { //copy pixel-by-pixel recieveBlender.BlendPixel(buffer, bufferOffset, c2); bufferOffset += m_DistanceInBytesBetweenPixelsInclusive; }while (--len != 0); } }
static void CopyOrBlend_BasedOnAlpha(IPixelBlender recieveBlender, byte[] destBuffer, int bufferOffset, ColorRGBA sourceColor) { //if (sourceColor.m_A != 0) { #if false // we blend regardless of the alpha so that we can get Light Opacity working (used this way we have addative and faster blending in one blender) LBB if (sourceColor.m_A == base_mask) { Blender.CopyPixel(pDestBuffer, sourceColor); } else #endif { recieveBlender.BlendPixel(destBuffer, bufferOffset, sourceColor); } } }
static void CopyOrBlend_BasedOnAlphaAndCover(IPixelBlender recieveBlender, byte[] destBuffer, int bufferOffset, Color sourceColor, int cover) { if (cover == 255) { CopyOrBlend_BasedOnAlpha(recieveBlender, destBuffer, bufferOffset, sourceColor); } else { //if (sourceColor.m_A != 0) { sourceColor.alpha = (byte)((sourceColor.alpha * (cover + 1)) >> 8); #if false // we blend regardless of the alpha so that we can get Light Opacity working (used this way we have addative and faster blending in one blender) LBB if (sourceColor.m_A == base_mask) { Blender.CopyPixel(pDestBuffer, sourceColor); } else #endif { recieveBlender.BlendPixel(destBuffer, bufferOffset, sourceColor); } } } }
void SubPixRender(IImageReaderWriter dest, Scanline scanline, ColorRGBA color) { byte[] covers = scanline.GetCovers(); int num_spans = scanline.SpanCount; int y = scanline.Y; byte[] buffer = dest.GetBuffer(); IPixelBlender blender = dest.GetRecieveBlender(); int last_x = int.MinValue; int prev_cover = 0; int bufferOffset = 0; ColorRGBA prevColor = ColorRGBA.White; for (int i = 1; i <= num_spans; ++i) { //render span by span ScanlineSpan span = scanline.GetSpan(i); if (span.x != last_x + 1) { bufferOffset = dest.GetBufferOffsetXY(span.x, y); //when skip then reset prev_cover = 0; prevColor = ColorRGBA.White; } last_x = span.x; int num_pix = span.len; if (num_pix < 0) { //special encode*** num_pix = -num_pix; //make it positive value last_x += (num_pix - 1); //long span with coverage int coverageValue = covers[span.cover_index]; //------------------------------------------- if (coverageValue >= 255) { //100% cover int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; ColorRGBA newc = prevColor = new ColorRGBA(color.red, color.green, color.blue); ColorRGBA todrawColor = new ColorRGBA(newc, a); prev_cover = 255;//full while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } else { prev_cover = coverageValue; int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; ColorRGBA newc = prevColor = new ColorRGBA(color.red, color.green, color.blue); ColorRGBA todrawColor = new ColorRGBA(newc, a); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } } else { int coverIndex = span.cover_index; last_x += (num_pix - 1); while (num_pix > 0) { int coverageValue = covers[coverIndex++]; if (coverageValue >= 255) { //100% cover ColorRGBA newc = new ColorRGBA(color.red, color.green, color.blue); prevColor = newc; int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); prev_cover = 255;//full } else { //check direction : bool isLeftToRight = coverageValue >= prev_cover; prev_cover = coverageValue; byte c_r, c_g, c_b; float subpix_percent = ((float)(coverageValue) / 256f); if (coverageValue < cover_1_3) { if (isLeftToRight) { c_r = 255; c_g = 255; c_b = (byte)(255 - (255f * (subpix_percent))); } else { c_r = (byte)(255 - (255f * (subpix_percent))); c_g = 255; c_b = 255; } ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); } else if (coverageValue < cover_2_3) { if (isLeftToRight) { c_r = prevColor.blue; c_g = (byte)(255 - (255f * (subpix_percent))); c_b = color.blue; } else { c_r = color.blue; c_g = (byte)(255 - (255f * (subpix_percent))); c_b = 255; } ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); } else { //cover > 2/3 but not full if (isLeftToRight) { c_r = (byte)(255 - (255f * (subpix_percent))); c_g = color.green; c_b = color.blue; } else { c_r = prevColor.green; c_g = prevColor.blue; c_b = (byte)(255 - (255f * (subpix_percent))); } ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); } } bufferOffset += 4; //1 pixel 4 bits --num_pix; } } } }