Commit 74bef044cc17a4f3c5aae27c5d30c6e82407db94

Authored by Jay Berkenbilt
1 parent b653929c

Update release notes for 8.3.0

ChangeLog
... ... @@ -53,6 +53,9 @@
53 53  
54 54 2019-01-03 Jay Berkenbilt <ejb@ql.org>
55 55  
  56 + * Add --generate-appearances flag to the qpdf command-line tool to
  57 + trigger generation of appearance streams.
  58 +
56 59 * Fix behavior of form field value setting to handle the following
57 60 cases:
58 61 - Strings are always written as UTF-16
... ...
ispell-words
... ... @@ -5,11 +5,9 @@ abacc
5 5 abc
6 6 ABCD
7 7 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom
8   -abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom
9 8 abcde
10 9 abcdefABCDEF
11 10 abcdefghbcdefghicdefghijdefghijkefghijklfghijklmg
12   -abcdefghbcdefghicdefghijdefghijkefghijklfghijklmg
13 11 abcdefghijklmnopqrstuvwxyz
14 12 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi
15 13 ABI
... ... @@ -896,7 +894,6 @@ HGeneric
896 894 hh
897 895 HighPart
898 896 hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstn
899   -hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstn
900 897 hlen
901 898 Hoffmann
902 899 HOi
... ... @@ -1860,6 +1857,7 @@ toupper
1860 1857 toUTF
1861 1858 tp
1862 1859 transcode
  1860 +transcoding
1863 1861 traverseField
1864 1862 travis
1865 1863 TrimBox
... ... @@ -2004,6 +2002,7 @@ xc
2004 2002 xcc
2005 2003 xcf
2006 2004 xD
  2005 +xd
2007 2006 xDC
2008 2007 xe
2009 2008 xeaa
... ...
manual/qpdf-manual.xml
... ... @@ -1843,7 +1843,7 @@ outfile.pdf&lt;/option&gt;
1843 1843 <term><option>--json</option></term>
1844 1844 <listitem>
1845 1845 <para>
1846   - Generate a json representation of the file. This is described
  1846 + Generate a JSON representation of the file. This is described
1847 1847 in depth in <xref linkend="ref.json"/>
1848 1848 </para>
1849 1849 </listitem>
... ... @@ -1852,7 +1852,7 @@ outfile.pdf&lt;/option&gt;
1852 1852 <term><option>--json-help</option></term>
1853 1853 <listitem>
1854 1854 <para>
1855   - Describe the format of the json output.
  1855 + Describe the format of the JSON output.
1856 1856 </para>
1857 1857 </listitem>
1858 1858 </varlistentry>
... ... @@ -1861,7 +1861,7 @@ outfile.pdf&lt;/option&gt;
1861 1861 <listitem>
1862 1862 <para>
1863 1863 This option is repeatable. If specified, only top-level keys
1864   - specified will be included in the json output. If not
  1864 + specified will be included in the JSON output. If not
1865 1865 specified, all keys will be shown.
1866 1866 </para>
1867 1867 </listitem>
... ... @@ -1872,7 +1872,7 @@ outfile.pdf&lt;/option&gt;
1872 1872 <para>
1873 1873 This option is repeatable. If specified, only specified
1874 1874 objects will be shown in the
1875   - &ldquo;<literal>objects</literal>&rdquo; key of the json
  1875 + &ldquo;<literal>objects</literal>&rdquo; key of the JSON
1876 1876 output. If absent, all objects will be shown.
1877 1877 </para>
1878 1878 </listitem>
... ... @@ -2150,7 +2150,7 @@ outfile.pdf&lt;/option&gt;
2150 2150 <listitem>
2151 2151 <para>
2152 2152 Starting with version 8.3.0, the <command>qpdf</command>
2153   - command-line tool can produce a json representation of the PDF
  2153 + command-line tool can produce a JSON representation of the PDF
2154 2154 file's non-content data. This can facilitate interacting
2155 2155 programmatically with PDF files through qpdf's command line
2156 2156 interface. For more information, please see <xref
... ... @@ -2167,10 +2167,10 @@ outfile.pdf&lt;/option&gt;
2167 2167 <title>Overview</title>
2168 2168 <para>
2169 2169 Beginning with qpdf version 8.3.0, the <command>qpdf</command>
2170   - command-line program can produce a json representation of the
2171   - non-content data in a PDF file. It includes a dump in json format
  2170 + command-line program can produce a JSON representation of the
  2171 + non-content data in a PDF file. It includes a dump in JSON format
2172 2172 of all objects in the PDF file excluding the content of streams.
2173   - This json representation makes it very easy to look in detail at
  2173 + This JSON representation makes it very easy to look in detail at
2174 2174 the structure of a given PDF file, and it also provides a great way
2175 2175 to work with PDF files programmatically from the command-line in
2176 2176 languages that can't call or link with the qpdf library directly.
... ... @@ -2181,17 +2181,17 @@ outfile.pdf&lt;/option&gt;
2181 2181 <sect1 id="ref.json-guarantees">
2182 2182 <title>JSON Guarantees</title>
2183 2183 <para>
2184   - The qpdf json representation includes a json serialization of the
  2184 + The qpdf JSON representation includes a JSON serialization of the
2185 2185 raw objects in the PDF file as well as some computed information in
2186 2186 a more easily extracted format. QPDF provides some guarantees about
2187   - its json format. These guarantees are designed to simplify the
  2187 + its JSON format. These guarantees are designed to simplify the
2188 2188 experience of a developer working with the JSON format.
2189 2189 <variablelist>
2190 2190 <varlistentry>
2191 2191 <term>Compatibility</term>
2192 2192 <listitem>
2193 2193 <para>
2194   - The top-level json object output is a dictionary. The json
  2194 + The top-level JSON object output is a dictionary. The JSON
2195 2195 output contains various nested dictionaries and arrays. With
2196 2196 the exception of dictionaries that are populated by the fields
2197 2197 of objects from the file, all instances of a dictionary are
... ... @@ -2204,7 +2204,7 @@ outfile.pdf&lt;/option&gt;
2204 2204 report.
2205 2205 </para>
2206 2206 <para>
2207   - The top-level json structure contains a
  2207 + The top-level JSON structure contains a
2208 2208 &ldquo;<literal>version</literal>&rdquo; key whose value is
2209 2209 simple integer. The value of the <literal>version</literal> key
2210 2210 will be incremented if a non-compatible change is made. A
... ... @@ -2221,16 +2221,16 @@ outfile.pdf&lt;/option&gt;
2221 2221 <listitem>
2222 2222 <para>
2223 2223 The <command>qpdf</command> command can be invoked with the
2224   - <option>--json-help</option> option. This will output a json
2225   - structure that has the same structure as the json output that
  2224 + <option>--json-help</option> option. This will output a JSON
  2225 + structure that has the same structure as the JSON output that
2226 2226 qpdf generates, except that each field in the help output is a
2227   - description of the corresponding field in the json output. The
  2227 + description of the corresponding field in the JSON output. The
2228 2228 specific guarantees are as follows:
2229 2229 <itemizedlist>
2230 2230 <listitem>
2231 2231 <para>
2232 2232 A dictionary in the help output means that the corresponding
2233   - location in the actual json output is also a dictionary with
  2233 + location in the actual JSON output is also a dictionary with
2234 2234 exactly the same keys; that is, no keys present in help are
2235 2235 absent in the real output, and no keys will be present in
2236 2236 the real output that are not in help.
... ... @@ -2259,7 +2259,7 @@ outfile.pdf&lt;/option&gt;
2259 2259 &ldquo;<literal>index</literal>&rdquo; and
2260 2260 &ldquo;<literal>label</literal>&rdquo;. In addition to
2261 2261 describing the meaning of those keys, this tells you that the
2262   - actual json output will contain a <literal>pagelabels</literal>
  2262 + actual JSON output will contain a <literal>pagelabels</literal>
2263 2263 array, each of whose elements is a dictionary that contains an
2264 2264 <literal>index</literal> key, a <literal>label</literal> key,
2265 2265 and no other keys.
... ... @@ -2270,7 +2270,7 @@ outfile.pdf&lt;/option&gt;
2270 2270 <term>Directness and Simplicity</term>
2271 2271 <listitem>
2272 2272 <para>
2273   - The json output contains the value of every object in the file,
  2273 + The JSON output contains the value of every object in the file,
2274 2274 but it also contains some processed data. This is analogous to
2275 2275 how qpdf's library interface works. The processed data is
2276 2276 similar to the helper functions in that it allows you to look
... ... @@ -2287,18 +2287,18 @@ outfile.pdf&lt;/option&gt;
2287 2287 <sect1 id="json.limitations">
2288 2288 <title>Limitations of JSON Representation</title>
2289 2289 <para>
2290   - There are a few limitations to be aware of with the json structure:
  2290 + There are a few limitations to be aware of with the JSON structure:
2291 2291 <itemizedlist>
2292 2292 <listitem>
2293 2293 <para>
2294 2294 Strings, names, and indirect object references in the original
2295   - PDF file are all converted to strings in the json
  2295 + PDF file are all converted to strings in the JSON
2296 2296 representation. In the case of a &ldquo;normal&rdquo; PDF file,
2297 2297 you can tell the difference because a name starts with a slash
2298 2298 (<literal>/</literal>), and an indirect object reference looks
2299 2299 like <literal>n n R</literal>, but if there were to be a string
2300 2300 that looked like a name or indirect object reference, there
2301   - would be no way to tell this from the json output. Note that
  2301 + would be no way to tell this from the JSON output. Note that
2302 2302 there are certain cases where you know for sure what something
2303 2303 is, such as knowing that dictionary keys in objects are always
2304 2304 names and that certain things in the higher-level computed data
... ... @@ -2307,9 +2307,9 @@ outfile.pdf&lt;/option&gt;
2307 2307 </listitem>
2308 2308 <listitem>
2309 2309 <para>
2310   - The json format doesn't support binary data very well. Mostly
  2310 + The JSON format doesn't support binary data very well. Mostly
2311 2311 the details are not important, but they are presented here for
2312   - information. When qpdf outputs a string in the json
  2312 + information. When qpdf outputs a string in the JSON
2313 2313 representation, it converts the string to UTF-8, assuming usual
2314 2314 PDF string semantics. Specifically, if the original string is
2315 2315 UTF-16, it is converted to UTF-8. Otherwise, it is assumed to
... ... @@ -2317,7 +2317,7 @@ outfile.pdf&lt;/option&gt;
2317 2317 assumption. This causes strange things to happen to binary
2318 2318 strings. For example, if you had the binary string
2319 2319 <literal>&lt;038051&gt;</literal>, this would be output to the
2320   - json as <literal>\u0003โ€ขQ</literal> because
  2320 + JSON as <literal>\u0003โ€ขQ</literal> because
2321 2321 <literal>03</literal> is not a printable character and
2322 2322 <literal>80</literal> is the bullet character in PDF doc
2323 2323 encoding and is mapped to the Unicode value
... ... @@ -2330,7 +2330,7 @@ outfile.pdf&lt;/option&gt;
2330 2330 tell the difference between a Unicode string that was originally
2331 2331 encoded as UTF-16 or one that was converted from PDF doc
2332 2332 encoding. In other words, it's best if you don't try to use the
2333   - json format to extract binary strings from the PDF file, but if
  2333 + JSON format to extract binary strings from the PDF file, but if
2334 2334 you really had to, it could be done. Note that qpdf's
2335 2335 <option>--show-object</option> option does not have this
2336 2336 limitation and will reveal the string as encoded in the original
... ... @@ -2362,11 +2362,11 @@ outfile.pdf&lt;/option&gt;
2362 2362 In a few places, there are keys with names containing
2363 2363 <literal>pageposfrom1</literal>. The values of these keys are
2364 2364 null or an integer. If an integer, they point to a page index
2365   - within the file numbering from 1. Note that json indexes from
  2365 + within the file numbering from 1. Note that JSON indexes from
2366 2366 0, and you would also use 0-based indexing using the API.
2367 2367 However, 1-based indexing is easier in this case because the
2368 2368 command-line syntax for specifying page ranges is 1-based. If
2369   - you were going to write a program that looked through the json
  2369 + you were going to write a program that looked through the JSON
2370 2370 for information about specific pages and then use the
2371 2371 command-line to extract those pages, 1-based indexing is
2372 2372 easier. Besides, it's more convenient to subtract 1 from a
... ... @@ -2377,11 +2377,11 @@ outfile.pdf&lt;/option&gt;
2377 2377 <listitem>
2378 2378 <para>
2379 2379 The image information included in the <literal>page</literal>
2380   - section of the json output includes the key
  2380 + section of the JSON output includes the key
2381 2381 &ldquo;<literal>filterable</literal>&rdquo;. Note that the
2382 2382 value of this field may depend on the
2383 2383 <option>--decode-level</option> that you invoke qpdf with. The
2384   - json output includes a top-level key
  2384 + JSON output includes a top-level key
2385 2385 &ldquo;<literal>parameters</literal>&rdquo; that indicates the
2386 2386 decode level used for computing whether a stream was
2387 2387 filterable. For example, jpeg images will be shown as not
... ... @@ -3871,6 +3871,322 @@ print &quot;\n&quot;;
3871 3871 </para>
3872 3872 <variablelist>
3873 3873 <varlistentry>
  3874 + <term>8.3.0: January 7, 2019</term>
  3875 + <listitem>
  3876 + <itemizedlist>
  3877 + <listitem>
  3878 + <para>
  3879 + Command-line Enhancements
  3880 + </para>
  3881 + <itemizedlist>
  3882 + <listitem>
  3883 + <para>
  3884 + Shell completion: you can now use eval <command>$(qpdf
  3885 + --completion-bash)</command> and eval <command>$(qpdf
  3886 + --completion-zsh)</command> to enable shell completion for
  3887 + bash and zsh.
  3888 + </para>
  3889 + </listitem>
  3890 + <listitem>
  3891 + <para>
  3892 + Page numbers (also known as page labels) are now preserved
  3893 + when merging and splitting files with the
  3894 + <option>--pages</option> and <option>--split-pages</option>
  3895 + options.
  3896 + </para>
  3897 + </listitem>
  3898 + <listitem>
  3899 + <para>
  3900 + Bookmarks are partially preserved when splitting pages with
  3901 + the <option>--split-pages</option> option. Specifically, the
  3902 + outlines dictionary and some supporting metadata are copied
  3903 + into the split files. The result is that all bookmarks from
  3904 + the original file appear, those that point to pages that are
  3905 + preserved work, and those that point to pages that are not
  3906 + preserved don't do anything. This is an interim step toward
  3907 + proper support for bookmarks in splitting and merging
  3908 + operations.
  3909 + </para>
  3910 + </listitem>
  3911 + <listitem>
  3912 + <para>
  3913 + Page collation: add new option <option>--collate</option>.
  3914 + When specified, the semantics of <option>--pages</option>
  3915 + change from concatenation to collation. See <xref
  3916 + linkend="ref.page-selection"/> for examples and discussion.
  3917 + </para>
  3918 + </listitem>
  3919 + <listitem>
  3920 + <para>
  3921 + Generation of information in JSON format, primarily to
  3922 + facilitate use of qpdf from languages other than C++. Add
  3923 + new options <option>--json</option>,
  3924 + <option>--json-key</option>, and
  3925 + <option>--json-object</option> to generate a JSON
  3926 + representation of the PDF file. Run <command>qpdf
  3927 + --json-help</command> to get a description of the JSON
  3928 + format. For more information, see <xref linkend="ref.json"/>.
  3929 + </para>
  3930 + </listitem>
  3931 + <listitem>
  3932 + <para>
  3933 + The <option>--generate-appearances</option> flag will cause
  3934 + qpdf to generate appearances for form fields if the PDF file
  3935 + indicates that form field appearances are out of date. This
  3936 + can happen when PDF forms are filled in by a program that
  3937 + doesn't know how to regenerate the appearances of the
  3938 + filled-in fields.
  3939 + </para>
  3940 + </listitem>
  3941 + <listitem>
  3942 + <para>
  3943 + The <option>--flatten-annotations</option> flag can be used
  3944 + to <emphasis>flatten</emphasis> annotations, including form
  3945 + fields. Ordinarily, annotations are drawn separately from
  3946 + the page. Flattening annotations is the process of combining
  3947 + their appearances into the page's contents. You might want
  3948 + to do this if you are going to rotate or combine pages using
  3949 + a tool that doesn't understand about annotations. You may
  3950 + also want to use <option>--generate-appearances</option>
  3951 + when using this flag since annotations for outdated form
  3952 + fields are not flattened as that would cause loss of
  3953 + information.
  3954 + </para>
  3955 + </listitem>
  3956 + <listitem>
  3957 + <para>
  3958 + The <option>--optimize-images</option> flag tells qpdf to
  3959 + recompresses every image using DCT (JPEG) compression as
  3960 + long as the image is not already compressed with lossy
  3961 + compression and recompressing the image reduces its size.
  3962 + The additional options <option>--oi-min-width</option>,
  3963 + <option>--oi-min-height</option>, and
  3964 + <option>--oi-min-area</option> prevent recompression of
  3965 + images whose width, height, or pixel area
  3966 + (width&nbsp;&#xd7;&nbsp;height) are below a specified
  3967 + threshold.
  3968 + </para>
  3969 + </listitem>
  3970 + <listitem>
  3971 + <para>
  3972 + The <option>--show-object</option> option can now be given
  3973 + as <option>--show-object=trailer</option> to show the
  3974 + trailer dictionary.
  3975 + </para>
  3976 + </listitem>
  3977 + </itemizedlist>
  3978 + </listitem>
  3979 + <listitem>
  3980 + <para>
  3981 + Bug Fixes and Enhancements
  3982 + </para>
  3983 + <itemizedlist>
  3984 + <listitem>
  3985 + <para>
  3986 + QPDF now automatically detects and recovers from dangling
  3987 + references. If a PDF file contained an indirect reference to
  3988 + a non-existent object, which is valid, when adding a new
  3989 + object to the file, it was possible for the new object to
  3990 + take the object ID of the dangling reference, thereby
  3991 + causing the dangling reference to point to the new object.
  3992 + This case is now prevented.
  3993 + </para>
  3994 + </listitem>
  3995 + <listitem>
  3996 + <para>
  3997 + Fixes to form field setting code: strings are always written
  3998 + in UTF-16 format, and checkboxes and radio buttons are
  3999 + handled properly with respect to synchronization of values
  4000 + and appearance states.
  4001 + </para>
  4002 + </listitem>
  4003 + <listitem>
  4004 + <para>
  4005 + The <function>QPDF::checkLinearization()</function> no
  4006 + longer causes the program to crash when it detects problems
  4007 + with linearization data. Instead, it issues a normal warning
  4008 + or error.
  4009 + </para>
  4010 + </listitem>
  4011 + <listitem>
  4012 + <para>
  4013 + Ordinarily qpdf treats an argument of the form
  4014 + <option>@file</option> to mean that command-line options
  4015 + should be read from <filename>file</filename>. Now, if
  4016 + <filename>file</filename> does not exist but
  4017 + <filename>@file</filename> does, qpdf will treat
  4018 + <filename>@file</filename> as a regular option. This makes
  4019 + it possible to work more easily with PDF files whose names
  4020 + happen to start with the <literal>@</literal> character.
  4021 + </para>
  4022 + </listitem>
  4023 + </itemizedlist>
  4024 + </listitem>
  4025 + <listitem>
  4026 + <para>
  4027 + Library Enhancements
  4028 + </para>
  4029 + <itemizedlist>
  4030 + <listitem>
  4031 + <para>
  4032 + Remove the restriction in most cases that the source QPDF
  4033 + object used in a
  4034 + <function>QPDF::copyForeignObject</function> call has to
  4035 + stick around until the destination QPDF is written. The
  4036 + exceptional case is when the source stream gets is data
  4037 + using a QPDFObjectHandle::StreamDataProvider. For a more
  4038 + in-depth discussion, see comments around
  4039 + <function>copyForeignObject</function> in
  4040 + <filename>QPDF.hh</filename>.
  4041 + </para>
  4042 + </listitem>
  4043 + <listitem>
  4044 + <para>
  4045 + Add new method
  4046 + <function>QPDFWriter::getFinalVersion()</function>, which
  4047 + returns the PDF version that will ultimately be written to
  4048 + the final file. See comments in
  4049 + <filename>QPDFWriter.hh</filename> for some restrictions on
  4050 + its use.
  4051 + </para>
  4052 + </listitem>
  4053 + <listitem>
  4054 + <para>
  4055 + Add several methods for transcoding strings to some of the
  4056 + character sets used in PDF files:
  4057 + <function>QUtil::utf8_to_ascii</function>,
  4058 + <function>QUtil::utf8_to_win_ansi</function>,
  4059 + <function>QUtil::utf8_to_mac_roman</function>, and
  4060 + <function>QUtil::utf8_to_utf16</function>. For the
  4061 + single-byte encodings that support only a limited character
  4062 + sets, these methods replace unsupported characters with a
  4063 + specified substitute.
  4064 + </para>
  4065 + </listitem>
  4066 + <listitem>
  4067 + <para>
  4068 + Add new methods to
  4069 + <classname>QPDFAnnotationObjectHelper</classname> and
  4070 + <classname>QPDFFormFieldObjectHelper</classname> for
  4071 + querying flags and interpretation of different field types.
  4072 + Define constants in <filename>qpdf/Constants.h</filename> to
  4073 + help with interpretation of flag values.
  4074 + </para>
  4075 + </listitem>
  4076 + <listitem>
  4077 + <para>
  4078 + Add new methods
  4079 + <function>QPDFAcroFormDocumentHelper::generateAppearancesIfNeeded</function>
  4080 + and
  4081 + <function>QPDFFormFieldObjectHelper::generateAppearance</function>
  4082 + for generating appearance streams. See discussion in
  4083 + <filename>QPDFFormFieldObjectHelper.hh</filename> for
  4084 + limitations.
  4085 + </para>
  4086 + </listitem>
  4087 + <listitem>
  4088 + <para>
  4089 + Add two new helper functions for dealing with resource
  4090 + dictionaries:
  4091 + <function>QPDFObjectHandle::getResourceNames()</function>
  4092 + returns a list of all second-level keys, which correspond to
  4093 + the names of resources, and
  4094 + <function>QPDFObjectHandle::mergeResources()</function>
  4095 + merges two resources dictionaries as long as they have
  4096 + non-conflicting keys. These methods are useful for certain
  4097 + types of objects that resolve resources from multiple places,
  4098 + such as form fields.
  4099 + </para>
  4100 + </listitem>
  4101 + <listitem>
  4102 + <para>
  4103 + Add methods
  4104 + <function>QPDFPageDocumentHelper::flattenAnnotations()</function>
  4105 + and
  4106 + <function>QPDFAnnotationObjectHelper::getPageContentForAppearance()</function>
  4107 + for handling low-level details of annotation flattening.
  4108 + </para>
  4109 + </listitem>
  4110 + <listitem>
  4111 + <para>
  4112 + Add new helper classes:
  4113 + <classname>QPDFOutlineDocumentHelper</classname>,
  4114 + <classname>QPDFOutlineObjectHelper</classname>,
  4115 + <classname>QPDFPageLabelDocumentHelper</classname>,
  4116 + <classname>QPDFNameTreeObjectHelper</classname>, and
  4117 + <classname>QPDFNumberTreeObjectHelper</classname>.
  4118 + </para>
  4119 + </listitem>
  4120 + <listitem>
  4121 + <para>
  4122 + Add method <function>QPDFObjectHandle::getJSON()</function>
  4123 + that returns a JSON representation of the object. Call
  4124 + <function>serialize()</function> on the result to convert it
  4125 + to a string.
  4126 + </para>
  4127 + </listitem>
  4128 + <listitem>
  4129 + <para>
  4130 + Add a simple JSON serializer. This is not a complete or
  4131 + general-purpose JSON library. It allows assembly and
  4132 + serialization of JSON structures with some restrictions,
  4133 + which are described in the header file. This is the
  4134 + serializer used by qpdf's new JSON representation.
  4135 + </para>
  4136 + </listitem>
  4137 + <listitem>
  4138 + <para>
  4139 + Add new <classname>QPDFObjectHandle::Matrix</classname>
  4140 + class along with a few convenience methods for dealing with
  4141 + six-element numerical arrays as matrices.
  4142 + </para>
  4143 + </listitem>
  4144 + <listitem>
  4145 + <para>
  4146 + Add new method
  4147 + <function>QPDFObjectHandle::wrapInArray</function>, which returns
  4148 + the object itself if it is an array, or an array containing
  4149 + the object otherwise. This is a common construct in PDF.
  4150 + This method prevents you from having to explicitly test
  4151 + whether something is a single element or an array.
  4152 + </para>
  4153 + </listitem>
  4154 + </itemizedlist>
  4155 + </listitem>
  4156 + <listitem>
  4157 + <para>
  4158 + Build Improvements
  4159 + </para>
  4160 + <itemizedlist>
  4161 + <listitem>
  4162 + <para>
  4163 + It is no longer necessary to run
  4164 + <command>autogen.sh</command> to build from a pristine
  4165 + checkout. Automatically generated files are now committed so
  4166 + that it is possible to build on platforms without autoconf
  4167 + directly from a clean checkout of the repository. The
  4168 + <command>configure</command> script detects if the files are
  4169 + out of date when it also determines that the tools are
  4170 + present to regenerate them.
  4171 + </para>
  4172 + </listitem>
  4173 + <listitem>
  4174 + <para>
  4175 + Pull requests and the master branch are now built
  4176 + automatically in <ulink
  4177 + url="https://dev.azure.com/qpdf/qpdf/_build">Azure
  4178 + Pipelines</ulink>, which is free for open source projects.
  4179 + The build includes Linux, mac, Windows 32-bit and 64-bit
  4180 + with mingw and MSVC, and an AppImage build. Official qpdf
  4181 + releases are now built with Azure Pipelines.
  4182 + </para>
  4183 + </listitem>
  4184 + </itemizedlist>
  4185 + </listitem>
  4186 + </itemizedlist>
  4187 + </listitem>
  4188 + </varlistentry>
  4189 + <varlistentry>
3874 4190 <term>8.2.1: August 18, 2018</term>
3875 4191 <listitem>
3876 4192 <itemizedlist>
... ...