Text Annotation Questions

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
Post Reply
rsb
I live to help wx-kind
I live to help wx-kind
Posts: 170
Joined: Fri May 29, 2015 7:26 pm

Text Annotation Questions

Post by rsb »

Hello,

We're using the wxPdfDC class to plot electronic schematics and at the same time add text annotations
in the PDF that display when a user hovers over a component body to display component information.

I have a couple of questions:

1. When using the wxPdfDC class we're able to display component bodies (rectangles) using the same location points
we use when displaying them in our wxPanel object using a wxDC object and it all works well.

When defining text annotations using the wxPdfDocument class using the same locations used in the wxDC class
the Annotation locations are way off. Is there a routine that transforms the wxPdfDC locations to wxPdfDocument
locations. I see the routines called ScaleLogicalToPdfX and ScaleLogicalToPdfY in the wxPdfDCImpl class but
they're private.

I was able to copy the code from the ScaleLogicalToPdfX,Y routines into our main draw routines and the result
looks good but I'm not sure it's the best way. See below.

// ScaleLogicalToPdfX
double docScaleX = 72.0 / ((double) dc.GetPPI().GetX() * pPdfDocument->GetScaleFactor()) ;
double xVal = docScaleX * (((double)((point2.x - dc.GetLogicalOrigin().x) * 1) * pPdfDocument->GetScaleFactor()) +
dc.GetDeviceOrigin().x + dc.GetLogicalOrigin().x) ;

2. After plotting the schematic, there's a blank spot on the component body where the text annotation is placed.
Is this by design or have I done something wrong? Not sure where it's coming from. I've attached two images, the
first is a block component displayed in our wxPanel using a wxDC object and the second is the same block
component displayed in the PDF viewer. Notice the blank spot in the upper left corner of the rectangle.

Thank you very much.
Robert.

wxWidgets 3.1.0 on WIndows 7 Pro.
Using the current source code from wxPdfDocument at github
Attachments
BlockDC1.PNG
BlockDC1.PNG (7.15 KiB) Viewed 2589 times
BlockPDF1.PNG
BlockPDF1.PNG (6.3 KiB) Viewed 2589 times
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Text Annotation Questions

Post by utelle »

rsb wrote:1. When using the wxPdfDC class we're able to display component bodies (rectangles) using the same location points
we use when displaying them in our wxPanel object using a wxDC object and it all works well.

When defining text annotations using the wxPdfDocument class using the same locations used in the wxDC class
the Annotation locations are way off. Is there a routine that transforms the wxPdfDC locations to wxPdfDocument
locations. I see the routines called ScaleLogicalToPdfX and ScaleLogicalToPdfY in the wxPdfDCImpl class but
they're private.
I think there would be no harm in making these methods public, since they do not change the wxPdfDC state. So, please test whether this change would solve your problem, and report back the result. You may also open an issue on github.
rsb wrote:2. After plotting the schematic, there's a blank spot on the component body where the text annotation is placed.
Is this by design or have I done something wrong? Not sure where it's coming from. I've attached two images, the
first is a block component displayed in our wxPanel using a wxDC object and the second is the same block
component displayed in the PDF viewer. Notice the blank spot in the upper left corner of the rectangle.
Unfortunately, screen shots do not help to analyze what might cause the unwanted rectangle. I would have to see at least the source code which is used to generate the annotation (and maybe other parts of the document).

However, it could be an effect introduced by the PDF viewer. For example, Acrobat Reader shows a rectangle with an icon at the place where the annotation is located.

I have to admit that support for annotations in wxPdfDocument is limited. In principle, the PDF specification allows to tweak the visual appearance of annotations, but that's currently not supported in wxPdfDocument.

Regards,

Ulrich
rsb
I live to help wx-kind
I live to help wx-kind
Posts: 170
Joined: Fri May 29, 2015 7:26 pm

Re: Text Annotation Questions

Post by rsb »

Thanks very much for your response.

Here's the snippet of code we're using to annotate:

-------------------------
std::string object_name ; // Set to the component name.
wxPoint point ; // Set to the origin of the graphic object, rectangle path, polygon, etc.

wxPdfDocument *pPdfDocument = ((wxPdfDC &) dc).GetPdfDocument() ;

double xVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfX(point.x) ;
double yVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfY(point.y) ;

pPdfDocument->Annotate(xVal,yVal,wxString::Format("%s",object_name.c_str())) ;
-------------------------

We also tried to use a link to create a popup tip window with a message in it.

Here's the similar snippet of code we tried:

-------------------------
std::string object_name ; // Set to the component name.
wxPoint point ; // Set to the origin of the graphic object, rectangle path, polygon, etc.

wxPdfDocument *pPdfDocument = ((wxPdfDC &) dc).GetPdfDocument() ;

double xVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfX(point.x) ;
double yVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfY(point.y) ;

int linkID = pPdfDocument->AddLink() ;
//pPdfDocument->Write(5, wxString::Format("%s",object_name.c_str()), wxPdfLink(linkID)) ;
pPdfDocument->Link(xVal, yVal, 50, 50, wxPdfLink(linkID)) ;
-------------------------

After running the above, I see a rectangular transparent white box when I select (LMB) in the area of the link.

Is there a way to insert text into this box. I tried the Write method, but I get an error from Acrobat
when I do.

What we would really like is to select within the boundary of an object and see a tip window with information
about the object. Is there a way to do this?

Thanks very much.
Robert
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Text Annotation Questions

Post by utelle »

rsb wrote:Thanks very much for your response.

Here's the snippet of code we're using to annotate:

Code: Select all

std::string object_name ; // Set to the component name.
wxPoint point ; // Set to the origin of the graphic object, rectangle path, polygon, etc.

wxPdfDocument *pPdfDocument = ((wxPdfDC &) dc).GetPdfDocument() ;

double xVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfX(point.x) ;
double yVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfY(point.y) ;

pPdfDocument->Annotate(xVal,yVal,wxString::Format("%s",object_name.c_str())) ;
This looks ok. However, the PDF viewer will always use the default appearance of text annotations (for Acrobat Reader this is usually a small rectangular icon looking like a small page with lines of text; it may be different for other PDF viewers). It would be necessary to extend wxPdfDocument, if better annotation support is required.
rsb wrote:We also tried to use a link to create a popup tip window with a message in it.

Here's the similar snippet of code we tried:

Code: Select all

std::string object_name ; // Set to the component name.
wxPoint point ; // Set to the origin of the graphic object, rectangle path, polygon, etc.

wxPdfDocument *pPdfDocument = ((wxPdfDC &) dc).GetPdfDocument() ;

double xVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfX(point.x) ;
double yVal = ((wxPdfDCImpl *) ((wxPdfDC &) dc).GetImpl())->ScaleLogicalToPdfY(point.y) ;

int linkID = pPdfDocument->AddLink() ;
//pPdfDocument->Write(5, wxString::Format("%s",object_name.c_str()), wxPdfLink(linkID)) ;
pPdfDocument->Link(xVal, yVal, 50, 50, wxPdfLink(linkID)) ;
After running the above, I see a rectangular transparent white box when I select (LMB) in the area of the link.

Is there a way to insert text into this box. I tried the Write method, but I get an error from Acrobat when I do.
Without knowing the error message you get, it's hard to tell what's going wrong. Maybe the current writing position within the PDF document is not properly set. The following lines of code should give you a clickable rectangular area with the given text.

Code: Select all

// Save current positions (might not be necessary)
double xSave = pPdfDocument->GetX();
double ySave = pPdfDocument->GetY();

// Set link position
pPdfDocument->SetXY(xVal, yVal);

// Draw link text with associated link
pPdfDocument->Cell(50, 50, "Your link text", wxPDF_BORDER_NONE, 0, wxPDF_ALIGN_LEFT, 0, wxPdfLink(linkID));

// Restore current position
pPdfDocument->SetXY(xSave, ySave);

// Additionally specify to which position in the document to jump if the link is clicked
pPdfDocument->SetLink(linkID, yPosOnTargetPage, pageTarget);
rsb wrote:What we would really like is to select within the boundary of an object and see a tip window with information
about the object. Is there a way to do this?
AFAIK the PDF specification supports pop up annotations. However, wxPdfDocument currently only supports simple text annotations. At the moment I have no concrete plans to extend the annotation feature of wxPdfDocument. I'm sorry that I can't give you a more pleasing answer.

Regards,

Ulrich
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Text Annotation Questions

Post by utelle »

utelle wrote:
rsb wrote:1. When using the wxPdfDC class we're able to display component bodies (rectangles) using the same location points
we use when displaying them in our wxPanel object using a wxDC object and it all works well.

When defining text annotations using the wxPdfDocument class using the same locations used in the wxDC class
the Annotation locations are way off. Is there a routine that transforms the wxPdfDC locations to wxPdfDocument
locations. I see the routines called ScaleLogicalToPdfX and ScaleLogicalToPdfY in the wxPdfDCImpl class but
they're private.
I think there would be no harm in making these methods public, since they do not change the wxPdfDC state. So, please test whether this change would solve your problem, and report back the result. You may also open an issue on github.
Just for your information: with the latest commit I made the scaling methods of the wxPdfDC implementation public, so you don't have to duplicate their code anymore.

Regards,

Ulrich
Post Reply