NiXPS
Ready for Leopard
For those early adopters that want to upgrade to Leopard, we are pleased to say that testing with our 1.5.1 release has revealed no bugs.
So, go ahead and upgrade if you want: your NiXPS.app is ready for Leopard!
Deutscher Drucker
We received a promotional copy of the german print magazine 'Deutscher Drucker' @ NiXPS towers... with an article about us!
Very nice - and we really appreciate the gesture of receiving a copy!
Labels: article press release v1.5
NiXPS v1.5.1 is available for download
We've released NiXPS v1.5.1 today. Quite a bit of bugfixes, and some new features in this release:
- improved page navigation
- a more polished UI
- easier access to the zoom functions
- improved rendering
This is an update release, free for every current v1.5 user.
Get it at:
http://nixps.com/download.html
Using NiXPS Library from VB.NET
We have chosen to develop our NiXPS Library in C++ and one of the nice advantages of this
unmanaged language, is that it allows porting to virtually every OS and development platform.
We distribute our NiXPS library on Windows as a DLL with a strict C interface - on top of that we supply the C headers, but also a
documented C++ object model which facilitates working with the library if you develop in C++.
If you're working in a productive
managed language such as VB.NET, you can also take advantage of the DLL, and this article gives a demonstration to get you going.
As an example we are going to develop an VB.NET app that uses our DLL to merge two XPS files into one single XPS file.
What you need:
- A VB.NET IDE, a nice free one can be downloaded here
- The NiXPS library SDK, get it here
Here goes:
As said, our NiXPS Library has a strict C interface. You can find this C api at the beginning of every header file, fi. this is the beginning of NOPackage.h - the header that contains all calls related to working with XPS packages:
extern "C"
{
DLLIMPORTEXPORT NOPackageHandler NOPackage_create(NCommon::UInt32 pCreateEmptyDoc, NCommon::UTF8Char *pName);
DLLIMPORTEXPORT void NOPackage_destroyPackage(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NOPackageHandler NOPackage_readPackageFromFile(NCommon::UTF8Char *pFilename);
DLLIMPORTEXPORT void NOPackage_writePackageToFile(NOPackageHandler* pPackage, NCommon::UTF8Char *pFilename);
DLLIMPORTEXPORT void NOPackage_save(NOPackageHandler* pPackage);
DLLIMPORTEXPORT void NOPackage_getFilename(NOPackageHandler* pPackage, NOStringHandler* pString);
DLLIMPORTEXPORT void NOPackage_setFilename(NOPackageHandler* pPackage, NCommon::UTF8Char* pString);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_hasFilename(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_getDirty(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_hasCoreProperties(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NOCorePropertiesHandler NOPackage_getCoreProperties(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NOCorePropertiesHandler NOPackage_createCoreProperties(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_getNumberOfDocuments(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NODocumentHandler NOPackage_getDocument(NOPackageHandler* pPackage, NCommon::UInt32 pNum);
DLLIMPORTEXPORT void NOPackage_addDocument(NOPackageHandler* pPackage, NODocumentHandler pDoc, NOProgressReporterHandler pReporter);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_getDocumentNumberOf(NOPackageHandler* pPackage, NODocumentHandler pDoc);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_hasThumbnail(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NOThumbnailHandler NOPackage_getThumbnail(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NCommon::UInt32 NOPackage_getNumberOfPages(NOPackageHandler* pPackage);
}
A lot of functions, but for this example we only need the following:
DLLIMPORTEXPORT NOPackageHandler NOPackage_create(NCommon::UInt32 pCreateEmptyDoc, NCommon::UTF8Char *pName);
DLLIMPORTEXPORT void NOPackage_destroyPackage(NOPackageHandler* pPackage);
DLLIMPORTEXPORT NOPackageHandler NOPackage_readPackageFromFile(NCommon::UTF8Char *pFilename);
DLLIMPORTEXPORT void NOPackage_writePackageToFile(NOPackageHandler* pPackage, NCommon::UTF8Char *pFilename);
DLLIMPORTEXPORT NODocumentHandler NOPackage_getDocument(NOPackageHandler* pPackage, NCommon::UInt32 pNum);
DLLIMPORTEXPORT void NOPackage_addDocument(NOPackageHandler* pPackage, NODocumentHandler pDoc, NOProgressReporterHandler pReporter);
Key here is getting access to these calls from our VB.NET program, we do this by
'Declare'-ing these calls. Also to be able to pass handlers back and forth between the VB.NET code and our DLL, we need to redefine the NOHandler and NOProgressReporterHandler in our VB.NET program. So let's start writing our VB.NET program:
Imports System.Runtime.InteropServices
Imports System.Text
Module Module1
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure Handler
Public mPackage As Integer
Public mID As Short
Public mType As Integer
Public mError As Integer
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure ProgressReporterHandler
Public mFunction As Integer
Public mHandler As Integer
End Structure
' Package functions we need
Declare Function NOPackage_readPackageFromFile Lib "NiXPSAccess_D.dll" (ByVal pFilename As String) As Handler
Declare Sub NOPackage_destroyPackage Lib "NiXPSAccess_D.dll" (ByRef pPackage As Handler)
Declare Sub NOPackage_writePackageToFile Lib "NiXPSAccess_D.dll" (ByRef pPackage As Handler, ByVal pFilename As String)
Declare Function NOPackage_create Lib "NiXPSAccess_D.dll" (ByVal pCreateEmptyDoc As Integer, ByVal pFilename As String) As Handler
Declare Sub NOPackage_addDocument Lib "NiXPSAccess_D.dll" (ByRef pPackage As Handler, ByVal pDocument As Handler, ByVal pReporter As ProgressReporterHandler)
Declare Function NOPackage_getDocument Lib "NiXPSAccess_D.dll" (ByRef pPackage As Handler, ByVal pNum As Integer) As Handler
Ok - that's maybe much in one go, let me go over this;
We use the 'StructLayout' magic to ensure that our structure has the same layout as what we expect in the DLL.
The 'Declare' (for functions that return something) and 'Sub' (for void functions) lines are really just the 6 functions described earlier, we declare these as being part from the 'NiXPSAccess_D.dll', and made sure the parameter list is in accordance with the DLL api.
Please note that I use the Debug build of the library (NiXPSAccess_D.dll), you should use the Release build (NiXPSAccess.dll) in production software.
Next, we write the routine that performs the merge:
Sub Main()
Dim lFileHandler, lFileOutHandler As Handler
Dim lDoc As Handler
Dim lProgress As ProgressReporterHandler
Dim lFile1 As String = "interface.xps"
Dim lFile2 As String = "Office2007.xps"
Dim lFileOut As String = "out.xps"
lProgress.mFunction = 0
lProgress.mHandler = 0
' create a new XPS file (package) which contains all the documents
lFileOutHandler = NOPackage_create(0, lFileOut)
' Open lFile1, get the first document, and insert it in the output document, close again
lFileHandler = NOPackage_readPackageFromFile(lFile1)
lDoc = NOPackage_getDocument(lFileHandler, 0)
NOPackage_addDocument(lFileOutHandler, lDoc, lProgress)
NOPackage_destroyPackage(lFileHandler)
' Same procedure for lFile2
lFileHandler = NOPackage_readPackageFromFile(lFile2)
lDoc = NOPackage_getDocument(lFileHandler, 0)
NOPackage_addDocument(lFileOutHandler, lDoc, lProgress)
NOPackage_destroyPackage(lFileHandler)
' write out the resulting XPS doc, and clean-up
NOPackage_writePackageToFile(lFileOutHandler, lFileOut)
NOPackage_destroyPackage(lFileOutHandler)
End Sub
We get handlers to the input files (File1 & File2), get a handler to the first document in those XPS files, and add that to our output file (FileOut). And of course clean everything up with destroy calls.
Please note that this code assumes all testfiles are located in the working directory, and also that NiXPSAccess_D.dll is copied to the working dir.
When you run this VB.NET app, you'll get a resulting XPS file that contains the two input files. Using the NiXPS Library from VB.NET!
NiXPS v1.5.1: the best NiXPS app ever!
Today we released previews for our NiXPS v1.5.1 update to selected users.
By name it is a minor update, but the software contains a lot of bugfixes, improvements and even some extra features. We also took some time to improve the UI of the app:
- New toolbar icons: zoom controls & page navigation.
We've added buttons for zoom in, zoom out and fit page on the toolbar for quick access.
- Reading a large doc: space is your friend
XPS documents can be large, so we want to make sure screen reading is a pleasant experience. One can navigate page per page via the page list panel, but to improve screen reading we've added a shortcut to help reading: space.
When you hit space, the preview window will advance the text a substantial bit - but not a complete page, so you do not get disoriented when reading.
Like all things you need to get used to it, but give it a shot, we're sure you'll like it: open a large document, View>Fit Width, and then during reading just hit space to advance the text.
- Cleaned up the tool dialogs
The interface for the extract, merge and search & replace tool has improved. You'll notice cleaner dialogs, with a better focus on displaying the important information to the user. The user is also presented with an improved UI for giving in the required parameters.
Most of these changes come from sharing experience with users. We want to make sure that the application is a pleasure to use, and a lot of this comes from having a good UI.
We expect to go final with v1.5.1 later this week.
Enjoy!
Labels: nixps, ui, update
Wikipedia politics
Wikipedia was/is already the subject of some controversy and debate here at the NiXPS office. Kristof is a big believer in the community spirit of the project, I'm a bit more skeptical - in the sense that I am a big supporter (and user) of the project, but I hold the opinion that the project will perish under its openness -- if it doesn't start taking measures to protect itself from vandalism, too opinionated/biased editing, advertising, etc... It's a philosophical discussion, which I would really like to postpone for a later date/post.
This post is about the
wikipedia entry for the 'XML Paper Specification'.
The article is there for over almost 2 years - in the beginning of this year I added a link to the NiXPS website in the wikipedia article. Take this literally: just a link - no add, no big blurb on how fantastic NiXPS is, no pricing, just the link. The idea being that 3rd party support is relevant for the format, and as not many 3rd party software is available for XPS, it made sense (at least it did for me).
A few weeks later this link was removed. Even worse: all links to commercial companies were removed - only a link to an open source project survived.
Also all traces to Global Graphics - a company that stood at the cradle of the format, was erased. Somebody 'purified' the article: no commercial companies - only open source links. And by doing so removed a lot of usefull information (sorry, Global Graphics -- being a commercial entity makes you too suspect to be part of the article; sorry NiXPS - you too, open source or be gone).
The changes of this person were reverted by someone from the wikipedia staff -- commercial companies were allowed back in (*whew*) - great, please note that it was not the community that made the system work.
Fast forward to this week;
Martin Bailey of Global Graphics contacts me: the XPS article on wikipedia received a 'this article is written like an advertisement' banner. Apparently some wording in the article was written too much like an endorsement.
I check the article - and guess what: a whole blurb about NiXPS being so great, and costing $300, and so on...
Huh? I didn't add this. But it sure has an impact on NiXPS.
I agree with Martin Bailey that the banner is unfortunate, so I edit the article to get rid of the overly promotional material.
In the mean time it has been rewritten a bit again, but as it stand it seems ok now: gives a good first intro of the format and the players, without being an advertisement for anyone.
Wikipedia is a great system, but the model needs work.
p.s. You can follow this also by looking at
the history of the article.
Babies, Blogwatch & Magazines
It was a fairly busy week for me. Monday started with a gigantic rush of blood to the head as Aiko decided the time was now.
It was a hell of a ride through morning rush hour Monday around 9am - the traffic jams seemed unusually long this time, and we had to wait 10 minutes on a passing train which drove around 5 km/h with 100 or so wagons.
But we got at the hospital just in time!
Needless to say we are absolutely delighted with our new baby daughter!!
A lot of hospital visits and 'arranging things' this week, but I found some time to read up on some XPS related blogs:
The nice folks over @ XPSReview took a closer look at
Adobe Acrobat's capability to import XPS files on Windows. I stumbled upon this a while ago - Adobe is not very vocal about this, and it is only supported in the Windows version of Acrobat 8. I share the view that in order to get XPS moving, we absolutely need a good quality reading (and corrective editing) application - it's our aim to deliver this with NiXPS.app.
Adrian Ford wrote a nice article on the MXDW (Microsoft XPS Document Writer: the 'print to xps' feature in Vista, and via the XPS Essential Pack also available on XP). More specifically
he scheds some light on the various ways one can use the MXDW from applications to print XPS.
This month's issue of 'Grafisch Nieuws' - a trade publication on the graphical arts business in the Benelux (Belgium-The Netherlands-Luxemburg) - has an article on XPS & the printing industry. NiXPS is also featured, I was interviewed by them a few weeks back. Take a look here:
in Dutch/
in French.
Another Fine Release
While we at the headquarters are still waiting for further details, it is my pleasure to announce Nick has become father for the second time in his life today.
Aiko was born on the 1st of October as the sister of Thor and the fine daughter of Katrien and Nick. She weighed 4.050kg at the time of birth and measured 52 cm. Congratulations!
kristof