Drawing custom objects with XFRX#DRAW
The XFRX#DRAW class described in the previous chapter is also able to modify the content of XFF files: to add custom graphics, text, new pages, hyperlinks and bookmarks, both during the report generation process as well as after the report is generated.
Drawing custom objects to existing XFF files
To add custom graphics objects to XFF files, instantiate the XFRX#DRAW object as described in previous chapter and use the properties and methods described in chapter 17.3 XFRX#DRAW functions below. All changes are immediately written to the XFF file and once the XFRX#DRAW class reference is released, the changes are written to the disk (or other media the XFF file is stored on).
Drawing custom objects during report generation process
Alternatively, you can create scripts, which can be invoked on the fly, during the report generation process. These scripts can either be implemented as methods of a class, or, for rectangle-bound scripts, can be entered into a comment field of a rectangle object on the report.
In XFRX for VFP 9.0, the XFF file is always internally used when a report is processed. However, in XFRX for VFP 8.0, you can generate the target documents “directly”, in which case, however, the XFF scripts would not be evaluated.
Page-bound scripts
The page-bound scripts are implemented as methods of an arbitrary class – you can use a custom class that is instantiated before XFRX is executed, implement the scripts as methods of the current form or whatever else is convenient in your application environment. Each script method accepts one parameter: the XFRX#DRAW object reference. This reference links to the document that is being generated.
Example:
DEFINE CLASS myXFRXScripts AS CUSTOM PROCEDURE drawBlueRectangle LPARAMETERS m.oXFD m.oXFD.setColor(0,0,255,-1,-1,-1) m.oXFD.drawRectangle(100,200,50,50) ENDPROC ENDDEFINE
Before XFRX is called, the scripts are registered with RegisterScript() in the XFRX session class instance so that XFRX new about these scripts and invoked them as required. You can execute the scripts on each page, odd or even pages or arbitrary pages. Please see RegisterScript chapter for detail description of this method and its parameters.
Example:
* *Draw blue rectangle on each page * m.loScripts = createobject("myXFRXScripts") m.loXFRXSession.registerScript(loScripts,"drawBlueRectangle",0,"ALL",0)
Rectangle-bound scripts
The rectangle-bound scripts are bound to a specific rectangle on the report and are executed instead of drawing this rectangle to the output.
There are two ways how the scripts can be implemented: named scripts, which are implemented as a method of a class, or scripts written directly to the comment field of the rectangle in the report definition.
Named scripts
If the script is implemented as a method of a class, it needs to be registered similarly as page-bound scripts, but only the first two parameters are required – the object reference and the script name:
m.loScripts = createobject("myXFRXScripts") m.loXFRXSession.registerScript(loScripts,"drawBlueRectangle")
To link the script with a rectangle, add “#UR SCRIPT NAME <script name>” (without the quotation marks) as a comment of the rectangle.
Scripts written in the rectangle comment field
Alternatively, the script can be entered into the comment field of the rectangle. This technique is available for VFP 8.0 and higher, but its usage is limited for VFP 8.0 because the comment field is small and only a limited amount of text can be entered into it.
The script is entered between #UR SCRIPT BEGIN and #UR SCRIPT END lines.
These scripts are neither named not registered. The content between these lines is supposed to accept the XFRX#DRAW object reference parameter and is evaluated via EXECSCRIPT( ) function.
Example:
When inside of the rectangle-bound script, the coordinates origin is shifted: 0,0 represents the upper left hand corner of the rectangle.
The position and size of the bounding rectangle can be retrieved with GetBoundingRectangle() method.
Converting rectangle-bound objects to pictures
The content of the rectangle-bound scripts can be alternatively rendered as a picture, which is then placed to the output. To do this, add PICTURE clause to the #UR SCRIPT BEGIN or #UR SCRIPT NAME <script name> line in the comment field.
The PICTURE can optionally be followed by a DPI value, representing the DPI (dots per inch) of the picture created. The default DPI is 96, which is suitable for previewing on screen, but you may want to increase the DPI value to increase the picture quality.
You can also specify the picture type by adding TYPE clause followed by one of the following values: BMP, JPEG (JPG), PNG, TIFF (TIF) and EMF. The default picture type is JPG.
- BPP - bits per pixel; default value is 24; values are 1,4,8,16,24,32; XFRX 15.5
- JPEGQ - jepg quality; default value is 96 ; XFRX 15.5
- TRANSPARENT- transparent background mode for TIFF, PNG and EMF; default is opaque; XFRX 15.5
Sending parameters to named scripts
The named scripts can optionally accept further parameters. The parameters are specified via PARAMETERS clause followed by the parameters, which are evaluated at the time of report processing.
Example:
DEFINE CLASS myXFRXScripts as Custom PROCEDURE fancyRectangle LPARAM m.oXFD, m.boxwidth, m.boxheight * * This script draws little boxes around the bounding rectangle. * The height and width of the rectangles can be sent as parameters. * The default width and height is 5 points. (1 point = 1/72 inch). * IF EMPTY(m.boxwidth) m.boxwidth = 5 ENDIF IF EMPTY(m.boxheight) m.boxheight = m.boxwidth ENDIF m.oXFD.setUnit("pt") m.loBox = m.oXFD.getBoundingRectangle() m.oXFD.setColor(0,0,0) LOCAL m.i FOR m.i = 0 TO INT(m.loBox.nwidth/m.BOXWIDTH)-1 m.oXFD.setColor(0,0,0,INT(RAND()*256),INT(RAND()*256),INT(RAND()*256)) m.oXFD.drawRectangle(m.i*m.BOXWIDTH, 0, m.BOXWIDTH, m.boxheight,1,1) m.oXFD.setColor(0,0,0,INT(RAND()*256),INT(RAND()*256),INT(RAND()*256)) m.oXFD.drawRectangle(m.i*m.BOXWIDTH, ; INT(m.loBox.nheight/m.boxheight-1)*m.boxheight, m.BOXWIDTH, m.boxheight,1,1) ENDFOR FOR m.i = 1 TO INT(m.loBox.nHeight/m.boxheight)-2 m.oXFD.setColor(0,0,0,INT(RAND()*256),INT(RAND()*256),INT(RAND()*256)) m.oXFD.drawRectangle(0, m.i*m.boxheight, m.BOXWIDTH, m.boxheight,1,1) m.oXFD.setColor(0,0,0,INT(RAND()*256),INT(RAND()*256),INT(RAND()*256)) m.oXFD.drawRectangle(int(m.loBox.nwidth/m.BOXWIDTH-1)*m.BOXWIDTH, ; m.i*m.boxheight, m.BOXWIDTH, m.boxheight,1,1) ENDFOR ENDPROC ENDDEFINE
XFRX#DRAW functions
This chapter gives a brief list of properties and methods implemented in the XFRX#DRAW class. For detailed description if the properties, methods and their parameters please see the XFRX#DRAW class reference on page 92).
XFF document navigation
Whenever you draw anything to a XFF document, the drawing is always added on top of the “current page”. The current page is stored in a readonly property CurrentPage nReportPageNo. The total number of pages is stored in PageCount property. To navigate on the pages, use GoTop(), GoBottom() and GoToPage(nPageNo) methods.
Adding pages
AddPage() method creates a new page at the end of the document. You can either specify the size of the new page or use the same size as the current page.
Coordinates units
The default unit is Point (1/72 inch). You can use setUnit(cUnit) method to switch to a different unit. The available units are: centimeters (cm), inches (in), points (pt) and pixels (px).
Use SetColor() method to set colors for subsequent drawing method calls, the default colors are black for pen and white for background.
Drawing text
Use setFont() method to set the font name, size and attributes. DrawText() draws a text either at a given position, at a position defined by SetPos() method or at end of an output of the previous DrawText() method call – “current position”. After each DrawText() method call, the “current position” advances depending on the height and width of the text. GetXPos() and GetYPos() return the current position. DrawTextBox() draws a text into a given bounding rectangle – word wraps long lines and optionally expands the height of the bounding box to accommodate the whole text.
To maintain backward compatibility with PDF Library, OutText() is a synonym of DrawText().
Drawing basic shapes
drawLine() draws a point to point line, drawRectangle() draws a rectangle, rounded rectangle or an ellipse.
Drawing pictures
DrawPicture() method draws a picture within a given bounding rectangle.
Tooltips, hyperlinks and bookmarks
Each text drawn by DrawText() or DrawTextBox() can have a tooltip, can serve as a target for a bookmark and can be a hyperlink or a target or a hyperlink. Please see tcLinkName, tcLinkRef, tcBookmark and tcTooltip parameters of DrawText() and DrawTextBox() methods in XFRX#DRAW class reference on page 92).