Text Annotation Questions

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
rsb
Experienced Solver
Experienced Solver
Posts: 89
Joined: Fri May 29, 2015 7:26 pm

Text Annotation Questions

Postby rsb » Wed Jun 07, 2017 9:10 pm

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 149 times
BlockPDF1.PNG
BlockPDF1.PNG (6.3 KiB) Viewed 149 times

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

Re: Text Annotation Questions

Postby utelle » Thu Jun 08, 2017 4:58 pm

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
Experienced Solver
Experienced Solver
Posts: 89
Joined: Fri May 29, 2015 7:26 pm

Re: Text Annotation Questions

Postby rsb » Fri Jun 09, 2017 2:06 pm

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: 754
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Text Annotation Questions

Postby utelle » Fri Jun 09, 2017 9:23 pm

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: 754
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Text Annotation Questions

Postby utelle » Sat Jul 01, 2017 12:54 pm

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


Return to “wxCode”

Who is online

Users browsing this forum: No registered users and 1 guest