There are lies, damn lies and benchmarks.
One of our competitors have published benchmark results regarding their XPS viewing software.
To much of anyone's surprise the study reveals that their solution is superior to every other solution on the market today!
Both in terms of features, and in performance and quality of rendering.
Ok.
The document presents a feature comparison. But it leaves out the numerous features (like pdf conversion, editing, unlimited Zoom, etc...) our competitor's product doesn't have, but some of the other products that were tested do have. (Of course, we need to speculate on this, as the competitor's product is not generally available - it cannot be downloaded for trial, nor purchased from their site).
The document also contains benchmark tests.
It's not very difficult to make sure that your application performs well on a set of test files.
What matters is if you perform well on the files that actual users are generating and sharing. And I seriously doubt that the benchmark in question is a good test for that.
I've been following the XPS market for quite a while now, one thing this market does seem to have in abundance are benchmark suites.
But the thing is, benchmarks really don't tell you anything.
They don't tell you that the tested software runs great on your files.
It tells you it runs great on the test set.
And if a vendor publishes these results, you bet that they will have made sure that their software performs well one these few files.
It's a debatably tactic to discredit competitors.
The relevancy of this to you as a customer I think is not that great.
I wouldn't buy the snake oil.
NiXPS SDK by example: selecting and enumerating objects on an XPS page
The NiXPS SDK provides a an object model of the XPS page content to its users.
This has the nice effect that objects can be refered to by their ID, and all sorts of other nice things become possible like selections etc...
I would like to illustrate some of these aspects via an example that I've sent to a customer the other day.
This customer is looking for ways to get hold of the geometrics of all the objects on an XPS page, and wants to do further calculations based on that.
This is fairly easy to do with our NiXPS SDK v2.5.3, and I'll describe the example and code here (in C++).
First - some housekeeping: opening a file, and getting a handler to page we're interested in:
void test_walk_content(ostream &os)
{
NOPackage *lPackage=NOPackage::readPackageFromFile("../testfiles/Virtual_PC_Technical_Overview_2007.xps");
// first document, first page
NODocument lDoc=lPackage->getDocument(0);
NOPage lPage=lDoc.getPage(0);
I use a test file here that I pulled from the internet.
Next, we need to make sure that the NiXPS library calculates the geometric information for the particular page.
Currently this is a by-product of rendering, so we instruct the library to render to a very small buffer.
(In v2.6 we are going to decouple geometric calculation from rendering.)
// render to calculate bounding boxes
UInt32 lBufferLength = 10 * 10 * 3;
UInt8 *lBuffer = (UInt8 *) malloc(lBufferLength);
memset(lBuffer,0,lBufferLength);
lPage.renderToImage(lBuffer,10,10,true);
free(lBuffer);
Next we select everything on the page, and get hold of the selections list, which is a NOSelection type:
// select all content on the page
lPage.selectAll();
// get selection
NOSelection lSelection = lPage.getCopyOfSelection();
With this NOSelection type, we can now enumerate all objects:
// enumerate the selection, get the boundng box (in XPS document coordinates), and
// print this out, together with the type of object and its ID
UInt32 lNumberOfSelectedObjects = lSelection.getNumberOfSelectedObjects();
UInt32 i=0; for (;i<lNumberOfSelectedObjects;i++)
{
For every selected object, we get the bounding box
NOBase lSelectedObject = lSelection.getSelectedObject(i);
NCommon::doubleRect lRect = lPage.getBoundingBox(lSelectedObject.mID);
And we find out the type, and store that in a string for printing it out later:
std::string lType="unknown";
switch (lSelectedObject.mType)
{
case xPath: lType="Path"; break;
case xGlyphs: lType="Glyphs"; break;
default: lType="SomethingElse"; break;
}
We now summerize everything by printing it out, this is also the end of our loop:
os << i << ": ID:" << lSelectedObject.mID << " Type:" << lType << " bbox [" << lRect.mTop << "," << lRect.mBottom << "," << lRect.mLeft << "," << lRect.mRight << "]" << std::endl;
}
and it also concludes our function
}
There is a lot of powerful functionality like this in our NiXPS SDK, everything is listed in our
api documentation.
But an API reference doesn't really have the same illustrative power, as a real code example holds.
That's why we ship code examples in our SDK, and continue to enhance this by adding more samples to the SDK.
NiXPS SDK v2.5.3 released
We released a maintenance update for our SDK: NiXPS SDK v2.5.3.
The release contains mainly bug fixes, but also a new API call to generate a PDF file from a multi-document XPS package in one go. This was requested by a customer, and we felt that it makes a lot of sense to add a such a convenience call to the API.
You can find the changelog for this v2.5.3 release
here.
You can apply for your trial version
here.
You'll receive a link to download the SDK.
I would also like to take this opportunity to thank our customers.
Your valuable feedback allows us to build an even better product!
Keep sending your feedback out our way!