Print Page | Close Window

GetCanvasDC - ClipRect Problem

Printed From: Debenu Quick PDF Library - PDF SDK Community Forum
Category: For Users of the Library
Forum Name: I need help - I can help
Forum Description: Problems and solutions while programming with the Debenu Quick PDF Library and Debenu PDF Viewer SDK
URL: http://www.quickpdf.org/forum/forum_posts.asp?TID=2747
Printed Date: 23 Jan 26 at 9:25AM
Software Version: Web Wiz Forums 11.01 - http://www.webwizforums.com


Topic: GetCanvasDC - ClipRect Problem
Posted By: HNRSoftware
Subject: GetCanvasDC - ClipRect Problem
Date Posted: 05 Oct 13 at 1:23PM
Yes, I'm using old library version (8.15), but I can't find any reverence to changes/fixes in GetCanvasDC in the product history documentation since version 7.

The problem is that the TCanvas returned by GetCanvasDC seems to be perfectly valid in terms of being able to draw successfully  on it, and the resulting pdf file is perfectly sensible and valid, but the "ClipRect" of the Canvas, which is needed to decide if items will fit on the page, is not valid.  What appears to be happening is that, no matter what size the canvas actually is, it returns a ClipRect of (0,0,1920,1200), which is probably not coincidentally, my screen dimensions.

**Psuedo-code** -- not precisely "real" code

//test  function  -- QPDF_TCanvasProcessTStoPDF(....);
var h,w : integer;
var ACanvasHDC : HDC;
var ACanvas : TCanvas;
var QP : TQuickPDF;  //Quick PDF Library Version = 8.15
     begin
     ... set up and unlock QP ...
     h := 2200; w := 1700;  // 8.5"x11" at 200 dpi
     ACanvasHDC := QP.GetCanvasDC(w,h); 
     ACanvas.handle := ACanvasHDC;
     // now look at --> ACanvas.Cliprect=(0,0),(1920,1200)  ???
     // returns the same 1920x1200 for several different heights and widths.
     // I doubt if it is coincidence, but my desktop screen is 1920x1200
     end;



Replies:
Posted By: HNRSoftware
Date Posted: 05 Oct 13 at 1:46PM
By an odd coincidence, I found a work-around in some very old code to solve a totally different problem.  I am guessing these calls are to "windows" routines, which I must have understood at some point in the past.  Once I placed a call to this function right after setting ACanvas.handle, the ACanvas ClipRect returns the proper value.  There is still a bug here, but not a serious one any more.

             h := 2200; w := 1700;  // 8.5"x11" at 200 dpi
             ACanvasHDC := QP.GetCanvasDC(w,h); 
             ACanvas.Handle := ACanvasHDC;
             TCanvasSetClipRegion(ACanvas,Rect(0,0,w,h));


where:

Function  TCanvasSetClipRegion(ACanvas : TCanvas; R : TRect) : TRect;
var Rgn : HRGN;
     begin
     result := ACanvas.ClipRect;   // this return is to solve an old problem 10/2013
     Rgn := CreateRectRgn(R.Left,R.Top,R.Right,R.Bottom);
     SelectClipRgn(ACanvas.Handle, Rgn);
     DeleteObject(Rgn);
     end;



Posted By: HNRSoftware
Date Posted: 05 Oct 13 at 3:07PM
No.....  that wasn't quite right.....

The TCanvasSetClipRegion DID set the Canvas ClipRect, but ONLY as a sub-rectangle of the "real" Cliprect which the Canvas thinks is 1920x1200.  This makes some amount of sense - a "region" would be a portion of a canvas, and would not change the dimensions of the canvas itself.......

My initial testing was with 100 dpi pages (850x1100) which is a valid subset of 1900x1200.  When I went to 200 dpi, the width was still OK at 1700, but the height was being truncated at 1200 - should have been obvious, but I had to fumble around some.

So, I'm left with a Quick PDF Library bug, that when it creates the TCanvas, it needs to do whatever is necessary to place the proper width and height values wherever it is that they need to go in the TCanvas.  I suppose I could go look at source for wherever TCanvas is defined to see how "ClipRect" is actually stored.  I suspect that what I will do is just create a "VirtualClipRect" structure that reflects what ClipRect ought to say.  The actual TCanvas itself is OK, it just won't admit how big it actually is.....  Sigh.....


Posted By: AndrewC
Date Posted: 07 Oct 13 at 8:11AM
The TCanvas class is a wrapper around the windows GDI calls.  The DQPL function GetCanvasDC gets a standard Windows DC handle to the DQPL PDF Canvas.  This is not related to a Delphi TCanvas in any way.  So it makes sense that you would have to call  ACanvas.Handle := ACanvasHDC; to get it to select the correct page size.

Maybe there are a few other parameters required to be set manually to transfer a DC across to a TCanvas object.  

This is just a guess but might able to use the following code.

hpixels := GetDeviceCaps(ACanvasHDC, HORZRES); 
vpixles := GetDeviceCaps(ACanvasHDC, VERTRES); 
TCanvas.Width := hpixels;
TCanvas.Heigth := vpixels;

Hopefully these values are the same as the values you passed into GetCanvasDC.



Posted By: HNRSoftware
Date Posted: 07 Oct 13 at 3:13PM
Thank you Andrew - I suspected something like that, but didn't want to try to dig that deep.  The Delphi TCanvas object is protected such that I can't set any of those actual values (although there was a trick for accessing a TPanel canvas that I might track down and try to adapt).  It turns out that most of my historic code can quickly adapt to being told what the canvas cliprect is rather than using the property itself, so it wasn't too hard to work around the problem.  I just assumed that the QuickPDF code was creating an actual TCanvas and omitted a setting step, but I really forgot that the library is bigger than Delphi, although extremely Delphi-friendly.  



Print Page | Close Window

Forum Software by Web Wiz Forums® version 11.01 - http://www.webwizforums.com
Copyright ©2001-2014 Web Wiz Ltd. - http://www.webwiz.co.uk