<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Two Pilots blog &#187; For software developers</title>
	<atom:link href="http://www.colorpilot.com/blog/category/for-software-developers/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.colorpilot.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 24 Aug 2010 20:11:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rounding Effect</title>
		<link>http://www.colorpilot.com/blog/rounding-effect/</link>
		<comments>http://www.colorpilot.com/blog/rounding-effect/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 15:36:52 +0000</pubDate>
		<dc:creator>Artem Golubnichenko</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/?p=50</guid>
		<description><![CDATA[Look at the picture of the line before inexact rounding of floating points, and at the
picture after rounding:

The problem arose while converting an EMF into a PDF or while drawing an HDC-context taken from a PDF. The problem was connected to the Polyline(To) function. The function transformed an array of points with close value coordinates. [...]]]></description>
			<content:encoded><![CDATA[<p>Look at the picture of the line before inexact rounding of floating points, and at the<br />
picture after rounding:</p>
<p><img class="aligncenter size-full wp-image-52" src="http://www.colorpilot.com/blog/wp-content/uploads/2010/07/blog.png" alt="blog" width="504" height="482" /></p>
<p>The problem arose while converting an EMF into a PDF or while drawing an HDC-context taken from a PDF. The problem was connected to the Polyline(To) function. The function transformed an array of points with close value coordinates. Then, to draw a set of lines in a PDF, transformation of the<br />
coordinates from HDC to PDF coordinates was necessary. For this transformation the LPtoDP function was used. But LPtoDP returns integer values. For example, this function transforms the (160, 74) and (159, 60) coordinates from EMF to (1, 1) and (1, 2) for a PDF. So a set of lines was generated as shown in the left picture. To improve the results, we have stopped using the LPtoDP function. Now Polyline(To) function gives the correct results.</p>
<p style="text-align: right">Artem Golubnichenko</p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/rounding-effect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Layers (Optional Content Groups)</title>
		<link>http://www.colorpilot.com/blog/layers-optional-content-groups/</link>
		<comments>http://www.colorpilot.com/blog/layers-optional-content-groups/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 13:00:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/?p=26</guid>
		<description><![CDATA[Layers or as they are more formally known Optional Content Groups (OCG) is representing a collection of graphics that can be made visible or invisible dynamically by users of viewer applications. (This ca­pability is useful in items such as CAD drawings, maps, and multi-language documents) With the introduction of PDF version 1.5 came the concept [...]]]></description>
			<content:encoded><![CDATA[<p>Layers or as they are more formally known Optional Content Groups (OCG) is representing a collection of graphics that can be made visible or invisible dynamically by users of viewer applications. (This ca­pability is useful in items such as CAD drawings, maps, and multi-language documents) With the introduction of PDF version 1.5 came the concept of Layers. Form and image and annotations can be made optional too.</p>
<p><span id="more-26"></span>A group is assigned a state, which is either ON or OFF. States can be set programmatically or through the viewer user interface to change the visibility of content. In the typical case, content belonging to a group is visible when the group is ON and invisible when it is OFF. When a piece of optional content in a PDF file is determined to be hidden, the content is not drawn.</p>
<p>You may see all layers in PDF document on Layers tab. (for Adobe Reader) Go into the &#8220;View&#8221; menu and select &#8220;Navigation Tabs&#8221; and then choose &#8220;Layers&#8221;.</p>
<p>So this gives us an instruction on how to create Layered PDFs within PDF Creator Pilot.  In our example we&#8217;ve created a PDF with several layers. (example for VBScript)</p>
<p><code>' create pdf library object<br />
Set PDF = CreateObject("PDFCreatorPilot.PDFDocument4")</code></p>
<p><code>' initialize PDF Engine<br />
PDF.SetLicenseData "demo@demo", "demo"</code></p>
<p><code>' set document title<br />
PDF.SetTitle "PDF with Layers", 1</p>
<p>'  For creating PDF with layers, we need create named content group. For every layer –<br />
' individual group:<br />
groupIndex = PDF.CreateContentGroup("Text Optional Content Group")</p>
<p>' Then you need to add content in layer. Sections of content in the PDF document can be made<br />
' optional by enclosing between the marked-content operators BeginMarkedContent and<br />
' EndMarkedContent. Between this operators you may draw graphic shapes, images, forms,<br />
' annotations or text:</p>
<p>'  Text content group example:<br />
PDF.BeginMarkedContent groupIndex<br />
PDF.ShowTextAt 10, 40, "Hello, optional content group!"<br />
PDF.EndMarkedContent</p>
<p>'  Image content group example:<br />
img = PDF.AddImageFromFile(L"image.jpg")<br />
PDF.BeginMarkedContent groupIndex<br />
PDF.ShowImage img, 150, 100<br />
PDF.EndMarkedContent</p>
<p>'  Annotation content group example:<br />
PDF.BeginMarkedContent groupIndex<br />
PDF.AddUnicodeTextAnnotation 10, 10, "Title", "Some text goes here..."<br />
PDF.EndMarkedContent</p>
<p>'   You may combine content of this group. For example,<br />
PDF.BeginMarkedContent groupIndex<br />
PDF.ShowTextAt 10, 40, "Hello, optional content group!"<br />
PDF.AddEditBox 50, 210, 150, 250, "edt1"<br />
PDF.SetColor 0.0, 0.9f, 0.0, 0.0<br />
PDF.ResetPath<br />
PDF.DrawEllipse 100, 200, 200, 300<br />
PDF.FillAndStroke<br />
PDF.EndMarkedContent</p>
<p>' finalize document generation<br />
PDF.SaveToFile "PdfWithContentGroups.pdf", true</p>
<p></code></p>
<p><code>' disconnect from library<br />
Set PDF = Nothing</code></p>
<p>Hopefully from the example code and the example PDFs you should see how useful Layers can be.</p>
<p>Here you can download examples of PDF documents created by PDF Creator Pilot:<br />
<a href="http://www.colorpilot.com/downloads/ContentGroupsExample.pdf">http://www.colorpilot.com/downloads/ContentGroupsExample.pdf</a><br />
<a href="http://www.colorpilot.com/downloads/ContentGroupsExample_SourceCode.zip">http://www.colorpilot.comdownloads/ContentGroupsExample_SourceCode.zip</a></p>
<p style="text-align: right;">Artem Golubnichenko<br />
Project Manager of <a href="http://www.colorpilot.com/emfprinterpilot.html">Virtual Printer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/layers-optional-content-groups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PDF Creator Project News</title>
		<link>http://www.colorpilot.com/blog/pdf-creator-project-news/</link>
		<comments>http://www.colorpilot.com/blog/pdf-creator-project-news/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 18:59:46 +0000</pubDate>
		<dc:creator>Vitaliy Shibaev</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/pdf-creator-project-news/</guid>
		<description><![CDATA[Hello,
Today I want to talk about important improvements in the current version of the PDF Creator Pilot Library.
It was always one of the weakest things about the Library &#8211; it demanded huge amounts of memory to work with larger documents. Quite often clients were not able to create a document consisting of more than 100 [...]]]></description>
			<content:encoded><![CDATA[<p>Hello,</p>
<p>Today I want to talk about important improvements in the current version of the PDF Creator Pilot Library.</p>
<p>It was always one of the weakest things about the Library &#8211; it demanded huge amounts of memory to work with larger documents. Quite often clients were not able to create a document consisting of more than 100 pages, because they did not have enough memory. In this version, we have managed to open up a bottleneck, which helped us significantly reduce memory requirements. In short, if a page contains a lot of graphics, it also contains a lot of page operation commands. Keeping all these commands in memory was the bottleneck. We cached the commands into a temporary file, and that solved the problem.</p>
<p>
<span id="more-25"></span></p>
<p>The other improvement concerns conversion of EMF files to PDF files. We&#8217;ve improved the processing of paths and clipping regions. This was no trivial task, because the path processing toolset of the PDF format isn&#8217;t as rich as required by GDI. Clipping regions are the worst supported; there are no other region operations in a PDF except intersection. To adequately process an EMF, we had to support all operations defined in Set theory. For a long time the problem remained unsolved, however we have now left the problem behind us. Now these kinds of EMF files converted correctly.</p>
<p>This last bit of news should be of interest to those who use &#8220;non-standard&#8221; versions of the Library, such as the 64-bit variant or the static variant (which is for C++ only). We&#8217;ve found that the x64 build failed to convert EMF files, and the static library refused to work from VS2005. All of these problems have also been fixed.</p>
<p>Here are the current builds:</p>
<p><a href="http://www.colorpilot.com/~builds/PDFCreatorPilot4_1_2492.zip">http://www.colorpilot.com/~builds/PDFCreatorPilot4_1_2492.zip</a><br /><a href="http://www.colorpilot.com/~builds/PDFCreatorPilot4_1_2492_x64.zip">http://www.colorpilot.com/~builds/PDFCreatorPilot4_1_2492_x64.zip</a><br /><a href="http://www.colorpilot.com/~builds/PDFCreatorPilot4_1_2492_static.zip">http://www.colorpilot.com/~builds/PDFCreatorPilot4_1_2492_static.zip</a> (18 Mb, contains both the Debug and the Release versions)</p>
<p>In the next release, we plan both to improve processing of TIFF files and to add support for CMYK TIFFs.</p>
<p>Vitaly Shibaev<br />Developer of <a href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/pdf-creator-project-news/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>COM: The First Steps</title>
		<link>http://www.colorpilot.com/blog/com-the-first-steps/</link>
		<comments>http://www.colorpilot.com/blog/com-the-first-steps/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 10:48:32 +0000</pubDate>
		<dc:creator>max.f</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/com-the-first-steps/</guid>
		<description><![CDATA[Let me show you the process of creating of a COM component with Visual Studio 2008 using ATL and C++.
First, let&#8217;s create a Visual C++/ATL project:


Click &#8220;OK&#8221; and then select &#8220;Allow merging of proxy/stub code&#8221;:

Click &#8220;Finish&#8221;. Studio creates a project for us. With the help of Solution Explorer, we can see the following files:

It&#8217;s just [...]]]></description>
			<content:encoded><![CDATA[<p>Let me show you the process of creating of a COM component with Visual Studio 2008 using ATL and C++.</p>
<p>First, let&#8217;s create a Visual C++/ATL project:</p>
<p><a rel="lightbox" href="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-001.png" title="com-001.png"><img border="0" width="200" src="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-001-tn.jpg" alt="com-001.png" height="133" /></a><br />
<span id="more-24"></span></p>
<p>Click &#8220;OK&#8221; and then select &#8220;Allow merging of proxy/stub code&#8221;:</p>
<p><a rel="lightbox" href="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-002.png" title="com-002.png"><img border="0" width="200" src="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-002-tn.jpg" alt="com-002.png" height="168" /></a></p>
<p>Click &#8220;Finish&#8221;. Studio creates a project for us. With the help of Solution Explorer, we can see the following files:</p>
<p><a rel="lightbox" href="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-003.png" title="com-003.png"><img border="0" width="125" src="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-003-tn.jpg" alt="com-003.png" height="200" /></a></p>
<p>It&#8217;s just a shell. If we would compile and build the project at this stage, there would be a DLL-file without a single component.</p>
<p>To add a component to our project, let&#8217;s review the &#8220;FirstCOM.idl&#8221; file. It&#8217;s the file that contains the definitions of the interfaces.</p>
<p>So far, this is all that file contains (comments have been removed):</p>
<blockquote><p><code>import "oaidl.idl";<br />
import "ocidl.idl";<br />
[<br />
    uuid(0652E0B7-4360-4542-8D22-8F52940AEFCE),<br />
    version(1.0),<br />
    helpstring("FirstCOM 1.0 Type Library")<br />
]<br />
library FirstCOMLib<br />
{<br />
    importlib("stdole2.tlb");<br />
};</code></p></blockquote>
<p>This means that there is a library of types named FirstCOM that lacks the types. There are two attributes, though, &#8220;version&#8221; that holds the version of our library and &#8220;helpstring&#8221; that should hold a description of the library.</p>
<p>Let&#8217;s add a component. Select &#8220;Add-&gt;Class&#8221; from the context menu:</p>
<p><a rel="lightbox" href="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-005.png" title="com-005.png"><img border="0" width="176" src="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-005-tn.jpg" alt="com-005.png" height="200" /></a></p>
<p>Select &#8220;ATL Simple Object&#8221;:</p>
<p><a rel="lightbox" href="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-006.png" title="com-006.png"><img border="0" width="200" src="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/com-006-tn.jpg" alt="com-006.png" height="119" /></a></p>
<p>Now let&#8217;s enter the class information, as illustrated below:</p>
<p><a rel="lightbox" href="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/122604845568-com-007.png" title="com_007.png"><img border="0" width="200" src="http://www.colorpilot.com/blog/wp-content/uploads/2008/11/122604845568-com-007-tn.jpg" alt="com_007.png" height="168" /></a></p>
<p>Click &#8220;Finish&#8221;. Studio will create all the necessary files and add the necessary constants to the resource files. &#8220;FirstCOM.idl&#8221; should now look like this:</p>
<blockquote><p><code>import "oaidl.idl";<br />
import "ocidl.idl";<br />
[<br />
    object,<br />
    uuid(5F9CB782-BDE1-48E3-91CC-E8EC0280EFA0),<br />
    dual,<br />
    nonextensible,<br />
    helpstring("IFirstCOMClass Interface"),<br />
    pointer_default(unique)<br />
]<br />
interface IFirstCOMClass : IDispatch<br />
{<br />
};<br />
[<br />
    uuid(FD0B5C1A-6E02-4EFA-958B-046A0AD17381),<br />
    version(1.0),<br />
    helpstring("FirstCOM 1.0 Type Library")<br />
]<br />
library FirstCOMLib<br />
{<br />
    importlib("stdole2.tlb");<br />
    [<br />
        uuid(61A52F01-320D-41E4-B5F2-A59C6E220292),<br />
        helpstring("FirstCOMClass Class")<br />
    ]<br />
    coclass FirstCOMClass<br />
    {<br />
        [default] interface IFirstCOMClass;<br />
    };<br />
};</code></p></blockquote>
<p>We have added a description of a class (component) with some interface IFirstCOMClass to the description section of the library (library FirstCOMLib{&#8230;}). The definition of that interface has been automatically added at the beginning of the file.</p>
<p>Now we have created a component (class) FirstCOMClass and declared its interface (IFirstCOMClass). This interface will be used to provide access to our component.</p>
<p>Now let&#8217;s define methods and functions for our component. For instance, let&#8217;s add two methods, one that would return the sum of two numbers and one to return the length of a string. Also, we&#8217;ll add a property &#8220;Author&#8221; to allow read and write access. To do that, in the section</p>
<blockquote><p><code>interface IFirstCOMClass : IDispatch<br />
{<br />
};</code></p></blockquote>
<p>we should add definitions of our methods and properties:</p>
<blockquote><p><code>interface IFirstCOMClass : IDispatch<br />
{<br />
    [id(1)] HRESULT CalcSumm([in] LONG lParam1, [in] LONG lParam2,<br />
        [out, retval] LONG* retVal);<br />
    [id(2)] HRESULT GetStringLen([in] BSTR strParam,<br />
        [out, retval] LONG* retVal);<br />
   <br />
    [propget, id(3)]<br />
    HRESULT Author([out, retval] BSTR* retVal);<br />
    [propput, id(3)]<br />
    HRESULT Author(BSTR strValue);<br />
};</code></p></blockquote>
<p>Where:<br />
[id(N)] &#8211; defines the identification number of a method or a property (This number must be unique.);<br />
[in] denotes an input parameter;<br />
[out, retval] &#8211; denotes an output parameter.Important: The read properties and the write properties should have the same name and identification (id).</p>
<p>Now let&#8217;s declare the methods described in CFirstCOMClass. Locate the &#8220;CFirstCOMClass.h&#8221; and open it. There is this:</p>
<blockquote><p><code>class ATL_NO_VTABLE CFirstCOMClass :<br />
    public CComObjectRootEx&lt;CComSingleThreadModel&gt;,<br />
    public CComCoClass&lt;CFirstCOMClass, &amp;CLSID_FirstCOMClass&gt;,<br />
    public IDispatchImpl&lt;IFirstCOMClass, &amp;IID_IFirstCOMClass,<br />
        &amp;LIBID_FirstCOMLib, /*wMajor =*/ 1, /*wMinor =*/ 0&gt;</code></p></blockquote>
<p>This declaration allows the compiler to bind the COM class and its interface with a real C++ class.</p>
<p>Add this to the public section:</p>
<blockquote><p><code>public:<br />
    STDMETHOD(CalcSumm)(LONG lParam1, LONG lParam2, VARIANT_BOOL* retVal);<br />
    STDMETHOD(GetStringLen)(BSTR strParam, VARIANT_BOOL* retVal;<br />
    STDMETHOD(get_Author)(BSTR* sVal);<br />
    STDMETHOD(put_Author)(BSTR sVal);</code></p></blockquote>
<p>It is recommended to declare a constructor and a destructor and then move their implementation into file &#8220;CFirstCOMClass.cpp&#8221;.</p>
<p><strong>Important:</strong> The read and write accessor methods of the property &#8220;Author&#8221; must begin with the &#8220;get_&#8221; and &#8220;put_&#8221; prefixes.</p>
<p>Then we create the private section. Here we will hold the value of the &#8220;Author&#8221; property.</p>
<blockquote><p><code>private:<br />
    CComBSTR m_author;</code></p></blockquote>
<p>In &#8220;CFirstCOMClass.cpp&#8221;:</p>
<blockquote><p><code>// FirstCOMClass.cpp : Implementation of CFirstCOMClass<br />
#include "stdafx.h"<br />
#include "FirstCOMClass.h" // CFirstCOMClass</code><code> </code><code>CFirstCOMClass::CFirstCOMClass()<br />
{<br />
    // initial value of the property Author<br />
    m_author = OLESTR("Vasya");<br />
}</code><code>CFirstCOMClass::~CFirstCOMClass()<br />
{<br />
}</p>
<p>STDMETHODIMP CFirstCOMClass::CalcSumm(LONG lParam1, LONG lParam2, LONG* retVal)<br />
{<br />
    // if pointer is invalid - return error<br />
    if (!retVal)<br />
        return S_FALSE;<br />
    *retVal = lParam1 + lParam2;</p>
<p>    // no errors - return OK<br />
    return S_OK;<br />
}</p>
<p>STDMETHODIMP CFirstCOMClass::GetStringLen(BSTR strParam, LONG* retVal)<br />
{<br />
    // if pointer is invalid - return error<br />
    if (!retVal)<br />
        return S_FALSE;</p>
<p>    CComBSTR str(strParam);<br />
    *retVal = (LONG)str.Length();</p>
<p>    // no errors - return OK<br />
    return S_OK;<br />
}</p>
<p>STDMETHODIMP CFirstCOMClass::get_Author(BSTR* retVal)<br />
{<br />
    // if pointer is invalid - return error<br />
    if (!retVal)<br />
        return S_FALSE;</p>
<p>    // don't forget to allocate memory for the result string<br />
    *retVal = SysAllocString((BSTR)m_author);</p>
<p>    // no errors - return OK<br />
    return S_OK;<br />
}</p>
<p>STDMETHODIMP CFirstCOMClass::put_Author(BSTR newVal)<br />
{<br />
    CComBSTR newAuthor(newVal);<br />
    m_author = newAuthor;</p>
<p>    // no errors - return OK<br />
    return S_OK;<br />
}</p>
<p></code></p></blockquote>
<p>Our COM library is almost ready. We have created the library itself, a class, and its interface. We&#8217;ve also added the implementation of the interface. It would be great to know the name of our COM library and its class. Their names are in the &#8220;FirstCOMClass.rgs&#8221;. Open it and find &#8220;VersionIndependentProgID&#8221;:</p>
<blockquote><p><code>VersionIndependentProgID = s 'FirstCOM.FirstCOMClass'</code></p></blockquote>
<p>The name of our library is FirstCOM, and the class is &#8220;FirstCOM.FirstCOMClass&#8221;.</p>
<p>When we add more classes, for each there will be an &#8220;.rgs&#8221; file with the following text:</p>
<blockquote><p><code>VersionIndependentProgID = s 'FirstCOM._class_name_'</code></p></blockquote>
<p>After building the project, in the &#8220;Debug&#8221; or &#8220;Release&#8221; folder we will find &#8220;FirstCOM.dll&#8221;, our COM library. To use it from another computer, it must be registered in its operating system. That can be done with an installer or with this command:</p>
<blockquote><p><code>regsvr32 FirstCOM.dll</code></p></blockquote>
<p>Now, let&#8217;s check whether it works. Create a text file &#8220;test.vbs&#8221; and copy the following Visual Basic Script into it:</p>
<blockquote><p><code>' create COM object, use library name and class name<br />
Set comObj = CreateObject("FirstCOM.FirstCOMClass")</code><code> </code><code>' test CalcSumm method<br />
res = comObj.CalcSumm(1, 2)<br />
WScript.Echo "1 + 2 = " &amp; res</code><code>' test GetStringLen method<br />
res = comObj.GetStringLen("QwertY123")<br />
WScript.Echo "Len = " &amp; res</p>
<p>' read property Author<br />
auth = comObj.Author<br />
WScript.Echo "Author = " &amp; auth</p>
<p>' read property Author<br />
comObj.Author = "Petya"<br />
auth = comObj.Author<br />
WScript.Echo "Author = " &amp; auth</p>
<p>' cleanup<br />
Set comObj = Nothing</p>
<p></code></p></blockquote>
<p>Save and launch the file this way:</p>
<blockquote><p><code>wscript.exe test.vbs</code></p></blockquote>
<p>or this:</p>
<blockquote><p><code>cscript.exe test.vbs</code></p></blockquote>
<p>If we did everything correctly, we should see the results of our tests.</p>
<p>We could execute it from PHP:</p>
<blockquote><p><code>&lt;?php<br />
// create COM object, use library name and class name<br />
$comObj = new COM("FirstCOM.FirstCOMClass") or die("Can't create COM.");</code><code> </code><code>// test CalcSumm method<br />
$res = $comObj.CalcSumm(1, 2);<br />
echo("1 + 2 = " . $res);</code><code>// test GetStringLen method<br />
$res = $comObj.GetStringLen("QwertY123");<br />
echo("Len = " . $res);</p>
<p>// read property Author<br />
$auth = $comObj.Author;<br />
$echo("Author = " . $auth);</p>
<p>// read property Author<br />
$comObj.Author = "Petya";<br />
$auth = $comObj.Author;<br />
echo("Author = " . $auth);</p>
<p>// cleanup<br />
$comObj = null;<br />
?&gt;</p>
<p></code></p></blockquote>
<p>If you want to learn how to use COM from C/C++ and .NET, look <a href="http://www.colorpilot.com/pdfcreatorpilotmanual/How_to_create_a_new_PDF_document_4.html">here</a>.</p>
<p>You can download the source of the COM library <a href="///C:/Downloads/src">here</a>.</p>
<p align="right">Max Filimonov.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/com-the-first-steps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PDF Creator &#8211; about project and development process</title>
		<link>http://www.colorpilot.com/blog/pdf-creator-about-project-and-development-process/</link>
		<comments>http://www.colorpilot.com/blog/pdf-creator-about-project-and-development-process/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 05:57:51 +0000</pubDate>
		<dc:creator>Vitaliy Shibaev</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/pdf-creator-about-project-and-development-process/</guid>
		<description><![CDATA[Hi,
In this article I describe the organization of the PDF Creator project and the tools that we use to develop and promote the product.
Development Tools
1. Subversion (SVN) Control
The life of a programmer would be unbearable without a source control manager  . As of this writing, we have executed 2387 commits in the PDF Creator [...]]]></description>
			<content:encoded><![CDATA[<p>Hi,<br />
In this article I describe the organization of the PDF Creator project and the tools that we use to develop and promote the product.</p>
<p align="center"><strong>Development Tools</strong></p>
<p><strong>1. Subversion (SVN) Control</strong></p>
<p>The life of a programmer would be unbearable without a source control manager <img src='http://www.colorpilot.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . As of this writing, we have executed 2387 commits in the PDF Creator project using the Tortoise SVN, (<a href="http://tortoisesvn.tigris.org/">http://tortoisesvn.tigris.org/</a>). Since every mistake would cost a lot, we try to follow this rule – one that we would recommend to everyone: Always commit smaller portions of the code. Every commit must correspond to a single task!</p>
<p>This way it is (a) easier to find an error during rollbacks (every commit changes a small amount of source code), (b) often easy to discover an error before the commit just by looking at it, and (c) easier for colleagues to be aware of the changes in the source code, since all they have to do is read the comments and look at the smaller portions of the code.</p>
<p>Of course, this is not possible in all cases, and sometimes we do have to perform huge commits. Still this is a rule worth following. After all, it is one of the refactoring rules: Change smaller portions of the code, preserving its workability between sessions.</p>
<p>Two more source-control rules:</p>
<ol>
<li>There must always be two versions in the SVN – a version that compiles and a workable version. It is easy to create code that compiles, but the real aim is its correctness.</li>
<li>Text comments should be supplied to every commit. This is also a good way to check whether the commit implements only a single task. If a comment describes several targets instead of just one, the rule has been violaled.</li>
</ol>
<p><strong>2. Bug Tracker</strong></p>
<p>We use Mantis (<a href="http://www.mantisbt.org/">http://www.mantisbt.org/</a>). PDF Creator is the base for a number of other products – converters, virtual printer, etc. (See <a href="http://www.colorpilot.com/developer.html">http://www.colorpilot.com/developer.html</a>) The number of its users is much higher than the count of those who purchased the base product. We needed to simplify communications between the developers and the users of the products.</p>
<p><span id="more-9"></span>To make the things clear for those who have never used a bug tracker, here is a sample of how it works. The virtual printer developers receive (from the users of their product) information about an incorrect conversion into a PDF. The Virtual Printer gets an EMF file from input, then our library converts it. The information from the user is used to create a &#8220;ticket&#8221; for the library developers. The ticket is accompanied by a description of the problem and the problematic EMF file. Then we investigate the degree of severity of the problem to find out how critical it is and appoint a specific developer to work on a fix. After the problem has been resolved, the ticket gets closed. Everybody concerned is notified and may keep an eye on what is going on.</p>
<p><strong>3. Technical Support</strong></p>
<p>To manage our correspondence with clients, we use RT (<a href="http://bestpractical.com/rt/">http://bestpractical.com/rt/</a>). We need the system for convenient storage of the archive, as well as assurance that every person who should read the messages does receive them.</p>
<p>Ideally, (2) and (3) might have been united into a single service, so that the clients were aware of their problem status. In the example above, the virtual printer user would keep an eye on developers’ correspondence concerning his problem. One such system that could help is FogBugz (<a href="http://fogcreek.com/FogBugz/">http://fogcreek.com/FogBugz/</a>).</p>
<p><strong>4. Technical Documentation</strong></p>
<p>Our internal technical documentation project, Squirrel (<a href="http://www.colorpilot.com/squirrel.html">http://www.colorpilot.com/squirrel.html</a>), isn&#8217;t widely known, however, it is publicly available. The program makes it easier to create a CHM-version of the documentation, integrates with SVN, and permits creation of the online documentation. See <a href="http://www.colorpilot.com/pdfcreatorpilotmanual/PDF_Creator_Pilot.html">http://www.colorpilot.com/pdfcreatorpilotmanual/PDF_Creator_Pilot.html</a> for the results of Squirrel’s work.</p>
<p><strong>5. Development Environment</strong></p>
<p>We use Visual Studio 2008, C++, and C#.</p>
<p><strong>6. Refactoring Tools</strong></p>
<p>There are no built-in tools for C++ refactoring in Visual Assist X (<a href="http://www.wholetomato.com/">http://www.wholetomato.com/</a>), so we have to use a third party plug-in for Visual Studio.</p>
<p><strong>7. Unit Tests in C++</strong></p>
<p>Here we use UnitTest++ (<a href="http://unittest-cpp.sourceforge.net/">http://unittest-cpp.sourceforge.net/</a>).</p>
<p><strong>8. Profiling Tools</strong></p>
<p>To diagnose memory leaks, we use <a href="http://www.colorpilot.com/~vit.shibaev/mmgr.zip">http://www.colorpilot.com/~vit.shibaev/mmgr.zip</a>. (I described that tool in one of my previous articles which you can find here: <a href="http://www.colorpilot.com/blog/about-pdf-creator-39/">http://www.colorpilot.com/blog/about-pdf-creator-39/</a>.) To control performance, we also use the Intel VTune, from time to time.</p>
<p align="center"><strong>Project Organization</strong></p>
<p>PDF Creator is a library for PDF processing: creation, reading, modification, text extraction, etc. Currently, the project exists as a solution with 18 sub-projects in Visual Studio 2008. There are five general types of sub-projects.</p>
<p><strong>1. The Library Core</strong></p>
<p>Here we define all the logic of PDF processing. This project is always in the process of modification. One of our old dreams (and still a dream today) is to make the core cross-platform. The biggest obstacle is the fact that EMF is a private Windows format. To make our dream come true, we should separate the conversion from the cross-platform part.</p>
<p>2<strong>. Client Interfaces</strong></p>
<p>Two of the projects implement the client interfaces. One of them implements the COM interface; the other one implements a static library. The COM interface delegates its tasks to the static library; the static library forwards them to the core. No code is duplicated.</p>
<p>The static library isn&#8217;t advertised on our site, however every client may receive it together with the COM version. The static library contains some undocumented features that allow users to get some additional information about a document. If you are a developer and your product is intended to view PDFs, these features may be very useful for you.</p>
<p><strong>3. Test Projects</strong></p>
<ol>
<li>Non-automated tests for the COM interface. A set of APIs that form and render PDF documents immediately after their launch.</li>
<li>Unit tests for the static library and the core. In addition to those described immediately above, the unit tests check the internal state of the classes, handle errors, etc.</li>
<li>Projects that check the EMF-conversion. The first one (written in WTL) converts the specified EMF file into a PDF. Its interafce is minimalistic, looking very much like our online service <a href="http://www.colorpilot.com/pdflibrary_convert-emf-to-pdf.html">http://www.colorpilot.com/pdflibrary_convert-emf-to-pdf.html</a>.<br />
The second one (written in C#) are a work in progress. However, it is already possible to convert all PDFs from a folder and to instantly review the results. This provides a significant speed increase during the testing process, which is especially great since we&#8217;ve got hundreds of test metafiles already.</li>
</ol>
<p><strong>4. Auxiliary Projects</strong></p>
<p>These include a font-processing library (that parses TrueType and Type1 fonts, works with encodings, and modifies the TrueType fonts), font installer, working with the keys, etc.</p>
<p><strong>5. Third Party Open-Source Products</strong></p>
<p>PDF is a complex format. It is based on many areas of science, multiple algorithms, and formats. It involves compression and encryption algorithms, various image and font formats, color spaces, etc. A big part of our implementation is based on open source projects with a free license, for instance, CxImage, ZLib, LibJPEG, Lcms, and UnitTest++.</p>
<p align="right">Vitaly Shibaev<br />
Developer of <a href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/pdf-creator-about-project-and-development-process/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What you should know before deploying your .NET application that uses PDF Creator Pilot and HTML2PDF Addon to another server.</title>
		<link>http://www.colorpilot.com/blog/what-you-should-know-before-deploying-your-net-application-that-uses-pdf-creator-pilot-and-html2pdf-addon-to-another-server/</link>
		<comments>http://www.colorpilot.com/blog/what-you-should-know-before-deploying-your-net-application-that-uses-pdf-creator-pilot-and-html2pdf-addon-to-another-server/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 08:37:14 +0000</pubDate>
		<dc:creator>max.f</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/what-you-should-know-before-deploying-your-net-application-that-uses-pdf-creator-pilot-and-html2pdf-addon-to-another-server/</guid>
		<description><![CDATA[First, you need to install PDF Creator Pilot and HTML2PDF Addon to this server.
It is not necessary to run installer programs for those products, you may register in system corresponding dll files running commands (both on x86 and x64 versions):
C:\Windows\system32\regsvr32 PDFCreatorPilot.dll
C:\Windows\system32\regsvr32 HTML2PDF.dll
Second, you need to re-create interop wrappers for these components. This can be done [...]]]></description>
			<content:encoded><![CDATA[<p>First, you need to install <strong>PDF Creator Pilot</strong> and <strong>HTML2PDF Addon</strong> to this server.<br />
It is not necessary to run installer programs for those products, you may register in system corresponding dll files running commands (both on x86 and x64 versions):</p>
<p><code>C:\Windows\system32\regsvr32 PDFCreatorPilot.dll<br />
C:\Windows\system32\regsvr32 HTML2PDF.dll</code></p>
<p>Second, you need to re-create interop wrappers for these components. This can be done with standard .NET SDK utility &#8211; <strong>TlbImp.exe</strong> (C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\TlbImp.exe)<br />
Example:</p>
<p><code>TlbImp.exe PDFCreatorPilot.dll /out:Interop.PDFCreatorPilotLib.dll<br />
TlbImp.exe HTML2PDF.DLL /out:Interop.HTML2PDFAddOn.dll</code></p>
<p>Note: It is not necessary to regenerate wrappers directly on the server, you may do it on the developer machine and copy theese wrappers to the server.</p>
<p>Third, you need to place these interop wrappers into the appropriate directory on the new server. For ASP.NET it is the <strong>&#8220;bin&#8221;</strong> folder of that application. For the rest applications you need to place wrappers near the exe module (at the same folder).
<p align="right">Filimonov MaximDeveloper of <a href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/what-you-should-know-before-deploying-your-net-application-that-uses-pdf-creator-pilot-and-html2pdf-addon-to-another-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>COM arrays in PHP</title>
		<link>http://www.colorpilot.com/blog/com-arrays-in-php/</link>
		<comments>http://www.colorpilot.com/blog/com-arrays-in-php/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 08:15:37 +0000</pubDate>
		<dc:creator>max.f</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/com-arrays-in-php/</guid>
		<description><![CDATA[We don&#8217;t claim to be experts in PHP, and an educated reader might find this article to be a redundant description of evident facts. Nevertheless, we hope that this article may be of some help to somebody.
We wanted to check whether our library (this one) works well with PHP. Below is the small script that we [...]]]></description>
			<content:encoded><![CDATA[<p>We don&#8217;t claim to be experts in PHP, and an educated reader might find this article to be a redundant description of evident facts. Nevertheless, we hope that this article may be of some help to somebody.</p>
<p>We wanted to check whether our library (<a target="_blank" href="http://www.colorpilot.com/pdflibrary.html">this one</a>) works well with PHP.<span id="more-7"></span> Below is the small script that we had created. All it was to do: create a plain PDF Document, and output it into the client&#8217;s stream:</p>
<p><code>&lt;?<br />
  $PDF = new COM("PDFCreatorPilot.PDFDocument4") or die("Unable to load instanciate.");<br />
  $PDF-&gt;SetLicenseData("demo", "demo");<br />
  $PDF-&gt;Compression = 1; // coFlate</code><br />
<code><br />
  $fnt = $PDF-&gt;AddBuiltInFont(1, false, false);<br />
  $PDF-&gt;UseFont($fnt, 14);<br />
  $PDF-&gt;ShowTextAt(30, 30, "Hello from PHP!");</code><br />
<code><br />
  $size = $PDF-&gt;GetBufferSize();<br />
  $buffer = $PDF-&gt;GetBuffer();<br />
  header("Content-type: application/pdf");<br />
  header("Content-Disposition: attachment; filename=test.pdf");<br />
  header("Content-Length: $size");<br />
  echo $buffer;<br />
  $PDF = null;<br />
?&gt;</code></p>
<p>The script did not work as expected.</p>
<p>The reason was: PHP does not work well with the VARIANT type representing VT_ARRAY. PHP easily converts all other COM types, and permits you to do with them whatever you wish. This is what the PHP script said about our <code>$buffer</code>:</p>
<p><code>echo var_dump($buffer)."\n";<br />
echo variant_get_type($buffer)."\n";<br />
// output:<br />
// 8209<br />
// object(variant)#2 (0){<br />
// }</code></p>
<p>The variable that we received was impossible to convert into any COM type, since PHP reported an &#8220;unsupported type&#8221;.</p>
<p>We&#8217;ve found a solution. PHP seems to be unable to convert a VT_ARRAY into a native PHP array, but it permits us to access a COM array’s data. Both, &#8220;<code>for</code>&#8221; and &#8220;<code>foreach</code>&#8221; work fine.</p>
<p>Here is the working script:</p>
<p><code>&lt;?<br />
  $PDF = new COM("PDFCreatorPilot.PDFDocument4") or die("Unable to load instanciate.");<br />
  $PDF-&gt;SetLicenseData("demo", "demo");<br />
  $PDF-&gt;Compression = 1; // coFlate</code><br />
<code><br />
  $fnt = $PDF-&gt;AddBuiltInFont(1, false, false);<br />
  $PDF-&gt;UseFont($fnt, 14);<br />
  $PDF-&gt;ShowTextAt(30, 30, "Hello from PHP!");</code><br />
<code><br />
  $size = $PDF-&gt;GetBufferSize();<br />
  $buffer = $PDF-&gt;GetBuffer();</code><br />
<code><br />
  header("Content-type: application/pdf");<br />
  header("Content-Disposition: attachment; filename=test.pdf");<br />
  header("Content-Length: $size");</code><br />
<code><br />
  // <font size="2">$PDF-&gt;GetBuffer() return a VARIANT array (VT_ARRAY) with elements of type VT_UI1, so we have to</font><br />
  // <font size="2">transform them into char ourselves</font>.<br />
  foreach ($buffer as $byte)<br />
  echo chr($byte);</code><br />
<code><br />
  $PDF = null;<br />
?&gt;</code></p>
<p>It works. Good luck and take care when you have to use COM from PHP.</p>
<p align="right">Filimonov Maxim<br />
Developer of <a target="_blank" href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/com-arrays-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using PDF Creator Pilot on ASP.NET Web Pages without Visual Studio</title>
		<link>http://www.colorpilot.com/blog/using-pdf-creator-pilot-on-aspnet-web-pages-without-visual-studio/</link>
		<comments>http://www.colorpilot.com/blog/using-pdf-creator-pilot-on-aspnet-web-pages-without-visual-studio/#comments</comments>
		<pubDate>Thu, 06 Mar 2008 06:20:34 +0000</pubDate>
		<dc:creator>max.f</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/using-pdf-creator-pilot-on-aspnet-web-pages-without-visual-studio/</guid>
		<description><![CDATA[ To do work with ASP.NET, we must perform three steps:

Create an Interop-wrapper
Copy the wrapper into a specific folder
Attach the namespace libraries to the application

To create the Interop-wrapper of PDF Creator Pilot (i.e. a wrapper that would make it possible to call unmanaged COM-object code of the library from the managed code of an ASP.NET application), [...]]]></description>
			<content:encoded><![CDATA[<p> To do work with ASP.NET, we must perform three steps:</p>
<ol>
<li>Create an Interop-wrapper</li>
<li>Copy the wrapper into a specific folder</li>
<li>Attach the namespace libraries to the application</li>
</ol>
<p>To create the Interop-wrapper of PDF Creator Pilot (i.e. a wrapper that would make it possible to call unmanaged COM-object code of the library from the managed code of an ASP.NET application), we should use one of the standard utilities from the .NET SDK &#8211; TlbImp.exe (C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\TlbImp.exe)</p>
<p><span id="more-6"></span></p>
<p><em>Example:</em></p>
<p><code>TlbImp.exe PDFCreatorPilot3.dll /out:Interop.PDFCreatorPilot3Lib.dll</code></p>
<p>Then we need to copy the wrapper into the &#8220;bin&#8221; subfolder of the web-application root folder. (If that folder does not yet exist, we will have to create it.)</p>
<p><em>Example:</em></p>
<p>If our web-application is located in “C:\Inetpub\wwwroot\MyApp”, then we should put the wrapper into “C:\Inetpub\wwwroot\MyApp\bin”.</p>
<p>To attach the web-application to the namespace library, we should append the following line to the &#8220;.aspx&#8221;-file:</p>
<p><code>&lt;%@ Import Namespace="Interop.PDFCreatorPilot3Lib.dll" %&gt;</code></p>
<p>After that, a COM-object of PDF Creator Pilot may be used from ASP.NET.</p>
<p><em>Example:</em></p>
<p><code>&lt;%@ Import Namespace="System" %&gt;<br />
&lt;!-- other import directives are here --&gt;<br />
&lt;%@ Import Namespace="Interop.PDFCreatorPilot3Lib.dll" %&gt;<br />
&lt;HTML&gt; &lt;HEAD&gt;<br />
  &lt;TITLE&gt;Test&lt;/TITLE&gt;<br />
  &lt;SCRIPT language="C#" runat="server"&gt;<br />
    void ButtonPerform_Click(object sender, System.EventArgs e)<br />
    {<br />
      PDFDocument3Class pdf = new PDFDocument3Class();<br />
      pdf.StartEngine("demo@demo", "demo");<br />
      pdf.AutoCreateURL = true;<br />
      // set other options if needed<br />
      pdf.BeginDoc();<br />
      // do something<br />
      pdf.EndDoc();<br />
    }<br />
  &lt;/SCRIPT&gt;<br />
&lt;/HEAD&gt;<br />
&lt;BODY&gt;<br />
  &lt;!-- here page content goes --&gt;<br />
  &lt;FORM runat="server"&gt;<br />
    &lt;INPUT type="button" id="ButtonPerform" value="Click Me"<br />
      OnServerClick="ButtonPerform_Click" runat="server" /&gt;<br />
    &lt;!-- or another vaiant --&gt;<br />
    &lt;asp:Button id="ButtonPerform1" Text="Click Me"<br />
      OnClick="ButtonPerform_Click" runat="server" /&gt;<br />
  &lt;/FORM&gt;<br />
&lt;/BODY&gt;<br />
&lt;/HTML&gt;</code></p>
<p align="right">Maxim Filimonov<br />
Developer of <a href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/using-pdf-creator-pilot-on-aspnet-web-pages-without-visual-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ Unit Tests</title>
		<link>http://www.colorpilot.com/blog/cpp-unit-tests/</link>
		<comments>http://www.colorpilot.com/blog/cpp-unit-tests/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 08:36:33 +0000</pubDate>
		<dc:creator>Vitaliy Shibaev</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/5/</guid>
		<description><![CDATA[Hi everybody!
Here I talk about various tools that may be used to develop the unit tests with C++, in particular about those that we use in PDF Creator, and about the way we deploy it.
As PDF Creator evolved, it started to become more evident that there was a need for an easy-to-use testing procedure. The huge [...]]]></description>
			<content:encoded><![CDATA[<p>Hi everybody!</p>
<p>Here I talk about various tools that may be used to develop the unit tests with C++, in particular about those that we use in PDF Creator, and about the way we deploy it.</p>
<p>As PDF Creator evolved, it started to become more evident that there was a need for an easy-to-use testing procedure. The huge code base, lots of clients, quirks of the PDF format and of the library itself &#8212; these were the factors that turned every change in the code into a difficult task. Currently, every time we release a new version (actually, even more frequently), we pass the library through a set of visual tests. Some tests produce PDF files; their quality and correctness may be checked visually. Other tests convert EMF files, producing a visible result, too. There are also ASP and VB scripts among the tests. The set of the tests grows constantly, however, even when the library passes through all of them OK, there is no guarantee that all the functions of the library have been retained.</p>
<p><span id="more-5"></span>Because of that, while developing PDF Creator 3.9, we paid a lot of attention to the refactoring of our code. One of our refactoring goals was to improve testability of the code. After we determined the goals, we had to choose an environment for creation of the test units. Initially, it was a choice between the classic CppUnit (<a href="http://sourceforge.net/projects/cppunit/">http://sourceforge.net/projects/cppunit/</a>) and the Boost.Test Library (<a href="http://www.boost.org/libs/test/doc/index.html">http://www.boost.org/libs/test/doc/index.html</a>).</p>
<p>Here is a summary of the requirements that we imposed on the testing environment:</p>
<ol>
<li>Writing a test should require minimal preparation.</li>
<li>Test results should be clearly revealed and easily observed. Integration into Visual Studio is a plus.</li>
<li>The environment must be cross platform. (In the future, we plan to make the PDF library platform independent.)</li>
<li>The size of the environment must be small.</li>
<li>Test units must be automatically excluded from the Release build.</li>
</ol>
<p>I’ve had some experience with the CppUnit before, and I was not pleased. It failed to pass requirements 1, 2, and 4. It contains a lot of redundant stuff we did not actually need. The interface of CppUnit is not trivial, and we would have to add a lot of code ourselves. Negative. Especially after nUnit.</p>
<p>We were going to use Boost.Test, however, we discovered that we would have to include the entire Boost Library, with all its bells and whistles. I am not a big expert in Boost. If there is a way to use Boost.Test without adding the entire library to the project, please tell us how. We had to reject Boost.</p>
<p>Then we had to look for an alternative. I think that <a href="http://www.gamesfromwithin.com/articles/0412/000061.html">http://www.gamesfromwithin.com/articles/0412/000061.html</a> is a must read. It is an excellent comparison of various test unit tools.</p>
<p>After reading the article, of course, we looked into CxxTest (<a href="http://cxxtest.sourceforge.net/">http://cxxtest.sourceforge.net/</a>), and it disappointed us. Documentation is huge, but not very understandable. The latest revision was outdated – from 2004! Compilation requires Perl ! Another wrong environment.</p>
<p>We looked into some other variants, and none of them seemed to fit. With our hope of finding anything slowly dying already, we found UnitTest++. (<em>Applause!</em>) You can see it here: <a href="http://unittest-cpp.sourceforge.net/">http://unittest-cpp.sourceforge.net/</a>. One of the UnitTest++ developers, Noel Llopis, is also the author of the excellent article referenced above. Here is his description of his own product: <a href="http://www.gamesfromwithin.com/articles/0603/000108.html">http://www.gamesfromwithin.com/articles/0603/000108.html</a></p>
<p>UnitTest++ fits all 5 of our requirements. It’s trivial to write a test. The environment is easy to understand and cross-platform. Whenever a test fails, it is detached into a separate project. The toolset seamlessly integrates into Visual Studio. When the tests are run, the output window displays the number of tests, elapsed time, and reviews of the failed tests. It was like a dream come true.</p>
<p>We started to use UnitTest++ in PDF Creator. Soon we discovered that we did not receive its excellent features “for free”. Let’s look under the hood of a typical test:</p>
<p><code>TEST(SomeTest)<br />
{<br />
const int expected = 123;<br />
int res = testedFunction();<br />
CHECK_EQUAL(res, expected);<br />
}</code></p>
<p>During compilation, the TEST macro turns into a class named TestSomeTest, that inherits from an unknown class UnitTest::Test. The last line of the code after that looks like this:</p>
<p><code>void TestSomeTest::RunImpl(UnitTest::TestResults&amp; testResults_) const</code></p>
<p>As you can see, the body of the test is created by RunImpl. After we looked inside the CHECK_EQUAL macro, we understood that it may render correct results only under some limited circumstances &#8212; only inside methods, defined with the Test macros. That meant that we had to forget about normal refactoring. In particular, it is impossible to separate a test method.</p>
<p>It is also impossible to temporarily disable a method, since it is a macro. To switch a test off, one has to comment it.</p>
<p>Another problem: IntelliSense doesn’t always work properly when a test method is being written. Evil consequences of the use of macros, again. It is also hard to extend and improve the functionalities of UnitTest++. Perhaps that’s the reason why it has not been updated for quite a long time &#8211; since April, 2007.</p>
<p>However, it is not a bad environment. Refactoring problems may be by-passed. The other problems may be put up with. In my next article, I plan to provide more details about testing with UnitTest++ and the process of hunting for memory leaks with the help of memleaks.</p>
<p align="right">Vitaly Shibaev<br />
Developer of <a href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/cpp-unit-tests/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>About PDF Creator Pilot 3.9</title>
		<link>http://www.colorpilot.com/blog/about-pdf-creator-39/</link>
		<comments>http://www.colorpilot.com/blog/about-pdf-creator-39/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 05:40:35 +0000</pubDate>
		<dc:creator>Vitaliy Shibaev</dc:creator>
				<category><![CDATA[For software developers]]></category>

		<guid isPermaLink="false">http://www.colorpilot.com/blog/?p=4</guid>
		<description><![CDATA[Hi, everybody! My name is Vitaly Shibaev. I am one of the developers of the PDF Creator library. In my first note, I want to talk specifically about version 3.9.
In my opinion, the most important improvement in this version is how it renders texts. Any kind of text renders correctly, as searchable and clipboard compatible. [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, everybody! My name is Vitaly Shibaev. I am one of the developers of the PDF Creator library. In my first note, I want to talk specifically about version 3.9.</p>
<p>In my opinion, the most important improvement in this version is how it renders texts. Any kind of text renders correctly, as searchable and clipboard compatible. In general, the library generates smaller output files, especially when the CJK fonts are used.</p>
<p><span id="more-4"></span>We also got rid of memory leaks, and along the way we have seriously refactored the code. As a result, the library works faster and is more stable.</p>
<p>Instead of using BoundsChecker to catch the leaks, we used great two code files (<a target="_blank" href="http://www.colorpilot.com/~vit.shibaev/mmgr.zip">http://www.colorpilot.com/~vit.shibaev/mmgr.zip</a>) that actually saved us. Just include them in your project, by adding “#include “mmgr.h”” in a header file, and you’re all set. After that, in the same location as the application executable, three log files will be created (memleaks.log, memory.log and memreport.log). The “memleaks.log” file will report any and all leaks. When you turn on the “memreport.log” in “mmgr.cpp” (by default it’s turned off), it provides detailed reports about all memory allocations and deallocations (when, how much, etc.). I would recommend mmgr to all C++ developers.</p>
<p>There are some more important improvements in the library. It now renders CMYK JPEG images. This feature is vital for users with special image quality requirements, especially in pre-press.</p>
<p>Other improvements are related to interactive forms and annotations. First, file sizes have been optimized. In most cases, their size will be 2-3 times smaller than previously. Second, we’ve improved the rendering of Unicode symbols.</p>
<p>We’ve added the Caption property to the radio button descriptions. Caption is now a part of the control. It’s coded like this:</p>
<p><code>PDF.PDFPAGE_CreateControl_RadioButton “rb_group”, 0, 0, 100, 20<br />
PDF.PDFANNOTATION_Caption = “Place some text here”</code></p>
<p>Revealing some of our secrets, we’ve reorganized and improved our code in version 3.9. We added some unit tests (not for all the code yet). The process of choosing a proper unit test environment for C++ was of special interest. It would be a good topic for the next time.</p>
<p align="right">Vitaly Shibaev<br />
Developer of <a href="http://www.colorpilot.com/pdflibrary.html">PDF Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.colorpilot.com/blog/about-pdf-creator-39/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
