Home » U++ Library support » Draw, Display, Images, Bitmaps, Icons » Painter and viewports 
	
		
		
			| Painter and viewports [message #43961] | 
			Sat, 29 November 2014 12:30   | 
		 
		
			
				
				
				
					
						  
						mdelfede
						 Messages: 1310 Registered: September 2007 
						
					 | 
					Ultimate Contributor  | 
					 | 
		 
		 
	 | 
 
	
		Hi, I'm using painter to draw inside a big working area, let's say of 20'000 (millimeters) 
size, given by a rectangle from (-10000, -10000) to (10000, 10000). 
To do this, I write: 
 
PaintingPainter sw(20000, 20000);
sw.Translate(-10000, -10000);
  
 
I guess it's correct. 
Now I want to take a viewport of my big area and display it inside a control, like 
following picture: 
 
  
 
Viewport is given by its origin and a zoom/scale factor. 
I can't find a way to do it.... 
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	
		
		
			| Re: Painter and viewports [message #43964 is a reply to message #43961] | 
			Mon, 01 December 2014 20:07    | 
		 
		
			
				
				
				
					
						  
						Didier
						 Messages: 736 Registered: November 2008  Location: France
						
					 | 
					Contributor   | 
					 | 
		 
		 
	 | 
 
	
		Hello Massimo, 
 
I think Painter and Drawing has all you need. 
You don't need to create PaintingPainter sw(20000, 20000);  with such a big size. 
All you need to do is: 
 
 PaintingPainter sw(viewPortXsize, viewPortYsize); 
 sw.Offset(viewportOrigin); 
 .... paint you're data 
 sw.end(); 
 
Ideally you may not even need to allocate a PaintingPainter ==> if Draw interface is sufficient you can reuse the draw instance of the control passed to ViewportCtrl::Paint() 
 
If you really need to use painter, I use the following code (or something close to it), look at GraphDraw::Paint()  method (in svn repo). 
ViewportCtrl::Paint(Draw& w) {
	ImageBuffer ib( Size() ); // Ctrl size
	Upp::Fill( ib.Begin(), bckgColor, ib.GetLength() ); // if you use transparent colors, you will need this
	BufferPainter bp(ib, drawMode);
	bp.Offset(viewportOrigin);
	.... paint you're data
	sw.end();
	DrawImage(0, 0, bp);
}
 
 
In fact, the data is first drawn to an image (using painter) and then the image is draw to the Ctrl 
Not very efficient, but I don't know a better way to achieve this when you use Painter. 
 
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	
		
		
			| Re: Painter and viewports [message #43965 is a reply to message #43964] | 
			Mon, 01 December 2014 22:03    | 
		 
		
			
				
				
				
					
						  
						mdelfede
						 Messages: 1310 Registered: September 2007 
						
					 | 
					Ultimate Contributor  | 
					 | 
		 
		 
	 | 
 
	
		Hi Didier, 
 
thank you for answer. 
 
I use Painter because I need to work in floating point units, scale and so on, 
and I don't want to replicate all that stuff   
Btw, I use a big painting area because I just do drawing regens when I modify it, 
then I "move" the viewport over it to pan/zoom, so I spare some graphic calculations. 
 
I found a solution, anyways. 
Now I've got the problem of transparency. 
 
I need to paint 2 transparent drawings over a background, i.e.: 
 
	// create an imagebuffer to paint inside
	ImageBuffer ib(sz);
	
	// place it on requested viewport
	BufferPainter bp(ib);
	bp.Scale(scale, scale);
	bp.Translate(-x1 - WORK_AREA / 2, -y1 + WORK_AREA / 2);
	
	// paint work area
	INTERLOCKED_(doc->RegenMutex()) {
		One<PaintingPainter> &workArea = doc->GetWorkArea();
		if(!workArea.IsEmpty())
			bp.Paint(*workArea);
	}
	// paint overlayer
	bp.Paint(*doc->GetOverlayArea());
	
	// display it
	w.DrawImage(0, 0, ib);
 
 
workArea and overlayArea are both cleared with RGBAZero() color. 
But when I paint on bp object (which has a white background...) I get garbage. 
If I clear the painters with a color, all is ok, but I loose the overlay stuff.
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |   
Goto Forum:
 
 Current Time: Tue Nov 04 08:42:03 CET 2025 
 Total time taken to generate the page: 0.03549 seconds 
 |