protected virtual void CustomRenderSingleScanLine( IImageReaderWriter dest, Scanline scline, ColorRGBA color) { //implement }
public void RenderScanline( IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { #if DEBUG int dbugMinScanlineCount = 0; #endif //1. ensure single line buffer width _grayScaleLine.EnsureLineStride(dest.Width + 4); //2. setup vars byte[] dest_buffer = dest.GetBuffer(); int dest_w = dest.Width; int dest_h = dest.Height; int dest_stride = dest.Stride; int src_w = dest_w; int src_stride = dest_stride; //*** set color before call Blend() this._color = color; byte color_alpha = color.alpha; //--------------------------- //3. loop, render single scanline with subpixel rendering byte[] lineBuff = _grayScaleLine.GetInternalBuffer(); while (sclineRas.SweepScanline(scline)) { //3.1. clear _grayScaleLine.Clear(); //3.2. write grayscale span to temp buffer //3.3 convert to subpixel value and write to dest buffer //render solid single scanline int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len _grayScaleLine.SubPixBlendSolidHSpan(span.x, span.len, color_alpha, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); _grayScaleLine.SubPixBlendHL(x, x2, color_alpha, covers[span.cover_index]); } } BlendScanline(dest_buffer, dest_stride, scline.Y, src_w, src_stride, lineBuff); #if DEBUG dbugMinScanlineCount++; #endif } }
public void RenderWithColor(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); switch (this.ScanlineRenderMode) { default: { while (sclineRas.SweepScanline(scline)) { //render solid single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len dest.BlendSolidHSpan(span.x, y, span.len, color, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); dest.BlendHL(x, y, x2, color, covers[span.cover_index]); } } } } break; case Agg.ScanlineRenderMode.SubPixelRendering: { scSubPixRas.RenderScanline(dest, sclineRas, scline, color); } break; case Agg.ScanlineRenderMode.Custom: { while (sclineRas.SweepScanline(scline)) { CustomRenderSingleScanLine(dest, scline, color); } } break; } }
public void RenderWithSpan(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, ISpanGenerator spanGenerator) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); spanGenerator.Prepare(); if (dest.Stride / 4 > (tempSpanColors.AllocatedSize)) { //if not enough -> alloc more tempSpanColors.Clear(dest.Stride / 4); } ColorRGBA[] colorArray = tempSpanColors.Array; while (sclineRas.SweepScanline(scline)) { //render single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); int x = span.x; int span_len = span.len; bool firstCoverForAll = false; if (span_len < 0) { span_len = -span_len; firstCoverForAll = true; } //make absolute value //1. generate colors -> store in colorArray spanGenerator.GenerateColors(colorArray, 0, x, y, span_len); //2. blend color in colorArray to destination image dest.BlendColorHSpan(x, y, span_len, colorArray, 0, covers, span.cover_index, firstCoverForAll); } } }
public void Draw( ScanlineRasToDestBitmapRenderer sclineRasToBmp, ScanlineRasterizer ras, Scanline sl, IImageReaderWriter destImage, ColorRGBA color, double x, double y) { ras.Reset(); ras.MoveTo(x * m_size, y * m_size); ras.LineTo(x * m_size + m_size, y * m_size); ras.LineTo(x * m_size + m_size, y * m_size + m_size); ras.LineTo(x * m_size, y * m_size + m_size); sclineRasToBmp.RenderWithColor(destImage, ras, sl, color); }
public static void RenderSolidAllPaths(this ScanlineRasToDestBitmapRenderer sclineRasToBmp, IImageReaderWriter destImage, ScanlineRasterizer sclineRas, Scanline scline, VertexStore vxs, Drawing.Color[] colors, int[] path_id, int num_paths) { for (int i = 0; i < num_paths; ++i) { sclineRas.Reset(); sclineRas.AddPath(new VertexStoreSnap(vxs, path_id[i])); sclineRasToBmp.RenderWithColor(destImage, sclineRas, scline, colors[i]); } }
void SubPixRender(IImageReaderWriter dest, Scanline scanline, Color 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 bufferOffset = 0; //------------------------------------------ Color bgColor = Color.White; float cb_R = bgColor.R / 255f; float cb_G = bgColor.G / 255f; float cb_B = bgColor.B / 255f; float cf_R = color.R / 255f; float cf_G = color.G / 255f; float cf_B = color.B / 255f; //------------------------------------------ int prevCover = -1; 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); } 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; Color todrawColor = Color.FromArgb(a, Color.FromArgb(color.R, color.G, color.B)); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } else { int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; Color newc = Color.FromArgb(color.R, color.G, color.B); Color todrawColor = Color.FromArgb(a, newc); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } prevCover = coverageValue; } else { int coverIndex = span.cover_index; last_x += (num_pix - 1); while (num_pix > 0) { int coverageValue = covers[coverIndex++]; if (coverageValue >= 255) { //100% cover Color newc = Color.FromArgb(color.R, color.G, color.B); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, newc)); prevCover = coverageValue; } else { //check direction : bool isUpHill = coverageValue >= prevCover; //if (isUpHill != ((coverageValue % 2) > 0)) //{ //} //---------------------------- byte c_r = 0, c_g = 0, c_b = 0; //---------------------------- //assume lcd screen is RGB float subpix_percent = ((float)(coverageValue) / 256f); if (coverageValue < cover_1_3) { //assume LCD color arrangement is BGR if (isUpHill) { c_r = bgColor.R; c_g = bgColor.G; c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255); c_g = bgColor.G; c_b = bgColor.B; } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } else if (coverageValue < cover_2_3) { if (isUpHill) { c_r = bgColor.R; c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255); c_b = (byte)(mix(cb_B, cf_B, 1) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, 1) * 255); c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255); c_b = bgColor.B; } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } else { //cover > 2/3 but not full if (isUpHill) { c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255); c_g = (byte)(mix(cb_G, cf_G, 1) * 255); c_b = (byte)(mix(cb_B, cf_B, 1) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, 1) * 255); c_g = (byte)(mix(cb_G, cf_G, 1) * 255); c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255); } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } } bufferOffset += 4; //1 pixel 4 bits --num_pix; prevCover = coverageValue; } } } }
protected virtual void CustomRenderSingleScanLine( IImageReaderWriter dest, Scanline scline, Color color) { //implement }
public void RenderWithSpan(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, ISpanGenerator spanGenerator) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); spanGenerator.Prepare(); if (dest.Stride / 4 > (tempSpanColors.AllocatedSize)) { //if not enough -> alloc more tempSpanColors.Clear(dest.Stride / 4); } Color[] colorArray = tempSpanColors.Array; while (sclineRas.SweepScanline(scline)) { //render single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); int x = span.x; int span_len = span.len; bool firstCoverForAll = false; if (span_len < 0) { span_len = -span_len; firstCoverForAll = true; } //make absolute value //1. generate colors -> store in colorArray spanGenerator.GenerateColors(colorArray, 0, x, y, span_len); //2. blend color in colorArray to destination image dest.BlendColorHSpan(x, y, span_len, colorArray, 0, covers, span.cover_index, firstCoverForAll); } } }
public void RenderWithColor(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); switch (this.ScanlineRenderMode) { default: { //prev mode //this mode while (sclineRas.SweepScanline(scline)) { //render solid single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len dest.BlendSolidHSpan(span.x, y, span.len, color, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); dest.BlendHL(x, y, x2, color, covers[span.cover_index]); } } } } break; case Agg.ScanlineRenderMode.SubPixelRendering: { #if DEBUG int dbugMinScanlineCount = 0; #endif while (sclineRas.SweepScanline(scline)) { SubPixRender(dest, scline, color); #if DEBUG dbugMinScanlineCount++; #endif } } break; case Agg.ScanlineRenderMode.Custom: { while (sclineRas.SweepScanline(scline)) { CustomRenderSingleScanLine(dest, scline, color); } } break; } }
//-------------------------------------------------------------------- internal bool SweepScanline(Scanline scline) { for (;;) { if (m_scan_y > m_cellAARas.MaxY) { return(false); } scline.ResetSpans(); //------------------------- CellAA[] cells; int offset; int num_cells; m_cellAARas.GetCells(m_scan_y, out cells, out offset, out num_cells); int cover = 0; while (num_cells != 0) { unsafe { fixed(CellAA *cur_cell_h = &cells[0]) { CellAA *cur_cell_ptr = cur_cell_h + offset; int x = cur_cell_ptr->x; int area = cur_cell_ptr->area; cover += cur_cell_ptr->cover; //accumulate all cells with the same X while (--num_cells != 0) { offset++; //move next cur_cell_ptr++; //move next if (cur_cell_ptr->x != x) { break; } area += cur_cell_ptr->area; cover += cur_cell_ptr->cover; } if (area != 0) { //----------------------------------------------- //single cell, for antialias look //----------------------------------------------- int alpha = CalculateAlpha((cover << (poly_subpix.SHIFT + 1)) - area); if (alpha != 0) { scline.AddCell(x, alpha); } x++; } if ((num_cells != 0) && (cur_cell_ptr->x > x)) { //----------------------------------------------- //this is long span , continuous color, solid look //----------------------------------------------- int alpha = CalculateAlpha(cover << (poly_subpix.SHIFT + 1)); if (alpha != 0) { scline.AddSpan(x, (cur_cell_ptr->x - x), alpha); } } } } } if (scline.SpanCount != 0) { break; } ++m_scan_y; } scline.CloseLine(m_scan_y); ++m_scan_y; return(true); }
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; } } } }
//-------------------------------------------------------------------- internal bool SweepScanline(Scanline scline) { for (;;) { if (m_scan_y > m_cellAARas.MaxY) { return(false); } scline.ResetSpans(); CellAA[] cells; int offset; int num_cells; m_cellAARas.GetCells(m_scan_y, out cells, out offset, out num_cells); int cover = 0; while (num_cells != 0) { unsafe { fixed(CellAA *cur_cell_h = &cells[0]) { CellAA *cur_cell_ptr = cur_cell_h + offset; int alpha; int x = cur_cell_ptr->x; int area = cur_cell_ptr->area; cover += cur_cell_ptr->cover; //accumulate all cells with the same X while (--num_cells != 0) { offset++; //move next cur_cell_ptr++; //move next if (cur_cell_ptr->x != x) { break; } area += cur_cell_ptr->area; cover += cur_cell_ptr->cover; } if (area != 0) { alpha = CalculateAlpha((cover << (poly_subpix.SHIFT + 1)) - area); if (alpha != 0) { scline.AddCell(x, alpha); } x++; } if ((num_cells != 0) && (cur_cell_ptr->x > x)) { alpha = CalculateAlpha(cover << (poly_subpix.SHIFT + 1)); if (alpha != 0) { scline.AddSpan(x, (cur_cell_ptr->x - x), alpha); } } } //CellAA cur_cell = cells[offset]; //int x = cur_cell.x; //int area = cur_cell.area; //int alpha; //cover += cur_cell.cover; ////accumulate all cells with the same X //while (--num_cells != 0) //{ // offset++; // cur_cell = cells[offset]; // if (cur_cell.x != x) // { // break; // } // area += cur_cell.area; // cover += cur_cell.cover; //} //if (area != 0) //{ // alpha = CalculateAlpha((cover << (poly_subpix.SHIFT + 1)) - area); // if (alpha != 0) // { // scline.AddCell(x, alpha); // } // x++; //} //if ((num_cells != 0) && (cur_cell.x > x)) //{ // alpha = CalculateAlpha(cover << (poly_subpix.SHIFT + 1)); // if (alpha != 0) // { // scline.AddSpan(x, (cur_cell.x - x), alpha); // } //} } } if (scline.SpanCount != 0) { break; } ++m_scan_y; } scline.CloseLine(m_scan_y); ++m_scan_y; return(true); }
//-------------------------------------------------------------------- internal bool SweepScanline(Scanline scline) { for (; ; ) { if (m_scan_y > m_cellAARas.MaxY) { return false; } scline.ResetSpans(); //------------------------- CellAA[] cells; int offset; int num_cells; m_cellAARas.GetCells(m_scan_y, out cells, out offset, out num_cells); int cover = 0; while (num_cells != 0) { unsafe { fixed (CellAA* cur_cell_h = &cells[0]) { CellAA* cur_cell_ptr = cur_cell_h + offset; int x = cur_cell_ptr->x; int area = cur_cell_ptr->area; cover += cur_cell_ptr->cover; //accumulate all cells with the same X while (--num_cells != 0) { offset++; //move next cur_cell_ptr++; //move next if (cur_cell_ptr->x != x) { break; } area += cur_cell_ptr->area; cover += cur_cell_ptr->cover; } if (area != 0) { //----------------------------------------------- //single cell, for antialias look //----------------------------------------------- int alpha = CalculateAlpha((cover << (poly_subpix.SHIFT + 1)) - area); if (alpha != 0) { scline.AddCell(x, alpha); } x++; } if ((num_cells != 0) && (cur_cell_ptr->x > x)) { //----------------------------------------------- //this is long span , continuous color, solid look //----------------------------------------------- int alpha = CalculateAlpha(cover << (poly_subpix.SHIFT + 1)); if (alpha != 0) { scline.AddSpan(x, (cur_cell_ptr->x - x), alpha); } } } } } if (scline.SpanCount != 0) { break; } ++m_scan_y; } scline.CloseLine(m_scan_y); ++m_scan_y; return true; }