void SoftwareRendererImp::draw_element(SVGElement* element) { // Task 4 (part 1): // Modify this to implement the transformation stack switch (element->type) { case POINT: draw_point(static_cast<Point&>(*element)); break; case LINE: draw_line(static_cast<Line&>(*element)); break; case POLYLINE: draw_polyline(static_cast<Polyline&>(*element)); break; case RECT: draw_rect(static_cast<Rect&>(*element)); break; case POLYGON: draw_polygon(static_cast<Polygon&>(*element)); break; case ELLIPSE: draw_ellipse(static_cast<Ellipse&>(*element)); break; case IMAGE: draw_image(static_cast<Image&>(*element)); break; case GROUP: draw_group(static_cast<Group&>(*element)); break; default: break; } }
/*-------------------------------------------------------------- Routine : draw_symbol Purpose : Draws the symbol. ---------------------------------------------------------------*/ void draw_symbol(Canvas canvas, CanvasCoord symbol_centre, SYMBOL *symbol) { SEGMENT *seg_list; ARC *arc; RECTANGLE *rect; POLYLINE *poly; LINE *line; ASSERT( symbol != NULL ); seg_list = symbol->segment_list; while (seg_list != NULL) { /* Identify and draw the segment type */ switch (seg_list->type) { case CLEAR_ARC_SEG : arc = (ARC *)(seg_list->seg); clear_arc(canvas, arc, symbol_centre); break; case FILL_ARC_SEG : arc = (ARC *)(seg_list->seg); fill_arc(canvas, arc, symbol_centre, symbol->type); break; case ARC_SEG : arc = (ARC *)(seg_list->seg); draw_arc(canvas, arc, symbol_centre); break; case RECTANGLE_SEG : rect = (RECTANGLE *)(seg_list->seg); draw_rectangle(canvas, rect, symbol_centre); break; case FILL_RECTANGLE_SEG : rect = (RECTANGLE *)(seg_list->seg); fill_rectangle(canvas, rect, symbol_centre, symbol->type); break; case FILL_POLYLINE_SEG : poly = (POLYLINE *)(seg_list->seg); fill_polyline(canvas, poly, symbol_centre, symbol->type); break; case POLYLINE_SEG : poly = (POLYLINE *)(seg_list->seg); draw_polyline(canvas, poly, symbol_centre); break; case LINE_SEG : line = (LINE *)(seg_list->seg); draw_line(canvas, line, symbol_centre); break; default: printf("\n*** draw_symbol : Invalid segment type ***\n\n"); exit(1); } seg_list = seg_list->next; } }
static void draw_polygon(DiaRenderer *object, Point *points, int num_points, Color *fill, Color *stroke) { Color *color = fill ? fill : stroke; DIAG_NOTE(g_message("draw_polygon n:%d %f,%f ...", num_points, points->x, points->y)); g_return_if_fail (color != NULL); draw_polyline(object,points,num_points, color); /* last to first */ draw_line(object, &points[num_points-1], &points[0], color); }
int draw_curve(const Vec coords[], size_t count) { int segc = 0; int ret; Vec* curve; if(coords == NULL) { return -1; // nurupo~ } for(int i = 0, j = 1; j < count; i++, j++) { segc += ceil(vecdist(coords[i], coords[j]) * 16); } curve = malloc(sizeof (Vec) * segc); if(curve == NULL) { return -1; // malloc error } for(int i = 0; i < segc; i++) { curve[i] = decasteljau(coords, count, (double)i / segc); } ret = draw_polyline(curve, segc); free(curve); return ret; }
void SoftwareRendererImp::draw_element( SVGElement* element ) { // Task 4 (part 1): // Modify this to implement the transformation stack //std::cout << element->transform << endl; //transform svg elements switch(element->type) { case POINT: { transformation = transformation * (element->transform); draw_point(static_cast<Point&>(*element)); transformation = transformation * (element->transform.inv()); break; } case LINE: { transformation = transformation * (element->transform); draw_line(static_cast<Line&>(*element)); transformation = transformation * (element->transform.inv()); break; } case POLYLINE: { transformation = transformation * (element->transform); draw_polyline(static_cast<Polyline&>(*element)); transformation = transformation * (element->transform.inv()); break; } case RECT: { transformation = transformation * (element->transform); draw_rect(static_cast<Rect&>(*element)); transformation = transformation * (element->transform.inv()); break; } case POLYGON: { transformation = transformation * (element->transform); draw_polygon(static_cast<Polygon&>(*element)); transformation = transformation * (element->transform.inv()); break; } case ELLIPSE: { transformation = transformation * (element->transform); draw_ellipse(static_cast<Ellipse&>(*element)); transformation = transformation * (element->transform.inv()); break; } case IMAGE: { transformation = transformation * (element->transform); draw_image(static_cast<Image&>(*element)); transformation = transformation * (element->transform.inv()); break; } case GROUP: { transformation = transformation * (element->transform); draw_group(static_cast<Group&>(*element)); transformation = transformation * (element->transform.inv()); break; } default: break; } }
// Parse the next command. BOOL WMFUpdateState::parse_next_command(BOOL *primitive) { BOOL fPrimitive = FALSE; // Remember the start of the record. ST_DEV_POSITION lRecordOffset; file.tell(&lRecordOffset); // Read the next record. METARECORD Record; if ((error = file.read(&Record, sizeof(Record)-sizeof(Record.rdParm))) != ERRORCODE_None) { return FALSE; } // TRACE("Record %d function: %04x, size: %08lx\n", m_nRecord, Record.rdFunction, Record.rdSize); // Process the record. switch (Record.rdFunction) { case 0: { // End of records. All done. return FALSE; } case META_ESCAPE: { // short n; // file.read(&n, sizeof(n)); // TRACE("Escape: %x\n", n); break; } case META_SETROP2: case META_SETRELABS: case META_SETMAPMODE: { // TRACE("IGNORED Record %d function: %04x, size: %08lx\n", m_nRecord, Record.rdFunction, Record.rdSize); break; } case META_SETTEXTALIGN: { short nAlign; file.read(&nAlign, sizeof(nAlign)); SetTextAlign(nAlign); break; } case META_SETBKCOLOR: { COLORREF Color; file.read(&Color, sizeof(Color)); SetBkColor(Color); break; } case META_SETBKMODE: { short nMode; file.read(&nMode, sizeof(nMode)); SetBkMode(nMode); break; } case META_SETTEXTCOLOR: { COLORREF Color; file.read(&Color, sizeof(Color)); SetTextColor(Color); break; } case META_SETWINDOWORG: { // Read the parameter. short Parms[2]; ASSERT(Record.rdSize == 5); file.read(Parms, sizeof(Parms)); m_DCState.m_cpWindowOrg.y = Parms[0]; m_DCState.m_cpWindowOrg.x = Parms[1]; NewSourceVars(); break; } case META_SETWINDOWEXT: { // Read the parameter. short Parms[2]; ASSERT(Record.rdSize == 5); file.read(Parms, sizeof(Parms)); m_DCState.m_cpWindowExt.y = Parms[0]; m_DCState.m_cpWindowExt.x = Parms[1]; NewSourceVars(); break; } case META_CREATEBRUSHINDIRECT: { CWMFBrushObject* pNewBrush = new CWMFBrushObject; file.read(&pNewBrush->m_LogBrush, sizeof(LOGBRUSH16)); NewObject(pNewBrush); break; } case META_DIBCREATEPATTERNBRUSH: { CWMFBrushObject* pNewBrush = new CWMFBrushObject; pNewBrush->m_LogBrush.lbStyle = BS_SOLID; pNewBrush->m_LogBrush.lbColor = RGB(128, 0, 0); NewObject(pNewBrush); break; } case META_CREATEPENINDIRECT: { CWMFPenObject* pNewPen = new CWMFPenObject; file.read(&pNewPen->m_LogPen, sizeof(LOGPEN16)); NewObject(pNewPen); // TRACE("New pen - s: %d; w: %d, %d; c: %08lx\n", // pNewPen->m_LogPen.lopnStyle, // pNewPen->m_LogPen.lopnWidth.x, // pNewPen->m_LogPen.lopnWidth.y, // pNewPen->m_LogPen.lopnColor); break; } case META_CREATEFONTINDIRECT: { CWMFFontObject* pNewFont = new CWMFFontObject; // Read the data. LOGFONT16 lf; file.read(&lf, sizeof(LOGFONT16)); // Translate it over. pNewFont->m_LogFont.lfHeight = lf.lfHeight; pNewFont->m_LogFont.lfWidth = lf.lfWidth; pNewFont->m_LogFont.lfEscapement = lf.lfEscapement; pNewFont->m_LogFont.lfOrientation = lf.lfOrientation; pNewFont->m_LogFont.lfWeight = lf.lfWeight; // Warning: hard-coded size ahead. memcpy(&pNewFont->m_LogFont.lfItalic, &lf.lfItalic, 8 + LF_FACESIZE); NewObject(pNewFont); break; } case META_CREATEPALETTE: { // This is mostly here to make sure the object array stays in sync. CWMFPaletteObject* pNewPalette = new CWMFPaletteObject; struct { WORD palVersion; WORD palNumEntries; } Header; file.read(&Header, sizeof(Header)); // Now we have the header. See how many entries we want. if (Header.palVersion == 0x0300) { int nPaletteSize = sizeof(PALETTEENTRY)*Header.palNumEntries; pNewPalette->m_pPalette = (LOGPALETTE*)new BYTE[sizeof(LOGPALETTE) + nPaletteSize - sizeof(PALETTEENTRY)]; pNewPalette->m_pPalette->palVersion = Header.palVersion; pNewPalette->m_pPalette->palNumEntries = Header.palNumEntries; file.read(pNewPalette->m_pPalette->palPalEntry, nPaletteSize); } NewObject(pNewPalette); break; } case META_CREATEREGION: { // This is mostly here to make sure the object array stays in sync. // I don't think there's hope of determining the parms format for // this record. CWMFRegionObject* pNewRegion = new CWMFRegionObject; NewObject(pNewRegion); break; } case META_SELECTPALETTE: case META_SELECTOBJECT: { short nIndex; file.read(&nIndex, sizeof(nIndex)); SelectObject(nIndex); // TRACE("SelectObject: %d\n", nIndex); break; } case META_DELETEOBJECT: { short nIndex; file.read(&nIndex, sizeof(nIndex)); DeleteObject(nIndex); // TRACE("DeleteObject: %d\n", nIndex); break; } case META_SETPOLYFILLMODE: { short nFillMode; file.read(&nFillMode, sizeof(nFillMode)); m_nFillMode = nFillMode; break; } case META_SETSTRETCHBLTMODE: { short nMode; file.read(&nMode, sizeof(nMode)); SetBltMode(nMode); break; } case META_POLYPOLYGON: { // Read the number of polygons. short nPolygons; file.read(&nPolygons, sizeof(nPolygons)); // Proceed to read counts and points (and draw). int* pCounts = NULL; POINT* pPoints = NULL; TRY { // Allocate the polygon counts. pCounts = new int[nPolygons]; // Read the polygon counts. int nPoints = 0; for (int nPolygon = 0; nPolygon < nPolygons; nPolygon++) { short p; file.read(&p, sizeof(p)); pCounts[nPolygon] = p; nPoints += p; } // Allocate the polygon points. pPoints = new POINT[nPoints]; // Read the polygon points. for (int nPoint = 0; nPoint < nPoints; nPoint++) { short p[2]; file.read(p, sizeof(p)); pPoints[nPoint].x = p[0]; pPoints[nPoint].y = p[1]; } // Draw the polypolygon. DrawPolyPolygon(pPoints, pCounts, nPolygons); } END_TRY delete [] pPoints; delete [] pCounts; fPrimitive = TRUE; break; } case META_POLYGON: { WORD wCount; file.read(&wCount, sizeof(wCount)); draw_polygon(wCount); fPrimitive = TRUE; break; } case META_POLYLINE: { WORD wCount; file.read(&wCount, sizeof(wCount)); draw_polyline(wCount, TRUE); fPrimitive = TRUE; break; } case META_ELLIPSE: { short Parms[4]; file.read(Parms, sizeof(Parms)); // Compute parameters to pass. // Parms[3] = left // Parms[2] = top // Parms[1] = right // Parms[0] = bottom OUTLINE_POINT center; center.x = (short)((int)Parms[3] + (int)Parms[1])/2; center.y = (short)((int)Parms[2] + (int)Parms[0])/2; short rx = Parms[3] - center.x; if (rx < 0) rx = -rx; short ry = Parms[2] - center.y; if (ry < 0) ry = -ry; draw_ellipse(center, rx, ry); fPrimitive = TRUE; break; } case META_ROUNDRECT: { // Cheat for now. Just draw it as a rectangle. // Skip the corner radii. file.seek(2*sizeof(short), ST_DEV_SEEK_CUR); // Fall through to... } case META_RECTANGLE: { short Parms[4]; file.read(Parms, sizeof(Parms)); // Parms[3] = left // Parms[2] = top // Parms[1] = right // Parms[0] = bottom OUTLINE_POINT p0, p1; p0.x = Parms[3]; p0.y = Parms[2]; p1.x = Parms[1]; p1.y = Parms[0]; draw_rectangle(p0, p1); fPrimitive = TRUE; break; } case META_DIBSTRETCHBLT: { // Read the numeric parameters. short Parms[10]; file.read(Parms, sizeof(Parms)); // Parms[0] = low-order word of raster op // Parms[1] = high-order word of raster op // Parms[2] = source y extent // Parms[3] = source x extent // Parms[4] = source y coordinate // Parms[5] = source x coordinate // Parms[6] = destination y extent // Parms[7] = destination x extent // Parms[8] = destination y coordinate // Parms[9] = destination x coordinate CRect crSource(CPoint(Parms[5], Parms[4]), CSize(Parms[3], Parms[2])); CRect crDest(CPoint(Parms[9], Parms[8]), CSize(Parms[7], Parms[6])); DWORD dwROP = MAKELONG(Parms[0], Parms[1]); // Process the rest of the dib blt. DoDibBlt(crSource, crDest, dwROP); fPrimitive = TRUE; break; } case META_DIBBITBLT: { // Read the numeric parameters. short Parms[7]; file.read(Parms, sizeof(Parms)); // Parms[0] = high-order word of raster op // Parms[1] = source y coordinate // Parms[2] = source x coordinate // Parms[3] = destination y extent // Parms[4] = destination x extent // Parms[5] = destination y coordinate // Parms[6] = destination x coordinate CRect crSource(CPoint(Parms[5], Parms[4]), CSize(Parms[7], Parms[6])); CRect crDest(CPoint(Parms[9], Parms[8]), CSize(Parms[7], Parms[6])); DWORD dwROP = MAKELONG(0, Parms[1]); // Process the rest of the dib blt. DoDibBlt(crSource, crDest, dwROP); fPrimitive = TRUE; break; } case META_STRETCHDIB: { // Read the numeric parameters. short Parms[11]; file.read(Parms, sizeof(Parms)); // Parms[0] = low-order word of raster op // Parms[1] = high-order word of raster op // Parms[2] = usage flag // Parms[3] = source y extent // Parms[4] = source x extent // Parms[5] = source y coordinate // Parms[6] = source x coordinate // Parms[7] = destination y extent // Parms[8] = destination x extent // Parms[9] = destination y coordinate // Parms[10] = destination x coordinate CRect crSource(CPoint(Parms[6], Parms[5]), CSize(Parms[4], Parms[3])); CRect crDest(CPoint(Parms[10], Parms[9]), CSize(Parms[8], Parms[7])); DWORD dwROP = MAKELONG(Parms[0], Parms[1]); WORD wUsage = (WORD)Parms[2]; // Process the rest of the dib blt. DoDibBlt(crSource, crDest, dwROP, wUsage); fPrimitive = TRUE; break; } case META_EXTTEXTOUT: { // Handle ExtTextOut call. // Read the numeric parameters. short Parms[4]; file.read(Parms, sizeof(Parms)); // Parms[0] = y // Parms[1] = x // Parms[2] = string length // Parms[3] = option flags RECTS rClip; if (Parms[3] != 0) { file.read(&rClip, sizeof(rClip)); } // String data follows int nStrLength = Parms[2]; int nStrSize = (nStrLength + 1) & ~1; LPBYTE pString = NULL; TRY { // Read the text. pString = new BYTE[nStrSize]; file.huge_read(pString, nStrSize); // See if there are any widths. ST_DEV_POSITION Here; file.tell(&Here); ST_DEV_POSITION lRecordEnd = lRecordOffset + Record.rdSize*sizeof(WORD); // TRACE("Count:%d; Here: %ld; lRecordEnd: %ld\n", // nStrLength, Here, lRecordEnd); int nDXSize = nStrLength*sizeof(short); short* pDX = NULL; if (lRecordEnd >= Here + nDXSize) { pDX = new short[nStrLength]; file.read(pDX, nDXSize); } OUTLINE_POINT p; p.x = (short)Parms[1]; p.y = (short)Parms[0]; RECT r; r.left = rClip.left; r.top = rClip.top; r.right = rClip.right; r.bottom = rClip.bottom; // Draw the text. DrawText(p, Parms[3], (LPCSTR)pString, nStrLength, &r, pDX); // Free the dx array. delete [] pDX; // Free the text. delete pString; } END_TRY fPrimitive = TRUE; break; } case META_TEXTOUT: { // Handle TextOut call. // Read the string size. short nStrLength; file.read(&nStrLength, sizeof(nStrLength)); int nStrSize = (nStrLength + 1) & ~1; LPBYTE pString = NULL; TRY { // Read the text. pString = new BYTE[nStrSize]; file.huge_read(pString, nStrSize); // Read the x and y. short Parms[2]; file.read(Parms, sizeof(Parms)); OUTLINE_POINT p; p.x = (short)Parms[1]; p.y = (short)Parms[0]; // Draw the text. DrawText(p, 0, (LPCSTR)pString, nStrLength, NULL); // Free the text. delete pString; } END_TRY fPrimitive = TRUE; break; } case META_MOVETO: case META_LINETO: { short Parms[2]; file.read(&Parms, sizeof(Parms)); // TRACE("%s: %d, %d\n", Record.rdFunction == META_MOVETO ? "MoveTo" : "LineTo", Parms[1], Parms[0]); OUTLINE_POINT p; p.x = Parms[1]; p.y = Parms[0]; if (Record.rdFunction == META_MOVETO) { // Move to. MoveTo(p); } else { // Must be Line to. LineTo(p); fPrimitive = TRUE; } break; } case META_PATBLT: { WORD Parms[6]; // Parms[0] - op low word // Parms[1] - op high word // Parms[2] - height // Parms[3] - width // Parms[4] - top // Parms[5] - left file.read(Parms, sizeof(Parms)); OUTLINE_POINT p0, p1; p0.x = Parms[5]; p0.y = Parms[4]; p1.x = p0.x + Parms[3]; p1.y = p0.y + Parms[2]; DoPatBlt(p0, p1, MAKELONG(Parms[0], Parms[1])); fPrimitive = TRUE; break; } case META_PIE: case META_ARC: { short Parms[8]; // Parms[0] = y4 end pt y // Parms[1] = x4 end pt x // Parms[2] = y3 start pt y // Parms[3] = x3 start pt x // Parms[4] = y2 Bound bottom // Parms[5] = x2 Bound right // Parms[6] = y1 Bound top // Parms[7] = x1 Bound left file.read(Parms, sizeof(Parms)); OUTLINE_POINT Center; Center.x = (short)midpoint(Parms[7], Parms[5]); Center.y = (short)midpoint(Parms[6], Parms[4]); double rx = Parms[5] - Center.x; if (rx < 0) rx = -rx; double ry = Parms[4] - Center.y; if (ry < 0) ry = -ry; double dStart = angle_from_vector(Parms[2] - Center.y, Parms[3] - Center.x); double dEnd = angle_from_vector(Parms[0] - Center.y, Parms[1] - Center.x); draw_elliptical_arc(Center, rx, ry, dStart-PI/2, dEnd-PI/2, (Record.rdFunction == META_PIE) ? 1 : -1); break; } case META_SAVEDC: { PushState(); break; } case META_RESTOREDC: { PopState(); break; } case META_SCALEVIEWPORTEXT: { // Read the parameter. short Parms[4]; // Parms[0] = ydenom // Parms[1] = ynum // Parms[2] = xdenom // Parms[3] = xnum file.read(Parms, sizeof(Parms)); m_DCState.m_cpViewportScaleNum.x = Parms[3]; m_DCState.m_cpViewportScaleDenom.x = Parms[2]; m_DCState.m_cpViewportScaleNum.y = Parms[1]; m_DCState.m_cpViewportScaleDenom.y = Parms[0]; NewSourceVars(); break; } default: { TRACE("UNKNOWN Record %d function: %04x, size: %08lx\n", m_nRecord, Record.rdFunction, Record.rdSize); break; } } m_nRecord++; // Seek past the record file.seek(lRecordOffset + Record.rdSize*sizeof(WORD), ST_DEV_SEEK_SET); *primitive = fPrimitive; return TRUE; }
gint button_press_event( GtkWidget *widget, GdkEventButton *event ) { modified=1; if (event->button == 1 && pixmap != NULL) switch(tool) { case RECT_SEL: gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); pre_x=event->x; pre_y=event->y; select_rectangular_region(widget,event->x,event->y,1); last_x=event->x; last_y=event->y; break; case ERASER: gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); last_x=event->x; last_y=event->y; eraser(widget,event->x,event->y); break; case LINE: gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); pre_x=event->x; pre_y=event->y; draw_line(widget,event->x,event->y,0); last_x=event->x; last_y=event->y; break; case TEXT: gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); draw_text(widget,event->x,event->y); break; case BRUSH:gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); last_x=event->x; last_y=event->y; paintbrush(widget,event->x,event->y); break; case SPRAYCAN:gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); last_x=event->x; last_y=event->y; spraycan(widget,event->x,event->y); break; case PENCIL:gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); last_x=event->x; last_y=event->y; draw_using_pencil(widget,event->x,event->y); break; case BUCKET: bucketfill(widget,event->x,event->y); break; case COLORPICK: gdk_gc_copy(undo_gc,fg_gc); undoflag=1; colorpicker(widget,event->x,event->y); break; case POLYLINE:if(!poly) {pre_x=event->x; pre_y=event->y; poly++;} draw_polyline(widget,event->x,event->y,1); break; case ELLIPSE:gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); pre_x=event->x; pre_y=event->y; draw_arc(widget,event->x,event->y,0); last_x=event->x; last_y=event->y; break; case POLYGON:if(!poly) { pre_x=event->x; pre_y=event->y; last_x=event->x; last_y=event->y; poly++; } draw_polygon(widget,event->x,event->y,1); break; case RECTANGLE:gdk_draw_drawable(undomap,fg_gc,pixmap,0,0,0,0,-1,-1); pre_x=event->x; pre_y=event->y; draw_rectangle(widget,event->x,event->y,0); last_x=event->x; last_y=event->y; break; } return TRUE; }
inline void draw(const quadratic_bezier<T,2>& bezier, const std::size_t& point_count) { std::vector< point2d<T> > point_list; wykobi::generate_bezier(bezier,point_count,point_list); draw_polyline(point_list); }
virtual void on_draw() { pixfmt pf(rbuf_window()); renderer_base ren_base(pf); ren_base.clear(agg::rgba(0.5, 0.75, 0.85)); renderer_scanline ren(ren_base); rasterizer_scanline ras; scanline sl; ras.clip_box(0, 0, width(), height()); // Pattern source. Must have an interface: // width() const // height() const // pixel(int x, int y) const // Any agg::renderer_base<> or derived // is good for the use as a source. //----------------------------------- pattern_src_brightness_to_alpha_rgba8 p1(rbuf_img(0)); agg::pattern_filter_bilinear_rgba8 fltr; // Filtering functor // agg::line_image_pattern is the main container for the patterns. It creates // a copy of the patterns extended according to the needs of the filter. // agg::line_image_pattern can operate with arbitrary image width, but if the // width of the pattern is power of 2, it's better to use the modified // version agg::line_image_pattern_pow2 because it works about 15-25 percent // faster than agg::line_image_pattern (because of using simple masking instead // of expensive '%' operation). typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::renderer_base<pixfmt> base_ren_type; typedef agg::renderer_outline_image<base_ren_type, pattern_type> renderer_img_type; typedef agg::rasterizer_outline_aa<renderer_img_type, agg::line_coord_sat> rasterizer_img_type; typedef agg::renderer_outline_aa<base_ren_type> renderer_line_type; typedef agg::rasterizer_outline_aa<renderer_line_type, agg::line_coord_sat> rasterizer_line_type; //-- Create with specifying the source //pattern_type patt(fltr, src); //-- Create uninitialized and set the source pattern_type patt(fltr); patt.create(p1); renderer_img_type ren_img(ren_base, patt); rasterizer_img_type ras_img(ren_img); //-- create uninitialized and set parameters agg::line_profile_aa profile; profile.smoother_width(10.0); //optional profile.width(8.0); //mandatory! renderer_line_type ren_line(ren_base, profile); ren_line.color(agg::rgba8(0,0,127)); //mandatory! rasterizer_line_type ras_line(ren_line); ras_line.round_cap(true); //optional //ras_line.line_join(agg::outline_no_join); //optional // Calculate the dilation value so that, the line caps were // drawn correctly. //--------------- double w2 = 9.0;//p1.height() / 2 + 2; // Set the clip box a bit bigger than you expect. You need it // to draw the clipped line caps correctly. The correct result // is achieved with raster clipping. //------------------------ ren_img.scale_x(m_scale_x.value()); ren_img.start_x(m_start_x.value()); ren_img.clip_box (50-w2, 50-w2, width()-50+w2, height()-50+w2); ren_line.clip_box(50-w2, 50-w2, width()-50+w2, height()-50+w2); // First, draw polyline without raster clipping just to show the idea //------------------------ draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points()); draw_polyline(ras_img, ren_img, m_line1.polygon(), m_line1.num_points()); // Clear the area, almost opaque, but not completely //------------------------ ren_base.blend_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1), 200); // Set the raster clip box and then, draw again. // In reality there shouldn't be two calls above. // It's done only for demonstration //------------------------ ren_base.clip_box((int)50, (int)50, (int)width()-50, (int)height()-50); // This "copy_bar" is also for demonstration only //------------------------ ren_base.copy_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1)); // Finally draw polyline correctly clipped: We use double clipping, // first is vector clipping, with extended clip box, second is raster // clipping with normal clip box. //------------------------ ren_img.scale_x(m_scale_x.value()); ren_img.start_x(m_start_x.value()); draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points()); draw_polyline(ras_img, ren_img, m_line1.polygon(), m_line1.num_points()); // Reset clipping and draw the controls and stuff ren_base.reset_clipping(true); m_line1.line_width(1/m_scale.scale()); m_line1.point_radius(5/m_scale.scale()); agg::render_ctrl(ras, sl, ren_base, m_line1); agg::render_ctrl(ras, sl, ren_base, m_scale_x); agg::render_ctrl(ras, sl, ren_base, m_start_x); char buf[256]; agg::gsv_text t; t.size(10.0); agg::conv_stroke<agg::gsv_text> pt(t); pt.width(1.5); pt.line_cap(agg::round_cap); const double* p = m_line1.polygon(); sprintf(buf, "Len=%.2f", agg::calc_distance(p[0], p[1], p[2], p[3]) * m_scale.scale()); t.start_point(10.0, 30.0); t.text(buf); ras.add_path(pt); ren.color(agg::rgba(0,0,0)); agg::render_scanlines(ras, sl, ren); }