Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Initial checkin with custom pdf4tcl package. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | trunk |
| Files: | files | file ages | folders |
| SHA1: |
7440b51a78db112bce6bd819032e88cf |
| User & Date: | gwlester 2017-09-12 00:42:37.357 |
Context
|
2017-09-12
| ||
| 00:42 | Initial checkin with custom pdf4tcl package. Leaf check-in: 7440b51a78 user: gwlester tags: trunk | |
| 00:36 | initial empty check-in check-in: cdc25b4f49 user: gwlester tags: trunk | |
Changes
Added PdfMailMerge.komodoproject.
> > > > > > > | 1 2 3 4 5 6 7 | <?xml version="1.0" encoding="UTF-8"?> <!-- Komodo Project File - DO NOT EDIT --> <project id="a9b9d969-f85c-4d04-9cf3-536ab47fe7cc" kpf_version="5" name="PdfMailMerge.komodoproject"> <preference-set idref="a9b9d969-f85c-4d04-9cf3-536ab47fe7cc" id="project" preftype="project"> <long id="prefs_version">1</long> </preference-set> </project> |
Added src/PdfMailMerge.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
#!/bin/sh
# the next line restarts using wish \
exec tclsh "$0" ${1+"$@"}
#################################################################################
##
## Copyright (c) 2017, Gerald W. Lester
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
##
## * Redistributions of source code must retain the above copyright notice,
## this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above copyright notice,
## this list of conditions and the following disclaimer in the documentation
## and/or other materials provided with the distribution.
## * Neither the name of the Visiprise Software, Inc nor the names of its
## contributors may be used to endorse or promote products derived from this
## software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
## POSSIBILITY OF SUCH DAMAGE.
##
#################################################################################
lappend auto_path [file join [file dirname [info script]] packages]
package require csv
package require tls
package require smtp
package require mime
package require pdf4tcl
#################################################################################
##
## Worker Procedures
##
#################################################################################
proc LoadSmptFile {fileName} {
set ifd [open $fileName r]
set smtpDict [read -nonewline $ifd]
close $ifd
return $smtpDict
}
proc LoadCvsFile {fileName} {
set resultList {}
set ifd [open $fileName r]
set headerLine [gets $ifd]
set headerList [::csv::split $headerLine]
while {[gets $ifd dataLine] != -1} {
if {$dataLine eq {}} {
continue
}
set dataDict {}
foreach column $headerList value [::csv::split $dataLine] {
dict set dataDict $column $value
}
lappend resultList $dataDict
}
close $ifd
return $resultList
}
proc LoadFormatFile {fileName} {
set resultList {}
set headerList {recordType objectName recordValueList startX startY endX endY comments}
set ifd [open $fileName r]
gets $ifd ; # Skip header line
while {[gets $ifd dataLine] != -1} {
if {$dataLine eq {}} {
continue
}
set dataDict {}
lappend resultList [::csv::split $dataLine]
}
close $ifd
return $resultList
}
proc GenerateAndSendPdf {mailRec formatList smtpDict pdfDir doMail} {
set email [dict get $mailRec email]
pdf4tcl::new pdfObj -paper letter -orient true -margin {50 50 100 100}
pdfObj startPage
foreach formatCmd $formatList {
set cmdName [lindex $formatCmd 0]
::pdfCmd::$cmdName pdfObj $mailRec {*}[lrange $formatCmd 1 end]
}
set fn [file join $pdfDir $email.pdf]
pdfObj write -file $fn
pdfObj destroy
if {$doMail} {
SendMail $email $smtpDict $fn
}
return;
}
proc SendMail {toEmail smtpDict attachmentFn} {
set pdfFormT [::mime::initialize -canonical application/pdf -file $attachmentFn -name [file tail $attachmentFn]]
set bodyT [::mime::initialize -canonical text/plain -string [dict get $smtpDict body]]
# create a multipart containing both, and a timestamp
set multiT [::mime::initialize \
-canonical multipart/mixed \
-parts [list $bodyT $pdfFormT]]
# send
set result [::smtp::sendmessage $multiT \
-header [list From [dict get $smtpDict from]] \
-header [list To $toEmail] \
-header [list Subject [dict get $smtpDict subject]] \
-atleastone yes \
-servers [list [dict get $smtpDict smptHost]] \
-ports [list [dict get $smtpDict smptPort]] \
-username [dict get $smtpDict username] \
-password [dict get $smtpDict password] \
-debug no]
if {$result ne {}} {
puts stderr "Sendmail error: {$result}"
flush stderr
}
# clean everything up
mime::finalize $multiT -subordinates all
}
namespace eval ::pdfCmd:: {
proc setFont {pdfObj mailRec fontName fontSize args} {
#puts [list $pdfObj setFont $fontSize $fontName]
$pdfObj setFont $fontSize $fontName
}
proc textString {pdfObj mailRec objectName string X Y args} {
#puts [list $pdfObj text $string -x ${X} -y ${Y}]
$pdfObj text $string -x ${X} -y ${Y}
}
proc mailMerge {pdfObj mailRec fieldName skip X Y args} {
#puts [list $pdfObj text [dict get $mailRec $fieldName] -x $X -y $Y]
$pdfObj text [dict get $mailRec $fieldName] -x $X -y $Y
}
proc inputField {pdfObj mailRec objectName string X Y width height args} {
#puts [list $pdfObj addForm text $X $Y $width $height]
$pdfObj addForm text $X $Y $width $height -id $objectName
}
proc inputBox {pdfObj mailRec objectName string X Y width height args} {
#puts [list $pdfObj addForm text $X $Y $width $height]
$pdfObj addForm text $X $Y $width $height -id $objectName -multiline yes
}
proc box {pdfObj mailRec objectName string X Y width height args} {
#puts [list $pdfObj rectangle $X $Y $width $height]
$pdfObj rectangle $X $Y $width $height
}
proc checkBox {pdfObj mailRec objectName initialValue X Y width height args} {
if {[string is boolean -strict $initialValue] && $initialValue} {
set initial -on
} else {
set initial -off
}
#puts [list $pdfObj addForm checkbox $X $Y $width $height $inital]
$pdfObj addForm checkbox $X $Y $width $height $inital
}
}
#################################################################################
##
## Main area
##
#################################################################################
set allowedOptions {-smptFile -csvFile -formatFile -pdfDir -doMail}
set defaultOptions {-doMail yes}
if {($argc == 0) || (($argc % 2) != 0)} {
set usageError yes
} else {
set usageError no
array set options $defaultOptions
array set options $argv
foreach {option value} $argv {
if {$option ni $allowedOptions} {
set usageError yes
}
}
}
if {$usageError} {
append usageErrorMsg {Usage error:} "\n\t"
append usageErrorMsg [info script] { -smptFile smtpFileName -csvFile csvFileName -formatFile formatFileName -pdfDir dirName ?-doMail [y]/n?}
puts stderr {}
puts stderr $usageErrorMsg
puts stderr {}
exit -1
}
set smtpDict [LoadSmptFile $options(-smptFile)]
set mailToList [LoadCvsFile $options(-csvFile)]
set formatList [LoadFormatFile $options(-formatFile)]
if {![file exists $options(-pdfDir)]} {
file mkdir $options(-pdfDir)
}
foreach mailRec $mailToList {
if {[string trim [dict get $mailRec email]] ne {}} {
GenerateAndSendPdf $mailRec $formatList $smtpDict $options(-pdfDir) $options(-doMail)
}
}
exit 0
|
Added src/packages/pdf4tcl091/bitmaps/error.xbm.
> > > > > > > > | 1 2 3 4 5 6 7 8 |
#define error_width 17
#define error_height 17
static unsigned char error_bits[] = {
0xf0, 0x0f, 0x00, 0x58, 0x15, 0x00, 0xac, 0x2a, 0x00, 0x16, 0x50, 0x00,
0x2b, 0xa0, 0x00, 0x55, 0x40, 0x01, 0xa3, 0xc0, 0x00, 0x45, 0x41, 0x01,
0x83, 0xc2, 0x00, 0x05, 0x45, 0x01, 0x03, 0xca, 0x00, 0x05, 0x74, 0x01,
0x0a, 0xa8, 0x00, 0x14, 0x58, 0x00, 0xe8, 0x2f, 0x00, 0x50, 0x15, 0x00,
0xa0, 0x0a, 0x00};
|
Added src/packages/pdf4tcl091/bitmaps/gray12.xbm.
> > > > > > | 1 2 3 4 5 6 |
#define gray12_width 16
#define gray12_height 16
static unsigned char gray12_bits[] = {
0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22,
0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88,
0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88};
|
Added src/packages/pdf4tcl091/bitmaps/gray25.xbm.
> > > > > > | 1 2 3 4 5 6 |
#define gray25_width 16
#define gray25_height 16
static unsigned char gray25_bits[] = {
0x88, 0x88, 0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88, 0x22, 0x22,
0x88, 0x88, 0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88, 0x22, 0x22,
0x88, 0x88, 0x22, 0x22, 0x88, 0x88, 0x22, 0x22};
|
Added src/packages/pdf4tcl091/bitmaps/gray50.xbm.
> > > > > > | 1 2 3 4 5 6 |
#define gray50_width 16
#define gray50_height 16
static unsigned char gray50_bits[] = {
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};
|
Added src/packages/pdf4tcl091/bitmaps/gray75.xbm.
> > > > > > | 1 2 3 4 5 6 |
#define gray75_width 16
#define gray75_height 16
static unsigned char gray75_bits[] = {
0x77, 0x77, 0xdd, 0xdd, 0x77, 0x77, 0xdd, 0xdd, 0x77, 0x77, 0xdd, 0xdd,
0x77, 0x77, 0xdd, 0xdd, 0x77, 0x77, 0xdd, 0xdd, 0x77, 0x77, 0xdd, 0xdd,
0x77, 0x77, 0xdd, 0xdd, 0x77, 0x77, 0xdd, 0xdd};
|
Added src/packages/pdf4tcl091/bitmaps/hourglass.xbm.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 |
#define hourglass_width 19
#define hourglass_height 21
static unsigned char hourglass_bits[] = {
0xff, 0xff, 0x07, 0x55, 0x55, 0x05, 0xa2, 0x2a, 0x03, 0x66, 0x15, 0x01,
0xa2, 0x2a, 0x03, 0x66, 0x15, 0x01, 0xc2, 0x0a, 0x03, 0x46, 0x05, 0x01,
0x82, 0x0a, 0x03, 0x06, 0x05, 0x01, 0x02, 0x03, 0x03, 0x86, 0x05, 0x01,
0xc2, 0x0a, 0x03, 0x66, 0x15, 0x01, 0xa2, 0x2a, 0x03, 0x66, 0x15, 0x01,
0xa2, 0x2a, 0x03, 0x66, 0x15, 0x01, 0xa2, 0x2a, 0x03, 0xff, 0xff, 0x07,
0xab, 0xaa, 0x02};
|
Added src/packages/pdf4tcl091/bitmaps/info.xbm.
> > > > > | 1 2 3 4 5 |
#define info_width 8
#define info_height 21
static unsigned char info_bits[] = {
0x3c, 0x2a, 0x16, 0x2a, 0x14, 0x00, 0x00, 0x3f, 0x15, 0x2e, 0x14, 0x2c,
0x14, 0x2c, 0x14, 0x2c, 0x14, 0x2c, 0xd7, 0xab, 0x55};
|
Added src/packages/pdf4tcl091/bitmaps/questhead.xbm.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 |
#define questhead_width 20
#define questhead_height 22
static unsigned char questhead_bits[] = {
0xf8, 0x1f, 0x00, 0xac, 0x2a, 0x00, 0x56, 0x55, 0x00, 0xeb, 0xaf, 0x00,
0xf5, 0x5f, 0x01, 0xfb, 0xbf, 0x00, 0x75, 0x5d, 0x01, 0xfb, 0xbe, 0x02,
0x75, 0x5d, 0x05, 0xab, 0xbe, 0x0a, 0x55, 0x5f, 0x07, 0xab, 0xaf, 0x00,
0xd6, 0x57, 0x01, 0xac, 0xab, 0x00, 0xd8, 0x57, 0x00, 0xb0, 0xaa, 0x00,
0x50, 0x55, 0x00, 0xb0, 0x0b, 0x00, 0xd0, 0x17, 0x00, 0xb0, 0x0b, 0x00,
0x58, 0x15, 0x00, 0xa8, 0x2a, 0x00};
|
Added src/packages/pdf4tcl091/bitmaps/question.xbm.
> > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 |
#define question_width 17
#define question_height 27
static unsigned char question_bits[] = {
0xf0, 0x0f, 0x00, 0x58, 0x15, 0x00, 0xac, 0x2a, 0x00, 0x56, 0x55, 0x00,
0x2b, 0xa8, 0x00, 0x15, 0x50, 0x01, 0x0b, 0xa0, 0x00, 0x05, 0x60, 0x01,
0x0b, 0xa0, 0x00, 0x05, 0x60, 0x01, 0x0b, 0xb0, 0x00, 0x00, 0x58, 0x01,
0x00, 0xaf, 0x00, 0x80, 0x55, 0x00, 0xc0, 0x2a, 0x00, 0x40, 0x15, 0x00,
0xc0, 0x02, 0x00, 0x40, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x40, 0x01, 0x00,
0xc0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xc0, 0x02, 0x00,
0x40, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x00, 0x01, 0x00};
|
Added src/packages/pdf4tcl091/bitmaps/warning.xbm.
> > > > > | 1 2 3 4 5 |
#define warning_width 6
#define warning_height 19
static unsigned char warning_bits[] = {
0x0c, 0x16, 0x2b, 0x15, 0x2b, 0x15, 0x2b, 0x16, 0x0a, 0x16, 0x0a, 0x16,
0x0a, 0x00, 0x00, 0x1e, 0x0a, 0x16, 0x0a};
|
Added src/packages/pdf4tcl091/glyph2uni.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 |
package provide pdf4tcl::glyph2unicode 0.1
namespace eval pdf4tcl {
variable GlName2Uni
array set GlName2Uni {
A 65
AE 198
AEacute 508
AEmacron 482
AEsmall 63462
Aacute 193
Aacutesmall 63457
Abreve 258
Abreveacute 7854
Abrevecyrillic 1232
Abrevedotbelow 7862
Abrevegrave 7856
Abrevehookabove 7858
Abrevetilde 7860
Acaron 461
Acircle 9398
Acircumflex 194
Acircumflexacute 7844
Acircumflexdotbelow 7852
Acircumflexgrave 7846
Acircumflexhookabove 7848
Acircumflexsmall 63458
Acircumflextilde 7850
Acute 63177
Acutesmall 63412
Acyrillic 1040
Adblgrave 512
Adieresis 196
Adieresiscyrillic 1234
Adieresismacron 478
Adieresissmall 63460
Adotbelow 7840
Adotmacron 480
Agrave 192
Agravesmall 63456
Ahookabove 7842
Aiecyrillic 1236
Ainvertedbreve 514
Alpha 913
Alphatonos 902
Amacron 256
Amonospace 65313
Aogonek 260
Aring 197
Aringacute 506
Aringbelow 7680
Aringsmall 63461
Asmall 63329
Atilde 195
Atildesmall 63459
Aybarmenian 1329
B 66
Bcircle 9399
Bdotaccent 7682
Bdotbelow 7684
Becyrillic 1041
Benarmenian 1330
Beta 914
Bhook 385
Blinebelow 7686
Bmonospace 65314
Brevesmall 63220
Bsmall 63330
Btopbar 386
C 67
Caarmenian 1342
Cacute 262
Caron 63178
Caronsmall 63221
Ccaron 268
Ccedilla 199
Ccedillaacute 7688
Ccedillasmall 63463
Ccircle 9400
Ccircumflex 264
Cdot 266
Cdotaccent 266
Cedillasmall 63416
Chaarmenian 1353
Cheabkhasiancyrillic 1212
Checyrillic 1063
Chedescenderabkhasiancyrillic 1214
Chedescendercyrillic 1206
Chedieresiscyrillic 1268
Cheharmenian 1347
Chekhakassiancyrillic 1227
Cheverticalstrokecyrillic 1208
Chi 935
Chook 391
Circumflexsmall 63222
Cmonospace 65315
Coarmenian 1361
Csmall 63331
D 68
DZ 497
DZcaron 452
Daarmenian 1332
Dafrican 393
Dcaron 270
Dcedilla 7696
Dcircle 9401
Dcircumflexbelow 7698
Dcroat 272
Ddotaccent 7690
Ddotbelow 7692
Decyrillic 1044
Deicoptic 1006
Delta 8710
Deltagreek 916
Dhook 394
Dieresis 63179
DieresisAcute 63180
DieresisGrave 63181
Dieresissmall 63400
Digammagreek 988
Djecyrillic 1026
Dlinebelow 7694
Dmonospace 65316
Dotaccentsmall 63223
Dslash 272
Dsmall 63332
Dtopbar 395
Dz 498
Dzcaron 453
Dzeabkhasiancyrillic 1248
Dzecyrillic 1029
Dzhecyrillic 1039
E 69
Eacute 201
Eacutesmall 63465
Ebreve 276
Ecaron 282
Ecedillabreve 7708
Echarmenian 1333
Ecircle 9402
Ecircumflex 202
Ecircumflexacute 7870
Ecircumflexbelow 7704
Ecircumflexdotbelow 7878
Ecircumflexgrave 7872
Ecircumflexhookabove 7874
Ecircumflexsmall 63466
Ecircumflextilde 7876
Ecyrillic 1028
Edblgrave 516
Edieresis 203
Edieresissmall 63467
Edot 278
Edotaccent 278
Edotbelow 7864
Efcyrillic 1060
Egrave 200
Egravesmall 63464
Eharmenian 1335
Ehookabove 7866
Eightroman 8551
Einvertedbreve 518
Eiotifiedcyrillic 1124
Elcyrillic 1051
Elevenroman 8554
Emacron 274
Emacronacute 7702
Emacrongrave 7700
Emcyrillic 1052
Emonospace 65317
Encyrillic 1053
Endescendercyrillic 1186
Eng 330
Enghecyrillic 1188
Enhookcyrillic 1223
Eogonek 280
Eopen 400
Epsilon 917
Epsilontonos 904
Ercyrillic 1056
Ereversed 398
Ereversedcyrillic 1069
Escyrillic 1057
Esdescendercyrillic 1194
Esh 425
Esmall 63333
Eta 919
Etarmenian 1336
Etatonos 905
Eth 208
Ethsmall 63472
Etilde 7868
Etildebelow 7706
Euro 8364
Ezh 439
Ezhcaron 494
Ezhreversed 440
F 70
Fcircle 9403
Fdotaccent 7710
Feharmenian 1366
Feicoptic 996
Fhook 401
Fitacyrillic 1138
Fiveroman 8548
Fmonospace 65318
Fourroman 8547
Fsmall 63334
G 71
GBsquare 13191
Gacute 500
Gamma 915
Gammaafrican 404
Gangiacoptic 1002
Gbreve 286
Gcaron 486
Gcedilla 290
Gcircle 9404
Gcircumflex 284
Gcommaaccent 290
Gdot 288
Gdotaccent 288
Gecyrillic 1043
Ghadarmenian 1346
Ghemiddlehookcyrillic 1172
Ghestrokecyrillic 1170
Gheupturncyrillic 1168
Ghook 403
Gimarmenian 1331
Gjecyrillic 1027
Gmacron 7712
Gmonospace 65319
Grave 63182
Gravesmall 63328
Gsmall 63335
Gsmallhook 667
Gstroke 484
H 72
H18533 9679
H18543 9642
H18551 9643
H22073 9633
HPsquare 13259
Haabkhasiancyrillic 1192
Hadescendercyrillic 1202
Hardsigncyrillic 1066
Hbar 294
Hbrevebelow 7722
Hcedilla 7720
Hcircle 9405
Hcircumflex 292
Hdieresis 7718
Hdotaccent 7714
Hdotbelow 7716
Hmonospace 65320
Hoarmenian 1344
Horicoptic 1000
Hsmall 63336
Hungarumlaut 63183
Hungarumlautsmall 63224
Hzsquare 13200
I 73
IAcyrillic 1071
IJ 306
IUcyrillic 1070
Iacute 205
Iacutesmall 63469
Ibreve 300
Icaron 463
Icircle 9406
Icircumflex 206
Icircumflexsmall 63470
Icyrillic 1030
Idblgrave 520
Idieresis 207
Idieresisacute 7726
Idieresiscyrillic 1252
Idieresissmall 63471
Idot 304
Idotaccent 304
Idotbelow 7882
Iebrevecyrillic 1238
Iecyrillic 1045
Ifraktur 8465
Igrave 204
Igravesmall 63468
Ihookabove 7880
Iicyrillic 1048
Iinvertedbreve 522
Iishortcyrillic 1049
Imacron 298
Imacroncyrillic 1250
Imonospace 65321
Iniarmenian 1339
Iocyrillic 1025
Iogonek 302
Iota 921
Iotaafrican 406
Iotadieresis 938
Iotatonos 906
Ismall 63337
Istroke 407
Itilde 296
Itildebelow 7724
Izhitsacyrillic 1140
Izhitsadblgravecyrillic 1142
J 74
Jaarmenian 1345
Jcircle 9407
Jcircumflex 308
Jecyrillic 1032
Jheharmenian 1355
Jmonospace 65322
Jsmall 63338
K 75
KBsquare 13189
KKsquare 13261
Kabashkircyrillic 1184
Kacute 7728
Kacyrillic 1050
Kadescendercyrillic 1178
Kahookcyrillic 1219
Kappa 922
Kastrokecyrillic 1182
Kaverticalstrokecyrillic 1180
Kcaron 488
Kcedilla 310
Kcircle 9408
Kcommaaccent 310
Kdotbelow 7730
Keharmenian 1364
Kenarmenian 1343
Khacyrillic 1061
Kheicoptic 998
Khook 408
Kjecyrillic 1036
Klinebelow 7732
Kmonospace 65323
Koppacyrillic 1152
Koppagreek 990
Ksicyrillic 1134
Ksmall 63339
L 76
LJ 455
LL 63167
Lacute 313
Lambda 923
Lcaron 317
Lcedilla 315
Lcircle 9409
Lcircumflexbelow 7740
Lcommaaccent 315
Ldot 319
Ldotaccent 319
Ldotbelow 7734
Ldotbelowmacron 7736
Liwnarmenian 1340
Lj 456
Ljecyrillic 1033
Llinebelow 7738
Lmonospace 65324
Lslash 321
Lslashsmall 63225
Lsmall 63340
M 77
MBsquare 13190
Macron 63184
Macronsmall 63407
Macute 7742
Mcircle 9410
Mdotaccent 7744
Mdotbelow 7746
Menarmenian 1348
Mmonospace 65325
Msmall 63341
Mturned 412
Mu 924
N 78
NJ 458
Nacute 323
Ncaron 327
Ncedilla 325
Ncircle 9411
Ncircumflexbelow 7754
Ncommaaccent 325
Ndotaccent 7748
Ndotbelow 7750
Nhookleft 413
Nineroman 8552
Nj 459
Njecyrillic 1034
Nlinebelow 7752
Nmonospace 65326
Nowarmenian 1350
Nsmall 63342
Ntilde 209
Ntildesmall 63473
Nu 925
O 79
OE 338
OEsmall 63226
Oacute 211
Oacutesmall 63475
Obarredcyrillic 1256
Obarreddieresiscyrillic 1258
Obreve 334
Ocaron 465
Ocenteredtilde 415
Ocircle 9412
Ocircumflex 212
Ocircumflexacute 7888
Ocircumflexdotbelow 7896
Ocircumflexgrave 7890
Ocircumflexhookabove 7892
Ocircumflexsmall 63476
Ocircumflextilde 7894
Ocyrillic 1054
Odblacute 336
Odblgrave 524
Odieresis 214
Odieresiscyrillic 1254
Odieresissmall 63478
Odotbelow 7884
Ogoneksmall 63227
Ograve 210
Ogravesmall 63474
Oharmenian 1365
Ohm 8486
Ohookabove 7886
Ohorn 416
Ohornacute 7898
Ohorndotbelow 7906
Ohorngrave 7900
Ohornhookabove 7902
Ohorntilde 7904
Ohungarumlaut 336
Oi 418
Oinvertedbreve 526
Omacron 332
Omacronacute 7762
Omacrongrave 7760
Omega 8486
Omegacyrillic 1120
Omegagreek 937
Omegaroundcyrillic 1146
Omegatitlocyrillic 1148
Omegatonos 911
Omicron 927
Omicrontonos 908
Omonospace 65327
Oneroman 8544
Oogonek 490
Oogonekmacron 492
Oopen 390
Oslash 216
Oslashacute 510
Oslashsmall 63480
Osmall 63343
Ostrokeacute 510
Otcyrillic 1150
Otilde 213
Otildeacute 7756
Otildedieresis 7758
Otildesmall 63477
P 80
Pacute 7764
Pcircle 9413
Pdotaccent 7766
Pecyrillic 1055
Peharmenian 1354
Pemiddlehookcyrillic 1190
Phi 934
Phook 420
Pi 928
Piwrarmenian 1363
Pmonospace 65328
Psi 936
Psicyrillic 1136
Psmall 63344
Q 81
Qcircle 9414
Qmonospace 65329
Qsmall 63345
R 82
Raarmenian 1356
Racute 340
Rcaron 344
Rcedilla 342
Rcircle 9415
Rcommaaccent 342
Rdblgrave 528
Rdotaccent 7768
Rdotbelow 7770
Rdotbelowmacron 7772
Reharmenian 1360
Rfraktur 8476
Rho 929
Ringsmall 63228
Rinvertedbreve 530
Rlinebelow 7774
Rmonospace 65330
Rsmall 63346
Rsmallinverted 641
Rsmallinvertedsuperior 694
S 83
SF010000 9484
SF020000 9492
SF030000 9488
SF040000 9496
SF050000 9532
SF060000 9516
SF070000 9524
SF080000 9500
SF090000 9508
SF100000 9472
SF110000 9474
SF190000 9569
SF200000 9570
SF210000 9558
SF220000 9557
SF230000 9571
SF240000 9553
SF250000 9559
SF260000 9565
SF270000 9564
SF280000 9563
SF360000 9566
SF370000 9567
SF380000 9562
SF390000 9556
SF400000 9577
SF410000 9574
SF420000 9568
SF430000 9552
SF440000 9580
SF450000 9575
SF460000 9576
SF470000 9572
SF480000 9573
SF490000 9561
SF500000 9560
SF510000 9554
SF520000 9555
SF530000 9579
SF540000 9578
Sacute 346
Sacutedotaccent 7780
Sampigreek 992
Scaron 352
Scarondotaccent 7782
Scaronsmall 63229
Scedilla 350
Schwa 399
Schwacyrillic 1240
Schwadieresiscyrillic 1242
Scircle 9416
Scircumflex 348
Scommaaccent 536
Sdotaccent 7776
Sdotbelow 7778
Sdotbelowdotaccent 7784
Seharmenian 1357
Sevenroman 8550
Shaarmenian 1351
Shacyrillic 1064
Shchacyrillic 1065
Sheicoptic 994
Shhacyrillic 1210
Shimacoptic 1004
Sigma 931
Sixroman 8549
Smonospace 65331
Softsigncyrillic 1068
Ssmall 63347
Stigmagreek 986
T 84
Tau 932
Tbar 358
Tcaron 356
Tcedilla 354
Tcircle 9417
Tcircumflexbelow 7792
Tcommaaccent 354
Tdotaccent 7786
Tdotbelow 7788
Tecyrillic 1058
Tedescendercyrillic 1196
Tenroman 8553
Tetsecyrillic 1204
Theta 920
Thook 428
Thorn 222
Thornsmall 63486
Threeroman 8546
Tildesmall 63230
Tiwnarmenian 1359
Tlinebelow 7790
Tmonospace 65332
Toarmenian 1337
Tonefive 444
Tonesix 388
Tonetwo 423
Tretroflexhook 430
Tsecyrillic 1062
Tshecyrillic 1035
Tsmall 63348
Twelveroman 8555
Tworoman 8545
U 85
Uacute 218
Uacutesmall 63482
Ubreve 364
Ucaron 467
Ucircle 9418
Ucircumflex 219
Ucircumflexbelow 7798
Ucircumflexsmall 63483
Ucyrillic 1059
Udblacute 368
Udblgrave 532
Udieresis 220
Udieresisacute 471
Udieresisbelow 7794
Udieresiscaron 473
Udieresiscyrillic 1264
Udieresisgrave 475
Udieresismacron 469
Udieresissmall 63484
Udotbelow 7908
Ugrave 217
Ugravesmall 63481
Uhookabove 7910
Uhorn 431
Uhornacute 7912
Uhorndotbelow 7920
Uhorngrave 7914
Uhornhookabove 7916
Uhorntilde 7918
Uhungarumlaut 368
Uhungarumlautcyrillic 1266
Uinvertedbreve 534
Ukcyrillic 1144
Umacron 362
Umacroncyrillic 1262
Umacrondieresis 7802
Umonospace 65333
Uogonek 370
Upsilon 933
Upsilon1 978
Upsilonacutehooksymbolgreek 979
Upsilonafrican 433
Upsilondieresis 939
Upsilondieresishooksymbolgreek 980
Upsilonhooksymbol 978
Upsilontonos 910
Uring 366
Ushortcyrillic 1038
Usmall 63349
Ustraightcyrillic 1198
Ustraightstrokecyrillic 1200
Utilde 360
Utildeacute 7800
Utildebelow 7796
V 86
Vcircle 9419
Vdotbelow 7806
Vecyrillic 1042
Vewarmenian 1358
Vhook 434
Vmonospace 65334
Voarmenian 1352
Vsmall 63350
Vtilde 7804
W 87
Wacute 7810
Wcircle 9420
Wcircumflex 372
Wdieresis 7812
Wdotaccent 7814
Wdotbelow 7816
Wgrave 7808
Wmonospace 65335
Wsmall 63351
X 88
Xcircle 9421
Xdieresis 7820
Xdotaccent 7818
Xeharmenian 1341
Xi 926
Xmonospace 65336
Xsmall 63352
Y 89
Yacute 221
Yacutesmall 63485
Yatcyrillic 1122
Ycircle 9422
Ycircumflex 374
Ydieresis 376
Ydieresissmall 63487
Ydotaccent 7822
Ydotbelow 7924
Yericyrillic 1067
Yerudieresiscyrillic 1272
Ygrave 7922
Yhook 435
Yhookabove 7926
Yiarmenian 1349
Yicyrillic 1031
Yiwnarmenian 1362
Ymonospace 65337
Ysmall 63353
Ytilde 7928
Yusbigcyrillic 1130
Yusbigiotifiedcyrillic 1132
Yuslittlecyrillic 1126
Yuslittleiotifiedcyrillic 1128
Z 90
Zaarmenian 1334
Zacute 377
Zcaron 381
Zcaronsmall 63231
Zcircle 9423
Zcircumflex 7824
Zdot 379
Zdotaccent 379
Zdotbelow 7826
Zecyrillic 1047
Zedescendercyrillic 1176
Zedieresiscyrillic 1246
Zeta 918
Zhearmenian 1338
Zhebrevecyrillic 1217
Zhecyrillic 1046
Zhedescendercyrillic 1174
Zhedieresiscyrillic 1244
Zlinebelow 7828
Zmonospace 65338
Zsmall 63354
Zstroke 437
a 97
a1 9985
a10 10017
a100 10078
a101 10081
a102 10082
a103 10083
a104 10084
a105 10000
a106 10085
a107 10086
a108 10087
a109 9824
a11 9755
a110 9829
a111 9830
a112 9827
a117 9993
a118 9992
a119 9991
a12 9758
a120 9312
a121 9313
a122 9314
a123 9315
a124 9316
a125 9317
a126 9318
a127 9319
a128 9320
a129 9321
a13 9996
a130 10102
a131 10103
a132 10104
a133 10105
a134 10106
a135 10107
a136 10108
a137 10109
a138 10110
a139 10111
a14 9997
a140 10112
a141 10113
a142 10114
a143 10115
a144 10116
a145 10117
a146 10118
a147 10119
a148 10120
a149 10121
a15 9998
a150 10122
a151 10123
a152 10124
a153 10125
a154 10126
a155 10127
a156 10128
a157 10129
a158 10130
a159 10131
a16 9999
a160 10132
a161 8594
a162 10147
a163 8596
a164 8597
a165 10137
a166 10139
a167 10140
a168 10141
a169 10142
a17 10001
a170 10143
a171 10144
a172 10145
a173 10146
a174 10148
a175 10149
a176 10150
a177 10151
a178 10152
a179 10153
a18 10002
a180 10155
a181 10157
a182 10159
a183 10162
a184 10163
a185 10165
a186 10168
a187 10170
a188 10171
a189 10172
a19 10003
a190 10173
a191 10174
a192 10138
a193 10154
a194 10166
a195 10169
a196 10136
a197 10164
a198 10167
a199 10156
a2 9986
a20 10004
a200 10158
a201 10161
a202 9987
a203 10064
a204 10066
a205 10094
a206 10096
a21 10005
a22 10006
a23 10007
a24 10008
a25 10009
a26 10010
a27 10011
a28 10012
a29 10018
a3 9988
a30 10019
a31 10020
a32 10021
a33 10022
a34 10023
a35 9733
a36 10025
a37 10026
a38 10027
a39 10028
a4 9742
a40 10029
a41 10030
a42 10031
a43 10032
a44 10033
a45 10034
a46 10035
a47 10036
a48 10037
a49 10038
a5 9990
a50 10039
a51 10040
a52 10041
a53 10042
a54 10043
a55 10044
a56 10045
a57 10046
a58 10047
a59 10048
a6 10013
a60 10049
a61 10050
a62 10051
a63 10052
a64 10053
a65 10054
a66 10055
a67 10056
a68 10057
a69 10058
a7 10014
a70 10059
a71 9679
a72 10061
a73 9632
a74 10063
a75 10065
a76 9650
a77 9660
a78 9670
a79 10070
a8 10015
a81 9687
a82 10072
a83 10073
a84 10074
a85 10095
a86 10097
a87 10098
a88 10099
a89 10088
a9 10016
a90 10089
a91 10092
a92 10093
a93 10090
a94 10091
a95 10100
a96 10101
a97 10075
a98 10076
a99 10077
aabengali 2438
aacute 225
aadeva 2310
aagujarati 2694
aagurmukhi 2566
aamatragurmukhi 2622
aarusquare 13059
aavowelsignbengali 2494
aavowelsigndeva 2366
aavowelsigngujarati 2750
abbreviationmarkarmenian 1375
abbreviationsigndeva 2416
abengali 2437
abopomofo 12570
abreve 259
abreveacute 7855
abrevecyrillic 1233
abrevedotbelow 7863
abrevegrave 7857
abrevehookabove 7859
abrevetilde 7861
acaron 462
acircle 9424
acircumflex 226
acircumflexacute 7845
acircumflexdotbelow 7853
acircumflexgrave 7847
acircumflexhookabove 7849
acircumflextilde 7851
acute 180
acutebelowcmb 791
acutecmb 769
acutecomb 769
acutedeva 2388
acutelowmod 719
acutetonecmb 833
acyrillic 1072
adblgrave 513
addakgurmukhi 2673
adeva 2309
adieresis 228
adieresiscyrillic 1235
adieresismacron 479
adotbelow 7841
adotmacron 481
ae 230
aeacute 509
aekorean 12624
aemacron 483
afii00208 8213
afii08941 8356
afii10017 1040
afii10018 1041
afii10019 1042
afii10020 1043
afii10021 1044
afii10022 1045
afii10023 1025
afii10024 1046
afii10025 1047
afii10026 1048
afii10027 1049
afii10028 1050
afii10029 1051
afii10030 1052
afii10031 1053
afii10032 1054
afii10033 1055
afii10034 1056
afii10035 1057
afii10036 1058
afii10037 1059
afii10038 1060
afii10039 1061
afii10040 1062
afii10041 1063
afii10042 1064
afii10043 1065
afii10044 1066
afii10045 1067
afii10046 1068
afii10047 1069
afii10048 1070
afii10049 1071
afii10050 1168
afii10051 1026
afii10052 1027
afii10053 1028
afii10054 1029
afii10055 1030
afii10056 1031
afii10057 1032
afii10058 1033
afii10059 1034
afii10060 1035
afii10061 1036
afii10062 1038
afii10063 63172
afii10064 63173
afii10065 1072
afii10066 1073
afii10067 1074
afii10068 1075
afii10069 1076
afii10070 1077
afii10071 1105
afii10072 1078
afii10073 1079
afii10074 1080
afii10075 1081
afii10076 1082
afii10077 1083
afii10078 1084
afii10079 1085
afii10080 1086
afii10081 1087
afii10082 1088
afii10083 1089
afii10084 1090
afii10085 1091
afii10086 1092
afii10087 1093
afii10088 1094
afii10089 1095
afii10090 1096
afii10091 1097
afii10092 1098
afii10093 1099
afii10094 1100
afii10095 1101
afii10096 1102
afii10097 1103
afii10098 1169
afii10099 1106
afii10100 1107
afii10101 1108
afii10102 1109
afii10103 1110
afii10104 1111
afii10105 1112
afii10106 1113
afii10107 1114
afii10108 1115
afii10109 1116
afii10110 1118
afii10145 1039
afii10146 1122
afii10147 1138
afii10148 1140
afii10192 63174
afii10193 1119
afii10194 1123
afii10195 1139
afii10196 1141
afii10831 63175
afii10832 63176
afii10846 1241
afii299 8206
afii300 8207
afii301 8205
afii57381 1642
afii57388 1548
afii57392 1632
afii57393 1633
afii57394 1634
afii57395 1635
afii57396 1636
afii57397 1637
afii57398 1638
afii57399 1639
afii57400 1640
afii57401 1641
afii57403 1563
afii57407 1567
afii57409 1569
afii57410 1570
afii57411 1571
afii57412 1572
afii57413 1573
afii57414 1574
afii57415 1575
afii57416 1576
afii57417 1577
afii57418 1578
afii57419 1579
afii57420 1580
afii57421 1581
afii57422 1582
afii57423 1583
afii57424 1584
afii57425 1585
afii57426 1586
afii57427 1587
afii57428 1588
afii57429 1589
afii57430 1590
afii57431 1591
afii57432 1592
afii57433 1593
afii57434 1594
afii57440 1600
afii57441 1601
afii57442 1602
afii57443 1603
afii57444 1604
afii57445 1605
afii57446 1606
afii57448 1608
afii57449 1609
afii57450 1610
afii57451 1611
afii57452 1612
afii57453 1613
afii57454 1614
afii57455 1615
afii57456 1616
afii57457 1617
afii57458 1618
afii57470 1607
afii57505 1700
afii57506 1662
afii57507 1670
afii57508 1688
afii57509 1711
afii57511 1657
afii57512 1672
afii57513 1681
afii57514 1722
afii57519 1746
afii57534 1749
afii57636 8362
afii57645 1470
afii57658 1475
afii57664 1488
afii57665 1489
afii57666 1490
afii57667 1491
afii57668 1492
afii57669 1493
afii57670 1494
afii57671 1495
afii57672 1496
afii57673 1497
afii57674 1498
afii57675 1499
afii57676 1500
afii57677 1501
afii57678 1502
afii57679 1503
afii57680 1504
afii57681 1505
afii57682 1506
afii57683 1507
afii57684 1508
afii57685 1509
afii57686 1510
afii57687 1511
afii57688 1512
afii57689 1513
afii57690 1514
afii57694 64298
afii57695 64299
afii57700 64331
afii57705 64287
afii57716 1520
afii57717 1521
afii57718 1522
afii57723 64309
afii57793 1460
afii57794 1461
afii57795 1462
afii57796 1467
afii57797 1464
afii57798 1463
afii57799 1456
afii57800 1458
afii57801 1457
afii57802 1459
afii57803 1474
afii57804 1473
afii57806 1465
afii57807 1468
afii57839 1469
afii57841 1471
afii57842 1472
afii57929 700
afii61248 8453
afii61289 8467
afii61352 8470
afii61573 8236
afii61574 8237
afii61575 8238
afii61664 8204
afii63167 1645
afii64937 701
agrave 224
agujarati 2693
agurmukhi 2565
ahiragana 12354
ahookabove 7843
aibengali 2448
aibopomofo 12574
aideva 2320
aiecyrillic 1237
aigujarati 2704
aigurmukhi 2576
aimatragurmukhi 2632
ainarabic 1593
ainfinalarabic 65226
aininitialarabic 65227
ainmedialarabic 65228
ainvertedbreve 515
aivowelsignbengali 2504
aivowelsigndeva 2376
aivowelsigngujarati 2760
akatakana 12450
akatakanahalfwidth 65393
akorean 12623
alef 1488
alefarabic 1575
alefdageshhebrew 64304
aleffinalarabic 65166
alefhamzaabovearabic 1571
alefhamzaabovefinalarabic 65156
alefhamzabelowarabic 1573
alefhamzabelowfinalarabic 65160
alefhebrew 1488
aleflamedhebrew 64335
alefmaddaabovearabic 1570
alefmaddaabovefinalarabic 65154
alefmaksuraarabic 1609
alefmaksurafinalarabic 65264
alefmaksurainitialarabic 65267
alefmaksuramedialarabic 65268
alefpatahhebrew 64302
alefqamatshebrew 64303
aleph 8501
allequal 8780
alpha 945
alphatonos 940
amacron 257
amonospace 65345
ampersand 38
ampersandmonospace 65286
ampersandsmall 63270
amsquare 13250
anbopomofo 12578
angbopomofo 12580
angkhankhuthai 3674
angle 8736
anglebracketleft 12296
anglebracketleftvertical 65087
anglebracketright 12297
anglebracketrightvertical 65088
angleleft 9001
angleright 9002
angstrom 8491
anoteleia 903
anudattadeva 2386
anusvarabengali 2434
anusvaradeva 2306
anusvaragujarati 2690
aogonek 261
apaatosquare 13056
aparen 9372
apostrophearmenian 1370
apostrophemod 700
apple 63743
approaches 8784
approxequal 8776
approxequalorimage 8786
approximatelyequal 8773
araeaekorean 12686
araeakorean 12685
arc 8978
arighthalfring 7834
aring 229
aringacute 507
aringbelow 7681
arrowboth 8596
arrowdashdown 8675
arrowdashleft 8672
arrowdashright 8674
arrowdashup 8673
arrowdblboth 8660
arrowdbldown 8659
arrowdblleft 8656
arrowdblright 8658
arrowdblup 8657
arrowdown 8595
arrowdownleft 8601
arrowdownright 8600
arrowdownwhite 8681
arrowheaddownmod 709
arrowheadleftmod 706
arrowheadrightmod 707
arrowheadupmod 708
arrowhorizex 63719
arrowleft 8592
arrowleftdbl 8656
arrowleftdblstroke 8653
arrowleftoverright 8646
arrowleftwhite 8678
arrowright 8594
arrowrightdblstroke 8655
arrowrightheavy 10142
arrowrightoverleft 8644
arrowrightwhite 8680
arrowtableft 8676
arrowtabright 8677
arrowup 8593
arrowupdn 8597
arrowupdnbse 8616
arrowupdownbase 8616
arrowupleft 8598
arrowupleftofdown 8645
arrowupright 8599
arrowupwhite 8679
arrowvertex 63718
asciicircum 94
asciicircummonospace 65342
asciitilde 126
asciitildemonospace 65374
ascript 593
ascriptturned 594
asmallhiragana 12353
asmallkatakana 12449
asmallkatakanahalfwidth 65383
asterisk 42
asteriskaltonearabic 1645
asteriskarabic 1645
asteriskmath 8727
asteriskmonospace 65290
asterisksmall 65121
asterism 8258
asuperior 63209
asymptoticallyequal 8771
at 64
atilde 227
atmonospace 65312
atsmall 65131
aturned 592
aubengali 2452
aubopomofo 12576
audeva 2324
augujarati 2708
augurmukhi 2580
aulengthmarkbengali 2519
aumatragurmukhi 2636
auvowelsignbengali 2508
auvowelsigndeva 2380
auvowelsigngujarati 2764
avagrahadeva 2365
aybarmenian 1377
ayin 1506
ayinaltonehebrew 64288
ayinhebrew 1506
b 98
babengali 2476
backslash 92
backslashmonospace 65340
badeva 2348
bagujarati 2732
bagurmukhi 2604
bahiragana 12400
bahtthai 3647
bakatakana 12496
bar 124
barmonospace 65372
bbopomofo 12549
bcircle 9425
bdotaccent 7683
bdotbelow 7685
beamedsixteenthnotes 9836
because 8757
becyrillic 1073
beharabic 1576
behfinalarabic 65168
behinitialarabic 65169
behiragana 12409
behmedialarabic 65170
behmeeminitialarabic 64671
behmeemisolatedarabic 64520
behnoonfinalarabic 64621
bekatakana 12505
benarmenian 1378
bet 1489
beta 946
betasymbolgreek 976
betdagesh 64305
betdageshhebrew 64305
bethebrew 1489
betrafehebrew 64332
bhabengali 2477
bhadeva 2349
bhagujarati 2733
bhagurmukhi 2605
bhook 595
bihiragana 12403
bikatakana 12499
bilabialclick 664
bindigurmukhi 2562
birusquare 13105
blackcircle 9679
blackdiamond 9670
blackdownpointingtriangle 9660
blackleftpointingpointer 9668
blackleftpointingtriangle 9664
blacklenticularbracketleft 12304
blacklenticularbracketleftvertical 65083
blacklenticularbracketright 12305
blacklenticularbracketrightvertical 65084
blacklowerlefttriangle 9699
blacklowerrighttriangle 9698
blackrectangle 9644
blackrightpointingpointer 9658
blackrightpointingtriangle 9654
blacksmallsquare 9642
blacksmilingface 9787
blacksquare 9632
blackstar 9733
blackupperlefttriangle 9700
blackupperrighttriangle 9701
blackuppointingsmalltriangle 9652
blackuppointingtriangle 9650
blank 9251
blinebelow 7687
block 9608
bmonospace 65346
bobaimaithai 3610
bohiragana 12412
bokatakana 12508
bparen 9373
bqsquare 13251
braceex 63732
braceleft 123
braceleftbt 63731
braceleftmid 63730
braceleftmonospace 65371
braceleftsmall 65115
bracelefttp 63729
braceleftvertical 65079
braceright 125
bracerightbt 63742
bracerightmid 63741
bracerightmonospace 65373
bracerightsmall 65116
bracerighttp 63740
bracerightvertical 65080
bracketleft 91
bracketleftbt 63728
bracketleftex 63727
bracketleftmonospace 65339
bracketlefttp 63726
bracketright 93
bracketrightbt 63739
bracketrightex 63738
bracketrightmonospace 65341
bracketrighttp 63737
breve 728
brevebelowcmb 814
brevecmb 774
breveinvertedbelowcmb 815
breveinvertedcmb 785
breveinverteddoublecmb 865
bridgebelowcmb 810
bridgeinvertedbelowcmb 826
brokenbar 166
bstroke 384
bsuperior 63210
btopbar 387
buhiragana 12406
bukatakana 12502
bullet 8226
bulletinverse 9688
bulletoperator 8729
bullseye 9678
c 99
caarmenian 1390
cabengali 2458
cacute 263
cadeva 2330
cagujarati 2714
cagurmukhi 2586
calsquare 13192
candrabindubengali 2433
candrabinducmb 784
candrabindudeva 2305
candrabindugujarati 2689
capslock 8682
careof 8453
caron 711
caronbelowcmb 812
caroncmb 780
carriagereturn 8629
cbopomofo 12568
ccaron 269
ccedilla 231
ccedillaacute 7689
ccircle 9426
ccircumflex 265
ccurl 597
cdot 267
cdotaccent 267
cdsquare 13253
cedilla 184
cedillacmb 807
cent 162
centigrade 8451
centinferior 63199
centmonospace 65504
centoldstyle 63394
centsuperior 63200
chaarmenian 1401
chabengali 2459
chadeva 2331
chagujarati 2715
chagurmukhi 2587
chbopomofo 12564
cheabkhasiancyrillic 1213
checkmark 10003
checyrillic 1095
chedescenderabkhasiancyrillic 1215
chedescendercyrillic 1207
chedieresiscyrillic 1269
cheharmenian 1395
chekhakassiancyrillic 1228
cheverticalstrokecyrillic 1209
chi 967
chieuchacirclekorean 12919
chieuchaparenkorean 12823
chieuchcirclekorean 12905
chieuchkorean 12618
chieuchparenkorean 12809
chochangthai 3594
chochanthai 3592
chochingthai 3593
chochoethai 3596
chook 392
cieucacirclekorean 12918
cieucaparenkorean 12822
cieuccirclekorean 12904
cieuckorean 12616
cieucparenkorean 12808
cieucuparenkorean 12828
circle 9675
circlemultiply 8855
circleot 8857
circleplus 8853
circlepostalmark 12342
circlewithlefthalfblack 9680
circlewithrighthalfblack 9681
circumflex 710
circumflexbelowcmb 813
circumflexcmb 770
clear 8999
clickalveolar 450
clickdental 448
clicklateral 449
clickretroflex 451
club 9827
clubsuitblack 9827
clubsuitwhite 9831
cmcubedsquare 13220
cmonospace 65347
cmsquaredsquare 13216
coarmenian 1409
colon 58
colonmonetary 8353
colonmonospace 65306
colonsign 8353
colonsmall 65109
colontriangularhalfmod 721
colontriangularmod 720
comma 44
commaabovecmb 787
commaaboverightcmb 789
commaaccent 63171
commaarabic 1548
commaarmenian 1373
commainferior 63201
commamonospace 65292
commareversedabovecmb 788
commareversedmod 701
commasmall 65104
commasuperior 63202
commaturnedabovecmb 786
commaturnedmod 699
compass 9788
congruent 8773
contourintegral 8750
control 8963
controlACK 6
controlBEL 7
controlBS 8
controlCAN 24
controlCR 13
controlDC1 17
controlDC2 18
controlDC3 19
controlDC4 20
controlDEL 127
controlDLE 16
controlEM 25
controlENQ 5
controlEOT 4
controlESC 27
controlETB 23
controlETX 3
controlFF 12
controlFS 28
controlGS 29
controlHT 9
controlLF 10
controlNAK 21
controlRS 30
controlSI 15
controlSO 14
controlSOT 2
controlSTX 1
controlSUB 26
controlSYN 22
controlUS 31
controlVT 11
copyright 169
copyrightsans 63721
copyrightserif 63193
cornerbracketleft 12300
cornerbracketlefthalfwidth 65378
cornerbracketleftvertical 65089
cornerbracketright 12301
cornerbracketrighthalfwidth 65379
cornerbracketrightvertical 65090
corporationsquare 13183
cosquare 13255
coverkgsquare 13254
cparen 9374
cruzeiro 8354
cstretched 663
curlyand 8911
curlyor 8910
currency 164
cyrBreve 63185
cyrFlex 63186
cyrbreve 63188
cyrflex 63189
d 100
daarmenian 1380
dabengali 2470
dadarabic 1590
dadeva 2342
dadfinalarabic 65214
dadinitialarabic 65215
dadmedialarabic 65216
dagesh 1468
dageshhebrew 1468
dagger 8224
daggerdbl 8225
dagujarati 2726
dagurmukhi 2598
dahiragana 12384
dakatakana 12480
dalarabic 1583
dalet 1491
daletdagesh 64307
daletdageshhebrew 64307
dalethebrew 1491
dalfinalarabic 65194
dammaarabic 1615
dammalowarabic 1615
dammatanaltonearabic 1612
dammatanarabic 1612
danda 2404
dargahebrew 1447
dargalefthebrew 1447
dasiapneumatacyrilliccmb 1157
dblGrave 63187
dblanglebracketleft 12298
dblanglebracketleftvertical 65085
dblanglebracketright 12299
dblanglebracketrightvertical 65086
dblarchinvertedbelowcmb 811
dblarrowleft 8660
dblarrowright 8658
dbldanda 2405
dblgrave 63190
dblgravecmb 783
dblintegral 8748
dbllowline 8215
dbllowlinecmb 819
dbloverlinecmb 831
dblprimemod 698
dblverticalbar 8214
dblverticallineabovecmb 782
dbopomofo 12553
dbsquare 13256
dcaron 271
dcedilla 7697
dcircle 9427
dcircumflexbelow 7699
dcroat 273
ddabengali 2465
ddadeva 2337
ddagujarati 2721
ddagurmukhi 2593
ddalarabic 1672
ddalfinalarabic 64393
dddhadeva 2396
ddhabengali 2466
ddhadeva 2338
ddhagujarati 2722
ddhagurmukhi 2594
ddotaccent 7691
ddotbelow 7693
decimalseparatorarabic 1643
decimalseparatorpersian 1643
decyrillic 1076
degree 176
dehihebrew 1453
dehiragana 12391
deicoptic 1007
dekatakana 12487
deleteleft 9003
deleteright 8998
delta 948
deltaturned 397
denominatorminusonenumeratorbengali 2552
dezh 676
dhabengali 2471
dhadeva 2343
dhagujarati 2727
dhagurmukhi 2599
dhook 599
dialytikatonos 901
dialytikatonoscmb 836
diamond 9830
diamondsuitwhite 9826
dieresis 168
dieresisacute 63191
dieresisbelowcmb 804
dieresiscmb 776
dieresisgrave 63192
dieresistonos 901
dihiragana 12386
dikatakana 12482
dittomark 12291
divide 247
divides 8739
divisionslash 8725
djecyrillic 1106
dkshade 9619
dlinebelow 7695
dlsquare 13207
dmacron 273
dmonospace 65348
dnblock 9604
dochadathai 3598
dodekthai 3604
dohiragana 12393
dokatakana 12489
dollar 36
dollarinferior 63203
dollarmonospace 65284
dollaroldstyle 63268
dollarsmall 65129
dollarsuperior 63204
dong 8363
dorusquare 13094
dotaccent 729
dotaccentcmb 775
dotbelowcmb 803
dotbelowcomb 803
dotkatakana 12539
dotlessi 305
dotlessj 63166
dotlessjstrokehook 644
dotmath 8901
dottedcircle 9676
doubleyodpatah 64287
doubleyodpatahhebrew 64287
downtackbelowcmb 798
downtackmod 725
dparen 9375
dsuperior 63211
dtail 598
dtopbar 396
duhiragana 12389
dukatakana 12485
dz 499
dzaltone 675
dzcaron 454
dzcurl 677
dzeabkhasiancyrillic 1249
dzecyrillic 1109
dzhecyrillic 1119
e 101
eacute 233
earth 9793
ebengali 2447
ebopomofo 12572
ebreve 277
ecandradeva 2317
ecandragujarati 2701
ecandravowelsigndeva 2373
ecandravowelsigngujarati 2757
ecaron 283
ecedillabreve 7709
echarmenian 1381
echyiwnarmenian 1415
ecircle 9428
ecircumflex 234
ecircumflexacute 7871
ecircumflexbelow 7705
ecircumflexdotbelow 7879
ecircumflexgrave 7873
ecircumflexhookabove 7875
ecircumflextilde 7877
ecyrillic 1108
edblgrave 517
edeva 2319
edieresis 235
edot 279
edotaccent 279
edotbelow 7865
eegurmukhi 2575
eematragurmukhi 2631
efcyrillic 1092
egrave 232
egujarati 2703
eharmenian 1383
ehbopomofo 12573
ehiragana 12360
ehookabove 7867
eibopomofo 12575
eight 56
eightarabic 1640
eightbengali 2542
eightcircle 9319
eightcircleinversesansserif 10129
eightdeva 2414
eighteencircle 9329
eighteenparen 9349
eighteenperiod 9369
eightgujarati 2798
eightgurmukhi 2670
eighthackarabic 1640
eighthangzhou 12328
eighthnotebeamed 9835
eightideographicparen 12839
eightinferior 8328
eightmonospace 65304
eightoldstyle 63288
eightparen 9339
eightperiod 9359
eightpersian 1784
eightroman 8567
eightsuperior 8312
eightthai 3672
einvertedbreve 519
eiotifiedcyrillic 1125
ekatakana 12456
ekatakanahalfwidth 65396
ekonkargurmukhi 2676
ekorean 12628
elcyrillic 1083
element 8712
elevencircle 9322
elevenparen 9342
elevenperiod 9362
elevenroman 8570
ellipsis 8230
ellipsisvertical 8942
emacron 275
emacronacute 7703
emacrongrave 7701
emcyrillic 1084
emdash 8212
emdashvertical 65073
emonospace 65349
emphasismarkarmenian 1371
emptyset 8709
enbopomofo 12579
encyrillic 1085
endash 8211
endashvertical 65074
endescendercyrillic 1187
eng 331
engbopomofo 12581
enghecyrillic 1189
enhookcyrillic 1224
enspace 8194
eogonek 281
eokorean 12627
eopen 603
eopenclosed 666
eopenreversed 604
eopenreversedclosed 606
eopenreversedhook 605
eparen 9376
epsilon 949
epsilontonos 941
equal 61
equalmonospace 65309
equalsmall 65126
equalsuperior 8316
equivalence 8801
erbopomofo 12582
ercyrillic 1088
ereversed 600
ereversedcyrillic 1101
escyrillic 1089
esdescendercyrillic 1195
esh 643
eshcurl 646
eshortdeva 2318
eshortvowelsigndeva 2374
eshreversedloop 426
eshsquatreversed 645
esmallhiragana 12359
esmallkatakana 12455
esmallkatakanahalfwidth 65386
estimated 8494
esuperior 63212
eta 951
etarmenian 1384
etatonos 942
eth 240
etilde 7869
etildebelow 7707
etnahtafoukhhebrew 1425
etnahtafoukhlefthebrew 1425
etnahtahebrew 1425
etnahtalefthebrew 1425
eturned 477
eukorean 12641
euro 8364
evowelsignbengali 2503
evowelsigndeva 2375
evowelsigngujarati 2759
exclam 33
exclamarmenian 1372
exclamdbl 8252
exclamdown 161
exclamdownsmall 63393
exclammonospace 65281
exclamsmall 63265
existential 8707
ezh 658
ezhcaron 495
ezhcurl 659
ezhreversed 441
ezhtail 442
f 102
fadeva 2398
fagurmukhi 2654
fahrenheit 8457
fathaarabic 1614
fathalowarabic 1614
fathatanarabic 1611
fbopomofo 12552
fcircle 9429
fdotaccent 7711
feharabic 1601
feharmenian 1414
fehfinalarabic 65234
fehinitialarabic 65235
fehmedialarabic 65236
feicoptic 997
female 9792
ff 64256
ffi 64259
ffl 64260
fi 64257
fifteencircle 9326
fifteenparen 9346
fifteenperiod 9366
figuredash 8210
filledbox 9632
filledrect 9644
finalkaf 1498
finalkafdagesh 64314
finalkafdageshhebrew 64314
finalkafhebrew 1498
finalmem 1501
finalmemhebrew 1501
finalnun 1503
finalnunhebrew 1503
finalpe 1507
finalpehebrew 1507
finaltsadi 1509
finaltsadihebrew 1509
firsttonechinese 713
fisheye 9673
fitacyrillic 1139
five 53
fivearabic 1637
fivebengali 2539
fivecircle 9316
fivecircleinversesansserif 10126
fivedeva 2411
fiveeighths 8541
fivegujarati 2795
fivegurmukhi 2667
fivehackarabic 1637
fivehangzhou 12325
fiveideographicparen 12836
fiveinferior 8325
fivemonospace 65301
fiveoldstyle 63285
fiveparen 9336
fiveperiod 9356
fivepersian 1781
fiveroman 8564
fivesuperior 8309
fivethai 3669
fl 64258
florin 402
fmonospace 65350
fmsquare 13209
fofanthai 3615
fofathai 3613
fongmanthai 3663
forall 8704
four 52
fourarabic 1636
fourbengali 2538
fourcircle 9315
fourcircleinversesansserif 10125
fourdeva 2410
fourgujarati 2794
fourgurmukhi 2666
fourhackarabic 1636
fourhangzhou 12324
fourideographicparen 12835
fourinferior 8324
fourmonospace 65300
fournumeratorbengali 2551
fouroldstyle 63284
fourparen 9335
fourperiod 9355
fourpersian 1780
fourroman 8563
foursuperior 8308
fourteencircle 9325
fourteenparen 9345
fourteenperiod 9365
fourthai 3668
fourthtonechinese 715
fparen 9377
fraction 8260
franc 8355
g 103
gabengali 2455
gacute 501
gadeva 2327
gafarabic 1711
gaffinalarabic 64403
gafinitialarabic 64404
gafmedialarabic 64405
gagujarati 2711
gagurmukhi 2583
gahiragana 12364
gakatakana 12460
gamma 947
gammalatinsmall 611
gammasuperior 736
gangiacoptic 1003
gbopomofo 12557
gbreve 287
gcaron 487
gcedilla 291
gcircle 9430
gcircumflex 285
gcommaaccent 291
gdot 289
gdotaccent 289
gecyrillic 1075
gehiragana 12370
gekatakana 12466
geometricallyequal 8785
gereshaccenthebrew 1436
gereshhebrew 1523
gereshmuqdamhebrew 1437
germandbls 223
gershayimaccenthebrew 1438
gershayimhebrew 1524
getamark 12307
ghabengali 2456
ghadarmenian 1394
ghadeva 2328
ghagujarati 2712
ghagurmukhi 2584
ghainarabic 1594
ghainfinalarabic 65230
ghaininitialarabic 65231
ghainmedialarabic 65232
ghemiddlehookcyrillic 1173
ghestrokecyrillic 1171
gheupturncyrillic 1169
ghhadeva 2394
ghhagurmukhi 2650
ghook 608
ghzsquare 13203
gihiragana 12366
gikatakana 12462
gimarmenian 1379
gimel 1490
gimeldagesh 64306
gimeldageshhebrew 64306
gimelhebrew 1490
gjecyrillic 1107
glottalinvertedstroke 446
glottalstop 660
glottalstopinverted 662
glottalstopmod 704
glottalstopreversed 661
glottalstopreversedmod 705
glottalstopreversedsuperior 740
glottalstopstroke 673
glottalstopstrokereversed 674
gmacron 7713
gmonospace 65351
gohiragana 12372
gokatakana 12468
gparen 9378
gpasquare 13228
gradient 8711
grave 96
gravebelowcmb 790
gravecmb 768
gravecomb 768
gravedeva 2387
gravelowmod 718
gravemonospace 65344
gravetonecmb 832
greater 62
greaterequal 8805
greaterequalorless 8923
greatermonospace 65310
greaterorequivalent 8819
greaterorless 8823
greateroverequal 8807
greatersmall 65125
gscript 609
gstroke 485
guhiragana 12368
guillemotleft 171
guillemotright 187
guilsinglleft 8249
guilsinglright 8250
gukatakana 12464
guramusquare 13080
gysquare 13257
h 104
haabkhasiancyrillic 1193
haaltonearabic 1729
habengali 2489
hadescendercyrillic 1203
hadeva 2361
hagujarati 2745
hagurmukhi 2617
haharabic 1581
hahfinalarabic 65186
hahinitialarabic 65187
hahiragana 12399
hahmedialarabic 65188
haitusquare 13098
hakatakana 12495
hakatakanahalfwidth 65418
halantgurmukhi 2637
hamzaarabic 1569
hamzalowarabic 1569
hangulfiller 12644
hardsigncyrillic 1098
harpoonleftbarbup 8636
harpoonrightbarbup 8640
hasquare 13258
hatafpatah 1458
hatafpatah16 1458
hatafpatah23 1458
hatafpatah2f 1458
hatafpatahhebrew 1458
hatafpatahnarrowhebrew 1458
hatafpatahquarterhebrew 1458
hatafpatahwidehebrew 1458
hatafqamats 1459
hatafqamats1b 1459
hatafqamats28 1459
hatafqamats34 1459
hatafqamatshebrew 1459
hatafqamatsnarrowhebrew 1459
hatafqamatsquarterhebrew 1459
hatafqamatswidehebrew 1459
hatafsegol 1457
hatafsegol17 1457
hatafsegol24 1457
hatafsegol30 1457
hatafsegolhebrew 1457
hatafsegolnarrowhebrew 1457
hatafsegolquarterhebrew 1457
hatafsegolwidehebrew 1457
hbar 295
hbopomofo 12559
hbrevebelow 7723
hcedilla 7721
hcircle 9431
hcircumflex 293
hdieresis 7719
hdotaccent 7715
hdotbelow 7717
he 1492
heart 9829
heartsuitblack 9829
heartsuitwhite 9825
hedagesh 64308
hedageshhebrew 64308
hehaltonearabic 1729
heharabic 1607
hehebrew 1492
hehfinalaltonearabic 64423
hehfinalalttwoarabic 65258
hehfinalarabic 65258
hehhamzaabovefinalarabic 64421
hehhamzaaboveisolatedarabic 64420
hehinitialaltonearabic 64424
hehinitialarabic 65259
hehiragana 12408
hehmedialaltonearabic 64425
hehmedialarabic 65260
heiseierasquare 13179
hekatakana 12504
hekatakanahalfwidth 65421
hekutaarusquare 13110
henghook 615
herutusquare 13113
het 1495
hethebrew 1495
hhook 614
hhooksuperior 689
hieuhacirclekorean 12923
hieuhaparenkorean 12827
hieuhcirclekorean 12909
hieuhkorean 12622
hieuhparenkorean 12813
hihiragana 12402
hikatakana 12498
hikatakanahalfwidth 65419
hiriq 1460
hiriq14 1460
hiriq21 1460
hiriq2d 1460
hiriqhebrew 1460
hiriqnarrowhebrew 1460
hiriqquarterhebrew 1460
hiriqwidehebrew 1460
hlinebelow 7830
hmonospace 65352
hoarmenian 1392
hohipthai 3627
hohiragana 12411
hokatakana 12507
hokatakanahalfwidth 65422
holam 1465
holam19 1465
holam26 1465
holam32 1465
holamhebrew 1465
holamnarrowhebrew 1465
holamquarterhebrew 1465
holamwidehebrew 1465
honokhukthai 3630
hookabovecomb 777
hookcmb 777
hookpalatalizedbelowcmb 801
hookretroflexbelowcmb 802
hoonsquare 13122
horicoptic 1001
horizontalbar 8213
horncmb 795
hotsprings 9832
house 8962
hparen 9379
hsuperior 688
hturned 613
huhiragana 12405
huiitosquare 13107
hukatakana 12501
hukatakanahalfwidth 65420
hungarumlaut 733
hungarumlautcmb 779
hv 405
hyphen 45
hypheninferior 63205
hyphenmonospace 65293
hyphensmall 65123
hyphensuperior 63206
hyphentwo 8208
i 105
iacute 237
iacyrillic 1103
ibengali 2439
ibopomofo 12583
ibreve 301
icaron 464
icircle 9432
icircumflex 238
icyrillic 1110
idblgrave 521
ideographearthcircle 12943
ideographfirecircle 12939
ideographicallianceparen 12863
ideographiccallparen 12858
ideographiccentrecircle 12965
ideographicclose 12294
ideographiccomma 12289
ideographiccommaleft 65380
ideographiccongratulationparen 12855
ideographiccorrectcircle 12963
ideographicearthparen 12847
ideographicenterpriseparen 12861
ideographicexcellentcircle 12957
ideographicfestivalparen 12864
ideographicfinancialcircle 12950
ideographicfinancialparen 12854
ideographicfireparen 12843
ideographichaveparen 12850
ideographichighcircle 12964
ideographiciterationmark 12293
ideographiclaborcircle 12952
ideographiclaborparen 12856
ideographicleftcircle 12967
ideographiclowcircle 12966
ideographicmedicinecircle 12969
ideographicmetalparen 12846
ideographicmoonparen 12842
ideographicnameparen 12852
ideographicperiod 12290
ideographicprintcircle 12958
ideographicreachparen 12867
ideographicrepresentparen 12857
ideographicresourceparen 12862
ideographicrightcircle 12968
ideographicsecretcircle 12953
ideographicselfparen 12866
ideographicsocietyparen 12851
ideographicspace 12288
ideographicspecialparen 12853
ideographicstockparen 12849
ideographicstudyparen 12859
ideographicsunparen 12848
ideographicsuperviseparen 12860
ideographicwaterparen 12844
ideographicwoodparen 12845
ideographiczero 12295
ideographmetalcircle 12942
ideographmooncircle 12938
ideographnamecircle 12948
ideographsuncircle 12944
ideographwatercircle 12940
ideographwoodcircle 12941
ideva 2311
idieresis 239
idieresisacute 7727
idieresiscyrillic 1253
idotbelow 7883
iebrevecyrillic 1239
iecyrillic 1077
ieungacirclekorean 12917
ieungaparenkorean 12821
ieungcirclekorean 12903
ieungkorean 12615
ieungparenkorean 12807
igrave 236
igujarati 2695
igurmukhi 2567
ihiragana 12356
ihookabove 7881
iibengali 2440
iicyrillic 1080
iideva 2312
iigujarati 2696
iigurmukhi 2568
iimatragurmukhi 2624
iinvertedbreve 523
iishortcyrillic 1081
iivowelsignbengali 2496
iivowelsigndeva 2368
iivowelsigngujarati 2752
ij 307
ikatakana 12452
ikatakanahalfwidth 65394
ikorean 12643
ilde 732
iluyhebrew 1452
imacron 299
imacroncyrillic 1251
imageorapproximatelyequal 8787
imatragurmukhi 2623
imonospace 65353
increment 8710
infinity 8734
iniarmenian 1387
integral 8747
integralbottom 8993
integralbt 8993
integralex 63733
integraltop 8992
integraltp 8992
intersection 8745
intisquare 13061
invbullet 9688
invcircle 9689
invsmileface 9787
iocyrillic 1105
iogonek 303
iota 953
iotadieresis 970
iotadieresistonos 912
iotalatin 617
iotatonos 943
iparen 9380
irigurmukhi 2674
ismallhiragana 12355
ismallkatakana 12451
ismallkatakanahalfwidth 65384
issharbengali 2554
istroke 616
isuperior 63213
iterationhiragana 12445
iterationkatakana 12541
itilde 297
itildebelow 7725
iubopomofo 12585
iucyrillic 1102
ivowelsignbengali 2495
ivowelsigndeva 2367
ivowelsigngujarati 2751
izhitsacyrillic 1141
izhitsadblgravecyrillic 1143
j 106
jaarmenian 1393
jabengali 2460
jadeva 2332
jagujarati 2716
jagurmukhi 2588
jbopomofo 12560
jcaron 496
jcircle 9433
jcircumflex 309
jcrossedtail 669
jdotlessstroke 607
jecyrillic 1112
jeemarabic 1580
jeemfinalarabic 65182
jeeminitialarabic 65183
jeemmedialarabic 65184
jeharabic 1688
jehfinalarabic 64395
jhabengali 2461
jhadeva 2333
jhagujarati 2717
jhagurmukhi 2589
jheharmenian 1403
jis 12292
jmonospace 65354
jparen 9381
jsuperior 690
k 107
kabashkircyrillic 1185
kabengali 2453
kacute 7729
kacyrillic 1082
kadescendercyrillic 1179
kadeva 2325
kaf 1499
kafarabic 1603
kafdagesh 64315
kafdageshhebrew 64315
kaffinalarabic 65242
kafhebrew 1499
kafinitialarabic 65243
kafmedialarabic 65244
kafrafehebrew 64333
kagujarati 2709
kagurmukhi 2581
kahiragana 12363
kahookcyrillic 1220
kakatakana 12459
kakatakanahalfwidth 65398
kappa 954
kappasymbolgreek 1008
kapyeounmieumkorean 12657
kapyeounphieuphkorean 12676
kapyeounpieupkorean 12664
kapyeounssangpieupkorean 12665
karoriisquare 13069
kashidaautoarabic 1600
kashidaautonosidebearingarabic 1600
kasmallkatakana 12533
kasquare 13188
kasraarabic 1616
kasratanarabic 1613
kastrokecyrillic 1183
katahiraprolongmarkhalfwidth 65392
kaverticalstrokecyrillic 1181
kbopomofo 12558
kcalsquare 13193
kcaron 489
kcedilla 311
kcircle 9434
kcommaaccent 311
kdotbelow 7731
keharmenian 1412
kehiragana 12369
kekatakana 12465
kekatakanahalfwidth 65401
kenarmenian 1391
kesmallkatakana 12534
kgreenlandic 312
khabengali 2454
khacyrillic 1093
khadeva 2326
khagujarati 2710
khagurmukhi 2582
khaharabic 1582
khahfinalarabic 65190
khahinitialarabic 65191
khahmedialarabic 65192
kheicoptic 999
khhadeva 2393
khhagurmukhi 2649
khieukhacirclekorean 12920
khieukhaparenkorean 12824
khieukhcirclekorean 12906
khieukhkorean 12619
khieukhparenkorean 12810
khokhaithai 3586
khokhonthai 3589
khokhuatthai 3587
khokhwaithai 3588
khomutthai 3675
khook 409
khorakhangthai 3590
khzsquare 13201
kihiragana 12365
kikatakana 12461
kikatakanahalfwidth 65399
kiroguramusquare 13077
kiromeetorusquare 13078
kirosquare 13076
kiyeokacirclekorean 12910
kiyeokaparenkorean 12814
kiyeokcirclekorean 12896
kiyeokkorean 12593
kiyeokparenkorean 12800
kiyeoksioskorean 12595
kjecyrillic 1116
klinebelow 7733
klsquare 13208
kmcubedsquare 13222
kmonospace 65355
kmsquaredsquare 13218
kohiragana 12371
kohmsquare 13248
kokaithai 3585
kokatakana 12467
kokatakanahalfwidth 65402
kooposquare 13086
koppacyrillic 1153
koreanstandardsymbol 12927
koroniscmb 835
kparen 9382
kpasquare 13226
ksicyrillic 1135
ktsquare 13263
kturned 670
kuhiragana 12367
kukatakana 12463
kukatakanahalfwidth 65400
kvsquare 13240
kwsquare 13246
l 108
labengali 2482
lacute 314
ladeva 2354
lagujarati 2738
lagurmukhi 2610
lakkhangyaothai 3653
lamaleffinalarabic 65276
lamalefhamzaabovefinalarabic 65272
lamalefhamzaaboveisolatedarabic 65271
lamalefhamzabelowfinalarabic 65274
lamalefhamzabelowisolatedarabic 65273
lamalefisolatedarabic 65275
lamalefmaddaabovefinalarabic 65270
lamalefmaddaaboveisolatedarabic 65269
lamarabic 1604
lambda 955
lambdastroke 411
lamed 1500
lameddagesh 64316
lameddageshhebrew 64316
lamedhebrew 1500
lamfinalarabic 65246
lamhahinitialarabic 64714
laminitialarabic 65247
lamjeeminitialarabic 64713
lamkhahinitialarabic 64715
lamlamhehisolatedarabic 65010
lammedialarabic 65248
lammeemhahinitialarabic 64904
lammeeminitialarabic 64716
largecircle 9711
lbar 410
lbelt 620
lbopomofo 12556
lcaron 318
lcedilla 316
lcircle 9435
lcircumflexbelow 7741
lcommaaccent 316
ldot 320
ldotaccent 320
ldotbelow 7735
ldotbelowmacron 7737
leftangleabovecmb 794
lefttackbelowcmb 792
less 60
lessequal 8804
lessequalorgreater 8922
lessmonospace 65308
lessorequivalent 8818
lessorgreater 8822
lessoverequal 8806
lesssmall 65124
lezh 622
lfblock 9612
lhookretroflex 621
lira 8356
liwnarmenian 1388
lj 457
ljecyrillic 1113
ll 63168
lladeva 2355
llagujarati 2739
llinebelow 7739
llladeva 2356
llvocalicbengali 2529
llvocalicdeva 2401
llvocalicvowelsignbengali 2531
llvocalicvowelsigndeva 2403
lmiddletilde 619
lmonospace 65356
lmsquare 13264
lochulathai 3628
logicaland 8743
logicalnot 172
logicalnotreversed 8976
logicalor 8744
lolingthai 3621
longs 383
lowlinecenterline 65102
lowlinecmb 818
lowlinedashed 65101
lozenge 9674
lparen 9383
lslash 322
lsquare 8467
lsuperior 63214
ltshade 9617
luthai 3622
lvocalicbengali 2444
lvocalicdeva 2316
lvocalicvowelsignbengali 2530
lvocalicvowelsigndeva 2402
lxsquare 13267
m 109
mabengali 2478
macron 175
macronbelowcmb 817
macroncmb 772
macronlowmod 717
macronmonospace 65507
macute 7743
madeva 2350
magujarati 2734
magurmukhi 2606
mahapakhhebrew 1444
mahapakhlefthebrew 1444
mahiragana 12414
maichattawalowleftthai 63637
maichattawalowrightthai 63636
maichattawathai 3659
maichattawaupperleftthai 63635
maieklowleftthai 63628
maieklowrightthai 63627
maiekthai 3656
maiekupperleftthai 63626
maihanakatleftthai 63620
maihanakatthai 3633
maitaikhuleftthai 63625
maitaikhuthai 3655
maitholowleftthai 63631
maitholowrightthai 63630
maithothai 3657
maithoupperleftthai 63629
maitrilowleftthai 63634
maitrilowrightthai 63633
maitrithai 3658
maitriupperleftthai 63632
maiyamokthai 3654
makatakana 12510
makatakanahalfwidth 65423
male 9794
mansyonsquare 13127
maqafhebrew 1470
mars 9794
masoracirclehebrew 1455
masquare 13187
mbopomofo 12551
mbsquare 13268
mcircle 9436
mcubedsquare 13221
mdotaccent 7745
mdotbelow 7747
meemarabic 1605
meemfinalarabic 65250
meeminitialarabic 65251
meemmedialarabic 65252
meemmeeminitialarabic 64721
meemmeemisolatedarabic 64584
meetorusquare 13133
mehiragana 12417
meizierasquare 13182
mekatakana 12513
mekatakanahalfwidth 65426
mem 1502
memdagesh 64318
memdageshhebrew 64318
memhebrew 1502
menarmenian 1396
merkhahebrew 1445
merkhakefulahebrew 1446
merkhakefulalefthebrew 1446
merkhalefthebrew 1445
mhook 625
mhzsquare 13202
middledotkatakanahalfwidth 65381
middot 183
mieumacirclekorean 12914
mieumaparenkorean 12818
mieumcirclekorean 12900
mieumkorean 12609
mieumpansioskorean 12656
mieumparenkorean 12804
mieumpieupkorean 12654
mieumsioskorean 12655
mihiragana 12415
mikatakana 12511
mikatakanahalfwidth 65424
minus 8722
minusbelowcmb 800
minuscircle 8854
minusmod 727
minusplus 8723
minute 8242
miribaarusquare 13130
mirisquare 13129
mlonglegturned 624
mlsquare 13206
mmcubedsquare 13219
mmonospace 65357
mmsquaredsquare 13215
mohiragana 12418
mohmsquare 13249
mokatakana 12514
mokatakanahalfwidth 65427
molsquare 13270
momathai 3617
moverssquare 13223
moverssquaredsquare 13224
mparen 9384
mpasquare 13227
mssquare 13235
msuperior 63215
mturned 623
mu 181
mu1 181
muasquare 13186
muchgreater 8811
muchless 8810
mufsquare 13196
mugreek 956
mugsquare 13197
muhiragana 12416
mukatakana 12512
mukatakanahalfwidth 65425
mulsquare 13205
multiply 215
mumsquare 13211
munahhebrew 1443
munahlefthebrew 1443
musicalnote 9834
musicalnotedbl 9835
musicflatsign 9837
musicsharpsign 9839
mussquare 13234
muvsquare 13238
muwsquare 13244
mvmegasquare 13241
mvsquare 13239
mwmegasquare 13247
mwsquare 13245
n 110
nabengali 2472
nabla 8711
nacute 324
nadeva 2344
nagujarati 2728
nagurmukhi 2600
nahiragana 12394
nakatakana 12490
nakatakanahalfwidth 65413
napostrophe 329
nasquare 13185
nbopomofo 12555
nbspace 160
ncaron 328
ncedilla 326
ncircle 9437
ncircumflexbelow 7755
ncommaaccent 326
ndotaccent 7749
ndotbelow 7751
nehiragana 12397
nekatakana 12493
nekatakanahalfwidth 65416
newsheqelsign 8362
nfsquare 13195
ngabengali 2457
ngadeva 2329
ngagujarati 2713
ngagurmukhi 2585
ngonguthai 3591
nhiragana 12435
nhookleft 626
nhookretroflex 627
nieunacirclekorean 12911
nieunaparenkorean 12815
nieuncieuckorean 12597
nieuncirclekorean 12897
nieunhieuhkorean 12598
nieunkorean 12596
nieunpansioskorean 12648
nieunparenkorean 12801
nieunsioskorean 12647
nieuntikeutkorean 12646
nihiragana 12395
nikatakana 12491
nikatakanahalfwidth 65414
nikhahitleftthai 63641
nikhahitthai 3661
nine 57
ninearabic 1641
ninebengali 2543
ninecircle 9320
ninecircleinversesansserif 10130
ninedeva 2415
ninegujarati 2799
ninegurmukhi 2671
ninehackarabic 1641
ninehangzhou 12329
nineideographicparen 12840
nineinferior 8329
ninemonospace 65305
nineoldstyle 63289
nineparen 9340
nineperiod 9360
ninepersian 1785
nineroman 8568
ninesuperior 8313
nineteencircle 9330
nineteenparen 9350
nineteenperiod 9370
ninethai 3673
nj 460
njecyrillic 1114
nkatakana 12531
nkatakanahalfwidth 65437
nlegrightlong 414
nlinebelow 7753
nmonospace 65358
nmsquare 13210
nnabengali 2467
nnadeva 2339
nnagujarati 2723
nnagurmukhi 2595
nnnadeva 2345
nohiragana 12398
nokatakana 12494
nokatakanahalfwidth 65417
nonbreakingspace 160
nonenthai 3603
nonuthai 3609
noonarabic 1606
noonfinalarabic 65254
noonghunnaarabic 1722
noonghunnafinalarabic 64415
nooninitialarabic 65255
noonjeeminitialarabic 64722
noonjeemisolatedarabic 64587
noonmedialarabic 65256
noonmeeminitialarabic 64725
noonmeemisolatedarabic 64590
noonnoonfinalarabic 64653
notcontains 8716
notelement 8713
notelementof 8713
notequal 8800
notgreater 8815
notgreaternorequal 8817
notgreaternorless 8825
notidentical 8802
notless 8814
notlessnorequal 8816
notparallel 8742
notprecedes 8832
notsubset 8836
notsucceeds 8833
notsuperset 8837
nowarmenian 1398
nparen 9385
nssquare 13233
nsuperior 8319
ntilde 241
nu 957
nuhiragana 12396
nukatakana 12492
nukatakanahalfwidth 65415
nuktabengali 2492
nuktadeva 2364
nuktagujarati 2748
nuktagurmukhi 2620
numbersign 35
numbersignmonospace 65283
numbersignsmall 65119
numeralsigngreek 884
numeralsignlowergreek 885
numero 8470
nun 1504
nundagesh 64320
nundageshhebrew 64320
nunhebrew 1504
nvsquare 13237
nwsquare 13243
nyabengali 2462
nyadeva 2334
nyagujarati 2718
nyagurmukhi 2590
o 111
oacute 243
oangthai 3629
obarred 629
obarredcyrillic 1257
obarreddieresiscyrillic 1259
obengali 2451
obopomofo 12571
obreve 335
ocandradeva 2321
ocandragujarati 2705
ocandravowelsigndeva 2377
ocandravowelsigngujarati 2761
ocaron 466
ocircle 9438
ocircumflex 244
ocircumflexacute 7889
ocircumflexdotbelow 7897
ocircumflexgrave 7891
ocircumflexhookabove 7893
ocircumflextilde 7895
ocyrillic 1086
odblacute 337
odblgrave 525
odeva 2323
odieresis 246
odieresiscyrillic 1255
odotbelow 7885
oe 339
oekorean 12634
ogonek 731
ogonekcmb 808
ograve 242
ogujarati 2707
oharmenian 1413
ohiragana 12362
ohookabove 7887
ohorn 417
ohornacute 7899
ohorndotbelow 7907
ohorngrave 7901
ohornhookabove 7903
ohorntilde 7905
ohungarumlaut 337
oi 419
oinvertedbreve 527
okatakana 12458
okatakanahalfwidth 65397
okorean 12631
olehebrew 1451
omacron 333
omacronacute 7763
omacrongrave 7761
omdeva 2384
omega 969
omega1 982
omegacyrillic 1121
omegalatinclosed 631
omegaroundcyrillic 1147
omegatitlocyrillic 1149
omegatonos 974
omgujarati 2768
omicron 959
omicrontonos 972
omonospace 65359
one 49
onearabic 1633
onebengali 2535
onecircle 9312
onecircleinversesansserif 10122
onedeva 2407
onedotenleader 8228
oneeighth 8539
onefitted 63196
onegujarati 2791
onegurmukhi 2663
onehackarabic 1633
onehalf 189
onehangzhou 12321
oneideographicparen 12832
oneinferior 8321
onemonospace 65297
onenumeratorbengali 2548
oneoldstyle 63281
oneparen 9332
oneperiod 9352
onepersian 1777
onequarter 188
oneroman 8560
onesuperior 185
onethai 3665
onethird 8531
oogonek 491
oogonekmacron 493
oogurmukhi 2579
oomatragurmukhi 2635
oopen 596
oparen 9386
openbullet 9702
option 8997
ordfeminine 170
ordmasculine 186
orthogonal 8735
oshortdeva 2322
oshortvowelsigndeva 2378
oslash 248
oslashacute 511
osmallhiragana 12361
osmallkatakana 12457
osmallkatakanahalfwidth 65387
ostrokeacute 511
osuperior 63216
otcyrillic 1151
otilde 245
otildeacute 7757
otildedieresis 7759
oubopomofo 12577
overline 8254
overlinecenterline 65098
overlinecmb 773
overlinedashed 65097
overlinedblwavy 65100
overlinewavy 65099
overscore 175
ovowelsignbengali 2507
ovowelsigndeva 2379
ovowelsigngujarati 2763
p 112
paampssquare 13184
paasentosquare 13099
pabengali 2474
pacute 7765
padeva 2346
pagedown 8671
pageup 8670
pagujarati 2730
pagurmukhi 2602
pahiragana 12401
paiyannoithai 3631
pakatakana 12497
palatalizationcyrilliccmb 1156
palochkacyrillic 1216
pansioskorean 12671
paragraph 182
parallel 8741
parenleft 40
parenleftaltonearabic 64830
parenleftbt 63725
parenleftex 63724
parenleftinferior 8333
parenleftmonospace 65288
parenleftsmall 65113
parenleftsuperior 8317
parenlefttp 63723
parenleftvertical 65077
parenright 41
parenrightaltonearabic 64831
parenrightbt 63736
parenrightex 63735
parenrightinferior 8334
parenrightmonospace 65289
parenrightsmall 65114
parenrightsuperior 8318
parenrighttp 63734
parenrightvertical 65078
partialdiff 8706
paseqhebrew 1472
pashtahebrew 1433
pasquare 13225
patah 1463
patah11 1463
patah1d 1463
patah2a 1463
patahhebrew 1463
patahnarrowhebrew 1463
patahquarterhebrew 1463
patahwidehebrew 1463
pazerhebrew 1441
pbopomofo 12550
pcircle 9439
pdotaccent 7767
pe 1508
pecyrillic 1087
pedagesh 64324
pedageshhebrew 64324
peezisquare 13115
pefinaldageshhebrew 64323
peharabic 1662
peharmenian 1402
pehebrew 1508
pehfinalarabic 64343
pehinitialarabic 64344
pehiragana 12410
pehmedialarabic 64345
pekatakana 12506
pemiddlehookcyrillic 1191
perafehebrew 64334
percent 37
percentarabic 1642
percentmonospace 65285
percentsmall 65130
period 46
periodarmenian 1417
periodcentered 183
periodhalfwidth 65377
periodinferior 63207
periodmonospace 65294
periodsmall 65106
periodsuperior 63208
perispomenigreekcmb 834
perpendicular 8869
perthousand 8240
peseta 8359
pfsquare 13194
phabengali 2475
phadeva 2347
phagujarati 2731
phagurmukhi 2603
phi 966
phi1 981
phieuphacirclekorean 12922
phieuphaparenkorean 12826
phieuphcirclekorean 12908
phieuphkorean 12621
phieuphparenkorean 12812
philatin 632
phinthuthai 3642
phisymbolgreek 981
phook 421
phophanthai 3614
phophungthai 3612
phosamphaothai 3616
pi 960
pieupacirclekorean 12915
pieupaparenkorean 12819
pieupcieuckorean 12662
pieupcirclekorean 12901
pieupkiyeokkorean 12658
pieupkorean 12610
pieupparenkorean 12805
pieupsioskiyeokkorean 12660
pieupsioskorean 12612
pieupsiostikeutkorean 12661
pieupthieuthkorean 12663
pieuptikeutkorean 12659
pihiragana 12404
pikatakana 12500
pisymbolgreek 982
piwrarmenian 1411
plus 43
plusbelowcmb 799
pluscircle 8853
plusminus 177
plusmod 726
plusmonospace 65291
plussmall 65122
plussuperior 8314
pmonospace 65360
pmsquare 13272
pohiragana 12413
pointingindexdownwhite 9759
pointingindexleftwhite 9756
pointingindexrightwhite 9758
pointingindexupwhite 9757
pokatakana 12509
poplathai 3611
postalmark 12306
postalmarkface 12320
pparen 9387
precedes 8826
prescription 8478
primemod 697
primereversed 8245
product 8719
projective 8965
prolongedkana 12540
propellor 8984
propersubset 8834
propersuperset 8835
proportion 8759
proportional 8733
psi 968
psicyrillic 1137
psilipneumatacyrilliccmb 1158
pssquare 13232
puhiragana 12407
pukatakana 12503
pvsquare 13236
pwsquare 13242
q 113
qadeva 2392
qadmahebrew 1448
qafarabic 1602
qaffinalarabic 65238
qafinitialarabic 65239
qafmedialarabic 65240
qamats 1464
qamats10 1464
qamats1a 1464
qamats1c 1464
qamats27 1464
qamats29 1464
qamats33 1464
qamatsde 1464
qamatshebrew 1464
qamatsnarrowhebrew 1464
qamatsqatanhebrew 1464
qamatsqatannarrowhebrew 1464
qamatsqatanquarterhebrew 1464
qamatsqatanwidehebrew 1464
qamatsquarterhebrew 1464
qamatswidehebrew 1464
qarneyparahebrew 1439
qbopomofo 12561
qcircle 9440
qhook 672
qmonospace 65361
qof 1511
qofdagesh 64327
qofdageshhebrew 64327
qofhebrew 1511
qparen 9388
quarternote 9833
qubuts 1467
qubuts18 1467
qubuts25 1467
qubuts31 1467
qubutshebrew 1467
qubutsnarrowhebrew 1467
qubutsquarterhebrew 1467
qubutswidehebrew 1467
question 63
questionarabic 1567
questionarmenian 1374
questiondown 191
questiondownsmall 63423
questiongreek 894
questionmonospace 65311
questionsmall 63295
quotedbl 34
quotedblbase 8222
quotedblleft 8220
quotedblmonospace 65282
quotedblprime 12318
quotedblprimereversed 12317
quotedblright 8221
quoteleft 8216
quoteleftreversed 8219
quotereversed 8219
quoteright 8217
quoterightn 329
quotesinglbase 8218
quotesingle 39
quotesinglemonospace 65287
r 114
raarmenian 1404
rabengali 2480
racute 341
radeva 2352
radical 8730
radicalex 63717
radoverssquare 13230
radoverssquaredsquare 13231
radsquare 13229
rafe 1471
rafehebrew 1471
ragujarati 2736
ragurmukhi 2608
rahiragana 12425
rakatakana 12521
rakatakanahalfwidth 65431
ralowerdiagonalbengali 2545
ramiddlediagonalbengali 2544
ramshorn 612
ratio 8758
rbopomofo 12566
rcaron 345
rcedilla 343
rcircle 9441
rcommaaccent 343
rdblgrave 529
rdotaccent 7769
rdotbelow 7771
rdotbelowmacron 7773
referencemark 8251
reflexsubset 8838
reflexsuperset 8839
registered 174
registersans 63720
registerserif 63194
reharabic 1585
reharmenian 1408
rehfinalarabic 65198
rehiragana 12428
rekatakana 12524
rekatakanahalfwidth 65434
resh 1512
reshdageshhebrew 64328
reshhebrew 1512
reversedtilde 8765
reviahebrew 1431
reviamugrashhebrew 1431
revlogicalnot 8976
rfishhook 638
rfishhookreversed 639
rhabengali 2525
rhadeva 2397
rho 961
rhook 637
rhookturned 635
rhookturnedsuperior 693
rhosymbolgreek 1009
rhotichookmod 734
rieulacirclekorean 12913
rieulaparenkorean 12817
rieulcirclekorean 12899
rieulhieuhkorean 12608
rieulkiyeokkorean 12602
rieulkiyeoksioskorean 12649
rieulkorean 12601
rieulmieumkorean 12603
rieulpansioskorean 12652
rieulparenkorean 12803
rieulphieuphkorean 12607
rieulpieupkorean 12604
rieulpieupsioskorean 12651
rieulsioskorean 12605
rieulthieuthkorean 12606
rieultikeutkorean 12650
rieulyeorinhieuhkorean 12653
rightangle 8735
righttackbelowcmb 793
righttriangle 8895
rihiragana 12426
rikatakana 12522
rikatakanahalfwidth 65432
ring 730
ringbelowcmb 805
ringcmb 778
ringhalfleft 703
ringhalfleftarmenian 1369
ringhalfleftbelowcmb 796
ringhalfleftcentered 723
ringhalfright 702
ringhalfrightbelowcmb 825
ringhalfrightcentered 722
rinvertedbreve 531
rittorusquare 13137
rlinebelow 7775
rlongleg 636
rlonglegturned 634
rmonospace 65362
rohiragana 12429
rokatakana 12525
rokatakanahalfwidth 65435
roruathai 3619
rparen 9389
rrabengali 2524
rradeva 2353
rragurmukhi 2652
rreharabic 1681
rrehfinalarabic 64397
rrvocalicbengali 2528
rrvocalicdeva 2400
rrvocalicgujarati 2784
rrvocalicvowelsignbengali 2500
rrvocalicvowelsigndeva 2372
rrvocalicvowelsigngujarati 2756
rsuperior 63217
rtblock 9616
rturned 633
rturnedsuperior 692
ruhiragana 12427
rukatakana 12523
rukatakanahalfwidth 65433
rupeemarkbengali 2546
rupeesignbengali 2547
rupiah 63197
ruthai 3620
rvocalicbengali 2443
rvocalicdeva 2315
rvocalicgujarati 2699
rvocalicvowelsignbengali 2499
rvocalicvowelsigndeva 2371
rvocalicvowelsigngujarati 2755
s 115
sabengali 2488
sacute 347
sacutedotaccent 7781
sadarabic 1589
sadeva 2360
sadfinalarabic 65210
sadinitialarabic 65211
sadmedialarabic 65212
sagujarati 2744
sagurmukhi 2616
sahiragana 12373
sakatakana 12469
sakatakanahalfwidth 65403
sallallahoualayhewasallamarabic 65018
samekh 1505
samekhdagesh 64321
samekhdageshhebrew 64321
samekhhebrew 1505
saraaathai 3634
saraaethai 3649
saraaimaimalaithai 3652
saraaimaimuanthai 3651
saraamthai 3635
saraathai 3632
saraethai 3648
saraiileftthai 63622
saraiithai 3637
saraileftthai 63621
saraithai 3636
saraothai 3650
saraueeleftthai 63624
saraueethai 3639
saraueleftthai 63623
sarauethai 3638
sarauthai 3640
sarauuthai 3641
sbopomofo 12569
scaron 353
scarondotaccent 7783
scedilla 351
schwa 601
schwacyrillic 1241
schwadieresiscyrillic 1243
schwahook 602
scircle 9442
scircumflex 349
scommaaccent 537
sdotaccent 7777
sdotbelow 7779
sdotbelowdotaccent 7785
seagullbelowcmb 828
second 8243
secondtonechinese 714
section 167
seenarabic 1587
seenfinalarabic 65202
seeninitialarabic 65203
seenmedialarabic 65204
segol 1462
segol13 1462
segol1f 1462
segol2c 1462
segolhebrew 1462
segolnarrowhebrew 1462
segolquarterhebrew 1462
segoltahebrew 1426
segolwidehebrew 1462
seharmenian 1405
sehiragana 12379
sekatakana 12475
sekatakanahalfwidth 65406
semicolon 59
semicolonarabic 1563
semicolonmonospace 65307
semicolonsmall 65108
semivoicedmarkkana 12444
semivoicedmarkkanahalfwidth 65439
sentisquare 13090
sentosquare 13091
seven 55
sevenarabic 1639
sevenbengali 2541
sevencircle 9318
sevencircleinversesansserif 10128
sevendeva 2413
seveneighths 8542
sevengujarati 2797
sevengurmukhi 2669
sevenhackarabic 1639
sevenhangzhou 12327
sevenideographicparen 12838
seveninferior 8327
sevenmonospace 65303
sevenoldstyle 63287
sevenparen 9338
sevenperiod 9358
sevenpersian 1783
sevenroman 8566
sevensuperior 8311
seventeencircle 9328
seventeenparen 9348
seventeenperiod 9368
seventhai 3671
sfthyphen 173
shaarmenian 1399
shabengali 2486
shacyrillic 1096
shaddaarabic 1617
shaddadammaarabic 64609
shaddadammatanarabic 64606
shaddafathaarabic 64608
shaddakasraarabic 64610
shaddakasratanarabic 64607
shade 9618
shadedark 9619
shadelight 9617
shademedium 9618
shadeva 2358
shagujarati 2742
shagurmukhi 2614
shalshelethebrew 1427
shbopomofo 12565
shchacyrillic 1097
sheenarabic 1588
sheenfinalarabic 65206
sheeninitialarabic 65207
sheenmedialarabic 65208
sheicoptic 995
sheqel 8362
sheqelhebrew 8362
sheva 1456
sheva115 1456
sheva15 1456
sheva22 1456
sheva2e 1456
shevahebrew 1456
shevanarrowhebrew 1456
shevaquarterhebrew 1456
shevawidehebrew 1456
shhacyrillic 1211
shimacoptic 1005
shin 1513
shindagesh 64329
shindageshhebrew 64329
shindageshshindot 64300
shindageshshindothebrew 64300
shindageshsindot 64301
shindageshsindothebrew 64301
shindothebrew 1473
shinhebrew 1513
shinshindot 64298
shinshindothebrew 64298
shinsindot 64299
shinsindothebrew 64299
shook 642
sigma 963
sigma1 962
sigmafinal 962
sigmalunatesymbolgreek 1010
sihiragana 12375
sikatakana 12471
sikatakanahalfwidth 65404
siluqhebrew 1469
siluqlefthebrew 1469
similar 8764
sindothebrew 1474
siosacirclekorean 12916
siosaparenkorean 12820
sioscieuckorean 12670
sioscirclekorean 12902
sioskiyeokkorean 12666
sioskorean 12613
siosnieunkorean 12667
siosparenkorean 12806
siospieupkorean 12669
siostikeutkorean 12668
six 54
sixarabic 1638
sixbengali 2540
sixcircle 9317
sixcircleinversesansserif 10127
sixdeva 2412
sixgujarati 2796
sixgurmukhi 2668
sixhackarabic 1638
sixhangzhou 12326
sixideographicparen 12837
sixinferior 8326
sixmonospace 65302
sixoldstyle 63286
sixparen 9337
sixperiod 9357
sixpersian 1782
sixroman 8565
sixsuperior 8310
sixteencircle 9327
sixteencurrencydenominatorbengali 2553
sixteenparen 9347
sixteenperiod 9367
sixthai 3670
slash 47
slashmonospace 65295
slong 383
slongdotaccent 7835
smileface 9786
smonospace 65363
sofpasuqhebrew 1475
softhyphen 173
softsigncyrillic 1100
sohiragana 12381
sokatakana 12477
sokatakanahalfwidth 65407
soliduslongoverlaycmb 824
solidusshortoverlaycmb 823
sorusithai 3625
sosalathai 3624
sosothai 3595
sosuathai 3626
space 32
spacehackarabic 32
spade 9824
spadesuitblack 9824
spadesuitwhite 9828
sparen 9390
squarebelowcmb 827
squarecc 13252
squarecm 13213
squarediagonalcrosshatchfill 9641
squarehorizontalfill 9636
squarekg 13199
squarekm 13214
squarekmcapital 13262
squareln 13265
squarelog 13266
squaremg 13198
squaremil 13269
squaremm 13212
squaremsquared 13217
squareorthogonalcrosshatchfill 9638
squareupperlefttolowerrightfill 9639
squareupperrighttolowerleftfill 9640
squareverticalfill 9637
squarewhitewithsmallblack 9635
srsquare 13275
ssabengali 2487
ssadeva 2359
ssagujarati 2743
ssangcieuckorean 12617
ssanghieuhkorean 12677
ssangieungkorean 12672
ssangkiyeokkorean 12594
ssangnieunkorean 12645
ssangpieupkorean 12611
ssangsioskorean 12614
ssangtikeutkorean 12600
ssuperior 63218
sterling 163
sterlingmonospace 65505
strokelongoverlaycmb 822
strokeshortoverlaycmb 821
subset 8834
subsetnotequal 8842
subsetorequal 8838
succeeds 8827
suchthat 8715
suhiragana 12377
sukatakana 12473
sukatakanahalfwidth 65405
sukunarabic 1618
summation 8721
sun 9788
superset 8835
supersetnotequal 8843
supersetorequal 8839
svsquare 13276
syouwaerasquare 13180
t 116
tabengali 2468
tackdown 8868
tackleft 8867
tadeva 2340
tagujarati 2724
tagurmukhi 2596
taharabic 1591
tahfinalarabic 65218
tahinitialarabic 65219
tahiragana 12383
tahmedialarabic 65220
taisyouerasquare 13181
takatakana 12479
takatakanahalfwidth 65408
tatweelarabic 1600
tau 964
tav 1514
tavdages 64330
tavdagesh 64330
tavdageshhebrew 64330
tavhebrew 1514
tbar 359
tbopomofo 12554
tcaron 357
tccurl 680
tcedilla 355
tcheharabic 1670
tchehfinalarabic 64379
tchehinitialarabic 64380
tchehmedialarabic 64381
tcircle 9443
tcircumflexbelow 7793
tcommaaccent 355
tdieresis 7831
tdotaccent 7787
tdotbelow 7789
tecyrillic 1090
tedescendercyrillic 1197
teharabic 1578
tehfinalarabic 65174
tehhahinitialarabic 64674
tehhahisolatedarabic 64524
tehinitialarabic 65175
tehiragana 12390
tehjeeminitialarabic 64673
tehjeemisolatedarabic 64523
tehmarbutaarabic 1577
tehmarbutafinalarabic 65172
tehmedialarabic 65176
tehmeeminitialarabic 64676
tehmeemisolatedarabic 64526
tehnoonfinalarabic 64627
tekatakana 12486
tekatakanahalfwidth 65411
telephone 8481
telephoneblack 9742
telishagedolahebrew 1440
telishaqetanahebrew 1449
tencircle 9321
tenideographicparen 12841
tenparen 9341
tenperiod 9361
tenroman 8569
tesh 679
tet 1496
tetdagesh 64312
tetdageshhebrew 64312
tethebrew 1496
tetsecyrillic 1205
tevirhebrew 1435
tevirlefthebrew 1435
thabengali 2469
thadeva 2341
thagujarati 2725
thagurmukhi 2597
thalarabic 1584
thalfinalarabic 65196
thanthakhatlowleftthai 63640
thanthakhatlowrightthai 63639
thanthakhatthai 3660
thanthakhatupperleftthai 63638
theharabic 1579
thehfinalarabic 65178
thehinitialarabic 65179
thehmedialarabic 65180
thereexists 8707
therefore 8756
theta 952
theta1 977
thetasymbolgreek 977
thieuthacirclekorean 12921
thieuthaparenkorean 12825
thieuthcirclekorean 12907
thieuthkorean 12620
thieuthparenkorean 12811
thirteencircle 9324
thirteenparen 9344
thirteenperiod 9364
thonangmonthothai 3601
thook 429
thophuthaothai 3602
thorn 254
thothahanthai 3607
thothanthai 3600
thothongthai 3608
thothungthai 3606
thousandcyrillic 1154
thousandsseparatorarabic 1644
thousandsseparatorpersian 1644
three 51
threearabic 1635
threebengali 2537
threecircle 9314
threecircleinversesansserif 10124
threedeva 2409
threeeighths 8540
threegujarati 2793
threegurmukhi 2665
threehackarabic 1635
threehangzhou 12323
threeideographicparen 12834
threeinferior 8323
threemonospace 65299
threenumeratorbengali 2550
threeoldstyle 63283
threeparen 9334
threeperiod 9354
threepersian 1779
threequarters 190
threequartersemdash 63198
threeroman 8562
threesuperior 179
threethai 3667
thzsquare 13204
tihiragana 12385
tikatakana 12481
tikatakanahalfwidth 65409
tikeutacirclekorean 12912
tikeutaparenkorean 12816
tikeutcirclekorean 12898
tikeutkorean 12599
tikeutparenkorean 12802
tilde 732
tildebelowcmb 816
tildecmb 771
tildecomb 771
tildedoublecmb 864
tildeoperator 8764
tildeoverlaycmb 820
tildeverticalcmb 830
timescircle 8855
tipehahebrew 1430
tipehalefthebrew 1430
tippigurmukhi 2672
titlocyrilliccmb 1155
tiwnarmenian 1407
tlinebelow 7791
tmonospace 65364
toarmenian 1385
tohiragana 12392
tokatakana 12488
tokatakanahalfwidth 65412
tonebarextrahighmod 741
tonebarextralowmod 745
tonebarhighmod 742
tonebarlowmod 744
tonebarmidmod 743
tonefive 445
tonesix 389
tonetwo 424
tonos 900
tonsquare 13095
topatakthai 3599
tortoiseshellbracketleft 12308
tortoiseshellbracketleftsmall 65117
tortoiseshellbracketleftvertical 65081
tortoiseshellbracketright 12309
tortoiseshellbracketrightsmall 65118
tortoiseshellbracketrightvertical 65082
totaothai 3605
tpalatalhook 427
tparen 9391
trademark 8482
trademarksans 63722
trademarkserif 63195
tretroflexhook 648
triagdn 9660
triaglf 9668
triagrt 9658
triagup 9650
ts 678
tsadi 1510
tsadidagesh 64326
tsadidageshhebrew 64326
tsadihebrew 1510
tsecyrillic 1094
tsere 1461
tsere12 1461
tsere1e 1461
tsere2b 1461
tserehebrew 1461
tserenarrowhebrew 1461
tserequarterhebrew 1461
tserewidehebrew 1461
tshecyrillic 1115
tsuperior 63219
ttabengali 2463
ttadeva 2335
ttagujarati 2719
ttagurmukhi 2591
tteharabic 1657
ttehfinalarabic 64359
ttehinitialarabic 64360
ttehmedialarabic 64361
tthabengali 2464
tthadeva 2336
tthagujarati 2720
tthagurmukhi 2592
tturned 647
tuhiragana 12388
tukatakana 12484
tukatakanahalfwidth 65410
tusmallhiragana 12387
tusmallkatakana 12483
tusmallkatakanahalfwidth 65391
twelvecircle 9323
twelveparen 9343
twelveperiod 9363
twelveroman 8571
twentycircle 9331
twentyhangzhou 21316
twentyparen 9351
twentyperiod 9371
two 50
twoarabic 1634
twobengali 2536
twocircle 9313
twocircleinversesansserif 10123
twodeva 2408
twodotenleader 8229
twodotleader 8229
twodotleadervertical 65072
twogujarati 2792
twogurmukhi 2664
twohackarabic 1634
twohangzhou 12322
twoideographicparen 12833
twoinferior 8322
twomonospace 65298
twonumeratorbengali 2549
twooldstyle 63282
twoparen 9333
twoperiod 9353
twopersian 1778
tworoman 8561
twostroke 443
twosuperior 178
twothai 3666
twothirds 8532
u 117
uacute 250
ubar 649
ubengali 2441
ubopomofo 12584
ubreve 365
ucaron 468
ucircle 9444
ucircumflex 251
ucircumflexbelow 7799
ucyrillic 1091
udattadeva 2385
udblacute 369
udblgrave 533
udeva 2313
udieresis 252
udieresisacute 472
udieresisbelow 7795
udieresiscaron 474
udieresiscyrillic 1265
udieresisgrave 476
udieresismacron 470
udotbelow 7909
ugrave 249
ugujarati 2697
ugurmukhi 2569
uhiragana 12358
uhookabove 7911
uhorn 432
uhornacute 7913
uhorndotbelow 7921
uhorngrave 7915
uhornhookabove 7917
uhorntilde 7919
uhungarumlaut 369
uhungarumlautcyrillic 1267
uinvertedbreve 535
ukatakana 12454
ukatakanahalfwidth 65395
ukcyrillic 1145
ukorean 12636
umacron 363
umacroncyrillic 1263
umacrondieresis 7803
umatragurmukhi 2625
umonospace 65365
underscore 95
underscoredbl 8215
underscoremonospace 65343
underscorevertical 65075
underscorewavy 65103
union 8746
universal 8704
uogonek 371
uparen 9392
upblock 9600
upperdothebrew 1476
upsilon 965
upsilondieresis 971
upsilondieresistonos 944
upsilonlatin 650
upsilontonos 973
uptackbelowcmb 797
uptackmod 724
uragurmukhi 2675
uring 367
ushortcyrillic 1118
usmallhiragana 12357
usmallkatakana 12453
usmallkatakanahalfwidth 65385
ustraightcyrillic 1199
ustraightstrokecyrillic 1201
utilde 361
utildeacute 7801
utildebelow 7797
uubengali 2442
uudeva 2314
uugujarati 2698
uugurmukhi 2570
uumatragurmukhi 2626
uuvowelsignbengali 2498
uuvowelsigndeva 2370
uuvowelsigngujarati 2754
uvowelsignbengali 2497
uvowelsigndeva 2369
uvowelsigngujarati 2753
v 118
vadeva 2357
vagujarati 2741
vagurmukhi 2613
vakatakana 12535
vav 1493
vavdagesh 64309
vavdagesh65 64309
vavdageshhebrew 64309
vavhebrew 1493
vavholam 64331
vavholamhebrew 64331
vavvavhebrew 1520
vavyodhebrew 1521
vcircle 9445
vdotbelow 7807
vecyrillic 1074
veharabic 1700
vehfinalarabic 64363
vehinitialarabic 64364
vehmedialarabic 64365
vekatakana 12537
venus 9792
verticalbar 124
verticallineabovecmb 781
verticallinebelowcmb 809
verticallinelowmod 716
verticallinemod 712
vewarmenian 1406
vhook 651
vikatakana 12536
viramabengali 2509
viramadeva 2381
viramagujarati 2765
visargabengali 2435
visargadeva 2307
visargagujarati 2691
vmonospace 65366
voarmenian 1400
voicediterationhiragana 12446
voicediterationkatakana 12542
voicedmarkkana 12443
voicedmarkkanahalfwidth 65438
vokatakana 12538
vparen 9393
vtilde 7805
vturned 652
vuhiragana 12436
vukatakana 12532
w 119
wacute 7811
waekorean 12633
wahiragana 12431
wakatakana 12527
wakatakanahalfwidth 65436
wakorean 12632
wasmallhiragana 12430
wasmallkatakana 12526
wattosquare 13143
wavedash 12316
wavyunderscorevertical 65076
wawarabic 1608
wawfinalarabic 65262
wawhamzaabovearabic 1572
wawhamzaabovefinalarabic 65158
wbsquare 13277
wcircle 9446
wcircumflex 373
wdieresis 7813
wdotaccent 7815
wdotbelow 7817
wehiragana 12433
weierstrass 8472
wekatakana 12529
wekorean 12638
weokorean 12637
wgrave 7809
whitebullet 9702
whitecircle 9675
whitecircleinverse 9689
whitecornerbracketleft 12302
whitecornerbracketleftvertical 65091
whitecornerbracketright 12303
whitecornerbracketrightvertical 65092
whitediamond 9671
whitediamondcontainingblacksmalldiamond 9672
whitedownpointingsmalltriangle 9663
whitedownpointingtriangle 9661
whiteleftpointingsmalltriangle 9667
whiteleftpointingtriangle 9665
whitelenticularbracketleft 12310
whitelenticularbracketright 12311
whiterightpointingsmalltriangle 9657
whiterightpointingtriangle 9655
whitesmallsquare 9643
whitesmilingface 9786
whitesquare 9633
whitestar 9734
whitetelephone 9743
whitetortoiseshellbracketleft 12312
whitetortoiseshellbracketright 12313
whiteuppointingsmalltriangle 9653
whiteuppointingtriangle 9651
wihiragana 12432
wikatakana 12528
wikorean 12639
wmonospace 65367
wohiragana 12434
wokatakana 12530
wokatakanahalfwidth 65382
won 8361
wonmonospace 65510
wowaenthai 3623
wparen 9394
wring 7832
wsuperior 695
wturned 653
wynn 447
x 120
xabovecmb 829
xbopomofo 12562
xcircle 9447
xdieresis 7821
xdotaccent 7819
xeharmenian 1389
xi 958
xmonospace 65368
xparen 9395
xsuperior 739
y 121
yaadosquare 13134
yabengali 2479
yacute 253
yadeva 2351
yaekorean 12626
yagujarati 2735
yagurmukhi 2607
yahiragana 12420
yakatakana 12516
yakatakanahalfwidth 65428
yakorean 12625
yamakkanthai 3662
yasmallhiragana 12419
yasmallkatakana 12515
yasmallkatakanahalfwidth 65388
yatcyrillic 1123
ycircle 9448
ycircumflex 375
ydieresis 255
ydotaccent 7823
ydotbelow 7925
yeharabic 1610
yehbarreearabic 1746
yehbarreefinalarabic 64431
yehfinalarabic 65266
yehhamzaabovearabic 1574
yehhamzaabovefinalarabic 65162
yehhamzaaboveinitialarabic 65163
yehhamzaabovemedialarabic 65164
yehinitialarabic 65267
yehmedialarabic 65268
yehmeeminitialarabic 64733
yehmeemisolatedarabic 64600
yehnoonfinalarabic 64660
yehthreedotsbelowarabic 1745
yekorean 12630
yen 165
yenmonospace 65509
yeokorean 12629
yeorinhieuhkorean 12678
yerahbenyomohebrew 1450
yerahbenyomolefthebrew 1450
yericyrillic 1099
yerudieresiscyrillic 1273
yesieungkorean 12673
yesieungpansioskorean 12675
yesieungsioskorean 12674
yetivhebrew 1434
ygrave 7923
yhook 436
yhookabove 7927
yiarmenian 1397
yicyrillic 1111
yikorean 12642
yinyang 9775
yiwnarmenian 1410
ymonospace 65369
yod 1497
yoddagesh 64313
yoddageshhebrew 64313
yodhebrew 1497
yodyodhebrew 1522
yodyodpatahhebrew 64287
yohiragana 12424
yoikorean 12681
yokatakana 12520
yokatakanahalfwidth 65430
yokorean 12635
yosmallhiragana 12423
yosmallkatakana 12519
yosmallkatakanahalfwidth 65390
yotgreek 1011
yoyaekorean 12680
yoyakorean 12679
yoyakthai 3618
yoyingthai 3597
yparen 9396
ypogegrammeni 890
ypogegrammenigreekcmb 837
yr 422
yring 7833
ysuperior 696
ytilde 7929
yturned 654
yuhiragana 12422
yuikorean 12684
yukatakana 12518
yukatakanahalfwidth 65429
yukorean 12640
yusbigcyrillic 1131
yusbigiotifiedcyrillic 1133
yuslittlecyrillic 1127
yuslittleiotifiedcyrillic 1129
yusmallhiragana 12421
yusmallkatakana 12517
yusmallkatakanahalfwidth 65389
yuyekorean 12683
yuyeokorean 12682
yyabengali 2527
yyadeva 2399
z 122
zaarmenian 1382
zacute 378
zadeva 2395
zagurmukhi 2651
zaharabic 1592
zahfinalarabic 65222
zahinitialarabic 65223
zahiragana 12374
zahmedialarabic 65224
zainarabic 1586
zainfinalarabic 65200
zakatakana 12470
zaqefgadolhebrew 1429
zaqefqatanhebrew 1428
zarqahebrew 1432
zayin 1494
zayindagesh 64310
zayindageshhebrew 64310
zayinhebrew 1494
zbopomofo 12567
zcaron 382
zcircle 9449
zcircumflex 7825
zcurl 657
zdot 380
zdotaccent 380
zdotbelow 7827
zecyrillic 1079
zedescendercyrillic 1177
zedieresiscyrillic 1247
zehiragana 12380
zekatakana 12476
zero 48
zeroarabic 1632
zerobengali 2534
zerodeva 2406
zerogujarati 2790
zerogurmukhi 2662
zerohackarabic 1632
zeroinferior 8320
zeromonospace 65296
zerooldstyle 63280
zeropersian 1776
zerosuperior 8304
zerothai 3664
zerowidthjoiner 65279
zerowidthnonjoiner 8204
zerowidthspace 8203
zeta 950
zhbopomofo 12563
zhearmenian 1386
zhebrevecyrillic 1218
zhecyrillic 1078
zhedescendercyrillic 1175
zhedieresiscyrillic 1245
zihiragana 12376
zikatakana 12472
zinorhebrew 1454
zlinebelow 7829
zmonospace 65370
zohiragana 12382
zokatakana 12478
zparen 9397
zretroflexhook 656
zstroke 438
zuhiragana 12378
zukatakana 12474
}
}
|
Added src/packages/pdf4tcl091/licence.terms.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | This software is copyrighted by Frank Richter, Jens Pönisch and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the U.S. government, the Government shall have only "Restricted Rights" in the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the terms specified in this license. |
Added src/packages/pdf4tcl091/pdf4tcl.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 |
<html><head>
<title>pdf4tcl - Pdf document generation</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
background: #FFFFFF;
color: black;
}
DIV.doctools {
margin-left: 10%;
margin-right: 10%;
}
DIV.doctools H1,DIV.doctools H2 {
margin-left: -5%;
}
H1, H2, H3, H4 {
margin-top: 1em;
font-family: sans-serif;
font-size: large;
color: #005A9C;
background: transparent;
text-align: left;
}
H1.title {
text-align: center;
}
UL,OL {
margin-right: 0em;
margin-top: 3pt;
margin-bottom: 3pt;
}
UL LI {
list-style: disc;
}
OL LI {
list-style: decimal;
}
DT {
padding-top: 1ex;
}
UL.toc,UL.toc UL, UL.toc UL UL {
font: normal 12pt/14pt sans-serif;
list-style: none;
}
LI.section, LI.subsection {
list-style: none;
margin-left: 0em;
text-indent: 0em;
padding: 0em;
}
PRE {
display: block;
font-family: monospace;
white-space: pre;
margin: 0%;
padding-top: 0.5ex;
padding-bottom: 0.5ex;
padding-left: 1ex;
padding-right: 1ex;
width: 100%;
}
PRE.example {
color: black;
background: #f5dcb3;
border: 1px solid black;
}
UL.requirements LI, UL.syntax LI {
list-style: none;
margin-left: 0em;
text-indent: 0em;
padding: 0em;
}
DIV.synopsis {
color: black;
background: #80ffff;
border: 1px solid black;
font-family: serif;
margin-top: 1em;
margin-bottom: 1em;
}
UL.syntax {
margin-top: 1em;
border-top: 1px solid black;
}
UL.requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<! -- Generated from file 'pdf4tcl.man' by tcllib/doctools with format 'html'
-->
<! -- Copyright © 2007-2016 Peter Spjuth -- Copyright © 2009 Yaroslav Schekin
-->
<! -- CVS: $Id$ pdf4tcl.n
-->
<body><div class="doctools">
<h1 class="title">pdf4tcl(n) 0.9.1 pdf4tcl "Pdf document generation"</h1>
<div id="name" class="section"><h2><a name="name">Name</a></h2>
<p>pdf4tcl - Pdf document generation</p>
</div>
<div id="toc" class="section"><h2><a name="toc">Table Of Contents</a></h2>
<ul class="toc">
<li class="section"><a href="#toc">Table Of Contents</a></li>
<li class="section"><a href="#synopsis">Synopsis</a></li>
<li class="section"><a href="#section1">Description</a></li>
<li class="section"><a href="#section2">COORDINATES</a></li>
<li class="section"><a href="#section3">UNITS</a></li>
<li class="section"><a href="#section4">PUBLIC API</a>
<ul>
<li class="subsection"><a href="#subsection1">PACKAGE COMMANDS</a></li>
<li class="subsection"><a href="#subsection2">OBJECT COMMAND</a></li>
<li class="subsection"><a href="#subsection3">OBJECT METHODS</a></li>
<li class="subsection"><a href="#subsection4">OBJECT METHODS, PAGE</a></li>
<li class="subsection"><a href="#subsection5">OBJECT METHODS, TEXT</a></li>
<li class="subsection"><a href="#subsection6">OBJECT METHODS, IMAGES</a></li>
<li class="subsection"><a href="#subsection7">OBJECT METHODS, COLORS</a></li>
<li class="subsection"><a href="#subsection8">OBJECT METHODS, GRAPHICS</a></li>
<li class="subsection"><a href="#subsection9">OBJECT CONFIGURATION</a></li>
<li class="subsection"><a href="#subsection10">PAGE CONFIGURATION</a></li>
</ul>
</li>
<li class="section"><a href="#section5">EXAMPLES</a></li>
<li class="section"><a href="#see-also">See Also</a></li>
<li class="section"><a href="#keywords">Keywords</a></li>
<li class="section"><a href="#copyright">Copyright</a></li>
</ul>
</div>
<div id="synopsis" class="section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="synopsis">
<ul class="requirements">
<li>package require <b class="pkgname">Tcl 8.6</b></li>
<li>package require <b class="pkgname">pdf4tcl <span class="opt">?0.9.1?</span></b></li>
</ul>
<ul class="syntax">
<li><a href="#1"><b class="cmd">::pdf4tcl::new</b> <i class="arg">objectName</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#2"><b class="cmd">::pdf4tcl::getPaperSize</b> <i class="arg">paper</i></a></li>
<li><a href="#3"><b class="cmd">::pdf4tcl::getPaperSizeList</b></a></li>
<li><a href="#4"><b class="cmd">::pdf4tcl::getPoints</b> <i class="arg">val</i></a></li>
<li><a href="#5"><b class="cmd">::pdf4tcl::loadBaseTrueTypeFont</b> <i class="arg">basefontname</i> <i class="arg">ttf_file_name</i></a></li>
<li><a href="#6"><b class="cmd">::pdf4tcl::createBaseTrueTypeFont</b> <i class="arg">basefontname</i> <i class="arg">ttf_data</i></a></li>
<li><a href="#7"><b class="cmd">::pdf4tcl::loadBaseType1Font</b> <i class="arg">basefontname</i> <i class="arg">AFM_file_name</i> <i class="arg">PFB_file_name</i></a></li>
<li><a href="#8"><b class="cmd">::pdf4tcl::createBaseType1Font</b> <i class="arg">basefontname</i> <i class="arg">AFM_data</i> <i class="arg">PFB_data</i></a></li>
<li><a href="#9"><b class="cmd">::pdf4tcl::createFont</b> <i class="arg">basefontname</i> <i class="arg">fontname</i> <i class="arg">encoding_name</i></a></li>
<li><a href="#10"><b class="cmd">::pdf4tcl::createFontSpecEnc</b> <i class="arg">basefontname</i> <i class="arg">fontname</i> <i class="arg">subset</i></a></li>
<li><a href="#11"><b class="cmd">::pdf4tcl::getFonts</b></a></li>
<li><a href="#12"><b class="cmd">::pdf4tcl::rgb2Cmyk</b> <i class="arg">rgb</i></a></li>
<li><a href="#13"><b class="cmd">::pdf4tcl::cmyk2Rgb</b> <i class="arg">cmyk</i></a></li>
<li><a href="#14"><b class="cmd">::pdf4tcl::catPdf</b> <i class="arg">infile</i> <span class="opt">?<i class="arg">infile ...</i>?</span> <i class="arg">outfile</i></a></li>
<li><a href="#15"><b class="cmd">objectName</b> <b class="method">method</b> <span class="opt">?<i class="arg">arg arg ...</i>?</span></a></li>
<li><a href="#16"><i class="arg">objectName</i> <b class="method">configure</b></a></li>
<li><a href="#17"><i class="arg">objectName</i> <b class="method">configure</b> <i class="arg">option</i></a></li>
<li><a href="#18"><i class="arg">objectName</i> <b class="method">configure</b> <b class="option">-option</b> <i class="arg">value</i>...</a></li>
<li><a href="#19"><i class="arg">objectName</i> <b class="method">cget</b> <b class="option">-option</b></a></li>
<li><a href="#20"><i class="arg">objectName</i> <b class="method">destroy</b></a></li>
<li><a href="#21"><i class="arg">objectName</i> <b class="method">startPage</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#22"><i class="arg">objectName</i> <b class="method">endPage</b></a></li>
<li><a href="#23"><i class="arg">objectName</i> <b class="method">startXObject</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#24"><i class="arg">objectName</i> <b class="method">endXObject</b></a></li>
<li><a href="#25"><i class="arg">objectName</i> <b class="method">finish</b></a></li>
<li><a href="#26"><i class="arg">objectName</i> <b class="method">get</b></a></li>
<li><a href="#27"><i class="arg">objectName</i> <b class="method">write</b> <span class="opt">?<i class="arg">-file filename</i>?</span></a></li>
<li><a href="#28"><i class="arg">objectName</i> <b class="method">addForm</b> <i class="arg">type</i> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#29"><i class="arg">objectName</i> <b class="method">getDrawableArea</b></a></li>
<li><a href="#30"><i class="arg">objectName</i> <b class="method">canvas</b> <i class="arg">path</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#31"><i class="arg">objectName</i> <b class="method">metadata</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#32"><i class="arg">objectName</i> <b class="method">bookmarkAdd</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#33"><i class="arg">objectName</i> <b class="method">embedFile</b> <i class="arg">filename</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#34"><i class="arg">objectName</i> <b class="method">attachFile</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <i class="arg">fid</i> <i class="arg">description</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#35"><i class="arg">objectName</i> <b class="method">setFont</b> <i class="arg">size</i> <span class="opt">?<i class="arg">fontname</i>?</span></a></li>
<li><a href="#36"><i class="arg">objectName</i> <b class="method">getStringWidth</b> <i class="arg">str</i></a></li>
<li><a href="#37"><i class="arg">objectName</i> <b class="method">getCharWidth</b> <i class="arg">char</i></a></li>
<li><a href="#38"><i class="arg">objectName</i> <b class="method">setTextPosition</b> <i class="arg">x</i> <i class="arg">y</i></a></li>
<li><a href="#39"><i class="arg">objectName</i> <b class="method">moveTextPosition</b> <i class="arg">dx</i> <i class="arg">dy</i></a></li>
<li><a href="#40"><i class="arg">objectName</i> <b class="method">getTextPosition</b></a></li>
<li><a href="#41"><i class="arg">objectName</i> <b class="method">newLine</b> <span class="opt">?<i class="arg">spacing</i>?</span></a></li>
<li><a href="#42"><i class="arg">objectName</i> <b class="method">setLineSpacing</b> <i class="arg">spacing</i></a></li>
<li><a href="#43"><i class="arg">objectName</i> <b class="method">getLineSpacing</b></a></li>
<li><a href="#44"><i class="arg">objectName</i> <b class="method">text</b> <i class="arg">str</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#45"><i class="arg">objectName</i> <b class="method">drawTextBox</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <i class="arg">str</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#46"><i class="arg">objectName</i> <b class="method">getFontMetric</b> <i class="arg">metric</i></a></li>
<li><a href="#47"><i class="arg">objectName</i> <b class="method">putImage</b> <i class="arg">id</i> <i class="arg">x</i> <i class="arg">y</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#48"><i class="arg">objectName</i> <b class="method">putRawImage</b> <i class="arg">data</i> <i class="arg">x</i> <i class="arg">y</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#49"><i class="arg">objectName</i> <b class="method">addImage</b> <i class="arg">filename</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#50"><i class="arg">objectName</i> <b class="method">addRawImage</b> <i class="arg">data</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#51"><i class="arg">objectName</i> <b class="method">getImageHeight</b> <i class="arg">id</i></a></li>
<li><a href="#52"><i class="arg">objectName</i> <b class="method">getImageSize</b> <i class="arg">id</i></a></li>
<li><a href="#53"><i class="arg">objectName</i> <b class="method">getImageWidth</b> <i class="arg">id</i></a></li>
<li><a href="#54"><i class="arg">objectName</i> <b class="method">setBgColor</b> <i class="arg">red</i> <i class="arg">green</i> <i class="arg">blue</i></a></li>
<li><a href="#55"><i class="arg">objectName</i> <b class="method">setBgColor</b> <i class="arg">c</i> <i class="arg">m</i> <i class="arg">y</i> <i class="arg">k</i></a></li>
<li><a href="#56"><i class="arg">objectName</i> <b class="method">setFillColor</b> <i class="arg">red</i> <i class="arg">green</i> <i class="arg">blue</i></a></li>
<li><a href="#57"><i class="arg">objectName</i> <b class="method">setFillColor</b> <i class="arg">c</i> <i class="arg">m</i> <i class="arg">y</i> <i class="arg">k</i></a></li>
<li><a href="#58"><i class="arg">objectName</i> <b class="method">setStrokeColor</b> <i class="arg">red</i> <i class="arg">green</i> <i class="arg">blue</i></a></li>
<li><a href="#59"><i class="arg">objectName</i> <b class="method">setStrokeColor</b> <i class="arg">c</i> <i class="arg">m</i> <i class="arg">y</i> <i class="arg">k</i></a></li>
<li><a href="#60"><i class="arg">objectName</i> <b class="method">setLineWidth</b> <i class="arg">width</i></a></li>
<li><a href="#61"><i class="arg">objectName</i> <b class="method">setLineDash</b> <span class="opt">?<i class="arg">on off</i>...?</span> <span class="opt">?<i class="arg">offset</i>?</span></a></li>
<li><a href="#62"><i class="arg">objectName</i> <b class="method">setLineStyle</b> <i class="arg">width</i> <i class="arg">args</i></a></li>
<li><a href="#63"><i class="arg">objectName</i> <b class="method">line</b> <i class="arg">x1</i> <i class="arg">y1</i> <i class="arg">x2</i> <i class="arg">y2</i></a></li>
<li><a href="#64"><i class="arg">objectName</i> <b class="method">curve</b> <i class="arg">x1</i> <i class="arg">y1</i> <i class="arg">x2</i> <i class="arg">y2</i> <i class="arg">x3</i> <i class="arg">y3</i> <span class="opt">?<i class="arg">x4 y4</i>?</span></a></li>
<li><a href="#65"><i class="arg">objectName</i> <b class="method">polygon</b> <span class="opt">?<i class="arg">x y</i>...?</span> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#66"><i class="arg">objectName</i> <b class="method">circle</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">radius</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#67"><i class="arg">objectName</i> <b class="method">oval</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">radiusx</i> <i class="arg">radiusy</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#68"><i class="arg">objectName</i> <b class="method">arc</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">radiusx</i> <i class="arg">radiusy</i> <i class="arg">phi</i> <i class="arg">extend</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#69"><i class="arg">objectName</i> <b class="method">arrow</b> <i class="arg">x1</i> <i class="arg">y1</i> <i class="arg">x2</i> <i class="arg">y2</i> <i class="arg">size</i> <span class="opt">?<i class="arg">angle</i>?</span></a></li>
<li><a href="#70"><i class="arg">objectName</i> <b class="method">rectangle</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
</ul>
</div>
</div>
<div id="section1" class="section"><h2><a name="section1">Description</a></h2>
<p>This package provides a container class for generating <i class="term">pdf</i> documents.</p>
</div>
<div id="section2" class="section"><h2><a name="section2">COORDINATES</a></h2>
<p>All coordinates and distances can be expressed with or without a unit. See
<span class="sectref"><a href="#section3">UNITS</a></span> for valid units.
When the page is configured with <b class="option">-orient</b> set to false, origin is in
the bottom left corner. With <b class="option">-orient</b> true (the default), origin is in the top left
corner.
Origin is displaced to account for margins, i.e. if margins are 100,
the user coordinate (0,0) corresponds to (100,100) on the paper.
Page option <b class="option">-orient</b> can also affect the anchor point for things like
images.</p>
</div>
<div id="section3" class="section"><h2><a name="section3">UNITS</a></h2>
<p>Any coordinates and distances can be expressed with or without an explicit
unit. If no unit is given, the default unit for the document is used.
A unit may be one of
<b class="option">mm</b> (millimeter),
<b class="option">m</b> (millimeter),
<b class="option">cm</b> (centimeter),
<b class="option">c</b> (centimeter),
<b class="option">p</b> (points) or
<b class="option">i</b> (inches).
Commands returning coordinates or distances always return a double value
in the document's default unit.</p>
</div>
<div id="section4" class="section"><h2><a name="section4">PUBLIC API</a></h2>
<div id="subsection1" class="subsection"><h3><a name="subsection1">PACKAGE COMMANDS</a></h3>
<dl class="definitions">
<dt><a name="1"><b class="cmd">::pdf4tcl::new</b> <i class="arg">objectName</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>This command creates a new pdf4tcl object with an associated Tcl
command whose name is <i class="arg">objectName</i>. This <i class="term">object</i> command is
explained in full detail in the sections <span class="sectref"><a href="#subsection2">OBJECT COMMAND</a></span>
and <span class="sectref"><a href="#subsection3">OBJECT METHODS</a></span>. The object command will be created
under the current namespace if the <i class="arg">objectName</i> is not fully
qualified, and in the specified namespace otherwise.
If <i class="arg">objectName</i> is %AUTO% a name will generated.
The return value is the newly created object's name.</p>
<p>The options and their values coming after the name of the object are
used to set the initial configuration of the object.
See <span class="sectref"><a href="#subsection9">OBJECT CONFIGURATION</a></span>.</p></dd>
<dt><a name="2"><b class="cmd">::pdf4tcl::getPaperSize</b> <i class="arg">paper</i></a></dt>
<dd><p>This call returns the size of a named paper type, e.g. "a4".
Paper names are case insensitive.
The argument <i class="arg">paper</i> may also be a two element list
with values as accepted by <b class="cmd">::pdf4tcl::getPoints</b>.
The return value is a list with width and height in points.</p></dd>
<dt><a name="3"><b class="cmd">::pdf4tcl::getPaperSizeList</b></a></dt>
<dd><p>This call returns the list of known paper types.</p></dd>
<dt><a name="4"><b class="cmd">::pdf4tcl::getPoints</b> <i class="arg">val</i></a></dt>
<dd><p>This call translates a measurement to points (1/72 inch).
The format of <i class="arg">val</i> is '<i class="arg">num</i> <span class="opt">?<i class="arg">unit</i>?</span>' where
<i class="arg">num</i> is a valid integer or double. See <span class="sectref"><a href="#section3">UNITS</a></span> for valid
<i class="arg">unit</i>s. If no <i class="arg">unit</i> is given, the value is interpreted
as points.</p></dd>
<dt><a name="5"><b class="cmd">::pdf4tcl::loadBaseTrueTypeFont</b> <i class="arg">basefontname</i> <i class="arg">ttf_file_name</i></a></dt>
<dd><p>This call loads a TTF font from file to be used by any pdf4tcl objects.
The <i class="arg">basefontname</i> is used to reference this font.
To use this base font in documents, a font with some encoding must be
created from it using createFont.
Note that the font loading functions require Tcl 8.5.</p></dd>
<dt><a name="6"><b class="cmd">::pdf4tcl::createBaseTrueTypeFont</b> <i class="arg">basefontname</i> <i class="arg">ttf_data</i></a></dt>
<dd><p>This call creates a base font from TTF binary data.</p></dd>
<dt><a name="7"><b class="cmd">::pdf4tcl::loadBaseType1Font</b> <i class="arg">basefontname</i> <i class="arg">AFM_file_name</i> <i class="arg">PFB_file_name</i></a></dt>
<dd><p>This call loads a Type1 font from two files (.afm and .pfb) to be used by
any pdf4tcl objects. The <i class="arg">basefontname</i> is used to reference this font.
To use this base font in documents, a font with some encoding must be
created from it using createFont.</p></dd>
<dt><a name="8"><b class="cmd">::pdf4tcl::createBaseType1Font</b> <i class="arg">basefontname</i> <i class="arg">AFM_data</i> <i class="arg">PFB_data</i></a></dt>
<dd><p>This call creates a base font from AFM text and PFB binary data.</p></dd>
<dt><a name="9"><b class="cmd">::pdf4tcl::createFont</b> <i class="arg">basefontname</i> <i class="arg">fontname</i> <i class="arg">encoding_name</i></a></dt>
<dd><p>This call creates a font that can be used in documents from a base font.</p>
<pre class="example">
pdf4tcl::loadBaseTrueTypeFont BaseArial "arial.ttf"
pdf4tcl::createFont BaseArial MyArial cp1251
pdf4tcl::loadBaseType1Font BaseType1 "a010013l.afm" "a010013l.pfb"
pdf4tcl::createFont BaseType1 MyType1 cp1251
pdf4tcl::new mypdf -paper a4 -compress 0
mypdf startPage
mypdf setFont 10 MyArial
set txt "\u042D\u0442\u043E \u0442\u0435\u043A\u0441\u0442 \u043D\u0430 \u0440\u0443\u0441\u0441\u043A\u043E\u043C\
\u044F\u0437\u044B\u043A\u0435. This is text in Russian."
mypdf text $txt -bg #CACACA -x 50 -y 100
mypdf setFont 10 MyType1
mypdf text $txt -x 50 -y 200
mypdf write -file fonts.pdf
mypdf destroy
</pre>
</dd>
<dt><a name="10"><b class="cmd">::pdf4tcl::createFontSpecEnc</b> <i class="arg">basefontname</i> <i class="arg">fontname</i> <i class="arg">subset</i></a></dt>
<dd><p>This call creates a font that can be used in documents from a base font.
The <i class="arg">subset</i> must be a list of unicode values.</p></dd>
<dt><a name="11"><b class="cmd">::pdf4tcl::getFonts</b></a></dt>
<dd><p>This call returns the list of known font names, i.e. those accepted in a call
to <b class="method">setFont</b>.
This includes the default fonts and fonts created by e.g.
<b class="cmd">::pdf4tcl::createFont</b>.</p></dd>
<dt><a name="12"><b class="cmd">::pdf4tcl::rgb2Cmyk</b> <i class="arg">rgb</i></a></dt>
<dd><p>This call translates an RGB color value to a CMYK color value.
It is used internally if <b class="option">-cmyk</b> was set at object creation to
translate colors.
You can redefine this procedure to provide your own translation.</p></dd>
<dt><a name="13"><b class="cmd">::pdf4tcl::cmyk2Rgb</b> <i class="arg">cmyk</i></a></dt>
<dd><p>This call translates a CMYK color value to an RGB color value.
It is used internally to translate colors.
You can redefine this procedure to provide your own translation.</p></dd>
<dt><a name="14"><b class="cmd">::pdf4tcl::catPdf</b> <i class="arg">infile</i> <span class="opt">?<i class="arg">infile ...</i>?</span> <i class="arg">outfile</i></a></dt>
<dd><p>This call concatenates PDF files into one.
Currently the implementation limits the PDFs a lot since not all details
are taken care of yet. Straightforward ones like those created with pdf4tcl
or ps2pdf should work mostly ok.</p></dd>
</dl>
</div>
<div id="subsection2" class="subsection"><h3><a name="subsection2">OBJECT COMMAND</a></h3>
<p>All commands created by <b class="cmd">::pdf4tcl::new</b> have the following
general form and may be used to invoke various operations on their
pdf object.</p>
<dl class="definitions">
<dt><a name="15"><b class="cmd">objectName</b> <b class="method">method</b> <span class="opt">?<i class="arg">arg arg ...</i>?</span></a></dt>
<dd><p>The method <b class="method">method</b> and its <i class="arg">arg</i>'uments determine the exact
behavior of the command. See section <span class="sectref"><a href="#subsection3">OBJECT METHODS</a></span> for
the detailed specifications.</p></dd>
</dl>
</div>
<div id="subsection3" class="subsection"><h3><a name="subsection3">OBJECT METHODS</a></h3>
<dl class="definitions">
<dt><a name="16"><i class="arg">objectName</i> <b class="method">configure</b></a></dt>
<dd><p>The method returns a list of all known options and their current
values when called without any arguments.</p></dd>
<dt><a name="17"><i class="arg">objectName</i> <b class="method">configure</b> <i class="arg">option</i></a></dt>
<dd><p>The method behaves like the method <b class="method">cget</b> when called with a
single argument and returns the value of the option specified by said
argument.</p></dd>
<dt><a name="18"><i class="arg">objectName</i> <b class="method">configure</b> <b class="option">-option</b> <i class="arg">value</i>...</a></dt>
<dd><p>The method reconfigures the specified <b class="option">option</b>s of the object,
setting them to the associated <i class="arg">value</i>s, when called with an even
number of arguments, at least two.</p>
<p>The legal options are described in the section
<span class="sectref"><a href="#subsection9">OBJECT CONFIGURATION</a></span>.</p></dd>
<dt><a name="19"><i class="arg">objectName</i> <b class="method">cget</b> <b class="option">-option</b></a></dt>
<dd><p>This method expects a legal configuration option as argument and will
return the current value of that option for the object the method was
invoked for.</p>
<p>The legal configuration options are described in section
<span class="sectref"><a href="#subsection9">OBJECT CONFIGURATION</a></span>.</p></dd>
<dt><a name="20"><i class="arg">objectName</i> <b class="method">destroy</b></a></dt>
<dd><p>This method destroys the object it is invoked for.
If the <b class="option">-file</b> option was given at object creation,
the output file will be finished and closed.</p></dd>
<dt><a name="21"><i class="arg">objectName</i> <b class="method">startPage</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>This method starts a new page in the document. The page will have the
default page settings for the document unless overridden by <i class="arg">option</i>.
See <span class="sectref"><a href="#subsection10">PAGE CONFIGURATION</a></span> for page settings.
This will end any ongoing page.</p></dd>
<dt><a name="22"><i class="arg">objectName</i> <b class="method">endPage</b></a></dt>
<dd><p>This method ends a page in the document. It is normally not needed since
it is implied by e.g. <b class="method">startPage</b> and <b class="method">finish</b>. However,
if the document is built page by page in e.g. an event driven environment
it can be good to call <b class="method">endPage</b> explicitly to have all the page's
work finished before reentering the event loop.</p></dd>
<dt><a name="23"><i class="arg">objectName</i> <b class="method">startXObject</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>This method starts a new XObject in the document. An XObject is a reusable
drawing object and behaves just like a page where you can draw any graphics.
An XObject must be created between pages and this method will end any ongoing
page. The return value is an id that can be used with <b class="method">putImage</b> to draw
it on the current page or with some forms.
All page settings (<span class="sectref"><a href="#subsection10">PAGE CONFIGURATION</a></span>) are
valid when creating an XObject. Default options are
<b class="option">-paper</b> = {100p 100p}, <b class="option">-landscape</b> = 0,
<b class="option">-orient</b> = document default, <b class="option">-margin</b>= 0.</p>
<dl class="options">
<dt><b class="option">-noimage</b> <i class="arg">bool</i></dt>
<dd><p>If this is set the XObject is not added to the image resource set and cannot
be used with putImage, only in forms. The XObject also gets access to resources
which is needed to use e.g. fonts within the XObject. This behaviour has shown
to be PDF reader dependent, and it is currently not known if this can be
made to work better.</p></dd>
</dl></dd>
<dt><a name="24"><i class="arg">objectName</i> <b class="method">endXObject</b></a></dt>
<dd><p>This method ends an XObject definition. It works just like <b class="method">endPage</b>.</p></dd>
<dt><a name="25"><i class="arg">objectName</i> <b class="method">finish</b></a></dt>
<dd><p>This method ends the document.
This will do <b class="method">endPage</b> if needed.
If the <b class="option">-file</b> option was given at object creation,
the output file will be finished and closed.</p></dd>
<dt><a name="26"><i class="arg">objectName</i> <b class="method">get</b></a></dt>
<dd><p>This method returns the generated pdf.
This will do <b class="method">endPage</b> and <b class="method">finish</b> if needed.
If the <b class="option">-file</b> option was given at object creation, nothing is returned.</p></dd>
<dt><a name="27"><i class="arg">objectName</i> <b class="method">write</b> <span class="opt">?<i class="arg">-file filename</i>?</span></a></dt>
<dd><p>This method writes the generated pdf to the given <i class="arg">filename</i>.
If no <i class="arg">filename</i> is given, it is written to stdout.
This will do <b class="method">endPage</b> and <b class="method">finish</b> if needed.
If the <b class="option">-file</b> option was given at object creation, an empty file
is created.</p></dd>
<dt><a name="28"><i class="arg">objectName</i> <b class="method">addForm</b> <i class="arg">type</i> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Add an interactive form at the given position and size. Supported types are <i class="arg">text</i> and <i class="arg">checkbutton</i>.
Option <i class="arg">-init</i> gives an initial value for the form.
For a checkbutton, options <i class="arg">-on</i> and <i class="arg">-off</i> can be given an xobject (created with <b class="method">startXObject</b>) to control its appearance.</p></dd>
</dl>
</div>
<div id="subsection4" class="subsection"><h3><a name="subsection4">OBJECT METHODS, PAGE</a></h3>
<dl class="definitions">
<dt><a name="29"><i class="arg">objectName</i> <b class="method">getDrawableArea</b></a></dt>
<dd><p>This method returns the size of the available area on the page,
after removing margins. The return value is a list of width and height,
in the document's default unit.</p></dd>
<dt><a name="30"><i class="arg">objectName</i> <b class="method">canvas</b> <i class="arg">path</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draws the contents of the canvas widget <i class="arg">path</i> on the current page.
Option <i class="arg">-bbox</i> gives the area of the canvas to be drawn. Default is
the entire contents, i.e. the result of $path bbox all.
Options <i class="arg">-x</i>, <i class="arg">-y</i>, <i class="arg">-width</i> and <i class="arg">-height</i> defines
an area on the page where to place the contents. Default area starts at origin,
stretching over the drawable area of the page.
Option <i class="arg">-sticky</i> defines how to place the contents within the area.
The area is always filled in one direction, preserving aspect ratio, unless
<i class="arg">-sticky</i> defines that the other direction should be filled too. Default
<i class="arg">-sticky</i> is <i class="arg">nw</i>.
If option <i class="arg">-bg</i> is true, a background is drawn in the canvas' background
color. Otherwise only objects are drawn. Default is false.
Option <i class="arg">-fontmap</i> gives a dictionary mapping from Tk font names to PDF font names.</p>
<p>Fonts:</p>
<p>If no font mapping is given, fonts for text items are limited to PDF's
builtins, i.e. Helvetica, Times and Courier. A guess is made to chose which
one to use to get a reasonable display on the page.</p>
<p>An element in a font mapping must exactly match the -font option in the
text item. The corresponding mapping value is a PDF font family, e.g. one
created by <b class="cmd">pdf4tcl::createFont</b>. It is recommended to use named fonts
in Tk to control the font mapping in detail.</p>
<p>Limitations:</p>
<p>Option -splinesteps for lines/polygons is ignored.</p>
<p>Stipple offset is limited. The form x,y should work.</p>
<p>Window items require Img to be present and must be visible on-screen when
the canvas is drawn.</p></dd>
<dt><a name="31"><i class="arg">objectName</i> <b class="method">metadata</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>This method sets metadata fields for this document. Supported field options are
<i class="arg">-author</i>, <i class="arg">-creator</i>, <i class="arg">-keywords</i>, <i class="arg">-producer</i>, <i class="arg">-subject</i>,
<i class="arg">-title</i>, <i class="arg">-creationdate</i> and <i class="arg">-format</i>.</p></dd>
<dt><a name="32"><i class="arg">objectName</i> <b class="method">bookmarkAdd</b> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Add a bookmark on the current page.</p>
<dl class="options">
<dt><b class="option">-title</b> <i class="arg">text</i></dt>
<dd><p>Set the text of the bookmark.</p></dd>
<dt><b class="option">-level</b> <i class="arg">level</i></dt>
<dd><p>Set the level of the bookmark. Default is 0.</p></dd>
<dt><b class="option">-closed</b> <i class="arg">boolean</i></dt>
<dd><p>Select if the bookmark is closed by default. Default is false, i.e. not closed.</p></dd>
</dl></dd>
<dt><a name="33"><i class="arg">objectName</i> <b class="method">embedFile</b> <i class="arg">filename</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>This method embeds a file into the PDF stream. File data is considered binary. Returns an id that can be used in subsequent calls to <b class="method">attachFile</b>.</p>
<dl class="options">
<dt><b class="option">-id</b> <i class="arg">id</i></dt>
<dd><p>Explicitly select an id for the file. The <i class="arg">id</i> must be unique within the document.</p></dd>
<dt><b class="option">-contents</b> <i class="arg">data</i></dt>
<dd><p>Provides the file contents instead of reading the actual file.</p></dd>
</dl></dd>
<dt><a name="34"><i class="arg">objectName</i> <b class="method">attachFile</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <i class="arg">fid</i> <i class="arg">description</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>This method adds a file annotation to the current page. The location of the file annotation is given by the coordinates <i class="arg">x</i>, <i class="arg">y</i>, <i class="arg">width</i>, <i class="arg">height</i>. The annotation is rendered by default as a paperclip icon, which allows the extraction of the attached file. An <i class="arg">fid</i> from a previous call to <b class="method">embedFile</b> must be set as well as a <i class="arg">description</i>, which is shown by the PDF viewer upon activating the annotation.</p>
<dl class="options">
<dt><b class="option">-icon</b> <i class="arg">icon</i></dt>
<dd><p>Controls the appearance of the attachment. Valid values are Paperclip, Tag, Graph, or PushPin. Default value is Paperclip.</p></dd>
</dl>
<pre class="example">
set fid [$pdfobject embedFile "data.txt" -contents "This should be stored in the file."]
$pdfobject attachFile 0 0 100 100 $fid "This is the description"
</pre>
</dd>
</dl>
</div>
<div id="subsection5" class="subsection"><h3><a name="subsection5">OBJECT METHODS, TEXT</a></h3>
<dl class="definitions">
<dt><a name="35"><i class="arg">objectName</i> <b class="method">setFont</b> <i class="arg">size</i> <span class="opt">?<i class="arg">fontname</i>?</span></a></dt>
<dd><p>This method sets the font used by text drawing routines. If <i class="arg">fontname</i>
is not provided, the previously set <i class="arg">fontname</i> is kept.</p></dd>
<dt><a name="36"><i class="arg">objectName</i> <b class="method">getStringWidth</b> <i class="arg">str</i></a></dt>
<dd><p>This method returns the width of a string under the current font.</p></dd>
<dt><a name="37"><i class="arg">objectName</i> <b class="method">getCharWidth</b> <i class="arg">char</i></a></dt>
<dd><p>This method returns the width of a character under the current font.</p></dd>
<dt><a name="38"><i class="arg">objectName</i> <b class="method">setTextPosition</b> <i class="arg">x</i> <i class="arg">y</i></a></dt>
<dd><p>Set coordinate for next text command.</p></dd>
<dt><a name="39"><i class="arg">objectName</i> <b class="method">moveTextPosition</b> <i class="arg">dx</i> <i class="arg">dy</i></a></dt>
<dd><p>Increment position by <i class="arg">dx</i>, <i class="arg">dy</i> for the next text command.</p></dd>
<dt><a name="40"><i class="arg">objectName</i> <b class="method">getTextPosition</b></a></dt>
<dd><p>This method returns the current text coordinate.</p></dd>
<dt><a name="41"><i class="arg">objectName</i> <b class="method">newLine</b> <span class="opt">?<i class="arg">spacing</i>?</span></a></dt>
<dd><p>Moves text coordinate down and resets x to where the latest
<b class="method">setTextPosition</b> was. The number of lines to move down can
be set by <i class="arg">spacing</i>. This may be any real number, including negative,
and defaults to the value set by <b class="method">setLineSpacing</b>.</p></dd>
<dt><a name="42"><i class="arg">objectName</i> <b class="method">setLineSpacing</b> <i class="arg">spacing</i></a></dt>
<dd><p>Set the default line spacing used be e.g. <b class="method">newLine</b>. Initially
the spacing is 1.</p></dd>
<dt><a name="43"><i class="arg">objectName</i> <b class="method">getLineSpacing</b></a></dt>
<dd><p>Get the current default line spacing.</p></dd>
<dt><a name="44"><i class="arg">objectName</i> <b class="method">text</b> <i class="arg">str</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw text at the position defined by setTextPosition using the font defined by
setFont.</p>
<dl class="options">
<dt><b class="option">-align</b> <i class="arg">left|right|center</i> (default left)</dt>
<dd></dd>
<dt><b class="option">-angle</b> <i class="arg">degrees</i> (default 0) - Orient string at the specified angle.</dt>
<dd></dd>
<dt><b class="option">-xangle</b> <i class="arg">degrees</i> (default 0)</dt>
<dd></dd>
<dt><b class="option">-yangle</b> <i class="arg">degrees</i> (default 0) - Apply x or y shear to the text.</dt>
<dd></dd>
<dt><b class="option">-x</b> <i class="arg">x</i> (default 0)</dt>
<dd></dd>
<dt><b class="option">-y</b> <i class="arg">y</i> (default 0) - Allow the text to be positioned without setTextPosition.</dt>
<dd></dd>
<dt><b class="option">-bg</b> <i class="arg">bool</i> (default 0)</dt>
<dd></dd>
<dt><b class="option">-background</b> <i class="arg">bool</i> (default 0)</dt>
<dd></dd>
<dt><b class="option">-fill</b> <i class="arg">bool</i> (default 0) </dt>
<dd><p>Any of <b class="option">-bg</b>, <b class="option">-background</b> or <b class="option">-fill</b> cause the text to be drawn
on a background whose color is set by setBgColor.</p></dd>
</dl></dd>
<dt><a name="45"><i class="arg">objectName</i> <b class="method">drawTextBox</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <i class="arg">str</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw the text string <i class="arg">str</i> wrapping at blanks and tabs so that it fits within the box defined
by <i class="arg">x</i>, <i class="arg">y</i>, <i class="arg">width</i> and <i class="arg">height</i>. An embedded newline in <i class="arg">str</i> causes
a new line in the output. If <i class="arg">str</i> is too long to fit in the specified box, it is truncated and the unused remainder is returned.</p>
<dl class="options">
<dt><b class="option">-align</b> <i class="arg">left|right|center|justify</i></dt>
<dd><p>Specifies the justification. If not given, the text is left justified.</p></dd>
<dt><b class="option">-linesvar</b> <i class="arg">var</i></dt>
<dd><p>Gives the name of a variable which will be set to the number of lines written.</p></dd>
<dt><b class="option">-dryrun</b> <i class="arg">bool</i></dt>
<dd><p>If true, no changes will be made to the PDF document. The return
value and <b class="option">-linesvar</b> gives information of what would happen
with the given text.</p></dd>
</dl></dd>
<dt><a name="46"><i class="arg">objectName</i> <b class="method">getFontMetric</b> <i class="arg">metric</i></a></dt>
<dd><p>Get information about current font. The available <i class="arg">metric</i>s are
<b class="option">ascend</b>, <b class="option">descend</b>, <b class="option">fixed</b>, <b class="option">bboxb</b>,
<b class="option">bboxt</b> and <b class="option">height</b>.</p>
<dl class="options">
<dt><b class="option">ascend</b></dt>
<dd><p>Top of typical glyph, displacement from anchor point. Typically a positive number since it is above the anchor point.</p></dd>
<dt><b class="option">descend</b></dt>
<dd><p>Bottom of typical glyph, displacement from anchor point. Typically a negative number since it is below the anchor point.</p></dd>
<dt><b class="option">fixed</b></dt>
<dd><p>Boolean which is true if this is a fixed width font.</p></dd>
<dt><b class="option">bboxb</b></dt>
<dd><p>Bottom of Bounding Box, displacement from anchor point. Typically a negative number since it is below the anchor point.</p></dd>
<dt><b class="option">bboxt</b></dt>
<dd><p>Top of Bounding Box, displacement from anchor point. Typically a positive number since it is above the anchor point.</p></dd>
<dt><b class="option">height</b></dt>
<dd><p>Height of font's Bounding Box.</p></dd>
</dl></dd>
</dl>
</div>
<div id="subsection6" class="subsection"><h3><a name="subsection6">OBJECT METHODS, IMAGES</a></h3>
<p>A limited set of image formats are directly understood by pdf4tcl, currently
JPEG and some PNG formats. To use unsupported formats, use Tk and the Img
package to load and dump images to raw format which can be fed to
<b class="method">putRawImage</b> and <b class="method">addRawImage</b>.</p>
<dl class="definitions">
<dt><a name="47"><i class="arg">objectName</i> <b class="method">putImage</b> <i class="arg">id</i> <i class="arg">x</i> <i class="arg">y</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Put an image on the current page. The image must have been added previously by
<b class="method">addImage</b> or <b class="method">addRawImage</b>. The <i class="arg">id</i> is the one returned
from the add command.</p>
<dl class="options">
<dt><b class="option">-angle</b> <i class="arg">degrees</i></dt>
<dd><p>Rotate image <i class="arg">degrees</i> counterclockwise around the anchor point.
Default is 0.</p></dd>
<dt><b class="option">-anchor</b> <i class="arg">anchor</i></dt>
<dd><p>Set the anchor point (nw, n, ne etc.) of the image.
Coordinates <i class="arg">x</i> and <i class="arg">y</i> places the anchor point, and any rotation is around the anchor point.
Default is nw if <b class="option">-orient</b> is true, otherwise se.</p></dd>
<dt><b class="option">-height</b> <i class="arg">height</i></dt>
<dd><p>Set the height of the image. Default height is one point per pixel. If <i class="arg">width</i> is set but not <i class="arg">height</i>,
the height is selected to preserve the aspect ratio of the image.</p></dd>
<dt><b class="option">-width</b> <i class="arg">width</i></dt>
<dd><p>Set the width of the image. Default width is one point per pixel.
If <i class="arg">height</i> is set but not <i class="arg">width</i>, the width is selected to
preserve the aspect ratio of the image.</p></dd>
</dl></dd>
<dt><a name="48"><i class="arg">objectName</i> <b class="method">putRawImage</b> <i class="arg">data</i> <i class="arg">x</i> <i class="arg">y</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Put an image on the current page. Works like <b class="method">putImage</b> except that the raw image data is given directly.</p>
<dl class="options">
<dt><b class="option">-compress</b> <i class="arg">boolean</i></dt>
<dd><p>Raw data will be zlib compressed if this option is set to true.
Default value is the document's <b class="option">-compress</b> setting.</p></dd>
</dl>
<pre class="example">
image create photo img1 -file image.gif
set imgdata [img1 data]
mypdf putRawImage $imgdata 60 20 -height 40
</pre>
</dd>
<dt><a name="49"><i class="arg">objectName</i> <b class="method">addImage</b> <i class="arg">filename</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Add an image to the document. Returns an id that can be used in subsequent
calls to <b class="method">putImage</b>. Supported formats are PNG and JPEG.</p>
<dl class="options">
<dt><b class="option">-id</b> <i class="arg">id</i></dt>
<dd><p>Explicitly select an id for the image. The <i class="arg">id</i> must be unique within the document.</p></dd>
<dt><b class="option">-type</b> <i class="arg">name</i></dt>
<dd><p>Set the image type. This can usually be deduced from the file name, this
option helps when that is not possible. This can be either "png" or "jpeg".</p></dd>
</dl></dd>
<dt><a name="50"><i class="arg">objectName</i> <b class="method">addRawImage</b> <i class="arg">data</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Add an image to the document. Works like <b class="method">addImage</b> except that the raw image data is given directly.</p>
<dl class="options">
<dt><b class="option">-compress</b> <i class="arg">boolean</i></dt>
<dd><p>Raw data will be zlib compressed if this option is set to true.
Default value is the document's <b class="option">-compress</b> setting.</p></dd>
</dl>
<pre class="example">
image create photo img1 -file image.gif
set imgdata [img1 data]
set id [mypdf addRawImage $imgdata]
mypdf putImage $id 20 60 -width 100
</pre>
</dd>
<dt><a name="51"><i class="arg">objectName</i> <b class="method">getImageHeight</b> <i class="arg">id</i></a></dt>
<dd><p>This method returns the height of the image identified by <i class="arg">id</i>.</p></dd>
<dt><a name="52"><i class="arg">objectName</i> <b class="method">getImageSize</b> <i class="arg">id</i></a></dt>
<dd><p>This method returns the size of the image identified by <i class="arg">id</i>. The
return value is a list of width and height.</p></dd>
<dt><a name="53"><i class="arg">objectName</i> <b class="method">getImageWidth</b> <i class="arg">id</i></a></dt>
<dd><p>This method returns the width of the image identified by <i class="arg">id</i>.</p></dd>
</dl>
</div>
<div id="subsection7" class="subsection"><h3><a name="subsection7">OBJECT METHODS, COLORS</a></h3>
<p>Colors can be expressed in various formats. First, as a three element list
of values in the range 0.0 to 1.0. Second, in the format #XXXXXX where
the Xes are two hexadecimal digits per color value. Third, if Tk is available,
any color accepted by winfo rgb is accepted.</p>
<dl class="definitions">
<dt><a name="54"><i class="arg">objectName</i> <b class="method">setBgColor</b> <i class="arg">red</i> <i class="arg">green</i> <i class="arg">blue</i></a></dt>
<dd><p>Sets the background color for text operations where -bg is true.</p></dd>
<dt><a name="55"><i class="arg">objectName</i> <b class="method">setBgColor</b> <i class="arg">c</i> <i class="arg">m</i> <i class="arg">y</i> <i class="arg">k</i></a></dt>
<dd><p>Alternative calling form, to set color in CMYK color space.</p></dd>
<dt><a name="56"><i class="arg">objectName</i> <b class="method">setFillColor</b> <i class="arg">red</i> <i class="arg">green</i> <i class="arg">blue</i></a></dt>
<dd><p>Sets the fill color for graphics operations, and the foreground color for
text operations.</p></dd>
<dt><a name="57"><i class="arg">objectName</i> <b class="method">setFillColor</b> <i class="arg">c</i> <i class="arg">m</i> <i class="arg">y</i> <i class="arg">k</i></a></dt>
<dd><p>Alternative calling form, to set color in CMYK color space.</p></dd>
<dt><a name="58"><i class="arg">objectName</i> <b class="method">setStrokeColor</b> <i class="arg">red</i> <i class="arg">green</i> <i class="arg">blue</i></a></dt>
<dd><p>Sets the stroke color for graphics operations.</p></dd>
<dt><a name="59"><i class="arg">objectName</i> <b class="method">setStrokeColor</b> <i class="arg">c</i> <i class="arg">m</i> <i class="arg">y</i> <i class="arg">k</i></a></dt>
<dd><p>Alternative calling form, to set color in CMYK color space.</p></dd>
</dl>
</div>
<div id="subsection8" class="subsection"><h3><a name="subsection8">OBJECT METHODS, GRAPHICS</a></h3>
<dl class="definitions">
<dt><a name="60"><i class="arg">objectName</i> <b class="method">setLineWidth</b> <i class="arg">width</i></a></dt>
<dd><p>Sets the width for subsequent line drawing.
Line width must be a non-negative number.</p></dd>
<dt><a name="61"><i class="arg">objectName</i> <b class="method">setLineDash</b> <span class="opt">?<i class="arg">on off</i>...?</span> <span class="opt">?<i class="arg">offset</i>?</span></a></dt>
<dd><p>Sets the dash pattern for subsequent line drawing.
Offset and any elements in the dash pattern must be non-negative numbers.
<em>on off</em> is a series of pairs of numbers which define a
dash pattern. The 1st, 3rd ... numbers give units to paint,
the 2nd, 4th ... numbers specify unpainted gaps. When all numbers have
been used, the pattern is re-started from the beginning.
An optional last argument sets the dash offset, which defaults to 0.
Calling <b class="method">setLineDash</b> with no arguments resets the dash pattern
to a solid line.</p></dd>
<dt><a name="62"><i class="arg">objectName</i> <b class="method">setLineStyle</b> <i class="arg">width</i> <i class="arg">args</i></a></dt>
<dd><p>Sets the width and dash pattern for subsequent line drawing.
Line width and any elements in the dash pattern must be non-negative numbers.
<em>args</em> is a series of numbers (not a tcl list) which define a
dash pattern. The 1st, 3rd ... numbers give units to paint,
the 2nd, 4th ... numbers specify unpainted gaps. When all numbers have
been used, the pattern is re-started from the beginning.
This method do not support offsetting the pattern, see <b class="method">setLineDash</b>
for a more complete method.</p></dd>
<dt><a name="63"><i class="arg">objectName</i> <b class="method">line</b> <i class="arg">x1</i> <i class="arg">y1</i> <i class="arg">x2</i> <i class="arg">y2</i></a></dt>
<dd><p>Draws a line from <em>x1,</em> <em>y1</em> to <em>x2,</em> <em>y2</em></p></dd>
<dt><a name="64"><i class="arg">objectName</i> <b class="method">curve</b> <i class="arg">x1</i> <i class="arg">y1</i> <i class="arg">x2</i> <i class="arg">y2</i> <i class="arg">x3</i> <i class="arg">y3</i> <span class="opt">?<i class="arg">x4 y4</i>?</span></a></dt>
<dd><p>If <em>x4,</em> <em>y4</em> are present, draws a cubic bezier from <em>x1,</em>
<em>y1</em> to <em>x4,</em> <em>y4</em> with control points <em>x2,</em> <em>y2</em> and
<em>x3,</em> <em>y3</em>. Otherwise draws a quadratic bezier from <em>x1,</em>
<em>y1</em> to <em>x3,</em> <em>y3</em>, with control point <em>x2,</em>
<em>y2</em></p></dd>
<dt><a name="65"><i class="arg">objectName</i> <b class="method">polygon</b> <span class="opt">?<i class="arg">x y</i>...?</span> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw a polygon. There must be at least 3 points.
The polygon is closed back to the first coordinate.</p>
<dl class="options">
<dt><b class="option">-filled</b> <i class="arg">bool</i> (default 0)</dt>
<dd><p>Fill the polygon.</p></dd>
<dt><b class="option">-stroke</b> <i class="arg">bool</i> (default 1)</dt>
<dd><p>Draw an outline of the polygon.</p></dd>
</dl></dd>
<dt><a name="66"><i class="arg">objectName</i> <b class="method">circle</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">radius</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw a circle at the given center coordinates.</p>
<dl class="options">
<dt><b class="option">-filled</b> <i class="arg">bool</i> (default 0)</dt>
<dd><p>Fill the circle.</p></dd>
<dt><b class="option">-stroke</b> <i class="arg">bool</i> (default 1)</dt>
<dd><p>Draw an outline of the circle.</p></dd>
</dl></dd>
<dt><a name="67"><i class="arg">objectName</i> <b class="method">oval</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">radiusx</i> <i class="arg">radiusy</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw an oval at the given center coordinates.</p>
<dl class="options">
<dt><b class="option">-filled</b> <i class="arg">bool</i> (default 0)</dt>
<dd><p>Fill the oval.</p></dd>
<dt><b class="option">-stroke</b> <i class="arg">bool</i> (default 1)</dt>
<dd><p>Draw an outline of the oval.</p></dd>
</dl></dd>
<dt><a name="68"><i class="arg">objectName</i> <b class="method">arc</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">radiusx</i> <i class="arg">radiusy</i> <i class="arg">phi</i> <i class="arg">extend</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw an arc, following the given oval. The arc starts at angle <i class="arg">phi</i>, given in degrees starting in the "east" direction, counting counter clockwise. The arc extends <i class="arg">extend</i> degrees.</p>
<dl class="options">
<dt><b class="option">-filled</b> <i class="arg">bool</i> (default 0)</dt>
<dd><p>Fill the arc.</p></dd>
<dt><b class="option">-stroke</b> <i class="arg">bool</i> (default 1)</dt>
<dd><p>Draw an outline of the arc.</p></dd>
<dt><b class="option">-style</b> <i class="arg">arc|pieslice|chord</i> (default <i class="arg">arc</i>)</dt>
<dd><p>Defines the style of the arc. An <i class="arg">arc</i> draws the perimeter of the arc and is never filled. A <i class="arg">pieslice</i> closes the arc with lines to the center of the oval. A <i class="arg">chord</i> closes the arc directly.</p></dd>
</dl></dd>
<dt><a name="69"><i class="arg">objectName</i> <b class="method">arrow</b> <i class="arg">x1</i> <i class="arg">y1</i> <i class="arg">x2</i> <i class="arg">y2</i> <i class="arg">size</i> <span class="opt">?<i class="arg">angle</i>?</span></a></dt>
<dd><p>Draw an arrow. Default <i class="arg">angle</i> is 20 degrees.</p></dd>
<dt><a name="70"><i class="arg">objectName</i> <b class="method">rectangle</b> <i class="arg">x</i> <i class="arg">y</i> <i class="arg">width</i> <i class="arg">height</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></dt>
<dd><p>Draw a rectangle.</p>
<dl class="options">
<dt><b class="option">-filled</b> <i class="arg">bool</i> (default 0)</dt>
<dd><p>Fill the rectangle.</p></dd>
<dt><b class="option">-stroke</b> <i class="arg">bool</i> (default 1)</dt>
<dd><p>Draw an outline of the rectangle.</p></dd>
</dl></dd>
</dl>
</div>
<div id="subsection9" class="subsection"><h3><a name="subsection9">OBJECT CONFIGURATION</a></h3>
<p>All pdf4tcl objects understand the options from <span class="sectref"><a href="#subsection10">PAGE CONFIGURATION</a></span>,
which defines default page settings when used with a pdf4tcl object.
The objects also understand the following configuration options:</p>
<dl class="options">
<dt><b class="option">-cmyk</b> <i class="arg">boolean</i></dt>
<dd><p>If true, pdf4tcl will try to generate the document in CMYK color space.
See <b class="cmd">::pdf4tcl::rgb2Cmyk</b> for a way to control color translation.
Default value is false.
This option can only be set at object creation.</p></dd>
<dt><b class="option">-compress</b> <i class="arg">boolean</i></dt>
<dd><p>Pages will be zlib compressed if this option is set to true.
Default value is true.
This option can only be set at object creation.</p></dd>
<dt><b class="option">-file</b> <i class="arg">filename</i></dt>
<dd><p>Continuously write pdf to <i class="arg">filename</i> instead of storing it
in memory.
This option can only be set at object creation.</p></dd>
<dt><b class="option">-unit</b> <i class="arg">defaultunit</i></dt>
<dd><p>Defines default unit for coordinates and distances. Any value given without
a unit is interpreted using this unit.
See <span class="sectref"><a href="#section3">UNITS</a></span> for valid units.
Default value is "p" as in points.
This option can only be set at object creation.</p></dd>
</dl>
</div>
<div id="subsection10" class="subsection"><h3><a name="subsection10">PAGE CONFIGURATION</a></h3>
<dl class="options">
<dt><b class="option">-paper</b> <i class="arg">name</i></dt>
<dd><p>The argument of this option defines the paper size.
The paper size may be a string like "a4", where valid values
are available through <b class="cmd">::pdf4tcl::getPaperSizeList</b>.
Paper size may also be a two element list specifying width and height.</p>
<p>The default value of this option is "a4".</p></dd>
<dt><b class="option">-landscape</b> <i class="arg">boolean</i></dt>
<dd><p>If true, paper width and height are switched.</p>
<p>The default value of this option is false.</p></dd>
<dt><b class="option">-orient</b> <i class="arg">boolean</i></dt>
<dd><p>This sets the orientation of the y axis of the coordinate system.
With <b class="option">-orient</b> false, origin is in the bottom left corner.
With <b class="option">-orient</b> true, origin is in the top left corner.</p>
<p>The default value of this option is true.</p></dd>
<dt><b class="option">-margin</b> <i class="arg">values</i></dt>
<dd><p>The margin is a one, two or four element list of margins.
For one element, it specifies all margins.
Two elements specify left/right and top/bottom.
Four elements specify left, right, top and bottom.</p>
<p>The default value of this option is zero.</p></dd>
<dt><b class="option">-rotate</b> <i class="arg">angle</i></dt>
<dd><p>This value defines a rotation angle for the display of the page.
Allowed values are multiples of 90.</p>
<p>The default value of this option is zero.</p></dd>
</dl>
</div>
</div>
<div id="section5" class="section"><h2><a name="section5">EXAMPLES</a></h2>
<pre class="example">
pdf4tcl::new mypdf -paper a3
mypdf startPage
mypdf setFont 12 Courier
mypdf text "Hejsan" -x 50 -y 50
mypdf write -file mypdf.pdf
mypdf destroy
</pre>
</div>
<div id="see-also" class="section"><h2><a name="see-also">See Also</a></h2>
<p>doctools</p>
</div>
<div id="keywords" class="section"><h2><a name="keywords">Keywords</a></h2>
<p>document, pdf</p>
</div>
<div id="copyright" class="section"><h2><a name="copyright">Copyright</a></h2>
<p>Copyright © 2007-2016 Peter Spjuth<br>
Copyright © 2009 Yaroslav Schekin</p>
</div>
</div></body></html>
|
Added src/packages/pdf4tcl091/pdf4tcl.man.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 |
[comment {-*- tcl -*- doctools manpage}]
[comment "Modifications by IDG, March 2012"]
[manpage_begin pdf4tcl n 0.9.1]
[copyright {2007-2016 Peter Spjuth}]
[copyright {2009 Yaroslav Schekin}]
[moddesc {Pdf document generation}]
[titledesc {Pdf document generation}]
[require Tcl 8.6]
[require pdf4tcl [opt 0.9.1]]
[description]
This package provides a container class for generating [term {pdf}] documents.
[section COORDINATES]
All coordinates and distances can be expressed with or without a unit. See
[sectref UNITS] for valid units.
When the page is configured with [option -orient] set to false, origin is in
the bottom left corner. With [option -orient] true (the default), origin is in the top left
corner.
Origin is displaced to account for margins, i.e. if margins are 100,
the user coordinate (0,0) corresponds to (100,100) on the paper.
Page option [option -orient] can also affect the anchor point for things like
images.
[section UNITS]
Any coordinates and distances can be expressed with or without an explicit
unit. If no unit is given, the default unit for the document is used.
A unit may be one of
[option "mm"] (millimeter),
[option "m"] (millimeter),
[option "cm"] (centimeter),
[option "c"] (centimeter),
[option "p"] (points) or
[option "i"] (inches).
Commands returning coordinates or distances always return a double value
in the document's default unit.
[section {PUBLIC API}]
[subsection {PACKAGE COMMANDS}]
[list_begin definitions]
[call [cmd ::pdf4tcl::new] [arg objectName] [opt [arg "option value"]...]]
This command creates a new pdf4tcl object with an associated Tcl
command whose name is [arg objectName]. This [term object] command is
explained in full detail in the sections [sectref {OBJECT COMMAND}]
and [sectref {OBJECT METHODS}]. The object command will be created
under the current namespace if the [arg objectName] is not fully
qualified, and in the specified namespace otherwise.
If [arg objectName] is %AUTO% a name will generated.
The return value is the newly created object's name.
[para]
The options and their values coming after the name of the object are
used to set the initial configuration of the object.
See [sectref {OBJECT CONFIGURATION}].
[call [cmd ::pdf4tcl::getPaperSize] [arg "paper"]]
This call returns the size of a named paper type, e.g. "a4".
Paper names are case insensitive.
The argument [arg "paper"] may also be a two element list
with values as accepted by [cmd ::pdf4tcl::getPoints].
The return value is a list with width and height in points.
[call [cmd ::pdf4tcl::getPaperSizeList]]
This call returns the list of known paper types.
[call [cmd ::pdf4tcl::getPoints] [arg "val"]]
This call translates a measurement to points (1/72 inch).
The format of [arg "val"] is '[arg "num"] [opt [arg "unit"]]' where
[arg "num"] is a valid integer or double. See [sectref UNITS] for valid
[arg "unit"]s. If no [arg "unit"] is given, the value is interpreted
as points.
[call [cmd ::pdf4tcl::loadBaseTrueTypeFont] [arg "basefontname"] [arg "ttf_file_name"]]
This call loads a TTF font from file to be used by any pdf4tcl objects.
The [arg "basefontname"] is used to reference this font.
To use this base font in documents, a font with some encoding must be
created from it using createFont.
Note that the font loading functions require Tcl 8.5.
[call [cmd ::pdf4tcl::createBaseTrueTypeFont] [arg "basefontname"] [arg "ttf_data"]]
This call creates a base font from TTF binary data.
[call [cmd ::pdf4tcl::loadBaseType1Font] [arg "basefontname"] [arg "AFM_file_name"] [arg "PFB_file_name"]]
This call loads a Type1 font from two files (.afm and .pfb) to be used by
any pdf4tcl objects. The [arg "basefontname"] is used to reference this font.
To use this base font in documents, a font with some encoding must be
created from it using createFont.
[call [cmd ::pdf4tcl::createBaseType1Font] [arg "basefontname"] [arg "AFM_data"] [arg "PFB_data"]]
This call creates a base font from AFM text and PFB binary data.
[call [cmd ::pdf4tcl::createFont] [arg "basefontname"] [arg "fontname"] [arg "encoding_name"]]
This call creates a font that can be used in documents from a base font.
[comment "String map used to be able to include backslash-nl in the example"]
[example [string map {% \\} {
pdf4tcl::loadBaseTrueTypeFont BaseArial "arial.ttf"
pdf4tcl::createFont BaseArial MyArial cp1251
pdf4tcl::loadBaseType1Font BaseType1 "a010013l.afm" "a010013l.pfb"
pdf4tcl::createFont BaseType1 MyType1 cp1251
pdf4tcl::new mypdf -paper a4 -compress 0
mypdf startPage
mypdf setFont 10 MyArial
set txt "\u042D\u0442\u043E \u0442\u0435\u043A\u0441\u0442 \u043D\u0430 \u0440\u0443\u0441\u0441\u043A\u043E\u043C%
\u044F\u0437\u044B\u043A\u0435. This is text in Russian."
mypdf text $txt -bg #CACACA -x 50 -y 100
mypdf setFont 10 MyType1
mypdf text $txt -x 50 -y 200
mypdf write -file fonts.pdf
mypdf destroy
}]]
[call [cmd ::pdf4tcl::createFontSpecEnc] [arg "basefontname"] [arg "fontname"] [arg "subset"]]
This call creates a font that can be used in documents from a base font.
The [arg "subset"] must be a list of unicode values.
[call [cmd ::pdf4tcl::getFonts]]
This call returns the list of known font names, i.e. those accepted in a call
to [method setFont].
This includes the default fonts and fonts created by e.g.
[cmd ::pdf4tcl::createFont].
[call [cmd ::pdf4tcl::rgb2Cmyk] [arg "rgb"]]
This call translates an RGB color value to a CMYK color value.
It is used internally if [option -cmyk] was set at object creation to
translate colors.
You can redefine this procedure to provide your own translation.
[call [cmd ::pdf4tcl::cmyk2Rgb] [arg "cmyk"]]
This call translates a CMYK color value to an RGB color value.
It is used internally to translate colors.
You can redefine this procedure to provide your own translation.
[call [cmd ::pdf4tcl::catPdf] [arg "infile"] [opt [arg "infile ..."]] [arg "outfile"]]
This call concatenates PDF files into one.
Currently the implementation limits the PDFs a lot since not all details
are taken care of yet. Straightforward ones like those created with pdf4tcl
or ps2pdf should work mostly ok.
[list_end]
[subsection {OBJECT COMMAND}]
All commands created by [cmd ::pdf4tcl::new] have the following
general form and may be used to invoke various operations on their
pdf object.
[list_begin definitions]
[call [cmd objectName] [method method] [opt [arg "arg arg ..."]]]
The method [method method] and its [arg arg]'uments determine the exact
behavior of the command. See section [sectref {OBJECT METHODS}] for
the detailed specifications.
[list_end]
[subsection {OBJECT METHODS}]
[list_begin definitions]
[call [arg objectName] [method configure]]
The method returns a list of all known options and their current
values when called without any arguments.
[call [arg objectName] [method configure] [arg option]]
The method behaves like the method [method cget] when called with a
single argument and returns the value of the option specified by said
argument.
[call [arg objectName] [method configure] [option -option] [arg value]...]
The method reconfigures the specified [option option]s of the object,
setting them to the associated [arg value]s, when called with an even
number of arguments, at least two.
[para]
The legal options are described in the section
[sectref {OBJECT CONFIGURATION}].
[call [arg objectName] [method cget] [option -option]]
This method expects a legal configuration option as argument and will
return the current value of that option for the object the method was
invoked for.
[para]
The legal configuration options are described in section
[sectref {OBJECT CONFIGURATION}].
[call [arg objectName] [method destroy]]
This method destroys the object it is invoked for.
If the [option -file] option was given at object creation,
the output file will be finished and closed.
[call [arg objectName] [method startPage] [opt [arg "option value"]...]]
This method starts a new page in the document. The page will have the
default page settings for the document unless overridden by [arg "option"].
See [sectref {PAGE CONFIGURATION}] for page settings.
This will end any ongoing page.
[call [arg objectName] [method endPage]]
This method ends a page in the document. It is normally not needed since
it is implied by e.g. [method startPage] and [method finish]. However,
if the document is built page by page in e.g. an event driven environment
it can be good to call [method endPage] explicitly to have all the page's
work finished before reentering the event loop.
[call [arg objectName] [method startXObject] [opt [arg "option value"]...]]
This method starts a new XObject in the document. An XObject is a reusable
drawing object and behaves just like a page where you can draw any graphics.
An XObject must be created between pages and this method will end any ongoing
page. The return value is an id that can be used with [method putImage] to draw
it on the current page or with some forms.
All page settings ([sectref {PAGE CONFIGURATION}]) are
valid when creating an XObject. Default options are
[option -paper] = {100p 100p}, [option -landscape] = 0,
[option -orient] = document default, [option -margin]= 0.
[list_begin options]
[opt_def -noimage [arg bool]]
If this is set the XObject is not added to the image resource set and cannot
be used with putImage, only in forms. The XObject also gets access to resources
which is needed to use e.g. fonts within the XObject. This behaviour has shown
to be PDF reader dependent, and it is currently not known if this can be
made to work better.
[list_end]
[call [arg objectName] [method endXObject]]
This method ends an XObject definition. It works just like [method endPage].
[call [arg objectName] [method finish]]
This method ends the document.
This will do [method endPage] if needed.
If the [option -file] option was given at object creation,
the output file will be finished and closed.
[call [arg objectName] [method get]]
This method returns the generated pdf.
This will do [method endPage] and [method finish] if needed.
If the [option -file] option was given at object creation, nothing is returned.
[call [arg objectName] [method write] [opt [arg "-file filename"]]]
This method writes the generated pdf to the given [arg "filename"].
If no [arg "filename"] is given, it is written to stdout.
This will do [method endPage] and [method finish] if needed.
If the [option -file] option was given at object creation, an empty file
is created.
[call [arg objectName] [method addForm] [arg "type"] [arg "x"] [arg "y"] [arg "width"] [arg "height"] [opt [arg "option value"]...]]
Add an interactive form at the given position and size. Supported types are [arg text] and [arg checkbutton].
Option [arg "-init"] gives an initial value for the form.
For a checkbutton, options [arg "-on"] and [arg "-off"] can be given an xobject (created with [method startXObject]) to control its appearance.
[list_end]
[subsection {OBJECT METHODS, PAGE}]
[list_begin definitions]
[call [arg objectName] [method getDrawableArea]]
This method returns the size of the available area on the page,
after removing margins. The return value is a list of width and height,
in the document's default unit.
[call [arg objectName] [method canvas] [arg "path"] [opt [arg "option value"]...]]
Draws the contents of the canvas widget [arg "path"] on the current page.
Option [arg "-bbox"] gives the area of the canvas to be drawn. Default is
the entire contents, i.e. the result of $path bbox all.
Options [arg "-x"], [arg "-y"], [arg "-width"] and [arg "-height"] defines
an area on the page where to place the contents. Default area starts at origin,
stretching over the drawable area of the page.
Option [arg "-sticky"] defines how to place the contents within the area.
The area is always filled in one direction, preserving aspect ratio, unless
[arg "-sticky"] defines that the other direction should be filled too. Default
[arg "-sticky"] is [arg "nw"].
If option [arg "-bg"] is true, a background is drawn in the canvas' background
color. Otherwise only objects are drawn. Default is false.
Option [arg "-fontmap"] gives a dictionary mapping from Tk font names to PDF font names.
[para]
Fonts:
[para]
If no font mapping is given, fonts for text items are limited to PDF's
builtins, i.e. Helvetica, Times and Courier. A guess is made to chose which
one to use to get a reasonable display on the page.
[para]
An element in a font mapping must exactly match the -font option in the
text item. The corresponding mapping value is a PDF font family, e.g. one
created by [cmd pdf4tcl::createFont]. It is recommended to use named fonts
in Tk to control the font mapping in detail.
[para]
Limitations:
[para]
Option -splinesteps for lines/polygons is ignored.
[para]
Stipple offset is limited. The form x,y should work.
[para]
Window items require Img to be present and must be visible on-screen when
the canvas is drawn.
[call [arg objectName] [method metadata] [opt [arg "option value"]...]]
This method sets metadata fields for this document. Supported field options are
[arg -author], [arg -creator], [arg -keywords], [arg -producer], [arg -subject],
[arg -title], [arg -creationdate] and [arg -format].
[call [arg objectName] [method bookmarkAdd] [opt [arg "option value"]...]]
Add a bookmark on the current page.
[list_begin options]
[opt_def -title [arg text]]
Set the text of the bookmark.
[opt_def -level [arg level]]
Set the level of the bookmark. Default is 0.
[opt_def -closed [arg boolean]]
Select if the bookmark is closed by default. Default is false, i.e. not closed.
[list_end]
[call [arg objectName] [method embedFile] [arg "filename"] [opt [arg "option value"]...]]
This method embeds a file into the PDF stream. File data is considered binary. Returns an id that can be used in subsequent calls to [method attachFile].
[list_begin options]
[opt_def -id [arg id]]
Explicitly select an id for the file. The [arg "id"] must be unique within the document.
[opt_def -contents [arg data]]
Provides the file contents instead of reading the actual file.
[list_end]
[call [arg objectName] [method attachFile] [arg "x"] [arg "y"] [arg "width"] [arg "height"] [arg "fid"] [arg "description"] [opt [arg "option value"]...]]
This method adds a file annotation to the current page. The location of the file annotation is given by the coordinates [arg "x"], [arg "y"], [arg "width"], [arg "height"]. The annotation is rendered by default as a paperclip icon, which allows the extraction of the attached file. An [arg "fid"] from a previous call to [method embedFile] must be set as well as a [arg "description"], which is shown by the PDF viewer upon activating the annotation.
[list_begin options]
[opt_def -icon [arg icon]]
Controls the appearance of the attachment. Valid values are Paperclip, Tag, Graph, or PushPin. Default value is Paperclip.
[list_end]
[example {
set fid [$pdfobject embedFile "data.txt" -contents "This should be stored in the file."]
$pdfobject attachFile 0 0 100 100 $fid "This is the description"
}]
[list_end]
[subsection {OBJECT METHODS, TEXT}]
[list_begin definitions]
[call [arg objectName] [method setFont] [arg "size"] [opt [arg "fontname"]]]
This method sets the font used by text drawing routines. If [arg "fontname"]
is not provided, the previously set [arg "fontname"] is kept.
[call [arg objectName] [method getStringWidth] [arg "str"]]
This method returns the width of a string under the current font.
[call [arg objectName] [method getCharWidth] [arg "char"]]
This method returns the width of a character under the current font.
[call [arg objectName] [method setTextPosition] [arg "x"] [arg "y"]]
Set coordinate for next text command.
[call [arg objectName] [method moveTextPosition] [arg "dx"] [arg "dy"]]
Increment position by [arg "dx"], [arg "dy"] for the next text command.
[call [arg objectName] [method getTextPosition]]
This method returns the current text coordinate.
[call [arg objectName] [method newLine] [opt [arg spacing]]]
Moves text coordinate down and resets x to where the latest
[method setTextPosition] was. The number of lines to move down can
be set by [arg spacing]. This may be any real number, including negative,
and defaults to the value set by [method setLineSpacing].
[call [arg objectName] [method setLineSpacing] [arg spacing]]
Set the default line spacing used be e.g. [method newLine]. Initially
the spacing is 1.
[call [arg objectName] [method getLineSpacing]]
Get the current default line spacing.
[call [arg objectName] [method text] [arg "str"] [opt [arg "option value"]...]]
Draw text at the position defined by setTextPosition using the font defined by
setFont.
[list_begin options]
[opt_def -align "[arg left|right|center] (default left)"]
[opt_def -angle "[arg degrees] (default 0) - Orient string at the specified angle."]
[opt_def -xangle "[arg degrees] (default 0)"]
[opt_def -yangle "[arg degrees] (default 0) - Apply x or y shear to the text."]
[opt_def -x "[arg x] (default 0)"]
[opt_def -y "[arg y] (default 0) - Allow the text to be positioned without setTextPosition."]
[opt_def -bg "[arg bool] (default 0)"]
[opt_def -background "[arg bool] (default 0)"]
[opt_def -fill "[arg bool] (default 0) "]
Any of [option -bg], [option -background] or [option -fill] cause the text to be drawn
on a background whose color is set by setBgColor.
[list_end]
[call [arg objectName] [method drawTextBox] [arg "x"] [arg "y"] [arg "width"] [arg "height"] [arg "str"] [opt [arg "option value"]...]]
Draw the text string [arg "str"] wrapping at blanks and tabs so that it fits within the box defined
by [arg "x"], [arg "y"], [arg "width"] and [arg "height"]. An embedded newline in [arg "str"] causes
a new line in the output. If [arg "str"] is too long to fit in the specified box, it is truncated and the unused remainder is returned.
[list_begin options]
[opt_def -align "[arg left|right|center|justify]"]
Specifies the justification. If not given, the text is left justified.
[opt_def -linesvar "[arg var]"]
Gives the name of a variable which will be set to the number of lines written.
[opt_def -dryrun "[arg bool]"]
If true, no changes will be made to the PDF document. The return
value and [option -linesvar] gives information of what would happen
with the given text.
[list_end]
[call [arg objectName] [method getFontMetric] [arg "metric"]]
Get information about current font. The available [arg "metric"]s are
[option ascend], [option descend], [option fixed], [option bboxb],
[option bboxt] and [option height].
[list_begin options]
[opt_def ascend]
Top of typical glyph, displacement from anchor point. Typically a positive number since it is above the anchor point.
[opt_def descend]
Bottom of typical glyph, displacement from anchor point. Typically a negative number since it is below the anchor point.
[opt_def fixed]
Boolean which is true if this is a fixed width font.
[opt_def bboxb]
Bottom of Bounding Box, displacement from anchor point. Typically a negative number since it is below the anchor point.
[opt_def bboxt]
Top of Bounding Box, displacement from anchor point. Typically a positive number since it is above the anchor point.
[opt_def height]
Height of font's Bounding Box.
[list_end]
[list_end]
[subsection {OBJECT METHODS, IMAGES}]
A limited set of image formats are directly understood by pdf4tcl, currently
JPEG and some PNG formats. To use unsupported formats, use Tk and the Img
package to load and dump images to raw format which can be fed to
[method putRawImage] and [method addRawImage].
[list_begin definitions]
[call [arg objectName] [method putImage] [arg "id"] [arg "x"] [arg "y"] [opt [arg "option value"]...]]
Put an image on the current page. The image must have been added previously by
[method addImage] or [method addRawImage]. The [arg "id"] is the one returned
from the add command.
[list_begin options]
[opt_def -angle [arg degrees]]
Rotate image [arg degrees] counterclockwise around the anchor point.
Default is 0.
[opt_def -anchor [arg anchor]]
Set the anchor point (nw, n, ne etc.) of the image.
Coordinates [arg "x"] and [arg "y"] places the anchor point, and any rotation is around the anchor point.
Default is nw if [option -orient] is true, otherwise se.
[opt_def -height [arg height]]
Set the height of the image. Default height is one point per pixel. If [arg width] is set but not [arg height],
the height is selected to preserve the aspect ratio of the image.
[opt_def -width [arg width]]
Set the width of the image. Default width is one point per pixel.
If [arg height] is set but not [arg width], the width is selected to
preserve the aspect ratio of the image.
[list_end]
[call [arg objectName] [method putRawImage] [arg "data"] [arg "x"] [arg "y"] [opt [arg "option value"]...]]
Put an image on the current page. Works like [method putImage] except that the raw image data is given directly.
[list_begin options]
[opt_def -compress [arg boolean]]
Raw data will be zlib compressed if this option is set to true.
Default value is the document's [option -compress] setting.
[list_end]
[example {
image create photo img1 -file image.gif
set imgdata [img1 data]
mypdf putRawImage $imgdata 60 20 -height 40
}]
[call [arg objectName] [method addImage] [arg "filename"] [opt [arg "option value"]...]]
Add an image to the document. Returns an id that can be used in subsequent
calls to [method putImage]. Supported formats are PNG and JPEG.
[list_begin options]
[opt_def -id [arg id]]
Explicitly select an id for the image. The [arg "id"] must be unique within the document.
[opt_def -type [arg name]]
Set the image type. This can usually be deduced from the file name, this
option helps when that is not possible. This can be either "png" or "jpeg".
[list_end]
[call [arg objectName] [method addRawImage] [arg "data"] [opt [arg "option value"]...]]
Add an image to the document. Works like [method addImage] except that the raw image data is given directly.
[list_begin options]
[opt_def -compress [arg boolean]]
Raw data will be zlib compressed if this option is set to true.
Default value is the document's [option -compress] setting.
[list_end]
[example {
image create photo img1 -file image.gif
set imgdata [img1 data]
set id [mypdf addRawImage $imgdata]
mypdf putImage $id 20 60 -width 100
}]
[call [arg objectName] [method getImageHeight] [arg "id"]]
This method returns the height of the image identified by [arg "id"].
[call [arg objectName] [method getImageSize] [arg "id"]]
This method returns the size of the image identified by [arg "id"]. The
return value is a list of width and height.
[call [arg objectName] [method getImageWidth] [arg "id"]]
This method returns the width of the image identified by [arg "id"].
[list_end]
[subsection {OBJECT METHODS, COLORS}]
Colors can be expressed in various formats. First, as a three element list
of values in the range 0.0 to 1.0. Second, in the format #XXXXXX where
the Xes are two hexadecimal digits per color value. Third, if Tk is available,
any color accepted by winfo rgb is accepted.
[list_begin definitions]
[call [arg objectName] [method setBgColor] [arg "red"] [arg "green"] [arg "blue"]]
Sets the background color for text operations where -bg is true.
[call [arg objectName] [method setBgColor] [arg "c"] [arg "m"] [arg "y"] [arg "k"]]
Alternative calling form, to set color in CMYK color space.
[call [arg objectName] [method setFillColor] [arg "red"] [arg "green"] [arg "blue"]]
Sets the fill color for graphics operations, and the foreground color for
text operations.
[call [arg objectName] [method setFillColor] [arg "c"] [arg "m"] [arg "y"] [arg "k"]]
Alternative calling form, to set color in CMYK color space.
[call [arg objectName] [method setStrokeColor] [arg "red"] [arg "green"] [arg "blue"]]
Sets the stroke color for graphics operations.
[call [arg objectName] [method setStrokeColor] [arg "c"] [arg "m"] [arg "y"] [arg "k"]]
Alternative calling form, to set color in CMYK color space.
[list_end]
[subsection {OBJECT METHODS, GRAPHICS}]
[list_begin definitions]
[call [arg objectName] [method setLineWidth] [arg "width"]]
Sets the width for subsequent line drawing.
Line width must be a non-negative number.
[call [arg objectName] [method setLineDash] [opt [arg "on off"]...] [opt [arg "offset"]]]
Sets the dash pattern for subsequent line drawing.
Offset and any elements in the dash pattern must be non-negative numbers.
[emph "on off"] is a series of pairs of numbers which define a
dash pattern. The 1st, 3rd ... numbers give units to paint,
the 2nd, 4th ... numbers specify unpainted gaps. When all numbers have
been used, the pattern is re-started from the beginning.
An optional last argument sets the dash offset, which defaults to 0.
Calling [method setLineDash] with no arguments resets the dash pattern
to a solid line.
[call [arg objectName] [method setLineStyle] [arg "width"] [arg "args"]]
Sets the width and dash pattern for subsequent line drawing.
Line width and any elements in the dash pattern must be non-negative numbers.
[emph "args"] is a series of numbers (not a tcl list) which define a
dash pattern. The 1st, 3rd ... numbers give units to paint,
the 2nd, 4th ... numbers specify unpainted gaps. When all numbers have
been used, the pattern is re-started from the beginning.
This method do not support offsetting the pattern, see [method setLineDash]
for a more complete method.
[call [arg objectName] [method line] [arg "x1"] [arg "y1"] [arg "x2"] [arg "y2"]]
Draws a line from [emph "x1,"] [emph "y1"] to [emph "x2,"] [emph "y2"]
[call [arg objectName] [method curve] [arg "x1"] [arg "y1"] [arg "x2"] [arg "y2"]\
[arg "x3"] [arg "y3"] [opt [arg "x4 y4"]] ]
If [emph "x4,"] [emph "y4"] are present, draws a cubic bezier from [emph "x1,"]
[emph "y1"] to [emph "x4,"] [emph "y4"] with control points [emph "x2,"] [emph "y2"] and
[emph "x3,"] [emph "y3"]. Otherwise draws a quadratic bezier from [emph "x1,"]
[emph "y1"] to [emph "x3,"] [emph "y3"], with control point [emph "x2,"]
[emph "y2"]
[call [arg objectName] [method polygon] [opt [arg "x y"]...] [opt [arg "option value"]...]]
Draw a polygon. There must be at least 3 points.
The polygon is closed back to the first coordinate.
[list_begin options]
[opt_def -filled "[arg bool] (default 0)"]
Fill the polygon.
[opt_def -stroke "[arg bool] (default 1)"]
Draw an outline of the polygon.
[list_end]
[call [arg objectName] [method circle] [arg "x"] [arg "y"] [arg "radius"] [opt [arg "option value"]...]]
Draw a circle at the given center coordinates.
[list_begin options]
[opt_def -filled "[arg bool] (default 0)"]
Fill the circle.
[opt_def -stroke "[arg bool] (default 1)"]
Draw an outline of the circle.
[list_end]
[call [arg objectName] [method oval] [arg "x"] [arg "y"] [arg "radiusx"] [arg "radiusy"] [opt [arg "option value"]...]]
Draw an oval at the given center coordinates.
[list_begin options]
[opt_def -filled "[arg bool] (default 0)"]
Fill the oval.
[opt_def -stroke "[arg bool] (default 1)"]
Draw an outline of the oval.
[list_end]
[call [arg objectName] [method arc] [arg "x"] [arg "y"] [arg "radiusx"] [arg "radiusy"] [arg "phi"] [arg "extend"] [opt [arg "option value"]...]]
Draw an arc, following the given oval. The arc starts at angle [arg "phi"], given in degrees starting in the "east" direction, counting counter clockwise. The arc extends [arg "extend"] degrees.
[list_begin options]
[opt_def -filled "[arg bool] (default 0)"]
Fill the arc.
[opt_def -stroke "[arg bool] (default 1)"]
Draw an outline of the arc.
[opt_def -style "[arg arc|pieslice|chord] (default [arg arc])"]
Defines the style of the arc. An [arg "arc"] draws the perimeter of the arc and is never filled. A [arg "pieslice"] closes the arc with lines to the center of the oval. A [arg "chord"] closes the arc directly.
[list_end]
[call [arg objectName] [method arrow] [arg "x1"] [arg "y1"] [arg "x2"] [arg "y2"] [arg "size"] [opt [arg "angle"]]]
Draw an arrow. Default [arg "angle"] is 20 degrees.
[call [arg objectName] [method rectangle] [arg "x"] [arg "y"] [arg "width"] [arg "height"] [opt [arg "option value"]...]]
Draw a rectangle.
[list_begin options]
[opt_def -filled "[arg bool] (default 0)"]
Fill the rectangle.
[opt_def -stroke "[arg bool] (default 1)"]
Draw an outline of the rectangle.
[list_end]
[list_end]
[subsection {OBJECT CONFIGURATION}]
All pdf4tcl objects understand the options from [sectref {PAGE CONFIGURATION}],
which defines default page settings when used with a pdf4tcl object.
The objects also understand the following configuration options:
[list_begin options]
[opt_def -cmyk [arg boolean]]
If true, pdf4tcl will try to generate the document in CMYK color space.
See [cmd ::pdf4tcl::rgb2Cmyk] for a way to control color translation.
Default value is false.
This option can only be set at object creation.
[opt_def -compress [arg boolean]]
Pages will be zlib compressed if this option is set to true.
Default value is true.
This option can only be set at object creation.
[opt_def -file [arg filename]]
Continuously write pdf to [arg filename] instead of storing it
in memory.
This option can only be set at object creation.
[opt_def -unit [arg defaultunit]]
Defines default unit for coordinates and distances. Any value given without
a unit is interpreted using this unit.
See [sectref UNITS] for valid units.
Default value is "p" as in points.
This option can only be set at object creation.
[list_end]
[subsection {PAGE CONFIGURATION}]
[list_begin options]
[opt_def -paper [arg name]]
The argument of this option defines the paper size.
The paper size may be a string like "a4", where valid values
are available through [cmd ::pdf4tcl::getPaperSizeList].
Paper size may also be a two element list specifying width and height.
[para]
The default value of this option is "a4".
[opt_def -landscape [arg boolean]]
If true, paper width and height are switched.
[para]
The default value of this option is false.
[opt_def -orient [arg boolean]]
This sets the orientation of the y axis of the coordinate system.
With [option -orient] false, origin is in the bottom left corner.
With [option -orient] true, origin is in the top left corner.
[para]
The default value of this option is true.
[opt_def -margin [arg values]]
The margin is a one, two or four element list of margins.
For one element, it specifies all margins.
Two elements specify left/right and top/bottom.
Four elements specify left, right, top and bottom.
[para]
The default value of this option is zero.
[opt_def -rotate [arg angle]]
This value defines a rotation angle for the display of the page.
Allowed values are multiples of 90.
[para]
The default value of this option is zero.
[list_end]
[section EXAMPLES]
[example_begin]
pdf4tcl::new mypdf -paper a3
mypdf startPage
mypdf setFont 12 Courier
mypdf text "Hejsan" -x 50 -y 50
mypdf write -file mypdf.pdf
mypdf destroy
[example_end]
[see_also doctools]
[keywords pdf document]
[manpage_end]
|
Added src/packages/pdf4tcl091/pdf4tcl.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 |
# library of tcl procedures for generating portable document format files
# this began as a port of pdf4php from php to tcl
#
# Copyright (c) 2004 by Frank Richter <frichter@truckle.in-chemnitz.de> and
# Jens Ponisch <jens@ruessel.in-chemnitz.de>
# Copyright (c) 2006-2016 by Peter Spjuth <peter.spjuth@gmail.com>
# Copyright (c) 2009 by Yaroslav Schekin <ladayaroslav@yandex.ru>
#
# See the file "licence.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package provide pdf4tcl 0.9.1
package require TclOO
package require pdf4tcl::stdmetrics
package require pdf4tcl::glyph2unicode
namespace eval pdf4tcl {
# helper variables (constants) packaged into arrays to minimize
# variable import statements
variable g
variable paper_sizes
variable units
variable dir [file dirname [file join [pwd] [info script]]]
# Make mathops available
namespace import ::tcl::mathop::*
# Known paper sizes. These are always in points.
array set paper_sizes {
a0 {2380.0 3368.0}
a1 {1684.0 2380.0}
a2 {1190.0 1684.0}
a3 { 842.0 1190.0}
a4 { 595.0 842.0}
a5 { 421.0 595.0}
a6 { 297.0 421.0}
11x17 { 792.0 1224.0}
ledger {1224.0 792.0}
legal { 612.0 1008.0}
letter { 612.0 792.0}
}
# Known units. The value is their relationship to points
array set units [list \
mm [expr {72.0 / 25.4}] \
m [expr {72.0 / 25.4}] \
cm [expr {72.0 / 2.54}] \
c [expr {72.0 / 2.54}] \
i 72.0 \
p 1.0 \
]
# Font Variables
variable ttfpos 0
variable ttfdata
# Base font attributes:
variable BFA
# BaseFontParts for TTF fonts:
variable BFP
# List of all created fonts:
variable Fonts
variable FontsAttrs
# For currently processed font:
variable ttfname ""
variable ttftables
variable type1AFM
variable type1PFB
# Utility to look up paper size by name
# A two element list of width and height is also allowed.
# Return value is in points
proc getPaperSize {papername {unit 1.0}} {
variable paper_sizes
set papername [string tolower $papername]
if {[info exists paper_sizes($papername)]} {
# This array is always correct format
return $paper_sizes($papername)
}
if {[catch {set len [llength $papername]}] || $len != 2} {
return {}
}
foreach {w h} $papername break
set w [getPoints $w $unit]
set h [getPoints $h $unit]
return [list $w $h]
}
# Return a list of known paper sizes
proc getPaperSizeList {} {
variable paper_sizes
return [array names paper_sizes]
}
# Get points from a measurement.
# No unit means points.
# Supported units are "mm", "m", "cm", "c", "p" and "i".
proc getPoints {val {unit 1.0}} {
variable units
if {[string is double -strict $val]} {
# Always return a pure double value
return [expr {$val * $unit}]
}
if {[regexp {^\s*(\S+?)\s*([[:alpha:]]+)\s*$} $val -> num unit]} {
if {[string is double -strict $num]} {
if {[info exists units($unit)]} {
return [expr {$num * $units($unit)}]
}
}
}
throw "PDF4TCL" "unknown value $val"
}
# Wrapper to create pdf4tcl object
proc new {args} {
set cmd create
# Support Snit style of naming
if {[lindex $args 0] eq "%AUTO%"} {
set args [lrange $args 1 end]
set cmd new
}
uplevel 1 pdf4tcl::pdf4tcl $cmd $args
}
# ===== Procs for TrueType fonts processing =====
proc createBaseTrueTypeFont {basefontname ttf_data {validate 0}} {
variable ttfname $basefontname
variable ttfdata $ttf_data
InitBaseTTF $validate
}
proc loadBaseTrueTypeFont {basefontname filename {validate 0}} {
variable ttfname $basefontname
variable ttfdata
set fd [open $filename]
fconfigure $fd -translation binary
set ttfdata [read $fd]
close $fd
InitBaseTTF $validate
}
proc InitBaseTTF {validate} {
variable BFA
variable BFP
variable ttfname
variable ttfdata
variable ttftables
variable ttfpos 0
set BFA($ttfname,FontType) TTF
set subfontIndex 0
if {[ReadHeader]} {
ReadTTCHeader
GetSubfont $subfontIndex $validate
} else {
ChecksumFile
ReadTableDirectory $validate
set BFA($ttfname,subfontNameX) ""
}
ExtractInfo
unset -nocomplain ttfdata
unset -nocomplain ttftables
set BFA($ttfname,SubFontIdx) 0
}
# Pad data with zero bytes to: len % 4 == 0
proc CalcTTFCheckSum {data pos len} {
binary scan $data "@${pos}Iu[expr {$len >> 2}]" datalst
if {$len & 3} {
set s [expr {$pos + (($len >> 2) << 2)}]
set e [expr {$s + ($len & 3)}]
set lc "[string range $data $s $e][string repeat "\0" 3]"
binary scan $lc "Iu" lastb
lappend datalst $lastb
}
set sum 0
foreach u_int32 $datalst {
incr sum $u_int32
}
set sum [expr {$sum & 0xFFFFFFFF}]
return $sum
}
# read the sfnt header at the current position:
proc ReadHeader {} {
variable ttfpos
variable ttfdata
set ttfVersions [list 65536 1953658213 1953784678]
binary scan $ttfdata "@${ttfpos}Iu" version
incr ttfpos 4
if {$version == 0x4F54544F} {
throw "PDF4TCL" "TTF: postscript outlines are not supported"
}
if {$version ni $ttfVersions} {
throw "PDF4TCL" "not a TrueType font: version=$version"
}
return [expr {$version == [lindex $ttfVersions end]}]
}
proc ChecksumFile {} {
variable ttfdata
set checksum [CalcTTFCheckSum $ttfdata 0 [string length $ttfdata]]
if {$checksum != 0xB1B0AFBA} {
throw "PDF4TCL" "invalid TTF file checksum [format %X $checksum]"
}
}
proc ReadTTCHeader {} {
variable ttfname
variable ttfpos
variable ttfdata
variable BFA
variable ttfSubFontOffsets
set ttcVersions [list 65536 131072]
binary scan $ttfdata "@${ttfpos}IuIu" \
ttcVersion BFA($ttfname,numSubfonts)
incr ttfpos 8
if {$ttcVersion ni $ttcVersions} {
throw "PDF4TCL" "not a TTC file"
}
binary scan $ttfdata "@${ttfpos}Iu$BFA($ttfname,numSubfonts)" \
ttfSubFontOffsets
incr ttfpos [expr {$BFA($ttfname,numSubfonts) * 4}]
}
proc GetSubfont {subfontIndex {validate 0}} {
variable ttfpos
variable ttfSubFontOffsets
if {$subfontIndex >= [llength $ttfSubFontOffsets]} {
throw "PDF4TCL" "bad subfontIndex $subfontIndex"
}
set ttfpos [lindex $ttfSubFontOffsets $subfontIndex]
ReadHeader
ReadTableDirectory $validate
}
proc ReadTableDirectory {validate} {
variable ttfdata
variable ttfpos
variable ttftables
variable ttfname
variable BFP
variable BFA
# Must copy only needed tables here, if they exist:
set NT [list "name" "OS/2" "cvt " "fpgm" "prep" \
"glyf" "post" "hhea" "maxp" "head"]
# 'srange', 'esel' and 'rshift' are UNUSED
binary scan $ttfdata "@${ttfpos}SuSuSuSu" numTables srange esel rshift
incr ttfpos 8
for {set f 0} {$f < $numTables} {incr f} {
# list is 'checksum offset length'
binary scan $ttfdata "@${ttfpos}a4Iu3" tag rlist
incr ttfpos 16
set ttftables($tag) $rlist
if {$tag in $NT} {
foreach {cksum offset len} $rlist break
set last [expr {$offset + $len - 1}]
set BFP($ttfname,$tag) [string range $ttfdata $offset $last]
lappend BFA($ttfname,tables) $tag
}
}
if {$validate} ChecksumTables
}
# Check the checksums for all tables
proc ChecksumTables {} {
variable ttftables
variable ttfdata
foreach t [array names ttftables] {
foreach {checksum offset length} $ttftables($t) break
set RCkSum [CalcTTFCheckSum $ttfdata $offset $length]
if {$t eq "head"} {
incr offset 8
binary scan $ttfdata "@${offset}Iu" adjustment
set RCkSum [expr {($RCkSum - $adjustment) & 0xFFFFFFFF}]
}
if {$RCkSum != $checksum} {
throw "PDF4TCL" "TTF: invalid checksum of table $t"
}
}
}
# Extract typographic information from the loaded font file.
#
# The following attributes will be set::
#
# name PostScript font name
# flags Font flags
# ascend Typographic ascender in 1/1000ths of a point
# descend Typographic descender in 1/1000ths of a point
# CapHeight Cap height in 1/1000ths of a point (0 if not available)
# bbox Glyph bounding box [l,b,r,t] in 1/1000ths of a point
# _bbox Glyph bounding box [l,b,r,t] in unitsPerEm
# unitsPerEm Glyph units per em
# ItalicAngle Italic angle in degrees ccw
# stemV stem weight in 1/1000ths of a point (approximate)
#
# If charInfo is true, the following will also be set::
#
# defaultWidth default glyph width in 1/1000ths of a point
# charWidths dictionary of character widths for every supported UCS
# character code
#
# This will only work if the font has a Unicode cmap (platform 3,
# encoding 1, format 4 or platform 0 any encoding format 4). Setting
# charInfo to false avoids this requirement
proc ExtractInfo {{charInfo 1}} {
variable ttfdata
variable ttftables
variable ttfpos
variable ttfname
variable BFA
# name - Naming table
set name_pos [lindex $ttftables(name) 1]
set ttfpos $name_pos
binary scan $ttfdata "@${ttfpos}SuSuSu" fmt NumRecords SDoffset
if {$fmt != 0} {
throw "PDF4TCL" "TTF: Unknown name table format $fmt"
}
incr ttfpos 6
set SDoffset [expr {$name_pos + $SDoffset}]
array set names {1 "" 2 "" 3 "" 4 "" 6 ""}
set NIDS [array names names]
set nameCount [llength $NIDS]
for {set f 0} {$f < $NumRecords} {incr f} {
binary scan $ttfdata "@${ttfpos}SuSuSuSuSuSu" PlId EncId LangId \
nameId length offset
incr ttfpos 12
if {$nameId ni $NIDS} {
continue
}
set npos [expr {$SDoffset + $offset}]
set nend [expr {$npos + $length - 1}]
set Nstr [string range $ttfdata $npos $nend]
set N ""
if {$PlId == 3 && $EncId == 1 && $LangId == 0x409} {
# Microsoft, Unicode, US English, PS Name
if {$length & 1} {
throw "PDF4TCL" \
"PostScript name is UTF-16 string of odd length"
}
# Try to read a string of unicode chars:
set N [encoding convertfrom unicode $Nstr]
} elseif {$PlId == 1 && $EncId == 0 && $LangId == 0} {
# Macintosh, Roman, English, PS Name
# According to OpenType spec, if PS name exists, it must exist
# both in MS Unicode and Macintosh Roman formats. Apparently,
# you can find live TTF fonts which only have Macintosh format.
set N [encoding convertfrom iso8859-1 $Nstr]
}
if {[string length $N] && $names($nameId) == ""} {
set names($nameId) $N
incr nameCount -1
if {$nameCount == 0} break
}
}
set BFA($ttfname,psName) [string map {" " -} $names(6)]
if {$BFA($ttfname,psName) eq ""} {
throw "PDF4TCL" "could not find PostScript font name"
}
#----------------------------------
# head - Font header table
set ttfpos [lindex $ttftables(head) 1]
binary scan $ttfdata "@${ttfpos}SuSuSux6Iux2Sux16SSSSx6SuSu" \
ver_maj ver_min fnt_rev magic \
BFA($ttfname,unitsPerEm) xMin yMin xMax yMax \
indexToLocFormat glyphDataFormat
if {$ver_maj != 1} {
throw "PDF4TCL" "unknown head table version $ver_maj"
}
if {$magic != 0x5F0F3CF5} {
throw "PDF4TCL" "invalid head table magic $magic"
}
set BFA($ttfname,bbox) [list \
[Rescale $xMin] [Rescale $yMin] [Rescale $xMax] [Rescale $yMax]]
# OS/2 - OS/2 and Windows metrics table (needs data from head table)
if {[info exists ttftables(OS/2)]} {
set ttfpos [lindex $ttftables(OS/2) 1]
binary scan $ttfdata "@${ttfpos}Sux2Sux2Sux58SS" \
version usWeightClass fsType sTypoAscender sTypoDescender
incr ttfpos 88
set BFA($ttfname,ascend) [Rescale $sTypoAscender]
set BFA($ttfname,descend) [Rescale $sTypoDescender]
if {$version > 1} {
binary scan $ttfdata "@${ttfpos}Su" sCapHeight
set BFA($ttfname,CapHeight) [Rescale $sCapHeight]
} else {
set BFA($ttfname,CapHeight) $BFA($ttfname,ascend)
}
} else {
# Microsoft TTFs require an OS/2 table; Apple ones do not. Try to
# cope. The data is not very important anyway.
set usWeightClass 500
set BFA($ttfname,ascend) [Rescale $yMax]
set BFA($ttfname,descend) [Rescale $yMin]
set BFA($ttfname,CapHeight) $BFA($ttfname,ascend)
}
set BFA($ttfname,stemV) [expr {50 + int(pow($usWeightClass / 65.0, 2))}]
#----------------------
# post - PostScript table (needs data from OS/2 table)
set ttfpos [lindex $ttftables(post) 1]
binary scan $ttfdata "@${ttfpos}SuSuSSuSSIu" \
ver_maj ver_min itan0 itan1 ulpos ulthick isFixedPitch
set BFA($ttfname,ItalicAngle) [expr {$itan0 + $itan1 / 65536.0}]
set flags 4 ; # "symbolic".
if {$BFA($ttfname,ItalicAngle) != 0} {set flags [expr {$flags | 64}]}
if {$usWeightClass >= 600} {set flags [expr {$flags | (1 << 18)}]}
if {$isFixedPitch} {set flags [expr {$flags | 1}]}
set BFA($ttfname,flags) $flags
set BFA($ttfname,fixed) $isFixedPitch
# hhea - Horizontal header table
set ttfpos [lindex $ttftables(hhea) 1]
binary scan $ttfdata "@${ttfpos}SuSux28SuSu" \
ver_maj ver_min metricDataFormat numberOfHMetrics
if {$ver_maj != 1} {
throw "PDF4TCL" "unknown hhea table version"
}
if {$metricDataFormat != 0} {
throw "PDF4TCL" "unknown horizontal metric data format"
}
if {$numberOfHMetrics == 0} {
throw "PDF4TCL" "number of horizontal metrics is 0"
}
# maxp - Maximum profile table
set ttfpos [lindex $ttftables(maxp) 1]
binary scan $ttfdata "@${ttfpos}SuSuSu" \
ver_maj ver_min numGlyphs
if {$ver_maj != 1} {
throw "PDF4TCL" "unknown maxp table version"
}
if {!$charInfo} return
# We don't care of this earlier:
if {$glyphDataFormat != 0} {
throw "PDF4TCL" "unknown glyph data format"
}
# cmap - Character to glyph index mapping table
set ttfpos [lindex $ttftables(cmap) 1]
set cmap_offset $ttfpos
binary scan $ttfdata "@${ttfpos}x2Su" cmapTableCount
incr ttfpos 4
set priority 0
for {set f 0} {$f < $cmapTableCount} {incr f} {
binary scan $ttfdata "@${ttfpos}SuSuIu" platformID encodingID offset
incr ttfpos 8
binary scan $ttfdata "@[expr {$cmap_offset+$offset}]Su" format
if {$format ni [list 4 6 10 12 13]} continue
switch -glob -- $platformID,$encodingID,$priority {
3,10,* {set stoffset $offset; break}
0,4,* - 0,6,* {set stoffset $offset; set priority 3}
3,1,0 - 3,1,1 {set stoffset $offset; set priority 2}
3,*,0 {set stoffset $offset; set priority 1}
0,5,0 {continue}
0,*,0 - 1,0,0 - 1,1,0 {set stoffset $offset}
}
}
if {![info exists stoffset]} {
throw "PDF4TCL" "font does not have cmap for Unicode"
}
set unicode_cmap_offset [expr {$cmap_offset + $stoffset}]
binary scan $ttfdata "@${unicode_cmap_offset}Su" format
switch -exact -- $format {
4 {
binary scan $ttfdata "@${unicode_cmap_offset}x2Su" length
set ttfpos [expr {$unicode_cmap_offset + 6}]
binary scan $ttfdata "@${ttfpos}Su" segCount
set segCount [expr {$segCount / 2}]
set limit [expr {$unicode_cmap_offset + $length}]
set ttfpos [expr {$unicode_cmap_offset + 14}]
binary scan $ttfdata "@${ttfpos}Su$segCount" endCount
set ttfpos [expr {$ttfpos + 2*$segCount + 2}]
binary scan $ttfdata "@${ttfpos}Su$segCount" startCount
set ttfpos [expr {$ttfpos + 2*$segCount}]
binary scan $ttfdata "@${ttfpos}S$segCount" idDelta
set ttfpos [expr {$ttfpos + 2*$segCount}]
set idRangeOffset_start $ttfpos
binary scan $ttfdata "@${ttfpos}Su$segCount" idRangeOffset
# Now it gets tricky.
for {set f 0} {$f < $segCount} {incr f} {
set r_start [lindex $startCount $f]
set r_end [lindex $endCount $f]
for {set unichar $r_start} {$unichar <= $r_end} {incr unichar} {
set r_offset [lindex $idRangeOffset $f]
set r_delta [lindex $idDelta $f]
if {$r_offset == 0} {
set glyph [expr {($unichar + $r_delta) & 0xFFFF}]
} else {
set offset [expr {($unichar - $r_start) * 2 + $r_offset}]
set offset [expr {$idRangeOffset_start + 2 * $f + $offset}]
if {$offset > $limit} {
# workaround for broken fonts (like Thryomanes)
set glyph 0
} else {
binary scan $ttfdata "@${offset}Su" glyph
if {$glyph != 0} {
set glyph [expr {($glyph + $r_delta) & 0xFFFF}]
}
}
}
dict set BFA($ttfname,charToGlyph) $unichar $glyph
lappend glyphToChar($glyph) $unichar
}
}
}
6 {
set ttfpos [expr {$unicode_cmap_offset + 6}]
binary scan $ttfdata "@${ttfpos}SuSu" first count
set last [expr {$first + $count}]
incr ttfpos 4
for {set unichar $first} {$unichar < $last} {incr unichar} {
binary scan $ttfdata "@${ttfpos}Su" glyph
dict set BFA($ttfname,charToGlyph) $unichar $glyph
lappend glyphToChar($glyph) $unichar
incr ttfpos 2
}
}
10 {
set ttfpos [expr {$unicode_cmap_offset + 12}]
binary scan $ttfdata "@${ttfpos}IuIu" first count
set last [expr {$first + $count}]
incr ttfpos 4
for {set unichar $first} {$unichar < $last} {incr unichar} {
binary scan $ttfdata "@${ttfpos}Su" glyph
dict set BFA($ttfname,charToGlyph) $unichar $glyph
lappend glyphToChar($glyph) $unichar
incr ttfpos 2
}
}
12 {
set ttfpos [expr {$unicode_cmap_offset + 12}]
binary scan $ttfdata "@${ttfpos}Iu" segCount
incr ttfpos 4
for {set f 0} {$f < $segCount} {incr f} {
binary scan $ttfdata "@${ttfpos}IuIuIu" start end glyph
for {set unichar $start} {$unichar <= $end} {incr unichar} {
dict set BFA($ttfname,charToGlyph) $unichar $glyph
lappend glyphToChar($glyph) $unichar
incr glyph
}
incr ttfpos 12
}
}
13 {
set ttfpos [expr {$unicode_cmap_offset + 12}]
binary scan $ttfdata "@${ttfpos}Iu" segCount
incr ttfpos 4
for {set f 0} {$f < $segCount} {incr f} {
binary scan $ttfdata "@${ttfpos}IuIuIu" start end glyph
for {set unichar $start} {$unichar <= $end} {incr unichar} {
dict set BFA($ttfname,charToGlyph) $unichar $glyph
lappend glyphToChar($glyph) $unichar
}
incr ttfpos 12
}
}
}
#-----------------------------------------------------
# hmtx - Horizontal metrics table
# (needs data from hhea, maxp, and cmap tables)
set ttfpos [lindex $ttftables(hmtx) 1]
for {set glyph 0} {$glyph < $numberOfHMetrics} {incr glyph} {
# advance width and left side bearing. lsb is actually signed
# short, but we don't need it anyway (except for subsetting)
binary scan $ttfdata "@${ttfpos}SuSu" aw lsb
incr ttfpos 4
lappend BFA($ttfname,hmetrics) [list $aw $lsb]
set aws [Rescale $aw]
if {$glyph == 0} {set BFA($ttfname,defaultWidth) $aws}
if {[info exists glyphToChar($glyph)]} {
foreach char $glyphToChar($glyph) {
dict set BFA($ttfname,charWidths) $char $aws
}
}
}
# The rest of the table only lists advance left side bearings.
# so we reuse aw set by the last iteration of the previous loop.
# -- BUG (in reportlab) fixed here: aw used scaled in hmetrics,
# -- i.e. float (must be int)
for {set glyph $numberOfHMetrics} {$glyph < $numGlyphs} {incr glyph} {
binary scan $ttfdata "@${ttfpos}Su" lsb
incr ttfpos 2
lappend BFA($ttfname,hmetrics) [list $aw $lsb]
if {[info exists glyphToChar($glyph)]} {
foreach char $glyphToChar($glyph) {
dict set BFA($ttfname,charWidths) $char $aws
}
}
}
# loca - Index to location
set ttfpos [lindex $ttftables(loca) 1]
incr numGlyphs
if {$indexToLocFormat == 0} {
binary scan $ttfdata "@${ttfpos}Su$numGlyphs" glyphPositions
foreach el $glyphPositions {
lappend BFA($ttfname,glyphPos) [expr {$el << 1}]
}
} elseif {$indexToLocFormat == 1} {
binary scan $ttfdata "@${ttfpos}Iu$numGlyphs" BFA($ttfname,glyphPos)
} else {
throw "PDF4TCL" "unknown location table format $indexToLocFormat"
}
}
proc Rescale {x} {
variable BFA
variable ttfname
return [expr {$x * 1000.0 / $BFA($ttfname,unitsPerEm)}]
}
proc ConvertToUTF16BE {uchar} {
if {$uchar < 65536} {
return $uchar
}
set uchar [expr {$uchar - 0x010000}]
return [expr {((0xD800 + ($uchar >> 10)) << 16) + (0xDC00 + ($uchar & 0x3FF))}]
}
# Creates a ToUnicode CMap for a given subset.
proc MakeToUnicodeCMap {fontname subset} {
set len [llength $subset]
set cmap "/CIDInit /ProcSet findresource begin\n"
append cmap "12 dict begin\n"
append cmap "begincmap\n"
append cmap "/CIDSystemInfo\n"
append cmap "<< /Registry ($fontname)\n"
append cmap "/Ordering ($fontname)\n"
append cmap "/Supplement 0\n"
append cmap ">> def\n"
append cmap "/CMapName /$fontname def\n"
append cmap "/CMapType 2 def\n"
append cmap "1 begincodespacerange\n"
append cmap "<00> <[format %02X [expr {$len-1}]]>\n"
append cmap "endcodespacerange\n"
append cmap "$len beginbfchar\n"
set f 0
foreach uchar $subset {
append cmap [format "<%02X> <%04X>\n" $f [ConvertToUTF16BE $uchar]]
incr f
}
append cmap "endbfchar\n"
append cmap "endcmap\n"
append cmap "CMapName currentdict /CMap defineresource pop\n"
append cmap "end\n"
append cmap "end\n"
return $cmap
}
# Create a subset of a TrueType font. Subset is a list of unicode values.
proc MakeTTFSubset {bfname fontname subset} {
variable BFA
variable BFP
variable FontsAttrs
set GF_ARG_1_AND_2_ARE_WORDS [expr {1 << 0}]
set GF_WE_HAVE_A_SCALE [expr {1 << 3}]
set GF_MORE_COMPONENTS [expr {1 << 5}]
set GF_WE_HAVE_AN_X_AND_Y_SCALE [expr {1 << 6}]
set GF_WE_HAVE_A_TWO_BY_TWO [expr {1 << 7}]
# Build a mapping of glyphs in the subset to glyph numbers in
# the original font. Also build a mapping of UCS codes to
# glyph values in the new font.
# Start with 0 -> 0: "missing character"
set glyphMap [list 0] ; # new glyph index -> old glyph index
set glyphSet(0) 0 ; # old glyph index -> new glyph index
#codeToGlyph # unicode -> new glyph index
foreach code $subset {
if {[dict exists $BFA($bfname,charToGlyph) $code]} {
set originalGlyphIdx [dict get $BFA($bfname,charToGlyph) $code]
} else {
set originalGlyphIdx 0
}
if {![info exists glyphSet($originalGlyphIdx)]} {
set glyphSet($originalGlyphIdx) [llength $glyphMap]
lappend glyphMap $originalGlyphIdx
}
set codeToGlyph($code) $glyphSet($originalGlyphIdx)
}
# Also include glyphs that are parts of composite glyphs
set n 0
while {$n < [llength $glyphMap]} {
set originalGlyphIdx [lindex $glyphMap $n]
set glyphPos [lindex $BFA($bfname,glyphPos) $originalGlyphIdx]
set glyphEnd [lindex $BFA($bfname,glyphPos) $originalGlyphIdx+1]
set glyphLen [expr {$glyphEnd - $glyphPos}]
set cpos $glyphPos
binary scan $BFP($bfname,glyf) "@${cpos}S" numberOfContours
if {$numberOfContours < 0} {
# composite glyph
incr cpos 10
set flags $GF_MORE_COMPONENTS
while {$flags & $GF_MORE_COMPONENTS} {
binary scan $BFP($bfname,glyf) "@${cpos}SuSu" flags glyphIdx
incr cpos 4
if {![info exists glyphSet($glyphIdx)]} {
set glyphSet($glyphIdx) [llength $glyphMap]
lappend glyphMap $glyphIdx
}
if {$flags & $GF_ARG_1_AND_2_ARE_WORDS} {
incr cpos 4
} else {
incr cpos 2
}
if {$flags & $GF_WE_HAVE_A_SCALE} {
incr cpos 2
} elseif {$flags & $GF_WE_HAVE_AN_X_AND_Y_SCALE} {
incr cpos 4
} elseif {$flags & $GF_WE_HAVE_A_TWO_BY_TWO} {
incr cpos 8
}
}
}
incr n
}
set n [llength $glyphMap]
set numGlyphs $n
while {$n > 1 && \
[lindex $BFA($bfname,hmetrics) $n 0] == \
[lindex $BFA($bfname,hmetrics) $n-1 0]} {
incr n -1
}
set numberOfHMetrics $n
# post - PostScript
set t(post) "\x00\x03\x00\x00"
append t(post) [string range $BFP($bfname,post) 4 15]
append t(post) [string repeat "\0" 16]
# hhea - Horizontal Header
set t(hhea) [string range $BFP($bfname,hhea) 0 33]
append t(hhea) [binary format Su $numberOfHMetrics]
append t(hhea) [string range $BFP($bfname,hhea) 36 end]
# maxp - Maximum Profile
set t(maxp) [string range $BFP($bfname,maxp) 0 3]
append t(maxp) [binary format Su $numGlyphs]
append t(maxp) [string range $BFP($bfname,maxp) 6 end]
# cmap - Character to glyph mapping
set entryCount [llength $subset]
set length [expr {10 + $entryCount * 2}]
foreach char $subset {lappend tlist $codeToGlyph($char)}
set t(cmap) [binary format "SuSuSuSuSuSuSuSuSuSuSuSu*" 0 1 1 0 0 12 6 \
$length 0 0 $entryCount $tlist]
# hmtx - Horizontal Metrics
for {set f 0} {$f < $numGlyphs} {incr f} {
set originalGlyphIdx [lindex $glyphMap $f]
foreach {aw lsb} [lindex $BFA($bfname,hmetrics) $originalGlyphIdx] break
if {$f < $numberOfHMetrics} {
append t(hmtx) [binary format Su $aw]
}
append t(hmtx) [binary format Su $lsb]
}
# glyf - Glyph data
set pos 0
for {set f 0} {$f < $numGlyphs} {incr f} {
lappend offsets $pos
set originalGlyphIdx [lindex $glyphMap $f]
set glyphPos [lindex $BFA($bfname,glyphPos) $originalGlyphIdx]
set glyphEnd [lindex $BFA($bfname,glyphPos) $originalGlyphIdx+1]
set glyphLen [expr {$glyphEnd - $glyphPos}]
set glyphEndPos [expr {$glyphPos + $glyphLen - 1}]
set data [string range $BFP($bfname,glyf) $glyphPos $glyphEndPos]
# Fix references in composite glyphs
if {$glyphLen > 2} {
binary scan $data "S" compos
if {$compos < 0} {
set pos_in_glyph 10
set flags $GF_MORE_COMPONENTS
while {$flags & $GF_MORE_COMPONENTS} {
binary scan $data "@${pos_in_glyph}SuSu" flags glyphIdx
set odata $data
set data [string range $odata 0 $pos_in_glyph+1]
append data [binary format Su $glyphSet($glyphIdx)]
append data [string range $odata $pos_in_glyph+4 end]
incr pos_in_glyph 4
if {$flags & $GF_ARG_1_AND_2_ARE_WORDS} {
incr pos_in_glyph 4
} else {
incr pos_in_glyph 2
}
if {$flags & $GF_WE_HAVE_A_SCALE} {
incr pos_in_glyph 2
} elseif {$flags & $GF_WE_HAVE_AN_X_AND_Y_SCALE} {
incr pos_in_glyph 4
} elseif {$flags & $GF_WE_HAVE_A_TWO_BY_TWO} {
incr pos_in_glyph 8
}
}
}
}
append t(glyf) $data
incr pos $glyphLen
if {$pos % 4 != 0} {
set padding [expr {4 - $pos % 4}]
append t(glyf) [string repeat "\0" $padding]
incr pos $padding
}
}
lappend offsets $pos
# loca - Index to location
if {(($pos + 1) >> 1) > 0xFFFF} {
set indexToLocFormat 1 ; # long format
set t(loca) [binary format "Iu*" $offsets]
} else {
set indexToLocFormat 0 ; # short format
foreach offset $offsets {
append t(loca) [binary format "Su" [expr {$offset >> 1}]]
}
}
# head - Font header
set t(head) [string range $BFP($bfname,head) 0 7]
append t(head) [string repeat "\0" 4]
append t(head) [string range $BFP($bfname,head) 12 49]
append t(head) [binary format Su $indexToLocFormat]
append t(head) [string range $BFP($bfname,head) 52 end]
#----------------------------------------------------------------------
set tables [lsort -unique [concat $BFA($bfname,tables) [array names t]]]
set numTables [llength $tables]
set searchRange 1
set entrySelector 0
while {$searchRange * 2 <= $numTables} {
set searchRange [expr {$searchRange * 2}]
incr entrySelector
}
set searchRange [expr {$searchRange * 16}]
set rangeShift [expr {$numTables * 16 - $searchRange}]
# Header
set res [binary format "IuSuSuSuSu" [expr {0x00010000}] $numTables \
$searchRange $entrySelector $rangeShift]
# Table directory
set offset [expr {12 + $numTables * 16}]
foreach tag $tables {
if {$tag eq "head"} {set head_start $offset}
if {[info exists t($tag)]} {
set len [string length $t($tag)]
set checksum [CalcTTFCheckSum $t($tag) 0 $len]
} else {
set len [string length $BFP($bfname,$tag)]
set checksum [CalcTTFCheckSum $BFP($bfname,$tag) 0 $len]
}
append res [binary format a4IuIuIu $tag $checksum $offset $len]
incr offset [expr {($len + 3) & ~3}]
}
# Table data.
foreach tag $tables {
if {[info exists t($tag)]} {
set len [string length $t($tag)]
append res $t($tag)
} else {
set len [string length $BFP($bfname,$tag)]
append res $BFP($bfname,$tag)
}
append res [string repeat "\0" [expr {(4 - ($len & 3)) & 3}]]
}
set len [string length $res]
set checksum [CalcTTFCheckSum $res 0 $len]
incr head_start 7
set checksum [expr {(0xB1B0AFBA - $checksum) & 0xFFFFFFFF}]
set res "[string range $res 0 $head_start][binary format Iu $checksum][string range $res $head_start+5 end]"
set FontsAttrs($fontname,data) $res
set FontsAttrs($fontname,SubFontIdx) $BFA($bfname,SubFontIdx)
incr BFA($bfname,SubFontIdx)
}
# make subfont name
proc MakeSFNamePrefix {idx} {
string map {0 A 1 B 2 C 3 D 4 E 5 F 6 G 7 H 8 I 9 J} [format %06d $idx]
}
# ----- General font support -----
# Create Font from BaseFont:
proc createFont {bfname fontname enc_name} {
variable FontsAttrs
variable BFA
variable Fonts
set subset [list]
for {set f 0} {$f<256} {incr f} {lappend codes $f}
set uchars [encoding convertfrom $enc_name [binary format cu* $codes]]
foreach unichar [split $uchars {}] {
lappend subset [scan $unichar %c]
}
if {$BFA($bfname,FontType) eq "TTF"} {
# Create TTF subset here:
MakeTTFSubset $bfname $fontname $subset
set FontsAttrs($fontname,type) TTF
} else {
set FontsAttrs($fontname,type) Type1
}
lappend Fonts $fontname
set FontsAttrs($fontname,basefontname) $bfname
set FontsAttrs($fontname,uniset) $subset
set FontsAttrs($fontname,specialencoding) 0
set FontsAttrs($fontname,encoding) $enc_name
}
# Give list of available fonts
proc getFonts {} {
variable Fonts
return $Fonts
}
# subset must be a list of unicode values:
proc createFontSpecEnc {bfname fontname subset} {
variable FontsAttrs
variable BFA
variable Fonts
if {$BFA($bfname,FontType) eq "TTF"} {
# Create TTF subset here:
MakeTTFSubset $bfname $fontname $subset
set FontsAttrs($fontname,type) TTF
} else {
set FontsAttrs($fontname,type) Type1
}
lappend Fonts $fontname
set FontsAttrs($fontname,basefontname) $bfname
set FontsAttrs($fontname,uniset) $subset
set FontsAttrs($fontname,specialencoding) 1
set symcode 0
foreach ucode $subset {
set uchar [format %c $ucode]
dict set FontsAttrs($fontname,encoding) $uchar \
[binary format cu $symcode]
incr symcode
}
}
# ===== Procs for Type1 fonts processing =====
# Create encoding differences list:
proc MakeEncDiff {BFN fontname} {
variable BFA
# get WinAnsiEncoding unicodes:
for {set f 0} {$f < 256} {incr f} {lappend bcodes $f}
set bchars [encoding convertfrom cp1252 [binary format cu* $bcodes]]
foreach unichar [split $bchars {}] {
lappend bset [scan $unichar %c]
}
set f 0
set res [list]
set eqflag 1
foreach ucode $::pdf4tcl::FontsAttrs($fontname,uniset) bcode $bset {
if {$ucode != $bcode} {
if {$eqflag} {lappend res $f}
if {[dict exists $BFA($BFN,uni2glyph) $ucode]} {
lappend res "/[dict get $BFA($BFN,uni2glyph) $ucode]"
} else {
lappend res "/.notdef"
}
set eqflag 0
} else {
set eqflag 1
}
incr f
}
return $res
}
proc PfbCheck {pos data mark} {
binary scan $data "@${pos}cucu" d0 d1
if {($d0 != 0x80) || ($d1 != $mark)} {
throw "PDF4TCL" "bad pfb data at $pos"
}
if {$mark == 3} return; #PFB_EOF
incr pos 2
binary scan $data "@${pos}iu" l
incr pos 4
set npos [expr {$pos + $l}]
if {$npos > [string length $data]} {
throw "PDF4TCL" "pfb data is too short"
}
return $npos
}
# There's no need to create NEW binary stream, use font as is:
proc ParsePFB {} {
variable type1PFB
variable type1name
variable BFA
set p1 [PfbCheck 0 $type1PFB 1]
set p2 [PfbCheck $p1 $type1PFB 2]
set p3 [PfbCheck $p2 $type1PFB 1]
PfbCheck $p3 $type1PFB 3
set BFA($type1name,Length1) [expr {$p1-6}]
set BFA($type1name,Length2) [expr {$p2-$p1-6}]
set BFA($type1name,Length3) [expr {$p3-$p2-6}]
# Extract the type 1 font from PFB
set d1 [string range $type1PFB 6 [expr {$p1 - 1}]]
set d2 [string range $type1PFB [expr {$p1 + 6}] [expr {$p2 - 1}]]
set d3 [string range $type1PFB [expr {$p2 + 6}] [expr {$p3 - 1}]]
set BFA($type1name,data) $d1$d2$d3
}
# Creates charWidths and mapping 'unicode=>glyph_name' for this font.
proc ParseAFM {} {
variable type1AFM
variable type1name
variable BFA
variable GlName2Uni
array set nmap {Ascender ascend Descender descend FontBBox bbox}
set BFA($type1name,ascend) 1000
set BFA($type1name,descend) 0
set BFA($type1name,CapHeight) 1000
set BFA($type1name,ItalicAngle) 0
set BFA($type1name,stemV) 0
set BFA($type1name,bbox) [list 0 0 1000 1000]
set lineslst [split $type1AFM "\n"]
if {[llength $lineslst] < 2} {
throw "PDF4TCL" "AFM hasn't enough data"
}
set InMetrics 0
set InHeader 0
foreach line $lineslst {
if {[string equal -nocase -length 7 $line comment]} continue
# StartCharMetrics terminates header:
switch -nocase -glob -- $line {
"StartCharMetrics*" {set InMetrics 1; continue}
"StartFontMetrics*" {set InHeader 1; continue}
"EndCharMetrics*" {break}
}
if {$InMetrics} {
set toklst [list]
set reslst [list]
# Create toklst -- list of needed tokens (only starting three):
foreach chunk [lrange [split $line ";"] 0 2] {
foreach el $chunk {
lappend toklst $el
}
}
# Convert and store tokens:
foreach {l r} $toklst {et ss} [list C %d WX %d N %s] {
if {$l != $et} {
throw "PDF4TCL" "bad line in font AFM ($et)"
}
if {![scan $r $ss val]} {
throw "PDF4TCL" "incorrect '$et' value in font AFM"
}
lappend reslst $val
}
# Must create charWidths and font's Uni2Glyph here:
set N [lindex $reslst 2]
set WX [lindex $reslst 1]
set ucode -1
if {$N ne ".notdef"} {
catch {set ucode $GlName2Uni($N)}
} else {
set ucode 0
}
if {($ucode == -1) && [string equal -length 3 $N "uni"]} {
scan $N "uni%x" ucode
}
if {$ucode != -1} {
dict set BFA($type1name,charWidths) $ucode $WX
dict set BFA($type1name,uni2glyph) $ucode $N
}
} elseif {$InHeader} {
# Split into 2 parts on first space:
set idx [string first " " $line]
set l [string range $line 0 $idx-1]
set r [string range $line $idx+1 end]
if {[info exists nmap($l)]} {
set l $nmap($l)
}
set BFA($type1name,$l) $r
}
}
}
proc createBaseType1Font {basefontname afm_data pfb_data} {
variable type1name $basefontname
variable type1AFM $afm_data
variable type1PFB $pfb_data
InitBaseType1
}
proc loadBaseType1Font {basefontname AFMfilename PFBfilename} {
variable type1name $basefontname
variable type1AFM
variable type1PFB
set fd [open $AFMfilename "r"]
set type1AFM [read $fd]
close $fd
set fd [open $PFBfilename "rb"]
set type1PFB [read $fd]
close $fd
InitBaseType1
}
proc InitBaseType1 {} {
variable type1name
variable type1AFM
variable type1PFB
ParseAFM
ParsePFB
set ::pdf4tcl::BFA($type1name,FontType) Type1
unset -nocomplain type1PFB
unset -nocomplain type1AFM
unset -nocomplain type1name
}
# The incoming RGB must contain three values in the range 0.0 to 1.0
# The return value is CMYK as a list of values in the range 0.0 to 1.0
proc rgb2Cmyk {RGB} {
foreach {r g b} $RGB break
# Black, including some margin for float roundings
if {$r <= 0.00001 && $g <= 0.00001 && $b <= 0.00001} {
return [list 0.0 0.0 0.0 1.0]
}
set c [expr {1.0 - $r}]
set m [expr {1.0 - $g}]
set y [expr {1.0 - $b}]
# k is min of c/m/y
set k [expr {min($c, $m, $y)}]
# k is less than 1 since only black would give exactly 1
# so all divisions are safe.
# Since k is min, all numerators are >= 0
# All numerators are <= denominators, leaving all results <= 1.0
set c [expr {($c - $k) / (1.0 - $k)}]
set m [expr {($m - $k) / (1.0 - $k)}]
set y [expr {($y - $k) / (1.0 - $k)}]
return [list $c $m $y $k]
}
# The incoming CMYK must contain four values in the range 0.0 to 1.0
# The return value is RGB as a list of values in the range 0.0 to 1.0
proc cmyk2Rgb {CMYK} {
foreach {c m y k} $CMYK break
# Black, including some margin for float roundings
if {$k >= 0.99999} {
return [list 0.0 0.0 0.0]
}
set c [expr {$c * (1.0 - $k) + $k}]
set m [expr {$m * (1.0 - $k) + $k}]
set y [expr {$y * (1.0 - $k) + $k}]
set r [expr {1.0 - $c}]
set g [expr {1.0 - $m}]
set b [expr {1.0 - $y}]
return [list $r $g $b]
}
}
#######################################################################
# Object used for generating pdf
#######################################################################
catch {oo::class create ::pdf4tcl::pdf4tcl}
oo::define ::pdf4tcl::pdf4tcl {
variable pdf
# In 8.5 recode these as dicts within the pdf array
variable images
variable files
variable fonts
variable bitmaps
variable extgs
variable patterns
variable grads
variable metadata
# Array of type1 base fonts already included in this PDF file:
variable type1basefonts
#######################################################################
# Snit-like option handling
#######################################################################
variable options
# Define an option
# Should be called from constructor
method Option {option args} {
my variable optiondefs
my variable optiondeflist
dict set optiondefs $option -readonly 0
dict set optiondefs $option -default ""
dict set optiondefs $option -validatemethod ""
dict set optiondefs $option -configuremethod ""
dict set optiondefs $option _Initialised 0
foreach {opt val} $args {
dict set optiondefs $option $opt $val
}
set options($option) [dict get $optiondefs $option -default]
# Keep a nice list available
set optiondeflist [lsort -dictionary [dict keys $optiondefs]]
}
# Handle a configuration command.
# Should always be called from constructor
method Configurelist {lst} {
my variable optiondefs
my variable optiondeflist
if {[llength $lst] % 2 != 0} {
throw "PDF4TCL" "wrong number of args"
}
foreach {option value} $lst {
# TODO: recode to use prefix matching
#tcl::prefix match $optiondeflist $option
if {![dict exists $optiondefs $option]} {
throw "PDF4TCL" "unknown option \"$option\""
}
if {[dict get $optiondefs $option -readonly] && \
[dict get $optiondefs $option _Initialised]} {
throw "PDF4TCL" \
"option $option can only be set at instance creation"
}
if {[dict get $optiondefs $option -validatemethod] ne ""} {
##nagelfar ignore Non static subcommand
my [dict get $optiondefs $option -validatemethod] \
$option $value
}
if {[dict get $optiondefs $option -configuremethod] ne ""} {
##nagelfar ignore Non static subcommand
my [dict get $optiondefs $option -configuremethod] \
$option $value
} else {
set options($option) $value
}
dict set optiondefs $option _Initialised 1
}
foreach option [dict keys $optiondefs] {
if {![dict get $optiondefs $option _Initialised]} {
# Uninitialised options should get their defaults through
# configuremethod if there is any.
if {[dict get $optiondefs $option -configuremethod] ne ""} {
##nagelfar ignore Non static subcommand
my [dict get $optiondefs $option -configuremethod] \
$option [dict get $optiondefs $option -default]
}
dict set optiondefs $option _Initialised 1
}
}
}
method cget {option} {
return $options($option)
}
method configure {args} {
if {$args eq {}} {
return [array get options]
}
if {[llength $args] == 1} {
return $options([lindex $args 0])
}
my Configurelist $args
}
#######################################################################
# Option handling methods
#######################################################################
# Validator for -paper
method CheckPaper {option value} {
set papersize [pdf4tcl::getPaperSize $value]
if {[llength $papersize] == 0} {
throw "PDF4TCL" "papersize \"$value\" is unknown"
}
}
# Validator for -unit
method CheckUnit {option value} {
if {![info exists ::pdf4tcl::units($value)]} {
throw "PDF4TCL" "unit \"$value\" is unknown"
}
}
# Validator for -margin
method CheckMargin {option value} {
switch [llength $value] {
1 - 2 - 4 {
foreach elem $value {
if {[catch {pdf4tcl::getPoints $elem}]} {
throw "PDF4TCL" "bad margin value \"$elem\""
}
}
}
default {
throw "PDF4TCL" "bad margin list \"$value\""
}
}
}
# Validator for boolean options
method CheckBoolean {option value} {
if {![string is boolean -strict $value]} {
throw "PDF4TCL" "option $option must have a boolean value"
}
}
# Validator for -rotate
method CheckRotation {option value} {
my CheckNumeric $value rotation -nonnegative -integer
if { $value % 90 } {
throw "PDF4TCL" "rotation $value not a multiple of 90"
}
}
# Validator helper for numerics
##nagelfar syntax _obj,pdf4tcl\ CheckNumeric x x o*
##nagelfar option _obj,pdf4tcl\ CheckNumeric \
-nonnegative -positive -integer -unit
##nagelfar option _obj,pdf4tcl\ CheckNumeric\ -unit x
method CheckNumeric {val what args} {
set origVal $val
# If -unit is given, the value should be interpreted by getPoints
set i [lsearch -exact $args -unit]
if {$i >= 0} {
set unit [lindex $args [expr {$i + 1}]]
if {[catch {pdf4tcl::getPoints $val $unit} p]} {
throw "PDF4TCL" "bad $what \"$val\", must be numeric"
}
set val $p
}
if {![string is double -strict $val]} {
throw "PDF4TCL" "bad $what \"$origVal\", must be numeric"
}
set nonneg [lsearch -exact $args -nonnegative]
set pos [lsearch -exact $args -positive]
set int [lsearch -exact $args -integer]
if {$nonneg >= 0 && $val < 0} {
throw "PDF4TCL" "bad $what \"$origVal\", may not be negative"
}
if {$pos >= 0 && $val <= 0} {
throw "PDF4TCL" "bad $what \"$origVal\", must be positive"
}
if {$int >= 0 && ![string is integer -strict $val]} {
throw "PDF4TCL" "bad $what \"$origVal\", must be integer"
}
return $val
}
# Configure method for page properties
method SetPageOption {option value} {
set options($option) $value
# Fill in page properties
my SetPageSize $options(-paper) $options(-landscape) \
$options(-rotate)
my SetPageMargin $options(-margin)
}
# Configure method for -unit
method SetUnit {option value} {
set options($option) $value
set pdf(unit) $::pdf4tcl::units($value)
}
#######################################################################
# Constructor
#######################################################################
constructor {args} {
# Object should be able to find pdf4tcl help procedures
namespace path [list {*}[namespace path] ::pdf4tcl]
set pdf(bookmarks) {}
set pdf(forms) {}
# The unit translation factor is needed before parsing arguments
set pdf(unit) 1.0
my Option -file -default "" -readonly 1
my Option -paper -default a4 -validatemethod CheckPaper \
-configuremethod SetPageOption
my Option -landscape -default 0 -validatemethod CheckBoolean \
-configuremethod SetPageOption
my Option -orient -default 1 -validatemethod CheckBoolean
my Option -cmyk -default 0 -validatemethod CheckBoolean \
-readonly 1
my Option -unit -default p -validatemethod CheckUnit \
-configuremethod SetUnit -readonly 1
my Option -compress -default 1 -validatemethod CheckBoolean \
-readonly 1
my Option -margin -default 0 -validatemethod CheckMargin \
-configuremethod SetPageOption
my Option -rotate -default 0 -validatemethod CheckRotation \
-configuremethod SetPageOption
my Configurelist $args
# Document data
set pdf(pages) {}
set pdf(pdf_obj) 4 ;# Objects 1-3 are reserved for use in "finish"
set pdf(out_pos) 0
set pdf(data_start) 0
set pdf(data_len) 0
array set fonts {}
array set type1basefonts {}
set pdf(font_set) false
set pdf(in_text_object) false
array set images {}
array set files {}
array set bitmaps {}
array set extgs {}
array set patterns {}
array set grads {}
set pdf(objects) {}
set pdf(compress) $options(-compress)
set pdf(finished) false
set pdf(inPage) false
set pdf(fillColor) [list 0 0 0]
# start without default font
set pdf(font_size) 1
set pdf(current_font) ""
set pdf(line_spacing) 1.0
# Page data
# Fill in page properties
my SetPageSize $options(-paper) $options(-landscape) \
$options(-rotate)
my SetPageMargin $options(-margin)
set pdf(orient) $options(-orient)
set pdf(cmyk) $options(-cmyk)
# The first buffer is for collecting page data until end of page.
# This is to support compressing whole pages.
set pdf(ob) ""
# Write to file directly if requested.
set pdf(ch) ""
if {$options(-file) ne ""} {
if {[catch {open $options(-file) "w"} ch]} {
throw "PDF4TCL" "could not open file $options(-file) for writing: $ch"
}
fconfigure $ch -translation binary
set pdf(ch) $ch
}
# collect output in memory
set pdf(pdf) ""
# Start on pdfout
my Pdfout "%PDF-1.4\n"
set pdf(version) 1.4
# Add some chars >= 0x80 as recommended by the PDF standard
# to make it easy to detect that this is not an ASCII file.
my Pdfout "%\xE5\xE4\xF6\n"
}
destructor {
# Close any open channel
if {[info exists pdf(ch)] && $pdf(ch) ne ""} {
catch {my finish}
catch {close $pdf(ch)}
set pdf(ch) ""
}
}
# This is only for internal testing
method DebugGetInternalState {} {
array get pdf
}
export DebugGetInternalState
#######################################################################
# Collect PDF Output
#######################################################################
# Add raw data to accumulated pdf output
method Pdfout {out} {
append pdf(ob) $out
incr pdf(out_pos) [string length $out]
}
# Add line of words to accumulated pdf output
method Pdfoutn {args} {
set out [join $args " "]\n
my Pdfout $out
}
# Helper to format a line consisting of numbers and last a command
method Pdfoutcmd {args} {
set str ""
foreach num [lrange $args 0 end-1] {
append str [Nf $num] " "
}
append str "[lindex $args end]\n"
my Pdfout $str
}
# Move data from pdf(ob) cache to final destination.
# Return number of bytes added
method Flush {{compress 0}} {
set data $pdf(ob)
set pdf(ob) ""
if {$compress} {
set data [zlib compress $data]
}
set len [string length $data]
if {$pdf(ch) eq ""} {
append pdf(pdf) $data
} else {
puts -nonewline $pdf(ch) $data
}
return $len
}
#######################################################################
# ?? Handling
#######################################################################
# If any feature requires PDF version > 1.4 they should call this
method RequireVersion {version} {
if {$version > $pdf(version)} {
set pdf(version) $version
}
}
#######################################################################
# Page Handling
#######################################################################
# Fill in page margin from a user specified value
method SetPageMargin {value} {
set value2 {}
foreach val $value {
lappend value2 [pdf4tcl::getPoints $val $pdf(unit)]
}
switch -- [llength $value2] {
1 {
set pdf(marginleft) [lindex $value2 0]
set pdf(marginright) [lindex $value2 0]
set pdf(margintop) [lindex $value2 0]
set pdf(marginbottom) [lindex $value2 0]
}
2 {
set pdf(marginleft) [lindex $value2 0]
set pdf(marginright) [lindex $value2 0]
set pdf(margintop) [lindex $value2 1]
set pdf(marginbottom) [lindex $value2 1]
}
4 {
set pdf(marginleft) [lindex $value2 0]
set pdf(marginright) [lindex $value2 1]
set pdf(margintop) [lindex $value2 2]
set pdf(marginbottom) [lindex $value2 3]
}
default { ##nagelfar nocover
# This should not happen since validation should catch it
puts "ARARARARARAR '$value'"
}
}
}
# Fill in page data from options
method SetPageSize {paper landscape rotation} {
set papersize [pdf4tcl::getPaperSize $paper $pdf(unit)]
set width [lindex $papersize 0]
set height [lindex $papersize 1]
# Switch if landscape has been asked for
if {$landscape} {
set tmp $width
set width $height
set height $tmp
}
set pdf(width) $width
set pdf(height) $height
set pdf(xpos) 0
set pdf(ypos) $height
set pdf(rotate) $rotation
set pdf(origxpos) 0
set pdf(origypos) $height
}
# Start on a new XObject
method startXObject {args} {
# Get some defaults from document
set localopts(-orient) $options(-orient)
set localopts(-landscape) 0
set localopts(-margin) 0
set localopts(-paper) {100p 100p}
set localopts(-rotate) 0
set localopts(-noimage) 0
set localopts(-xobject) 1
# Parse options
foreach {option value} $args {
switch -- $option {
-paper {
my CheckPaper $option $value
}
-landscape {
my CheckBoolean $option $value
}
-margin {
my CheckMargin $option $value
}
-orient {
my CheckBoolean $option $value
}
-rotate {
my CheckRotation $option $value
}
-noimage {
my CheckBoolean $option $value
}
default {
throw "PDF4TCL" "unknown option \"$option\""
}
}
set localopts($option) $value
}
set oid [eval \my startPage [array get localopts]]
set id xobject$oid
set images($id) [list $pdf(width) $pdf(height) $oid $localopts(-noimage)]
return $id
}
# Finish an XObject, this is just a wrapper for endPage available
# for symmetry with startXObject.
method endXObject {} {
my endPage
}
# Start on a new page
method startPage {args} {
# Get defaults from document
set localopts(-orient) $options(-orient)
set localopts(-landscape) $options(-landscape)
set localopts(-margin) $options(-margin)
set localopts(-paper) $options(-paper)
set localopts(-rotate) $options(-rotate)
# Unofficial option to overlay startXObject on startPage
set localopts(-xobject) 0
set localopts(-noimage) 0
if {[llength $args] % 2 != 0} {
# Uneven, error
throw "PDF4TCL" "uneven number of arguments to startPage"
} else {
# Parse options
foreach {option value} $args {
switch -- $option {
-paper {
my CheckPaper $option $value
}
-landscape {
my CheckBoolean $option $value
}
-margin {
my CheckMargin $option $value
}
-orient {
my CheckBoolean $option $value
}
-rotate {
my CheckRotation $option $value
}
-xobject {
my CheckBoolean $option $value
}
-noimage {
my CheckBoolean $option $value
}
default {
throw "PDF4TCL" "unknown option \"$option\""
}
}
set localopts($option) $value
}
}
if {$pdf(inPage)} {
my endPage
}
# Fill in page properties
my SetPageSize $localopts(-paper) $localopts(-landscape) \
$localopts(-rotate)
my SetPageMargin $localopts(-margin)
set pdf(orient) $localopts(-orient)
set pdf(inPage) 1
set pdf(inXObject) $localopts(-xobject)
# dimensions
if {!$pdf(inXObject)} {
set oid [my GetOid]
lappend pdf(pages) $oid
set pdf(pageobjid) $oid
# create page object without delimiter
set pdf(pageobj) {}
append pdf(pageobj) "$oid 0 obj\n"
append pdf(pageobj) "<</Type /Page\n"
append pdf(pageobj) "/Parent 2 0 R\n"
append pdf(pageobj) "/Resources 3 0 R\n"
append pdf(pageobj) "/Group <</S /Transparency /CS /DeviceRGB /I false /K false>>\n"
append pdf(pageobj) [format "/MediaBox \[0 0 %g %g\]\n" $pdf(width) $pdf(height)]
if {$pdf(rotate) != 0} {
append pdf(pageobj) "/Rotate $pdf(rotate)\n"
}
append pdf(pageobj) "/Contents \[[my NextOid] 0 R\]\n"
}
# reset annotations (this variable contains a list)
set pdf(annotations) {}
# start of contents
set oid [my GetOid]
my Pdfout "$oid 0 obj\n"
# Allocate an object for the page length
set pdf(pagelengthoid) [my GetOid 1]
my Pdfout "<<\n"
if {$pdf(inXObject)} {
my Pdfout "/Type /XObject\n"
my Pdfout "/Subtype /Form\n"
# If the XObject is created with -noimage it is not included in
# the image list in Resources. It then needs a ref to Resources.
if {$localopts(-noimage)} {
my Pdfout "/Resources 3 0 R\n"
}
my Pdfout [format "/BBox \[0 0 %g %g\]\n" $pdf(width) $pdf(height)]
# This matrix makes the final Xobject to be size 1x1 in user space
# just like an image
my Pdfout [format "/Matrix \[%g 0 0 %g 0 0\]\n" \
[expr {1.0/$pdf(width)}] \
[expr {1.0/$pdf(height)}]]
# TBD: Resources?
}
if {$pdf(compress)} {
my Pdfout "/Filter \[/FlateDecode\]\n"
}
my Pdfout "/Length $pdf(pagelengthoid) 0 R\n"
my Pdfout ">>\nstream\n"
set pdf(data_start) $pdf(out_pos)
set pdf(in_text_object) false
# no font set on new pages
set pdf(font_set) false
# capture output
my Flush
return $oid
}
# Finish a page
method endPage {} {
if {! $pdf(inPage)} {
return
}
if {$pdf(in_text_object)} {
my Pdfout "\nET\n"
}
# get buffer
set data_len [my Flush $pdf(compress)]
set pdf(out_pos) [expr {$pdf(data_start)+$data_len}]
my Pdfout "\nendstream\n"
my Pdfout "endobj\n\n"
# Create Length object
my StoreXref $pdf(pagelengthoid)
my Pdfout "$pdf(pagelengthoid) 0 obj\n"
incr data_len
my Pdfout "$data_len\n"
my Pdfout "endobj\n\n"
set pdf(inPage) false
# insert annotations array and write page object
if {!$pdf(inXObject)} {
if {[llength $pdf(annotations)] > 0} {
append pdf(pageobj) "/Annots \[[join $pdf(annotations) \n]\]\n"
}
append pdf(pageobj) ">>\n"
append pdf(pageobj) "endobj\n\n"
my StoreXref $pdf(pageobjid)
my Pdfout $pdf(pageobj)
}
# Dump stored objects
my FlushObjects
}
method FlushObjects {} {
if {$pdf(inPage)} {
throw "PDF4TCL" "FlushObjects may not be called when in a page"
}
# Dump stored objects
foreach {oid body} $pdf(objects) {
my StoreXref $oid
my Pdfout $body
}
set pdf(objects) {}
my Flush
}
# This must create optionally compressed PDF stream.
# dictval must contain correct string value without >> terminator.
# Terminator and length will be added by this proc.
proc ::pdf4tcl::MakeStream {dictval body compress} {
set res $dictval
if {$compress} {
set body2 [zlib compress $body]
# Any win?
if {[string length $body2] + 20 < [string length $body]} {
append res "\n/Filter \[/FlateDecode\]"
set body $body2
}
}
set len [string length $body]
append res "\n/Length $len\n>>\nstream\n"
append res $body
append res "\nendstream"
return $res
}
# Create an object to be added to the stream at a suitable time.
# Returns the Object Id.
method AddObject {body} {
set oid [my GetOid 1]
lappend pdf(objects) $oid "$oid 0 obj\n$body\nendobj\n"
return $oid
}
# Finish document
method finish {} {
if {$pdf(finished)} {
return
}
if {$pdf(inPage)} {
my endPage
}
# Object 1 is the Root of the document
my StoreXref 1
my Pdfout "1 0 obj\n"
my Pdfout "<<\n"
my Pdfout "/Type /Catalog\n"
if {$pdf(version) > 1.4} {
my Pdfout "/Version $pdf(version)\n"
}
my Pdfout "/Pages 2 0 R\n"
# Determine the number of bookmarks to add to the document.
set nbookmarks [llength $pdf(bookmarks)]
if {$nbookmarks > 0} {
set bookmark_oid [my GetOid 1]
my Pdfout "/Outlines $bookmark_oid 0 R\n"
}
# Any forms?
if {[llength $pdf(forms)] > 0} {
set form_oid [my GetOid 1]
my Pdfout "/AcroForm $form_oid 0 R\n"
}
my Pdfout ">>\n"
my Pdfout "endobj\n\n"
# Object 2 lists the pages
my StoreXref 2
my Pdfout "2 0 obj\n"
my Pdfout "<<\n/Type /Pages\n"
my Pdfout "/Count [llength $pdf(pages)]\n"
my Pdfout "/Kids \["
foreach oid $pdf(pages) {
my Pdfout "$oid 0 R "
}
my Pdfout "\]\n"
my Pdfout ">>\n"
my Pdfout "endobj\n\n"
# Object 3 is the Resources Object
my StoreXref 3
my Pdfout "3 0 obj\n"
my Pdfout "<<\n"
my Pdfout "/ProcSet\[/PDF /Text /ImageC\]\n"
# font references
if {[array size fonts] > 0} {
my Pdfout "/Font <<\n"
foreach fontname [array names fonts] {
set oid $fonts($fontname)
my Pdfout "/$fontname $oid 0 R\n"
}
my Pdfout ">>\n"
}
# extended graphics state references
if {[array size extgs] > 0} {
my Pdfout "/ExtGState <<\n"
foreach egs [array names extgs] {
set oid $extgs($egs)
my Pdfout "/$egs $oid 0 R\n"
}
my Pdfout ">>\n"
}
# image references
if {[array size images] > 0} {
my Pdfout "/XObject <<\n"
foreach key [array names images] {
# If it is an XObject created with -noimage, it is not added.
if {![lindex $images($key) 3]} {
set oid [lindex $images($key) 2]
my Pdfout "/$key $oid 0 R\n"
}
}
my Pdfout ">>\n"
}
# pattern references
if {[array size patterns] > 0} {
my Pdfout "/ColorSpace <<\n"
if {$pdf(cmyk)} {
my Pdfout "/Cs1 \[/Pattern /DeviceCMYK\]\n"
} else {
my Pdfout "/Cs1 \[/Pattern /DeviceRGB\]\n"
}
my Pdfout ">>\n"
my Pdfout "/Pattern <<\n"
foreach key [array names patterns] {
set oid [lindex $patterns($key) 2]
my Pdfout "/$key $oid 0 R\n"
}
my Pdfout ">>\n"
}
# gradient references
if {[array size grads] > 0} {
my Pdfout "/Shading <<\n"
foreach key [array names grads] {
set oid [lindex $grads($key) 2]
my Pdfout "/$key $oid 0 R\n"
}
my Pdfout ">>\n"
}
my Pdfout ">>\nendobj\n\n" ;# Resources object
if {$nbookmarks > 0} {
set count [BookmarkCount $pdf(bookmarks) -1]
# Create the outline dictionary.
set oid [my NextOid]
my StoreXref $bookmark_oid
my Pdfout "$bookmark_oid 0 obj\n"
my Pdfout "<<\n/Type /Outlines\n"
my Pdfout "/First $oid 0 R\n"
my Pdfout "/Last [expr {$oid + $nbookmarks - 1}] 0 R\n"
if {$count} {
my Pdfout "/Count $count\n"
}
my Pdfout ">>\nendobj\n\n"
# Create the outline item dictionary for each bookmark.
set nbookmark 0
set parent $bookmark_oid
set previous {}
foreach bookmark $pdf(bookmarks) {
if {[lindex $bookmark 1] == 0} {
set previous [my BookmarkObject $parent $previous \
[lrange $pdf(bookmarks) $nbookmark end]]
}
incr nbookmark
}
}
# Any forms?
if {[llength $pdf(forms)] > 0} {
my StoreXref $form_oid
my Pdfout "$form_oid 0 obj\n"
my Pdfout "<<\n/Fields \[[join $pdf(forms) \n]\]\n"
my Pdfout "/DR 3 0 R\n"
my Pdfout ">>\nendobj\n\n"
}
# Create the PDF document information dictionary.
if {[array exists metadata]} {
set metadata_oid [my GetOid]
my StoreXref $metadata_oid
my Pdfout "$metadata_oid 0 obj\n<<\n"
foreach {name value} [array get metadata] {
my Pdfout "/$name ([CleanText $value $pdf(current_font)])\n"
}
my Pdfout ">>\nendobj\n\n"
}
# Cross reference table
set xref_pos $pdf(out_pos)
my Pdfout "xref\n"
my Pdfout "0 [my NextOid]\n"
my Pdfout "0000000000 65535 f \n"
for {set a 1} {$a<[my NextOid]} {incr a} {
set xref $pdf(xref,$a)
my Pdfout [format "%010ld 00000 n \n" $xref]
}
# Document trailer
my Pdfout "trailer\n"
my Pdfout "<<\n"
my Pdfout "/Size [my NextOid]\n"
my Pdfout "/Root 1 0 R\n"
if {[info exists metadata_oid]} {
my Pdfout "/Info $metadata_oid 0 R\n"
}
my Pdfout ">>\n"
my Pdfout "\nstartxref\n"
my Pdfout "$xref_pos\n"
my Pdfout "%%EOF\n"
my Flush
set pdf(finished) true
}
# Get finished PDF data
method get {} {
if {$pdf(inPage)} {
my endPage
}
if {! $pdf(finished)} {
my finish
}
return $pdf(pdf)
}
# Write PDF data to file
method write {args} {
set chan stdout
set outfile 0
foreach {arg value} $args {
switch -- $arg {
"-file" {
if {[catch {open $value "w"} chan]} {
throw "PDF4TCL" "could not open file $value for writing: $chan"
} else {
set outfile 1
}
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
fconfigure $chan -translation binary
puts -nonewline $chan [my get]
if {$outfile} {
close $chan
}
}
# Transform absolute user coordinates to page coordinates
# This should take into account orientation, margins.
method Trans {x y txName tyName} {
upvar 1 $txName tx $tyName ty
set px [pdf4tcl::getPoints $x $pdf(unit)]
set py [pdf4tcl::getPoints $y $pdf(unit)]
set tx [expr {$px + $pdf(marginleft)}]
if {$pdf(orient)} {
set ty [expr {$py + $pdf(margintop)}]
set ty [expr {$pdf(height) - $ty}]
} else {
set ty [expr {$py + $pdf(marginbottom)}]
}
}
# Transform relative user coordinates to page coordinates
# This should take into account orientation, but not margins.
method TransR {x y txName tyName} {
upvar 1 $txName tx $tyName ty
set tx [pdf4tcl::getPoints $x $pdf(unit)]
set ty [pdf4tcl::getPoints $y $pdf(unit)]
if {$pdf(orient)} {
set ty [expr {- $ty}]
}
}
# Returns width and height of drawable area, excluding margins.
method getDrawableArea {} {
set w [expr {$pdf(width) - $pdf(marginleft) - $pdf(marginright)}]
set h [expr {$pdf(height) - $pdf(margintop) - $pdf(marginbottom)}]
# Translate to current unit
set w [expr {$w / $pdf(unit)}]
set h [expr {$h / $pdf(unit)}]
return [list $w $h]
}
#######################################################################
# Bookmark Handling
#######################################################################
method bookmarkAdd {args} {
set closed 0
set level 0
set title {}
foreach {option value} $args {
switch -- $option {
-title {
set value [string trim $value]
if {[string length $value] == 0} {
throw "PDF4TCL" "option $option requires a string"
}
set title $value
}
-level {
my CheckNumeric $value -level -nonnegative -integer
set level $value
}
-closed {
my CheckBoolean $option $value
set closed $value
}
default {
throw "PDF4TCL" "unknown option \"$option\""
}
}
}
if {$pdf(pages) == {}} {
throw "PDF4TCL" "no pages defined"
}
# Determine the object id of the current page.
set oid [lindex $pdf(pages) end]
# Add the bookmark to the list.
lappend pdf(bookmarks) [list $oid $level $closed $title]
}
#---------------------------------------------------------------------------
# This procedure determines the number of open items of an outline
# dictionary object.
proc ::pdf4tcl::BookmarkCount {bookmarks level} {
set count 0
# Increment the count if the bookmark is not closed.
foreach bookmark $bookmarks {
if {[lindex $bookmark 1] <= $level} {break}
if {! [lindex $bookmark 2]} {
incr count
}
}
return $count
}
#---------------------------------------------------------------------------
# This procedure creates a outline item dictionary object.
method BookmarkObject {parent previous bookmarks} {
set bookmark [lindex $bookmarks 0]
set destination [lindex $bookmark 0]
set level [lindex $bookmark 1]
set closed [lindex $bookmark 2]
set title [lindex $bookmark 3]
set oid [my GetOid]
my StoreXref $oid
BookmarkProperties $oid $level [lrange $bookmarks 1 end] \
next first last count
if {$closed} {
set count [expr {-$count}]
}
my Pdfout "$oid 0 obj\n"
my Pdfout "<<\n/Title ([CleanText $title $pdf(current_font)])\n"
my Pdfout "/Parent $parent 0 R\n"
if {$previous != {}} {my Pdfout "/Prev $previous 0 R\n"}
if {$next != {}} {my Pdfout "/Next $next 0 R\n"}
if {$first != {}} {my Pdfout "/First $first 0 R\n"}
if {$last != {}} {my Pdfout "/Last $last 0 R\n"}
if {$count} {my Pdfout "/Count $count\n"}
my Pdfout "/Dest \[$destination 0 R /XYZ null null null\]\n"
my Pdfout ">>\n"
my Pdfout "endobj\n\n"
if {$next != {}} {
set previous $oid
}
# Create the bookmark objects for all bookmarks that are children of
# this bookmark.
if {$first != {}} {
set parent $oid
set prev {}
incr level
set n 0
foreach bookmark [lrange $bookmarks 1 end] {
incr n
if {[lindex $bookmark 1] < $level} {break}
if {[lindex $bookmark 1] == $level} {
set prev [my BookmarkObject $parent $prev \
[lrange $bookmarks $n end]]
}
}
}
return $previous
}
#---------------------------------------------------------------------------
# This procedure determines the properties for an outline item dictionary
# object.
proc ::pdf4tcl::BookmarkProperties {oid current bookmarks n f l c} {
upvar 1 $n next $f first $l last $c count
set next {}
set first {}
set last {}
# Determine the number of open descendants.
set count [BookmarkCount $bookmarks $current]
set child [expr {$current + 1}]
set n 0
foreach bookmark $bookmarks {
incr n
set level [lindex $bookmark 1]
if {$level < $current} {break}
# Determine the object ID for the next bookmark at the same level.
if {$next == {}} {
if {$level == $current} {
set next [expr {$oid + $n}]
continue
}
# Determine the object ID for the first and last child
# bookmarks.
if {$level == $child} {
if {$first == {}} {
set first [expr {$oid + $n}]
}
set last [expr {$oid + $n}]
}
}
}
}
#--------------------------------------------------------------------------
# Configure method for the PDF document metadata options.
method metadata {args} {
foreach {option value} $args {
set value [string trim $value]
if {[string length $value] > 0} {
switch -- $option {
-author {set metadata(Author) $value}
-creator {set metadata(Creator) $value}
-keywords {set metadata(Keywords) $value}
-producer {set metadata(Producer) $value}
-subject {set metadata(Subject) $value}
-title {set metadata(Title) $value}
-creationdate {
if {$value == 0} {
set value [clock seconds]
}
set c [clock format $value -format {D:%Y%m%d%H%M%S%z} -gmt 0]
set metadata(CreationDate) [string range $c 0 end-2]
}
}
}
}
}
#######################################################################
# Text Handling
#######################################################################
# Set current font
method setFont {size {fontname ""} {internal 0}} {
if {$fontname eq ""} {
if {$pdf(current_font) eq ""} {
throw "PDF4TCL" "no font family set"
}
set fontname $pdf(current_font)
}
# Font already loaded?
if {$fontname ni $::pdf4tcl::Fonts} {
throw "PDF4TCL" "font $fontname doesn't exist"
}
if {!$internal} {
set size [pdf4tcl::getPoints $size $pdf(unit)]
}
set pdf(current_font) $fontname
set pdf(font_size) $size
# Delay putting things in until we are actually on a page
if {$pdf(inPage)} {
my SetupFont
}
}
# Set current font for tkpath ptext object
method setTkpfont {size name weight slant} {
my variable canvasFontMapping
set bold [expr {$weight eq "bold"}]
set italic [expr {$slant ne "normal"}]
switch -glob [string tolower $name] {
*courier* - *fixed* {
set family Courier
if {$bold && $italic} {
append family -BoldOblique
} elseif {$bold} {
append family -Bold
} elseif {$italic} {
append family -BoldOblique
}
}
*times* - {*nimbus roman*} {
if {$bold && $italic} {
set family Times-BoldItalic
} elseif {$bold} {
set family Times-Bold
} elseif {$italic} {
set family Times-Italic
} else {
set family Times-Roman
}
}
*helvetica* - *arial* - {*nimbus sans*} - default {
set family Helvetica
if {$bold && $italic} {
append family -BoldOblique
} elseif {$bold} {
append family -Bold
} elseif {$italic} {
append family -BoldOblique
}
}
}
array set userMappingArr $canvasFontMapping
if {[info exists userMappingArr($name)]} {
set family $userMappingArr($name)
}
my setFont $size $family 1
}
# Helpers to temporarily store and restore the current font state
method PushFont {} {
lappend pdf(font_stack) \
[list $pdf(current_font) $pdf(font_size) $pdf(font_set)]
}
method PopFont {} {
if {![info exists pdf(font_stack)] || [llength $pdf(font_stack)] < 1} {
return
}
set old [lindex $pdf(font_stack) end]
set pdf(font_stack) [lrange $pdf(font_stack) 0 end-1]
foreach {pdf(current_font) pdf(font_size) pdf(font_set)} $old break
}
# Make Sure ZaDb font is available, for internal use
method SetupZaDbFont {} {
set fontname ZaDb
if {[info exists fonts($fontname)]} return
set body "<<\n/Type /Font\n"
append body "/Subtype /Type1\n"
append body "/Name /$fontname\n"
append body "/BaseFont /ZapfDingbats\n"
append body ">>"
set oid [my AddObject $body]
set fonts($fontname) $oid
}
# Set the current font on the page
method SetupFont {} {
variable ::pdf4tcl::BFA
if {$pdf(current_font) eq ""} {
throw "PDF4TCL" "no font set"
}
set fontname $pdf(current_font)
my Pdfoutn "/$fontname [Nf $pdf(font_size)]" "Tf"
my Pdfoutcmd 0 "Tr"
my Pdfoutcmd $pdf(font_size) "TL"
# Make sure a font object exists
if {![info exists fonts($fontname)]} {
set fonttype $::pdf4tcl::FontsAttrs($fontname,type)
if {$fonttype eq "std"} {
set body "<<\n/Type /Font\n"
append body "/Subtype /Type1\n"
append body "/Encoding /WinAnsiEncoding\n"
append body "/Name /$fontname\n"
append body "/BaseFont /$fontname\n"
append body ">>"
} elseif {$fonttype eq "TTF"} {
# Add truetype font objects:
set BFN $::pdf4tcl::FontsAttrs($fontname,basefontname)
set SFI $::pdf4tcl::FontsAttrs($fontname,SubFontIdx)
set BaseFN "[MakeSFNamePrefix $SFI]+$BFN"
# 1. Font subset binary data.
set lc [string length $::pdf4tcl::FontsAttrs($fontname,data)]
set dictv "<<\n/Length1 $lc"
set body [MakeStream $dictv \
$::pdf4tcl::FontsAttrs($fontname,data) \
$pdf(compress)]
set fsoid [my AddObject $body]
# 2. Font subset descriptor.
set body "<<\n/FontName /$BaseFN\n"
append body "/StemV [Nf $BFA($BFN,stemV)]\n"
append body "/FontFile2 $fsoid 0 R\n"
append body "/Ascent [Nf $BFA($BFN,ascend)]\n"
append body "/Flags $BFA($BFN,flags)\n"
append body "/Descent [Nf $BFA($BFN,descend)]\n"
append body "/ItalicAngle [Nf $BFA($BFN,ItalicAngle)]\n"
foreach n $BFA($BFN,bbox) {lappend fbbox [Nf $n]}
append body "/FontBBox \[$fbbox\]\n"
append body "/Type /FontDescriptor\n"
append body "/CapHeight [Nf $BFA($BFN,CapHeight)]\n>>"
set foid [my AddObject $body]
# 3. ToUnicode Cmap for subset.
set body [MakeStream "<<" \
[MakeToUnicodeCMap $BaseFN \
$::pdf4tcl::FontsAttrs($fontname,uniset)] \
$pdf(compress)]
set uoid [my AddObject $body]
# 4. Font object.
# Make array of widths here:
set Widths [list]
foreach ucode $::pdf4tcl::FontsAttrs($fontname,uniset) {
set res 0.0
if {[dict exists $BFA($BFN,charWidths) $ucode]} {
set res [dict get $::pdf4tcl::BFA($BFN,charWidths) $ucode]
}
lappend Widths [Nf $res]
}
set body "<<\n/FirstChar 0\n"
append body "/LastChar [expr {[llength $Widths]-1}]\n"
append body "/ToUnicode $uoid 0 R\n"
append body "/FontDescriptor $foid 0 R\n"
append body "/Name /$fontname\n"
append body "/BaseFont /$BaseFN\n"
append body "/Subtype /TrueType\n"
append body "/Widths \[$Widths\]\n"
append body "/Type /Font\n"
append body ">>"
} else {
# Add type1 font objects:
set BFN $::pdf4tcl::FontsAttrs($fontname,basefontname)
# Font data & descriptor if not already included in PDF file:
if {![info exists type1basefonts($BFN)]} {
#1. Font data:
set dictv "<<\n/Length1 $BFA($BFN,Length1)"
append dictv "\n/Length2 $BFA($BFN,Length2)"
append dictv "\n/Length3 $BFA($BFN,Length3)"
set body [MakeStream $dictv $BFA($BFN,data) $pdf(compress)]
set fsoid [my AddObject $body]
#2. Font descriptor:
set body "<<\n/FontName /$BFN\n"
append body "/StemV [Nf $BFA($BFN,stemV)]\n"
append body "/FontFile $fsoid 0 R\n"
append body "/Ascent [Nf $BFA($BFN,ascend)]\n"
append body "/Flags 34\n"
append body "/Descent [Nf $BFA($BFN,descend)]\n"
append body "/ItalicAngle [Nf $BFA($BFN,ItalicAngle)]\n"
foreach n $BFA($BFN,bbox) {lappend fbbox [Nf $n]}
append body "/FontBBox \[$fbbox\]\n"
append body "/Type /FontDescriptor\n"
append body "/CapHeight [Nf $BFA($BFN,CapHeight)]\n>>"
set foid [my AddObject $body]
set type1basefonts($BFN) $foid
} else {
set foid $type1basefonts($BFN)
}
# 3. ToUnicode Cmap.
set body [MakeStream "<<" \
[MakeToUnicodeCMap $BFN \
$::pdf4tcl::FontsAttrs($fontname,uniset)] \
$pdf(compress)]
set uoid [my AddObject $body]
# 4. Font object:
set Widths [list]
foreach ucode $::pdf4tcl::FontsAttrs($fontname,uniset) {
set res 0.0
if {[dict exists $BFA($BFN,charWidths) $ucode]} {
set res [dict get $::pdf4tcl::BFA($BFN,charWidths) $ucode]
}
lappend Widths [Nf $res]
}
set body "<<\n/FirstChar 0\n"
append body "/LastChar [expr {[llength $Widths]-1}]\n"
append body "/ToUnicode $uoid 0 R\n"
append body "/FontDescriptor $foid 0 R\n"
append body "/Name /$fontname\n"
append body "/BaseFont /$BFN\n"
append body "/Subtype /Type1\n"
append body "/Widths \[$Widths\]\n"
append body "/Type /Font\n"
set diffs [MakeEncDiff $BFN $fontname]
append body "/Encoding <<\n/Type /Encoding\n"
append body "/BaseEncoding /WinAnsiEncoding\n"
append body "/Differences \[$diffs\]\n>>\n>>"
}
set oid [my AddObject $body]
set fonts($fontname) $oid
}
set pdf(font_set) true
}
# Get metrics from current font.
# Supported metrics are:
# height = height of font's Bounding Box.
# ascend = top of typical glyph, displacement from anchor point.
# Typically positive.
# descend = bottom of typical glyph, displacement from anchor point.
# Typically negative.
# fixed = Boolean which is true if this is a fixed width font.
# bboxb = Bottom of Bounding Box displacement from anchor point.
# Typically a negative number since it is below the anchor point.
# bboxt = Top of Bounding Box displacement from anchor point.
# Typically a positive number.
# bboxy = bboxb, kept for backward compatibility
method getFontMetric {metric {internal 0}} {
if {$pdf(current_font) eq ""} {
throw "PDF4TCL" "no font set"
}
set BFN $::pdf4tcl::FontsAttrs($pdf(current_font),basefontname)
set bbox $::pdf4tcl::BFA($BFN,bbox)
switch $metric {
bboxy {set val [expr {[lindex $bbox 1] * 0.001}]}
bboxb {set val [expr {[lindex $bbox 1] * 0.001}]}
bboxt {set val [expr {[lindex $bbox 3] * 0.001}]}
fixed {return $::pdf4tcl::BFA($BFN,fixed)}
height {set val [expr {([lindex $bbox 3] - [lindex $bbox 1])* 0.001}]}
ascend - descend {
set val [expr {$::pdf4tcl::BFA($BFN,$metric) * 0.001}]
}
default {
if {![info exists ::pdf4tcl::BFA($BFN,$metric)]} {
throw "PDF4TCL" "metric $metric doesn't exist"
}
return $::pdf4tcl::BFA($BFN,$metric)
}
}
# Translate to current unit
if {!$internal} {
set val [expr {$val/ $pdf(unit)}]
}
return [expr {$val * $pdf(font_size)}]
}
# Get the width of a string under the current font.
method getStringWidth {txt {internal 0}} {
if {$pdf(current_font) eq ""} {
throw "PDF4TCL" "no font set"
}
set w 0.0
foreach ch [split $txt ""] {
set w [expr {$w + [GetCharWidth $pdf(current_font) $ch]}]
}
if {!$internal} {
set w [expr {$w / $pdf(unit)}]
}
return [expr {$w * $pdf(font_size)}]
}
# Get the width of a character. "ch" must be exactly one char long.
proc ::pdf4tcl::GetCharWidth {font ch} {
if {$ch eq "\n"} {
return 0.0
}
# This can't fail since ch is always 1 char long
scan $ch %c n
set BFN $::pdf4tcl::FontsAttrs($font,basefontname)
set res 0.0
catch {set res [dict get $::pdf4tcl::BFA($BFN,charWidths) $n]}
set res [expr {$res * 0.001}]
return $res
}
# Get the width of a character under the current font.
method getCharWidth {ch {internal 0}} {
if {$pdf(current_font) eq ""} {
throw "PDF4TCL" "no font set"
}
set len [string length $ch]
if {$len == 0} {
return 0.0
} elseif {$len > 1} {
set ch [string index $ch 0]
}
set width [expr {[GetCharWidth $pdf(current_font) $ch] * $pdf(font_size)}]
if {!$internal} {
set width [expr {$width / $pdf(unit)}]
}
return $width
}
# Set coordinate for next text command. Internal version
method SetTextPosition {x y} {
my BeginTextObj
set pdf(xpos) $x
set pdf(ypos) $y
my Pdfoutcmd 1 0 0 1 $pdf(xpos) $pdf(ypos) "Tm"
}
proc ::pdf4tcl::MulVxM {vector matrix} {
foreach {x y} $vector break
foreach {a b c d e f} $matrix break
lappend res [expr {$a*$x + $c*$y + $e}]
lappend res [expr {$b*$x + $d*$y + $f}]
return $res
}
proc ::pdf4tcl::MulMxM {m1 m2} {
foreach {a1 b1 c1 d1 e1 f1} $m1 break
foreach {a2 b2 c2 d2 e2 f2} $m2 break
lappend res [expr {$a1*$a2 + $b1*$c2}]
lappend res [expr {$a1*$b2 + $b1*$d2}]
lappend res [expr {$c1*$a2 + $d1*$c2}]
lappend res [expr {$c1*$b2 + $d1*$d2}]
lappend res [expr {$e1*$a2 + $f1*$c2 + $e2}]
lappend res [expr {$e1*$b2 + $f1*$d2 + $f2}]
return $res
}
method SetTextPositionAngle {x y angle xangle yangle} {
my BeginTextObj
set rad [expr {$angle*3.1415926/180.0}]
set c [expr {cos($rad)}]
set s [expr {sin($rad)}]
set pdf(xpos) $x
set pdf(ypos) $y
if {$xangle == 0 && $yangle == 0} {
my Pdfoutcmd $c $s [expr {-$s}] $c $x $y "Tm"
return
}
# Add skew if specified
set tx [expr {tan($xangle*3.1415926/180.0)}]
set ty [expr {tan($yangle*3.1415926/180.0)}]
set mr [list $c $s [expr {-$s}] $c 0 0]
set ms [list 1 $tx $ty 1 0 0]
set ma [MulMxM $mr $ms]
lset ma 4 $x
lset ma 5 $y
my Pdfoutcmd {*}$ma "Tm"
}
# Set coordinate for next text command.
method setTextPosition {x y} {
my BeginTextObj
my Trans $x $y x y
# Store for reference
set pdf(origxpos) $x
set pdf(origypos) $y
my SetTextPosition $x $y
}
# Move coordinate for next text command.
method moveTextPosition {x y} {
my TransR $x $y x y
set y [expr {$pdf(ypos) + $y}]
set x [expr {$pdf(xpos) + $x}]
my SetTextPosition $x $y
}
# Get current test position
method getTextPosition {} {
# This is basically a reverse Trans
set tx [expr {$pdf(xpos) - $pdf(marginleft)}]
if {$pdf(orient)} {
set ty [expr {$pdf(height) - $pdf(ypos)}]
set ty [expr {$ty - $pdf(margintop)}]
} else {
set ty [expr {$pdf(ypos) - $pdf(marginbottom)}]
}
# Translate to current unit
set tx [expr {$tx / $pdf(unit)}]
set ty [expr {$ty / $pdf(unit)}]
return [ list $tx $ty ]
}
# Move text position to new line, relative to last
# setTextPosition command.
method newLine {{spacing {}}} {
if {$spacing eq ""} {
set spacing $pdf(line_spacing)
} else {
my CheckNumeric $spacing "line spacing"
}
# Update to next line
set y [expr {$pdf(ypos) - $pdf(font_size) * $spacing}]
set x $pdf(origxpos)
my SetTextPosition $x $y
}
# Set Line spacing factor (which is used by method newLine
# if no explicit spacing is given)
method setLineSpacing {spacing} {
my CheckNumeric $spacing "line spacing"
set pdf(line_spacing) $spacing
}
# Return the current line spacing factor
method getLineSpacing {} {
return $pdf(line_spacing)
}
# Draw a text string
# Returns the width of the drawn string.
method text {str args} {
if {!$pdf(inPage)} { my startPage }
set align "left"
set angle 0
set xangle 0
set yangle 0
set bg 0
set x $pdf(xpos)
set y $pdf(ypos)
set posSet 0
foreach {arg value} $args {
switch -- $arg {
"-align" {
set align $value
}
"-angle" {
set angle $value
}
"-xangle" {
set xangle $value
}
"-yangle" {
set yangle $value
}
"-background" - "-bg" - "-fill" {
if {[string is boolean -strict $value]} {
set bg $value
} else {
set bg [my GetColor $value]
}
}
"-y" {
my Trans 0 $value _ y
set posSet 1
}
"-x" {
my Trans $value 0 x _
set posSet 1
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
if {!$pdf(font_set)} {
my SetupFont
}
set strWidth [my getStringWidth $str 1]
if {$align == "right"} {
set x [expr {$x - $strWidth * cos($angle*3.1415926/180.0)}]
set y [expr {$y - $strWidth * sin($angle*3.1415926/180.0)}]
set posSet 1
} elseif {$align == "center"} {
set x [expr {$x - $strWidth / 2 * cos($angle*3.1415926/180.0)}]
set y [expr {$y - $strWidth / 2 * sin($angle*3.1415926/180.0)}]
set posSet 1
}
# Draw a background box if needed.
if {[llength $bg] > 1 || $bg} {
set bboxb [my getFontMetric bboxb 1]
set bboxt [my getFontMetric bboxt 1]
set ytop [expr {$y + $bboxt}]
set ybot [expr {$y + $bboxb}]
set dh [expr {$bboxt - $bboxb}]
my EndTextObj
# Temporarily shift fill color
my Pdfoutcmd "q"
if {[llength $bg] > 1} {
my SetFillColor $bg
} else {
my SetFillColor $pdf(bgColor)
}
if {$angle || $xangle || $yangle} {
# Create rotated and skewed background polygon:
# Translation from x,y to origin matrix:
set mt [list 1 0 0 1 [expr {-$x}] [expr {-$y}]]
# Rotation matrix:
set r1 [expr {$angle*3.1415926/180.0}]
set c [expr {cos($r1)}]
set s [expr {sin($r1)}]
set mr [list $c $s [expr {-$s}] $c 0 0]
# Skew matrix:
set tx [expr {tan($xangle*3.1415926/180.0)}]
set ty [expr {tan($yangle*3.1415926/180.0)}]
set ms [list 1 $tx $ty 1 0 0]
# Translation from origin to x,y matrix:
set mtb [list 1 0 0 1 $x $y]
# Matrix of all operations:
set ma [MulMxM $mt $mr]
set ma [MulMxM $ma $ms]
set ma [MulMxM $ma $mtb]
# Four points must be translated:
set x2 [expr {$x+$strWidth}]
set y2 $ybot
set p1 [MulVxM [list $x $ytop] $ma]
set p2 [MulVxM [list $x2 $ytop] $ma]
set p3 [MulVxM [list $x2 $y2] $ma]
set p4 [MulVxM [list $x $y2] $ma]
eval \my DrawPoly 0 1 $p1 $p2 $p3 $p4
} else {
my DrawRect $x $ybot $strWidth $dh 0 1
}
my Pdfoutcmd "Q"
# Position needs to be set since we left the text object
set posSet 1
}
my BeginTextObj
if {$angle || $xangle || $yangle} {
my SetTextPositionAngle $x $y $angle $xangle $yangle
} elseif {$posSet} {
my SetTextPosition $x $y
}
my Pdfout "([CleanText $str $pdf(current_font)]) Tj\n"
set pdf(xpos) [expr {$x + $strWidth}]
return $strWidth
}
# Draw a text string at a given position.
method DrawTextAt {x y str {align left}} {
if {! $pdf(font_set)} {
my SetupFont
}
set strWidth [my getStringWidth $str 1]
if {$align == "right"} {
set x [expr {$x - $strWidth}]
} elseif {$align == "center"} {
set x [expr {$x - $strWidth / 2}]
}
my BeginTextObj
my SetTextPosition $x $y
my Pdfout "([CleanText $str $pdf(current_font)]) Tj\n"
}
method drawTextBox {x y width height txt args} {
set align left
set linesVar ""
set dryrun 0
foreach {arg value} $args {
switch -- $arg {
"-align" {
set align $value
}
"-linesvar" {
set linesVar $value
}
"-dryrun" {
my CheckBoolean -dryrun $value
set dryrun $value
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
if {!$pdf(inPage) && !$dryrun} { my startPage }
if {$linesVar ne ""} {
upvar 1 $linesVar lines
}
set lines 0
my Trans $x $y x y
my TransR $width $height width height
if {!$pdf(orient)} {
# Always have anchor position upper left
set y [expr {$y + $height}]
} else {
# Restore a positive height
set height [expr {- $height}]
}
if {!$dryrun} {
my BeginTextObj
if {! $pdf(font_set)} {
my SetupFont
}
}
# pre-calculate some values
set font_height [expr {$pdf(font_size) * $pdf(line_spacing)}]
set space_width [my getCharWidth " " 1]
# Displace y to put the first line within the box
set bboxb [my getFontMetric bboxb 1]
set ystart $y
set y [expr {$y - $pdf(font_size) - $bboxb}]
set len [string length $txt]
# run through chars until we exceed width or reach end
set start 0
set pos 0
set cwidth 0
set lastbp 0
set done false
while {! $done} {
set ch [string index $txt $pos]
# test for breakable character
if {[regexp "\[ \t\r\n-\]" $ch]} {
set lastbp $pos
}
set w [my getCharWidth $ch 1]
if {($cwidth+$w)>$width || $pos>=$len || $ch=="\n"} {
if {$pos>=$len} {
set done true
} else {
# backtrack to last breakpoint
if {$lastbp != $start} {
set pos $lastbp
} else {
# Word longer than line.
# Back up one char if possible
if {$pos > $start} {
incr pos -1
}
}
}
set sent [string trim [string range $txt $start $pos]]
switch -- $align {
"justify" {
# count number of spaces
set words [split $sent " "]
if {[llength $words]>1 && (!$done) && $ch!="\n"} {
# determine additional width per space
set sw [my getStringWidth $sent 1]
set add [expr {($width-$sw)/([llength $words]-1)}]
# display words
if {!$dryrun} {
my Pdfoutcmd $add "Tw"
my DrawTextAt $x $y $sent
my Pdfoutcmd 0 "Tw"
}
} else {
if {!$dryrun} {
my DrawTextAt $x $y $sent
}
}
}
"right" {
if {!$dryrun} {
my DrawTextAt [expr {$x+$width}] $y $sent right
}
}
"center" {
if {!$dryrun} {
my DrawTextAt [expr {$x+$width/2.0}] $y $sent center
}
}
default {
if {!$dryrun} {
my DrawTextAt $x $y $sent
}
}
}
# Move y down to next line
set y [expr {$y-$font_height}]
incr lines
set start $pos
incr start
set cwidth 0
set lastbp $start
# Will another line fit?
if {($ystart - ($y + $bboxb)) > $height} {
return [string range $txt $start end]
}
} else {
set cwidth [expr {$cwidth+$w}]
}
incr pos
}
return ""
}
# start text object, if not already in text
method BeginTextObj {} {
if {!$pdf(in_text_object)} {
my Pdfout "BT\n"
set pdf(in_text_object) true
}
}
# end text object, if in text, else do nothing
method EndTextObj {} {
if {!$pdf(inPage)} { my startPage }
if {$pdf(in_text_object)} {
my Pdfout "ET\n"
set pdf(in_text_object) false
}
}
#######################################################################
# Graphics Handling
#######################################################################
# Convert any user color to PDF color
method GetColor {color} {
# Remove list layers, to accept things that have been
# multiply listified
if {[llength $color] == 1} {
set color [lindex $color 0]
}
if {[llength $color] == 4} {
# Maybe range check them here...
if {$pdf(cmyk)} {
return $color
}
# Convert CMYK to RGB
set color [pdf4tcl::cmyk2Rgb $color]
}
if {[llength $color] == 3} {
# Maybe range check them here...
set RGB $color
} elseif {[regexp {^\#([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})$} \
$color -> rHex gHex bHex]} {
set red [expr {[scan $rHex %x] / 255.0}]
set green [expr {[scan $gHex %x] / 255.0}]
set blue [expr {[scan $bHex %x] / 255.0}]
set RGB [list $red $green $blue]
} else {
# Use catch both to catch bad color, and to catch Tk not present
if {[catch {winfo rgb . $color} tkcolor]} {
throw "PDF4TCL" "unknown color: $color"
}
foreach {red green blue} $tkcolor break
set red [expr {($red & 0xFF00) / 65280.0}]
set green [expr {($green & 0xFF00) / 65280.0}]
set blue [expr {($blue & 0xFF00) / 65280.0}]
set RGB [list $red $green $blue]
}
if {!$pdf(cmyk)} {
return $RGB
}
# Convert RGB to CMYK
return [pdf4tcl::rgb2Cmyk $RGB]
}
###<jpo 2004-11-08: replaced "on off" by "args"
### to enable resetting dashed lines
method setLineStyle {width args} {
set width [my CheckNumeric $width "line width" -nonnegative \
-unit $pdf(unit)]
# Validate dash pattern
set sum 0
set pattern {}
foreach p $args {
set p [my CheckNumeric $p "dash pattern" -nonnegative \
-unit $pdf(unit)]
set sum [expr {$sum + $p}]
lappend pattern [Nf $p]
}
if {[llength $args] > 0 && $sum == 0} {
throw "PDF4TCL" "dash pattern may not be all zeroes"
}
my EndTextObj
my Pdfoutcmd $width "w"
my Pdfout "\[$pattern\] 0 d\n"
}
method setLineWidth {width} {
set width [my CheckNumeric $width "line width" -nonnegative \
-unit $pdf(unit)]
my EndTextObj
my Pdfoutcmd $width "w"
}
# Arguments are pairs for dash pattern plus an optional offset
method setLineDash {args} {
if {([llength $args] % 2) == 1} {
set offset [lindex $args end]
set args [lrange $args 0 end-1]
} else {
set offset 0
}
set offset [my CheckNumeric $offset "dash offset" -nonnegative \
-unit $pdf(unit)]
# Validate dash pattern
set sum 0
set pattern {}
foreach p $args {
set p [my CheckNumeric $p "dash pattern" -nonnegative \
-unit $pdf(unit)]
set sum [expr {$sum + $p}]
lappend pattern [Nf $p]
}
if {[llength $args] > 0 && $sum == 0} {
throw "PDF4TCL" "dash pattern may not be all zeroes"
}
my EndTextObj
my Pdfout "\[$pattern\] [Nf $offset] d\n"
}
method DrawLine {args} {
my EndTextObj
set cmd "m"
foreach {x y} $args {
my Pdfoutcmd $x $y $cmd
set cmd "l"
}
my Pdfoutcmd "S"
}
method line {x1 y1 x2 y2} {
if {!$pdf(inPage)} { my startPage }
my Trans $x1 $y1 x1 y1
my Trans $x2 $y2 x2 y2
my DrawLine $x1 $y1 $x2 $y2
}
# Draw a quadratic or cubic bezier curve
method curve {x1 y1 x2 y2 x3 y3 args} {
if {[llength $args] != 2 && [llength $args] != 0} {
throw "PDF4TCL" "wrong # args: should be curve x1 y1 x2 y2 x3 y3 ?x4 y4?"
}
my EndTextObj
my Trans $x1 $y1 x1 y1
my Trans $x2 $y2 x2 y2
my Trans $x3 $y3 x3 y3
if {[llength $args] == 2} {
# Cubic curve
my Trans {*}$args x4 y4
} else {
# Quadratic curve
set x4 $x3
set y4 $y3
set x3 [expr {($x4+2.0*$x2)/3.0}]
set y3 [expr {($y4+2.0*$y2)/3.0}]
set x2 [expr {($x1+2.0*$x2)/3.0}]
set y2 [expr {($y1+2.0*$y2)/3.0}]
}
my Pdfoutcmd $x1 $y1 "m"
my Pdfoutcmd $x2 $y2 $x3 $y3 $x4 $y4 "c"
my Pdfoutcmd "S"
}
# Draw a polygon
method polygon {args} {
my EndTextObj
set filled 0
set stroke 1
set start 1
foreach {x y} $args {
if {[string match {-[a-z]*} $x]} {
switch -- $x {
"-filled" {
set filled $y
}
"-stroke" {
set stroke $y
}
default {
throw "PDF4TCL" "unknown option \"$x\""
}
}
} else {
my Trans $x $y x y
if {$start} {
my Pdfoutcmd $x $y "m"
set start 0
} else {
my Pdfoutcmd $x $y "l"
}
}
}
if {$filled && $stroke} {
my Pdfoutcmd "b"
} elseif {$filled && !$stroke} {
my Pdfoutcmd "f"
} else {
my Pdfoutcmd "s"
}
}
method DrawOval {x y rx ry stroke filled} {
my EndTextObj
set sq [expr {4.0*(sqrt(2.0)-1.0)/3.0}]
set x0(0) [expr {$x+$rx}]
set y0(0) $y
set x1(0) [expr {$x+$rx}]
set y1(0) [expr {$y+$ry*$sq}]
set x2(0) [expr {$x+$rx*$sq}]
set y2(0) [expr {$y+$ry}]
set x3(0) $x
set y3(0) [expr {$y+$ry}]
set x1(1) [expr {$x-$rx*$sq}]
set y1(1) [expr {$y+$ry}]
set x2(1) [expr {$x-$rx}]
set y2(1) [expr {$y+$ry*$sq}]
set x3(1) [expr {$x-$rx}]
set y3(1) $y
set x1(2) [expr {$x-$rx}]
set y1(2) [expr {$y-$ry*$sq}]
set x2(2) [expr {$x-$rx*$sq}]
set y2(2) [expr {$y-$ry}]
set x3(2) $x
set y3(2) [expr {$y-$ry}]
set x1(3) [expr {$x+$rx*$sq}]
set y1(3) [expr {$y-$ry}]
set x2(3) [expr {$x+$rx}]
set y2(3) [expr {$y-$ry*$sq}]
set x3(3) [expr {$x+$rx}]
set y3(3) $y
my Pdfoutcmd $x0(0) $y0(0) "m"
for {set i 0} {$i < 4} {incr i} {
my Pdfoutcmd $x1($i) \
$y1($i) \
$x2($i) \
$y2($i) \
$x3($i) \
$y3($i) "c"
}
if {$filled && $stroke} {
my Pdfoutcmd "b"
} elseif {$filled && !$stroke} {
my Pdfoutcmd "f"
} else {
my Pdfoutcmd " s"
}
}
method circle {x y r args} {
if {!$pdf(inPage)} { my startPage }
set filled 0
set stroke 1
foreach {arg value} $args {
switch -- $arg {
"-filled" {
set filled $value
}
"-stroke" {
set stroke $value
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
my Trans $x $y x y
set r [pdf4tcl::getPoints $r $pdf(unit)]
my DrawOval $x $y $r $r $stroke $filled
}
method oval {x y rx ry args} {
if {!$pdf(inPage)} { my startPage }
set filled 0
set stroke 1
foreach {arg value} $args {
switch -- $arg {
"-filled" {
set filled $value
}
"-stroke" {
set stroke $value
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
my Trans $x $y x y
set rx [pdf4tcl::getPoints $rx $pdf(unit)]
set ry [pdf4tcl::getPoints $ry $pdf(unit)]
my DrawOval $x $y $rx $ry $stroke $filled
}
# rotate by phi, scale with rx/ry and move by (dx, dy)
proc ::pdf4tcl::Transform {rx ry phi dx dy points} {
set cos_phi [expr {cos($phi)}]
set sin_phi [expr {sin($phi)}]
set res [list]
foreach {x y} $points {
set xn [expr {$rx * ($x*$cos_phi - $y*$sin_phi) + $dx}]
set yn [expr {$ry * ($x*$sin_phi + $y*$cos_phi) + $dy}]
lappend res $xn $yn
}
return $res
}
# Create a four-point spline that forms an arc along the unit circle
# from angle -phi2 to +phi2 (where phi2 is in radians)
proc ::pdf4tcl::Simplearc {phi2} {
set x0 [expr {cos($phi2)}]
set y0 [expr {-sin($phi2)}]
set x3 $x0
set y3 [expr {-$y0}]
set x1 [expr {0.3333*(4.0-$x0)}]
set y1 [expr {(1.0-$x0)*(3.0-$x0)/(3.0*$y0)}]
set x2 $x1
set y2 [expr {-$y1}]
return [list $x0 $y0 $x1 $y1 $x2 $y2 $x3 $y3]
}
method DrawArc {x0 y0 rx ry phi extend stroke filled style} {
if {abs($extend) >= 360.0} {
my DrawOval $x0 $y0 $rx $ry $stroke $filled
return
}
if {abs($extend) < 0.01} return
my EndTextObj
set count 1
while {abs($extend) > 90} {
set count [expr {2*$count}]
set extend [expr {0.5*$extend}]
}
set phi [expr {$phi/180.0*3.1416}]
set extend [expr {$extend/180.0*3.1416}]
set phi2 [expr {0.5*$extend}]
set x [expr {$x0+$rx*cos($phi)}]
set y [expr {$y0+$ry*sin($phi)}]
my Pdfoutcmd $x $y "m"
set points [Simplearc $phi2]
set phi [expr {$phi+$phi2}]
for {set i 0} {$i < $count} {incr i} {
foreach {x y x1 y1 x2 y2 x3 y3} \
[Transform $rx $ry $phi $x0 $y0 $points] break
set phi [expr {$phi+$extend}]
my Pdfoutcmd $x1 $y1 $x2 $y2 $x3 $y3 "c"
}
switch $style {
"arc" {
set filled 0
}
"pieslice" {
# Add the line to the center
my Pdfoutcmd $x0 $y0 "l"
# Close the path
my Pdfoutcmd "h"
}
"chord" {
# Close the path
my Pdfoutcmd "h"
}
}
if {$filled && $stroke} {
my Pdfoutcmd "B"
} elseif {$filled && !$stroke} {
my Pdfoutcmd "f"
} else {
my Pdfoutcmd "S"
}
}
# Draw an arc
method arc {x0 y0 rx ry phi extend args} {
if {!$pdf(inPage)} { my startPage }
set filled 0
set stroke 1
set style arc
foreach {arg value} $args {
switch -- $arg {
"-filled" {
set filled $value
}
"-stroke" {
set stroke $value
}
"-style" {
set style $value
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
my Trans $x0 $y0 x0 y0
set rx [pdf4tcl::getPoints $rx $pdf(unit)]
set ry [pdf4tcl::getPoints $ry $pdf(unit)]
my DrawArc $x0 $y0 $rx $ry $phi $extend $stroke $filled $style
}
method arrow {x1 y1 x2 y2 sz {angle 20}} {
if {!$pdf(inPage)} { my startPage }
my Trans $x1 $y1 x1 y1
my Trans $x2 $y2 x2 y2
set sz [pdf4tcl::getPoints $sz $pdf(unit)]
my DrawLine $x1 $y1 $x2 $y2
set rad [expr {$angle*3.1415926/180.0}]
set ang [expr {atan2(($y1-$y2), ($x1-$x2))}]
my DrawLine $x2 $y2 [expr {$x2+$sz*cos($ang+$rad)}] \
[expr {$y2+$sz*sin($ang+$rad)}]
my DrawLine $x2 $y2 [expr {$x2+$sz*cos($ang-$rad)}] \
[expr {$y2+$sz*sin($ang-$rad)}]
}
method setBgColor {args} {
set pdf(bgColor) [my GetColor $args]
}
method SetFillColor {color} {
if {$pdf(cmyk)} {
foreach {red green blue k} $color break
my Pdfoutcmd $red $green $blue $k "k"
} else {
foreach {red green blue} $color break
my Pdfoutcmd $red $green $blue "rg"
}
}
method setFillColor {args} {
if {!$pdf(inPage)} { my startPage }
set pdf(fillColor) [my GetColor $args]
my SetFillColor $pdf(fillColor)
}
method SetStrokeColor {color} {
if {$pdf(cmyk)} {
foreach {red green blue k} $color break
my Pdfoutcmd $red $green $blue $k "K"
} else {
foreach {red green blue} $color break
my Pdfoutcmd $red $green $blue "RG"
}
}
method setStrokeColor {args} {
if {!$pdf(inPage)} { my startPage }
set pdf(strokeColor) [my GetColor $args]
my SetStrokeColor $pdf(strokeColor)
}
# Draw a rectangle, internal version
method DrawRect {x y w h stroke filled} {
my Pdfoutcmd $x $y $w $h "re"
if {$filled && $stroke} {
my Pdfoutcmd "B"
} elseif {$filled && !$stroke} {
my Pdfoutcmd "f"
} else {
my Pdfoutcmd "S"
}
}
# Draw a polygon, internal version
method DrawPoly {stroke filled args} {
set start 1
foreach {x y} $args {
if {$start} {
my Pdfoutcmd $x $y "m"
set start 0
} else {
my Pdfoutcmd $x $y "l"
}
}
if {$filled && $stroke} {
my Pdfoutcmd "b"
} elseif {$filled && !$stroke} {
my Pdfoutcmd "f"
} else {
my Pdfoutcmd "s"
}
}
# Draw a rectangle
method rectangle {x y w h args} {
my EndTextObj
set filled 0
set stroke 1
foreach {arg value} $args {
switch -- $arg {
"-filled" {
set filled $value
}
"-stroke" {
set stroke $value
}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
my Trans $x $y x y
my TransR $w $h w h
my DrawRect $x $y $w $h $stroke $filled
}
#######################################################################
# Image Handling
#######################################################################
# Add an image to the document
method addImage {filename args} {
set id ""
set type ""
foreach {arg val} $args {
switch -- $arg {
-id {
set id $val
}
-type {
set type $val
}
}
}
if {$type eq ""} {
switch -glob $filename {
*.png {
set type png
}
*.jpg - *.jpeg {
set type jpg
}
default {
throw "PDF4TCL" "unknown image type \"$filename\""
}
}
}
switch $type {
png {
set id [my AddPng $filename $id]
}
jpg - jpeg {
set id [my AddJpeg $filename $id]
}
default {
throw "PDF4TCL" "unknown image type \"$type\""
}
}
return $id
}
# JPEG part of addImage
method AddJpeg {filename id} {
if {!$pdf(inPage)} { my startPage }
set imgOK false
if {[catch {open $filename "r"} if]} {
throw "PDF4TCL" "could not open file $filename"
}
fconfigure $if -translation binary
set img [read $if]
close $if
binary scan $img "H4" h
if {$h != "ffd8"} {
throw "PDF4TCL" "file $filename does not contain JPEG data"
}
set pos 2
set img_length [string length $img]
while {$pos < $img_length} {
set endpos [expr {$pos+4}]
binary scan [string range $img $pos $endpos] "H4S" h length
set length [expr {$length & 0xffff}]
if {$h == "ffc0"} {
incr pos 4
set endpos [expr {$pos+6}]
binary scan [string range $img $pos $endpos] "cSS" depth height width
set height [expr {$height & 0xffff}]
set width [expr {$width & 0xffff}]
set imgOK true
break
} else {
incr pos 2
incr pos $length
}
}
if {!$imgOK} {
throw "PDF4TCL" "something is wrong with jpeg data in file $filename"
}
set xobject "<<\n/Type /XObject\n"
append xobject "/Subtype /Image\n"
append xobject "/Width $width\n/Height $height\n"
append xobject "/ColorSpace /DeviceRGB\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /DCTDecode\n"
append xobject "/Length $img_length >>\n"
append xobject "stream\n"
append xobject $img
append xobject "\nendstream"
set oid [my AddObject $xobject]
if {$id eq ""} {
set id image$oid
}
set images($id) [list $width $height $oid 0]
return $id
}
# PNG support
#
# This implementation uses tricks in PDF to avoid unpacking the
# compressed data stream. Currently this means that interlaced
# images are not supported.
# Decompressing (using zlib) would be feasible I guess, but the
# de-filtering and de-interlacing steps would be rather costly.
# Anyone needing such png images can always load them themselves
# and provide them as raw images.
method AddPng {filename id} {
set imgOK false
if {[catch {open $filename "r"} if]} {
throw "PDF4TCL" "could not open file $filename"
}
fconfigure $if -translation binary
if {[read $if 8] != "\x89PNG\r\n\x1a\n"} {
close $if
throw "PDF4TCL" "file does not contain PNG data"
}
set img [read $if]
close $if
set pos 0
set img_length [string length $img]
set img_data ""
set palette ""
while {$pos < $img_length} {
# Scan one chunk
binary scan $img "@${pos}Ia4" length type
incr pos 8
set data [string range $img $pos [expr {$pos + $length - 1}]]
incr pos $length
binary scan $img "@${pos}I" crc
incr pos 4
switch $type {
"IHDR" {
set imgOK 1
binary scan $data IIccccc width height depth color \
compression filter interlace
}
"PLTE" {
set palette $data
}
"IDAT" {
append img_data $data
}
}
}
if {!$imgOK} {
throw "PDF4TCL" "something is wrong with PNG data in file $filename"
}
if {[string length $img_data] == 0} {
throw "PDF4TCL" "PNG file does not contain any IDAT chunks"
}
if {$compression != 0} {
throw "PDF4TCL" "PNG file is of an unsupported compression type"
}
if {$filter != 0} {
throw "PDF4TCL" "PNG file is of an unsupported filter type"
}
if {$interlace != 0} {
# Would need to unpack and repack to do interlaced
throw "PDF4TCL" "interlaced PNG is not supported"
}
if {$palette ne ""} {
# Transform the palette into a PDF Indexed color space
binary scan $palette H* PaletteHex
set PaletteLen [expr {[string length $palette] / 3 - 1}]
set paletteX "\[ /Indexed /DeviceRGB "
append paletteX $PaletteLen " < "
append paletteX $PaletteHex
append paletteX " > \]"
}
set xobject "<<\n/Type /XObject\n"
append xobject "/Subtype /Image\n"
append xobject "/Width $width\n/Height $height\n"
if {$depth > 8} {
my RequireVersion 1.5
}
switch $color {
0 { # Grayscale
append xobject "/ColorSpace /DeviceGray\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 1 /BitsPerComponent $depth /Columns $width>>\n"
}
2 { # RGB
append xobject "/ColorSpace /DeviceRGB\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 3 /BitsPerComponent $depth /Columns $width>>\n"
}
3 { # Palette
append xobject "/ColorSpace $paletteX\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 1 /BitsPerComponent $depth /Columns $width>>\n"
}
4 { # Gray + alpha
my PngInitGrayAlpha
append xobject "/ColorSpace $pdf(png_ga) 0 R\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 2 /BitsPerComponent $depth /Columns $width>>\n"
}
6 { # RGBA
my PngInitRgba
append xobject "/ColorSpace $pdf(png_rgba) 0 R\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 4 /BitsPerComponent $depth /Columns $width>>\n"
}
}
append xobject "/Length [string length $img_data] >>\n"
append xobject "stream\n"
append xobject $img_data
append xobject "\nendstream"
set oid [my AddObject $xobject]
if {$id eq ""} {
set id image$oid
}
set images($id) [list $width $height $oid 0]
return $id
}
# Create the Color Space needed to display RGBA as RGB
method PngInitRgba {} {
if {[info exists pdf(png_rgba)]} return
set body "<< /FunctionType 4\n"
append body {/Domain [ 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 ]} \n
append body {/Range [ 0.0 1.0 0.0 1.0 0.0 1.0 ]} \n
append body {/Length 5} \n
append body {>>} \n
append body {stream} \n
append body {{pop}} \n
append body {endstream}
set oid [my AddObject $body]
set body "\[ /DeviceN\n"
append body " \[ /Red /Green /Blue /Alpha \]\n"
append body " /DeviceRGB\n"
append body " $oid 0 R % Tint transformation function\n"
append body "\]"
set pdf(png_rgba) [my AddObject $body]
}
# Create the Color Space needed to display Gray+Alpha as Gray
method PngInitGrayAlpha {} {
if {[info exists pdf(png_ga)]} return
set body "<< /FunctionType 4\n"
append body {/Domain [ 0.0 1.0 0.0 1.0 ]} \n
append body {/Range [ 0.0 1.0 ]} \n
append body {/Length 5} \n
append body {>>} \n
append body {stream} \n
append body {{pop}} \n
append body {endstream}
set oid [my AddObject $body]
set body "\[ /DeviceN\n"
append body " \[ /_Gray_ /_Alpha_ \]\n"
append body " /DeviceGray\n"
append body " $oid 0 R % Tint transformation function\n"
append body "\]"
set pdf(png_ga) [my AddObject $body]
}
# Incomplete gif experiment...
method AddGif {filename id} {
set imgOK false
if {[catch {open $filename "r"} if]} {
throw "PDF4TCL" "could not open file $filename"
}
fconfigure $if -translation binary
set sign [read $if 6]
if {![string match "GIF*" $sign]} {
close $if
throw "PDF4TCL" "file does not contain GIF data"
}
set img [read $if]
close $if
set pos 0
set img_length [string length $img]
set img_data ""
set palette ""
# Read the screen descriptor
binary scan $img "ssccc" scrWidth scrHeight cr bg dummy
set pos 7
set depth [expr {($cr & 7) + 1}]
set colorMap [expr {($cr >> 7) & 1}]
set colorRes [expr {($cr >> 4) & 7}]
set nColor [expr {1 << $colorRes}]
set gMap {}
if {$colorMap} {
for {set t 0} {$t < $nColor} {incr t} {
binary scan $img "@${pos}ccc" red green blue
incr pos 3
lappend gMap $red $green $blue
}
}
while {$pos < $img_length} {
# Scan one chunk
binary scan $img "@${pos}Ia4" length type
incr pos 8
set data [string range $img $pos [expr {$pos + $length - 1}]]
incr pos $length
binary scan $img "@${pos}I" crc
incr pos 4
switch $type {
"IHDR" {
set imgOK 1
binary scan $data IIccccc width height depth color \
compression filter interlace
}
"PLTE" {
set palette $data
}
"IDAT" {
append img_data $data
}
}
}
if {!$imgOK} {
throw "PDF4TCL" "something is wrong with PNG data in file $filename"
}
if {[string length $img_data] == 0} {
throw "PDF4TCL" "PNG file does not contain any IDAT chunks"
}
if {$compression != 0} {
throw "PDF4TCL" "PNG file is of an unsupported compression type"
}
if {$filter != 0} {
throw "PDF4TCL" "PNG file is of an unsupported filter type"
}
if {$interlace != 0} {
# Would need to unpack and repack to do interlaced
throw "PDF4TCL" "interlaced PNG is not supported"
}
if {$palette ne ""} {
# Transform the palette into a PDF Indexed color space
binary scan $palette H* PaletteHex
set PaletteLen [expr {[string length $palette] / 3 - 1}]
set paletteX "\[ /Indexed /DeviceRGB "
append paletteX $PaletteLen " < "
append paletteX $PaletteHex
append paletteX " > \]"
}
set xobject "<<\n/Type /XObject\n"
append xobject "/Subtype /Image\n"
append xobject "/Width $width\n/Height $height\n"
if {$depth > 8} {
my RequireVersion 1.5
}
switch $color {
0 { # Grayscale
append xobject "/ColorSpace /DeviceGray\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 1 /BitsPerComponent $depth /Columns $width>>\n"
}
2 { # RGB
append xobject "/ColorSpace /DeviceRGB\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 3 /BitsPerComponent $depth /Columns $width>>\n"
}
3 { # Palette
append xobject "/ColorSpace $paletteX\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 1 /BitsPerComponent $depth /Columns $width>>\n"
}
4 { # Gray + alpha
my PngInitGrayAlpha
append xobject "/ColorSpace $pdf(png_ga) 0 R\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 2 /BitsPerComponent $depth /Columns $width>>\n"
}
6 { # RGBA
my PngInitRgba
append xobject "/ColorSpace $pdf(png_rgba) 0 R\n"
append xobject "/BitsPerComponent $depth\n"
append xobject "/Filter /FlateDecode\n"
append xobject "/DecodeParms << /Predictor 15 /Colors 4 /BitsPerComponent $depth /Columns $width>>\n"
}
}
append xobject "/Length [string length $img_data] >>\n"
append xobject "stream\n"
append xobject $img_data
append xobject "\nendstream"
set oid [my AddObject $xobject]
if {$id eq ""} {
set id image$oid
}
set images($id) [list $width $height $oid 0]
return $id
}
# Return the height of an image.
method getImageHeight {id} {
set status {}
if {[info exists images($id)]} {
set status [lindex $images($id) 1]
}
return $status
}
# Return the size of an image. The size is returned as a list containing
# the width and height of the image.
method getImageSize {id} {
set status {}
if {[info exists images($id)]} {
set status [lrange $images($id) 0 1]
}
return $status
}
# Return the width of an image.
method getImageWidth {id} {
set status {}
if {[info exists images($id)]} {
set status [lindex $images($id) 0]
}
return $status
}
# Check an anchor value and optionally translate it
method CheckAnchor {value {dxName ""} {dyName ""}} {
if {$value ni {nw n ne e se s sw w center}} {
throw "PDF4TCL" "bad anchor \"$value\""
}
if {$dxName eq "" && $dyName eq ""} return
upvar 1 $dxName dx $dyName dy
switch $value {
nw { set dx 0.0 ; set dy 1.0 }
n { set dx 0.5 ; set dy 1.0 }
ne { set dx 1.0 ; set dy 1.0 }
e { set dx 1.0 ; set dy 0.5 }
se { set dx 1.0 ; set dy 0.0 }
s { set dx 0.5 ; set dy 0.0 }
sw { set dx 0.0 ; set dy 0.0 }
w { set dx 0.0 ; set dy 0.5 }
default { set dx 0.5 ; set dy 0.5 }
}
}
# Place an image at the page
method putImage {id x y args} {
my EndTextObj
foreach {width height oid} $images($id) {break}
my Trans $x $y x y
set w $width
set h $height
set wfix 0
set hfix 0
set angle 0
# Default anchor depends on coordinate system
if {$pdf(orient)} {
set anchor nw
} else {
set anchor sw
}
foreach {arg value} $args {
switch -- $arg {
"-angle" {
my CheckNumeric $value "angle"
set angle $value
}
"-anchor" {
my CheckAnchor $value
set anchor $value
}
"-width" {
set w [pdf4tcl::getPoints $value $pdf(unit)]
set wfix 1
}
"-height" {
set h [pdf4tcl::getPoints $value $pdf(unit)]
set hfix 1
}
}
}
if {$wfix && !$hfix} {
set h [expr {$height*$w/$width}]
}
if {$hfix && !$wfix} {
set w [expr {$width*$h/$height}]
}
my Pdfoutcmd "q"
# 1: Translate origin, to rotate around the anchor
#
my CheckAnchor $anchor dx dy
set mt [list 1 0 0 1 [- $dx] [- $dy]]
# 2: Scale while in the right direction
set mt [MulMxM $mt [list $w 0 0 $h 0 0]]
# 3: Rotate
if {$angle != 0} {
# Rotation matrix:
set r1 [expr {$angle*3.1415926/180.0}]
set c [expr {cos($r1)}]
set s [expr {sin($r1)}]
set mr [list $c $s [- $s] $c 0 0]
# Which order should this be?
set mt [MulMxM $mt $mr]
}
# Move into place
set mt [MulMxM $mt [list 1 0 0 1 $x $y]]
my Pdfoutcmd {*}$mt "cm"
my Pdfout "/$id Do\nQ\n"
}
# Add a raw image to the document, to be placed later
method addRawImage {img_data args} {
# Determine the width and height of the image, which is
# a list of lists(rows).
set width [llength [lindex $img_data 0]]
set height [llength $img_data]
set compress $pdf(compress)
set id ""
foreach {arg value} $args {
switch -- $arg {
"-compress" {
my CheckBoolean -compress $value
set compress $value
}
"-id" {set id $value}
}
}
set xobject "<<\n/Type /XObject\n"
append xobject "/Subtype /Image\n"
append xobject "/Width $width\n/Height $height\n"
append xobject "/ColorSpace /DeviceRGB\n"
append xobject "/BitsPerComponent 8\n"
# Iterate on each row of the image data.
set img ""
foreach rawRow $img_data {
# Remove spaces and # characters
set row [string map "# {} { } {}" $rawRow]
# Convert data to binary format and
# add to data stream.
append img [binary format H* $row]
}
if {$compress} {
append xobject "/Filter \[/FlateDecode\]\n"
set img [zlib compress $img]
}
append xobject "/Length [string length $img]>>\n"
append xobject "stream\n"
append xobject $img
append xobject "\nendstream"
set oid [my AddObject $xobject]
if {$id eq ""} {
set id image$oid
}
set images($id) [list $width $height $oid 0]
return $id
}
# Place a raw image at the page
method putRawImage {img_data x y args} {
my EndTextObj
# Determine the width and height of the image, which is
# a list of lists(rows).
set width [llength [lindex $img_data 0]]
set height [llength $img_data]
my Trans $x $y x y
set w $width
set h $height
set wfix 0
set hfix 0
set angle 0
set compress $pdf(compress)
# Default anchor depends on coordinate system
if {$pdf(orient)} {
set anchor nw
} else {
set anchor sw
}
foreach {arg value} $args {
switch -- $arg {
"-angle" {
my CheckNumeric $value "angle"
set angle $value
}
"-anchor" {
my CheckAnchor $value
set anchor $value
}
"-compress" {
my CheckBoolean -compress $value
set compress $value
}
"-width" {
set w [pdf4tcl::getPoints $value $pdf(unit)]
set wfix 1
}
"-height" {
set h [pdf4tcl::getPoints $value $pdf(unit)]
set hfix 1
}
}
}
if {$wfix && !$hfix} {
set h [expr {$height*$w/$width}]
}
if {$hfix && !$wfix} {
set w [expr {$width*$h/$height}]
}
my Pdfoutcmd "q"
# 1: Translate origin, to rotate around the anchor
#
my CheckAnchor $anchor dx dy
set mt [list 1 0 0 1 [- $dx] [- $dy]]
# 2: Scale while in the right direction
set mt [MulMxM $mt [list $w 0 0 $h 0 0]]
# 3: Rotate
if {$angle != 0} {
# Rotation matrix:
set r1 [expr {$angle*3.1415926/180.0}]
set c [expr {cos($r1)}]
set s [expr {sin($r1)}]
set mr [list $c $s [- $s] $c 0 0]
# Which order should this be?
set mt [MulMxM $mt $mr]
}
# Move into place
set mt [MulMxM $mt [list 1 0 0 1 $x $y]]
my Pdfoutcmd {*}$mt "cm"
my Pdfoutcmd "BI"
my Pdfoutn "/W [Nf $width]"
my Pdfoutn "/H [Nf $height]"
my Pdfoutn "/CS /RGB"
my Pdfoutn "/BPC 8"
# Iterate on each row of the image data.
set img ""
foreach rawRow $img_data {
# Remove spaces and # characters
set row [string map "# {} { } {}" $rawRow]
# Convert data to binary format and
# add to data stream.
append img [binary format H* $row]
}
if {$compress} {
my Pdfoutn "/F /Fl"
set img [zlib compress $img]
}
my Pdfoutcmd "ID"
my Pdfout $img
my Pdfout \n
my Pdfoutcmd "EI"
my Pdfoutcmd "Q"
}
# Add a bitmap to the document, as a pattern
method AddBitmap {bitmap args} {
set id ""
set pattern ""
foreach {arg value} $args {
switch -- $arg {
"-id" {set id $value}
"-pattern" {set pattern $value}
}
}
# Load the bitmap file
if {[string index $bitmap 0] eq "@"} {
set filename [string range $bitmap 1 end]
} else {
# Internal bitmap
set filename [file join $::pdf4tcl::dir "bitmaps" ${bitmap}.xbm]
}
if {![file exists $filename]} {
throw "PDF4TCL" "no such bitmap $bitmap"
}
set ch [open $filename "r"]
set bitmapdata [read $ch]
close $ch
if {![regexp {_width (\d+)} $bitmapdata -> width]} {
throw "PDF4TCL" "not a bitmap $bitmap"
}
if {![regexp {_height (\d+)} $bitmapdata -> height]} {
throw "PDF4TCL" "not a bitmap $bitmap"
}
if {![regexp {_bits\s*\[\]\s*=\s*\{(.*)\}} $bitmapdata -> rawdata]} {
throw "PDF4TCL" "not a bitmap $bitmap"
}
set bytes [regexp -all -inline {0x[a-fA-F0-9]{2}} $rawdata]
set bytesPerLine [expr {[llength $bytes] / $height}]
set bits ""
foreach byte $bytes {
# Reverse bit order
for {set t 0} {$t < 8} {incr t} {
append bits [expr {1 & $byte}]
set byte [expr {$byte >> 1}]
}
}
set bitstream [binary format B* $bits]
if {$pattern eq ""} {
# The Image Mask Object can be used as transparency Mask
# for something else, e.g. when drawing the bitmap itself
# with transparent background.
set xobject "<<\n/Type /XObject\n"
append xobject "/Subtype /Image\n"
append xobject "/Width $width\n/Height $height\n"
append xobject {/ImageMask true /Decode [ 1 0 ]} \n
append xobject "/BitsPerComponent 1\n"
append xobject "/Length [string length $bitstream]\n"
append xobject ">>\nstream\n"
append xobject $bitstream
append xobject "\nendstream"
set imoid [my AddObject $xobject]
if {$id eq ""} {
set id bitmap$imoid
}
set bitmaps($id) [list $width $height $imoid $bitstream]
return $id
} else {
# Inline image within the Pattern Object
set stream "q\n"
append stream "$width 0 0 $height 0 0 " "cm" \n
append stream "BI\n"
append stream "/W [Nf $width]\n"
append stream "/H [Nf $height]\n"
append stream {/IM true /Decode [ 1 0 ]} \n
append stream "/BPC 1\n"
append stream "ID\n"
append stream $bitstream
append stream ">\nEI\nQ"
# The Pattern Object can be used as a stipple Mask with the Cs1
# Colorspace.
if {[llength $pattern] == 4} {
foreach {xscale yscale xoffset yoffset} $pattern break
} else {
set xscale 1
set yscale 1
set xoffset 0
set yoffset 0
}
set xobject "<<\n/Type /Pattern\n"
append xobject "/PatternType 1\n"
append xobject "/PaintType 2\n"
append xobject "/TilingType 1\n"
append xobject "/BBox \[ 0 0 $width $height \]\n"
append xobject "/XStep $width\n"
append xobject "/YStep $height\n"
append xobject "/Matrix \[ $xscale 0 0 $yscale $xoffset $yoffset \] \n"
append xobject "/Resources <<\n"
append xobject ">>\n"
append xobject "/Length [string length $stream]\n"
append xobject ">>\n"
append xobject "stream\n"
append xobject $stream
append xobject "\nendstream"
set oid [my AddObject $xobject]
if {$id eq ""} {
set id pattern$oid
}
set patterns($id) [list $width $height $oid]
return $id
}
}
# Add tkpath pimage object, this can be either an alpha mask
# or a RGB image, both formatted as an PDF object with stream
# of pixel data appended
method addTkpimgObj {width height xobject} {
if {!$pdf(inPage)} { my startPage }
set oid [my AddObject $xobject]
set id pimg$oid
set images($id) [list $width $height $oid 0]
return [list $oid $id]
}
# Format one line of tkpath ptext
method getTkpptext {font line} {
return [CleanText $line $font]
}
# Add tkpath extended graphics state object
method addTkpextgs {body {smoid {}}} {
if {!$pdf(inPage)} { my startPage }
if {$smoid ne {}} {
set id smask$smoid
set extgs($id) $smoid
}
set oid [my AddObject $body]
set id extgs$oid
set extgs($id) $oid
return [list $oid $id]
}
# Add tkpath object e.g. for gradient fills
method addTkpobj {body} {
if {!$pdf(inPage)} { my startPage }
return [my AddObject $body]
}
# Add tkpath shading/pattern object for gradient fills
method addTkpgrad {oid} {
if {!$pdf(inPage)} { my startPage }
set id grad$oid
set grads($id) [list 0 0 $oid]
return [list $oid $id]
}
# Embed a file and return a handle to the File Specification Object.
method embedFile {fn args} {
set id ""
set contents ""
set contentsIsSet 0
foreach {arg val} $args {
switch -- $arg {
-id {
set id $val
}
-contents {
set contents $val
set contentsIsSet 1
}
}
}
if {!$contentsIsSet} {
set ch [open $fn r]
fconfigure $ch -translation binary
set contents [read $ch]
close $ch
}
# 1. make stream with file contents
set body [MakeStream "<< /Type /EmbeddedFile " $contents $pdf(compress)]
set sid [my AddObject $body]
# 2. create file specification dictionary
set fsdict "<< /Type /Filespec\n"
append fsdict " /F [QuoteString $fn]\n"
append fsdict " /EF << /F $sid 0 R >>\n"
append fsdict ">>\n"
set fsid [my AddObject $fsdict]
if {$id eq ""} {
set id file$fsid
}
set files($id) $fsid
return $id
}
# Embed a file and create a file annotation
method attachFile {x y width height fid description args} {
set icon Paperclip
foreach {option value} $args {
switch -- $option {
-icon {
if {$value ni {Paperclip Tag Graph PushPin}} {
if {![info exists images($value)]} {
throw "PDF4TCL" "unknown value for -icon"
}
}
set icon $value
}
default {
throw "PDF4TCL" "unknown option \"$option\""
}
}
}
# recompute coordinates to current system
my Trans $x $y x y
my TransR $width $height width height
set x2 [expr {$x+$width}]
set y2 [expr {$y+$height}]
set fsid $files($fid)
# Create annotation
set andict "<< /Type /Annot\n"
append andict " /Subtype /FileAttachment\n"
append andict " /FS $fsid 0 R\n"
append andict " /Contents [QuoteString $description]\n"
if {[info exists images($icon)]} {
foreach {_ _ iconOid} $images($icon) break
append andict " /AP << /N $iconOid 0 R >>\n"
} else {
append andict " /Name /$icon\n"
}
append andict " /Rect \[$x $y $x2 $y2\]\n"
append andict ">>\n"
set anid [my AddObject $andict]
# 4. Insert annotation into current page
lappend pdf(annotations) "$anid 0 R"
}
# Add an interactive form
# Currently supports text and checkbutton
method addForm {ftype x y width height args} {
if {$ftype ni {text checkbutton}} {
throw "PDF4TCL" "unknown form type $ftype"
}
set initValue ""
set onObj ""
set offObj ""
if {$ftype eq "checkbutton"} {
set initValue 0
}
# Handle options
foreach {option value} $args {
switch -- $option {
-init {
set initValue $value
}
-on {
set onObj $value
}
-off {
set offObj $value
}
-id {
set idObj $value
}
-multiline {
set multiObj $value
}
default {
throw "PDF4TCL" "unknown option \"$option\""
}
}
}
# Check init value
if {$ftype eq "checkbutton"} {
if {![string is boolean -strict $initValue]} {
throw "PDF4TCL" "initial value for checkbutton must be boolean"
}
if {$offObj ne ""} {
if {![info exists images($offObj)]} {
throw "PDF4TCL" "bad id for -off"
}
# Must have been created by xobject, image is no good
if {![string match xobject* $offObj]} {
throw "PDF4TCL" "bad id for -off"
}
}
if {$onObj ne ""} {
if {![info exists images($onObj)]} {
throw "PDF4TCL" "bad id for -on"
}
# Must have been created by xobject, image is no good
if {![string match xobject* $onObj]} {
throw "PDF4TCL" "bad id for -on"
}
}
}
# recompute coordinates to current system
my Trans $x $y x y
my TransR $width $height width height
set x2 [expr {$x+$width}]
# Make sure we have a positive height, regardless of coordinate system.
if {$height < 0} {
set y2 $y
set y [expr {$y2+$height}]
set height [expr {-$height}]
} else {
set y2 [expr {$y+$height}]
}
if {$ftype eq "checkbutton"} {
# Note, the xobject will be scaled to fit in the form's Rect and
# thus do not need to be the same size.
my SetupZaDbFont
# Appearance streams for on and off state of check button.
set obj "<< /BBox \[ 0 0 [Nf $width] [Nf $height]\] \n"
append obj "/Resources 3 0 R\n"
append obj "/Subtype /Form\n/Type /XObject\n"
if {$onObj ne ""} {
set onid [lindex $images($onObj) 2]
} else {
# Use char 4 from Zapf, which is a checkmark (unicode 0x2714)
set fs [expr {$height * 0.9}]
set charW [expr {0.846 * $fs}] ;# Char width 846 for checkmark
set baseL [expr {0.143 * $fs}] ;# Baseline 143 for Zapf
set cX [expr {($width-$charW)/2.0}]
set cY [expr {$height*0.05 + $baseL}]
set stream "/Tx BMC BT 0 Tc 0 Tw 100 Tz 0 g 0 Tr /ZaDb [Nf $fs] Tf "
append stream "1 0 0 1 [Nf $cX] [Nf $cY] Tm "
append stream "\[(4)\]TJ ET EMC"
set body [MakeStream $obj $stream $pdf(compress)]
set onid [my AddObject $body]
}
if {$offObj ne ""} {
set offid [lindex $images($offObj) 2]
} else {
# Empty, for off
if {![info exists pdf(checkboxoffobj)]} {
set stream ""
set body [MakeStream $obj $stream $pdf(compress)]
set pdf(checkboxoffobj) [my AddObject $body]
}
set offid $pdf(checkboxoffobj)
}
} else {
if {$initValue ne ""} {
# Appearance stream for init value of text
set obj "<< /BBox \[ 0 0 [Nf $width] [Nf $height]\] \n"
append obj "/Resources 3 0 R\n"
append obj "/Subtype /Form\n/Type /XObject\n"
set stream "/Tx BMC BT "
append stream "/$pdf(current_font) [Nf $pdf(font_size)] Tf 0 g "
# TODO: correct placement?
append stream "2 1.1 Td "
append stream "([CleanText $initValue $pdf(current_font)]) Tj "
append stream "ET EMC"
set body [MakeStream $obj $stream $pdf(compress)]
set onid [my AddObject $body]
}
}
# Create annotation
set andict "<<\n"
append andict " /Subtype /Widget\n"
# Page reference
append andict " /P $pdf(pageobjid) 0 R\n"
# Placement
append andict " /Rect \[[Nf $x] [Nf $y] [Nf $x2] [Nf $y2]\]\n"
if {$ftype eq "text"} {
# Form type text
append andict " /FT /Tx\n"
# Unique Identity
if {[info exists idObj]} {
append andict " /T (textform_$idObj)\n"
} else {
append andict " /T (textform[my NextOid])\n"
}
if {[info exists multiObj] && [string is boolean -strict $multiObj] && $multiObj} {
append andict " /P 1 0 R\n"
append andict " /Ff 4096\n"
append andict " /V <FEFF>\n"
append andict " /DV <FEFF>\n"
}
# Appearance
append andict " /DA (/$pdf(current_font) [Nf $pdf(font_size)] Tf 0 g)\n"
# Left justified flag
append andict " /Q 0\n"
# Value
if {$initValue ne ""} {
append andict " /V ([CleanText $initValue $pdf(current_font)])\n"
# Appearance
append andict " /AP << /N $onid 0 R >>\n"
}
} else {
# Form type checkbutton (Ff flags are zero for checkbutton)
append andict " /FT /Btn\n"
# Unique Identity
if {[info exists idObj]} {
append andict " /T (checkbuttonform)\n"
} else {
append andict " /T (checkbuttonform[my NextOid])\n"
}
# State
if {$initValue} {
append andict " /AS /Yes\n"
append andict " /V /Yes\n"
} else {
append andict " /AS /Off\n"
append andict " /V /Off\n"
}
# Appearance
append andict " /AP << "
append andict " /N << /Yes $onid 0 R /Off $offid 0 R >>\n"
append andict " /D << /Yes $onid 0 R /Off $offid 0 R >>\n"
append andict " >>\n"
# Highlight mode = Push
append andict " /H /P\n"
# ??
#append andict " /MK << /CA (4) >>\n"
}
# Flag for print
append andict " /F 4\n"
append andict ">>\n"
set anid [my AddObject $andict]
# Insert annotation into current page
lappend pdf(annotations) "$anid 0 R"
# Insert form into document
lappend pdf(forms) "$anid 0 R"
}
#######################################################################
# Canvas Handling
#######################################################################
method canvas {path args} {
my variable canvasFontMapping
my EndTextObj
set sticky "nw"
my Trans 0 0 x y
set width ""
set height ""
set bbox [$path bbox all]
set bg 0
# A dict mapping from Tk font name to PDF font family name can be given
set canvasFontMapping {}
foreach {arg value} $args {
switch -- $arg {
"-width" {set width [pdf4tcl::getPoints $value $pdf(unit)]}
"-height" {set height [pdf4tcl::getPoints $value $pdf(unit)]}
"-sticky" {set sticky $value}
"-y" {my Trans 0 $value _ y}
"-x" {my Trans $value 0 x _}
"-bbox" {set bbox $value}
"-bg" {set bg $value}
"-fontmap" {set canvasFontMapping $value}
default {
throw "PDF4TCL" "unknown option \"$arg\""
}
}
}
if {$bbox eq ""} {
# Nothing to display
return
}
if {$width eq ""} {
set width [expr {$pdf(width) - \
$pdf(marginright) - $x}]
}
if {$height eq ""} {
if {$pdf(orient)} {
set height [expr {$y - $pdf(marginbottom)}]
} else {
set height [expr {$pdf(height) - $pdf(margintop) - $y}]
}
}
if {[llength $bbox] != 4} {
throw "PDF4TCL" "-bbox must be a four element list"
}
foreach {bbx1 bby1 bbx2 bby2} $bbox break
set bbw [expr {$bbx2 - $bbx1}]
set bbh [expr {$bby2 - $bby1}]
set stickyw [string match "*w*" $sticky]
set stickye [string match "*e*" $sticky]
set stickyn [string match "*n*" $sticky]
set stickys [string match "*s*" $sticky]
set fillx [expr {$stickyw && $stickye}]
set filly [expr {$stickyn && $stickys}]
# Now calculate offset and scale between canvas coords
# and pdf coords.
set xscale [expr {$width / $bbw}]
set yscale [expr {$height / $bbh}]
if {$xscale > $yscale && !$fillx} {
set xscale $yscale
}
if {$yscale > $xscale && !$filly} {
set yscale $xscale
}
set xoffset [expr {$x - $bbx1 * $xscale}]
if {!$fillx && !$stickyw} {
# Move right
set xoffset [expr {$xoffset + ($width - $bbw * $xscale)}]
}
if {$pdf(orient)} {
set yoffset $y
} else {
set yoffset [expr {$y + $height}]
}
set yoffset [expr {$yoffset + $bby1 * $yscale}]
if {!$filly && !$stickyn} {
# Move down
set yoffset [expr {$yoffset - ($height - $bbh * $yscale)}]
}
# Canvas coordinate system starts in upper corner
# Thus we need to flip the y axis
set yscale [expr {-$yscale}]
# Set up clean graphics modes
my Pdfoutcmd "q"
my Pdfoutcmd 1.0 "w"
my Pdfout "\[\] 0 d\n"
if {$pdf(cmyk)} {
my Pdfoutcmd 0 0 0 1 "k"
my Pdfoutcmd 0 0 0 1 "K"
} else {
my Pdfoutcmd 0 0 0 "rg"
my Pdfoutcmd 0 0 0 "RG"
}
my Pdfoutcmd 0 "J" ;# Butt cap style
my Pdfoutcmd 0 "j" ;# Miter join style
# Miter limit; Tk switches from miter to bevel at 11 degrees
my Pdfoutcmd [expr {1.0/sin(11.0/180.0*3.14159265/2.0)}] "M"
# Store scale. Used to get the correct size of stipple patterns.
set pdf(canvasscale) [list [Nf $xscale] [Nf [expr {-$yscale}]] \
[Nf $xoffset] [Nf $yoffset]]
# Use better resolution for the scale since that can be small numbers
my Pdfoutn [Nf $xscale 6] 0 0 [Nf $yscale 6] \
[Nf $xoffset] [Nf $yoffset] "cm"
# Clip region
my Pdfoutcmd $bbx1 $bby1 "m"
my Pdfoutcmd $bbx1 $bby2 "l"
my Pdfoutcmd $bbx2 $bby2 "l"
my Pdfoutcmd $bbx2 $bby1 "l"
#my Pdfoutcmd $bbx1 $bby1 $bbw $bbh "re"
my Pdfoutcmd "W"
if {$bg} {
# Draw the region in background color if requested
my SetFillColor [my GetColor [$path cget -background]]
my Pdfoutcmd "f"
if {$pdf(cmyk)} {
my Pdfoutcmd 0 0 0 1 "k"
} else {
my Pdfoutcmd 0 0 0 "rg"
}
} else {
my Pdfoutcmd "n"
}
#set enclosed [$path find enclosed $bbx1 $bby1 $bbx2 $bby2]
set overlapping [$path find overlapping $bbx1 $bby1 $bbx2 $bby2]
foreach id $overlapping {
CanvasGetOpts $path $id opts
if {[info exists opts(-state)] && $opts(-state) eq "hidden"} {
continue
}
# Save graphics state for each item
my Pdfoutcmd "q"
# Special handling for tkpath items
if {[$path type $id] in {pimage ptext pline polyline ppolygon prect circle ellipse path group}} {
my CanvasDoTkpathItem $path $id
} else {
# Standard Tk Canvas
my CanvasDoItem $path $id [$path coords $id] opts
}
# Restore graphics state after the item
my Pdfoutcmd "Q"
}
# Restore graphics state after the canvas
my Pdfoutcmd "Q"
}
# Handle one tkpath item
method CanvasDoTkpathItem {path id} {
switch [$path type $id] {
pimage {
my Pdfout [$path itempdf $id [list my addTkpimgObj]]
}
ptext {
my setTkpfont \
[$path itemcget $id -fontsize] \
[$path itemcget $id -fontfamily] \
[$path itemcget $id -fontweight] \
[$path itemcget $id -fontslant]
my Pdfout \
[$path itempdf $id \
[list my addTkpextgs] \
[list my getTkpptext $pdf(current_font)] \
$pdf(current_font)]
}
pline - polyline - ppolygon - prect - circle - ellipse -
path - group {
my Pdfout [$path itempdf $id \
[list my addTkpextgs] \
[list my addTkpobj] \
[list my addTkpgrad]]
}
}
}
# Handle one canvas item
method CanvasDoItem {path id coords optsName} {
upvar 1 $optsName opts
my variable canvasFontMapping
# Not implemented: line/polygon -splinesteps
# Not implemented: stipple offset
# Limited: Stipple scale and offset does not match screen display
# Limited: window item needs Img, and needs to be mapped
switch [$path type $id] {
rectangle {
foreach {x1 y1 x2 y2} $coords break
set w [expr {$x2 - $x1}]
set h [expr {$y2 - $y1}]
my CanvasStdOpts opts
set stroke [expr {$opts(-outline) ne ""}]
set filled [expr {$opts(-fill) ne ""}]
my DrawRect $x1 $y1 $w $h $stroke $filled
}
line {
# For a line, -fill means the stroke colour
set opts(-outline) $opts(-fill)
set opts(-outlinestipple) $opts(-stipple)
set opts(-outlineoffset) $opts(-offset)
my CanvasStdOpts opts
set arrows {}
if {$opts(-arrow) eq "first" || $opts(-arrow) eq "both"} {
lappend arrows [lindex $coords 2] [lindex $coords 3] \
[lindex $coords 0] [lindex $coords 1] 0
}
if {$opts(-arrow) eq "last" || $opts(-arrow) eq "both"} {
lappend arrows [lindex $coords end-3] [lindex $coords end-2] \
[lindex $coords end-1] [lindex $coords end] \
[expr {[llength $coords] - 2}]
}
if {[llength $arrows] > 0} {
foreach {shapeA shapeB shapeC} $opts(-arrowshape) break
# Adjust like Tk does
set shapeA [expr {$shapeA + 0.001}]
set shapeB [expr {$shapeB + 0.001}]
set shapeC [expr {$shapeC + $opts(-width) / 2.0 + 0.001}]
set fracHeight [expr {($opts(-width)/2.0)/$shapeC}]
set backup [expr {$fracHeight * $shapeB + \
$shapeA * (1.0 - $fracHeight)/2.0}]
foreach {x1 y1 x2 y2 ix} $arrows {
set poly [list 0 0 0 0 0 0 0 0 0 0 0 0]
lset poly 0 $x2
lset poly 10 $x2
lset poly 1 $y2
lset poly 11 $y2
set dx [expr {$x2 - $x1}]
set dy [expr {$y2 - $y1}]
set length [expr {hypot($dx, $dy)}]
if {$length == 0} {
set sinTheta 0.0
set cosTheta 0.0
} else {
set sinTheta [expr {$dy / $length}]
set cosTheta [expr {$dx / $length}]
}
set vertX [expr {[lindex $poly 0] - $shapeA * $cosTheta}]
set vertY [expr {[lindex $poly 1] - $shapeA * $sinTheta}]
set temp [expr { $shapeC * $sinTheta}]
lset poly 2 [expr {[lindex $poly 0] - $shapeB * $cosTheta + $temp}]
lset poly 8 [expr {[lindex $poly 2] - 2 * $temp}]
set temp [expr { $shapeC * $cosTheta}]
lset poly 3 [expr {[lindex $poly 1] - $shapeB * $sinTheta - $temp}]
lset poly 9 [expr {[lindex $poly 3] + 2 * $temp}]
lset poly 4 [expr {[lindex $poly 2] * $fracHeight + $vertX * (1.0-$fracHeight)}]
lset poly 5 [expr {[lindex $poly 3] * $fracHeight + $vertY * (1.0-$fracHeight)}]
lset poly 6 [expr {[lindex $poly 8] * $fracHeight + $vertX * (1.0-$fracHeight)}]
lset poly 7 [expr {[lindex $poly 9] * $fracHeight + $vertY * (1.0-$fracHeight)}]
# Adjust line end to draw it under the arrow
lset coords $ix [expr {[lindex $coords $ix] - $backup * $cosTheta}]
incr ix
lset coords $ix [expr {[lindex $coords $ix] - $backup * $sinTheta}]
# Draw polygon
set cmd "m"
foreach {x y} $poly {
my Pdfoutcmd $x $y $cmd
set cmd "l"
}
my Pdfoutcmd "f"
}
}
# Draw lines
if {([string is true -strict $opts(-smooth)] || \
$opts(-smooth) eq "bezier") && [llength $coords] > 4} {
my CanvasBezier $coords
} elseif {$opts(-smooth) eq "raw"} {
my CanvasRawCurve $coords
} else {
set cmd "m"
foreach {x y} $coords {
my Pdfoutcmd $x $y $cmd
set cmd "l"
}
}
my Pdfoutcmd "S"
}
oval {
foreach {x1 y1 x2 y2} $coords break
set x [expr {($x2 + $x1) / 2.0}]
set y [expr {($y2 + $y1) / 2.0}]
set rx [expr {($x2 - $x1) / 2.0}]
set ry [expr {($y2 - $y1) / 2.0}]
my CanvasStdOpts opts
set stroke [expr {$opts(-outline) ne ""}]
set filled [expr {$opts(-fill) ne ""}]
my DrawOval $x $y $rx $ry $stroke $filled
}
arc {
foreach {x1 y1 x2 y2} $coords break
set x [expr {($x2 + $x1) / 2.0}]
set y [expr {($y2 + $y1) / 2.0}]
set rx [expr {($x2 - $x1) / 2.0}]
# Flip y-axis
set ry [expr {-($y2 - $y1) / 2.0}]
# Canvas draws arc with bevel style
if {![info exists opts(-joinstyle)]} {
set opts(-joinstyle) bevel
}
my CanvasStdOpts opts
set stroke [expr {$opts(-outline) ne ""}]
set filled [expr {$opts(-fill) ne ""}]
set phi $opts(-start)
set extend $opts(-extent)
my DrawArc $x $y $rx $ry $phi $extend $stroke $filled \
$opts(-style)
}
polygon {
my CanvasStdOpts opts
set stroke [expr {$opts(-outline) ne ""}]
set filled [expr {$opts(-fill) ne ""}]
if {[string is true -strict $opts(-smooth)] || \
$opts(-smooth) eq "bezier"} {
# Close the coordinates if necessary
if {[lindex $coords 0] != [lindex $coords end-1] || \
[lindex $coords 1] != [lindex $coords end]} {
lappend coords [lindex $coords 0] [lindex $coords 1]
}
my CanvasBezier $coords
} elseif {$opts(-smooth) eq "raw"} {
my CanvasRawCurve $coords
} else {
set cmd "m"
foreach {x y} $coords {
my Pdfoutcmd $x $y $cmd
set cmd "l"
}
}
if {$filled && $stroke} {
my Pdfoutcmd "b"
} elseif {$filled && !$stroke} {
my Pdfoutcmd "f"
} else {
my Pdfoutcmd "s"
}
}
text {
# Width is not a stroke option here
array unset opts -width
my CanvasStdOpts opts
set lines [CanvasGetWrappedText $path $id underline]
foreach {x y} $coords break
foreach {x1 y1 x2 y2} [$path bbox $id] break
my PushFont
my CanvasSetFont $opts(-font) $canvasFontMapping
set fontsize $pdf(font_size)
# Next, figure out if the text fits within the bbox
# with the current font, or it needs to be scaled.
# compute width on canvas using font measure instead of bbox
# to get it right for angled text
set widest 0.0
set cwidest 0.0
foreach line $lines {
set width [my getStringWidth $line 1]
set cwidth [font measure $opts(-font) $line]
if {$width > $widest} {
set widest $width
}
if {$cwidth > $cwidest} {
set cwidest $cwidth
}
}
if {$cwidest == 0} {
# The text does not produce any size, which probably
# mean it is empty.
return
}
set xscale [expr {$widest / $cwidest}]
set yscale [expr {([llength $lines] * $fontsize) / \
($y2 - $y1)}]
# Scale down if the font is too big
if {$xscale > 1.001} {
my setFont [expr {$fontsize / $xscale}] "" 1
set fontsize $pdf(font_size)
set widest [expr {$widest / $xscale}]
}
# Now we have selected an appropriate font and size.
# Move x/y to point nw/n/ne depending on anchor
# and justification
set width $widest
set xc $x ;# center of rotation coordinates
set yc $y ;# they are not adjusted
# First line is assumed to be height of bounding box.
# Add font size for each new line.
# Thus it is assumed that:
# line spacing = font size
# canvas coordinate = corner of bounding box
set bboxHeight [my getFontMetric height 1]
set height [expr {$fontsize * [llength $lines] + \
$bboxHeight - $fontsize}]
if {[string match "s*" $opts(-anchor)]} {
set y [expr {$y - $height}]
} elseif {![string match "n*" $opts(-anchor)]} {
set y [expr {$y - ($height / 2.0)}]
}
if {[string match "*w" $opts(-anchor)]} {
set xanchor 0
} elseif {[string match "*e" $opts(-anchor)]} {
set xanchor 2
} else {
set xanchor 1
}
set xjustify [lsearch {left center right} $opts(-justify)]
set x [expr {$x + ($xjustify - $xanchor) * $width / 2.0}]
# Displace y to base line of font
# Since canvas coordinates are assumed to point to corner of
# bounding box, we use bboxt to displace.
set bboxt [my getFontMetric bboxt 1]
# The -1 is a fudge factor that has given better results in
# practice. I do not understand why it is needed.
set y [expr {$y + $bboxt - 1.0}]
set lineNo 0
set ulcoords {}
foreach line $lines {
set width [my getStringWidth $line 1]
set x0 [expr {$x - $xjustify * $width / 2.0}]
# Since we have put the coordinate system upside
# down to follow canvas coordinates we need a
# negative y scale here to get the text correct.
# if -angle is present, turn
if {$opts(-angle) != 0} {
#puts "Angle is $opts(-angle)"
set sx [expr {sin(-$opts(-angle)*3.14159265358979/180)}]
set cx [expr {cos(-$opts(-angle)*3.14159265358979/180)}]
set msx [expr {-$sx}]
set mcx [expr {-$cx}]
set mxc [expr {-$xc}]
set myc [expr {-$yc}]
# Compute test rotation matrix.
# First subtract center of rotation, rotate, shift back
set rotationmatrix [list 1 0 0 1 $mxc $myc]
set rotationmatrix [MulMxM $rotationmatrix \
[list $cx $sx $msx $cx 0 0]]
set rotationmatrix [MulMxM $rotationmatrix \
[list 1 0 0 1 $xc $yc]]
# compute final coordinates.
foreach {xs ys} [MulVxM [list $x0 $y] $rotationmatrix] break
my Pdfoutcmd $cx $sx $sx $mcx $xs $ys "Tm"
} else {
my Pdfoutcmd 1 0 0 -1 $x0 $y "Tm"
}
my Pdfout "([CleanText $line $pdf(current_font)]) Tj\n"
if {$underline != -1} {
if {[lindex $underline 0] eq $lineNo} {
set index [lindex $underline 1]
set ulx [my getStringWidth [string range $line \
0 [expr {$index - 1}]] 1]
set ulw [my getStringWidth [string index $line $index] 1]
lappend ulcoords [expr {$x0 + $ulx}] \
[expr {$y + 1.0}] $ulw
}
}
incr lineNo
set y [expr {$y + $fontsize}]
}
my EndTextObj
my PopFont
# Draw any underline
if {[info exists rotationmatrix]} {
# transform underlines by same matrix as text anchor point
foreach {x y w} $ulcoords {
my Pdfoutcmd {*}[MulVxM [list $x $y] $rotationmatrix] "m"
my Pdfoutcmd {*}[MulVxM [list [expr {$x + $w}] $y] $rotationmatrix] "l"
my Pdfoutcmd "S"
}
} else {
foreach {x y w} $ulcoords {
my Pdfoutcmd $x $y "m"
my Pdfoutcmd [expr {$x + $w}] $y "l"
my Pdfoutcmd "S"
}
}
}
bitmap {
set bitmap $opts(-bitmap)
if {$bitmap eq ""} {
return
}
set id bitmap_canvas_[file rootname [file tail $bitmap]]
if {![info exists bitmaps($id)]} {
my AddBitmap $bitmap -id $id
}
foreach {width height imoid stream} $bitmaps($id) break
foreach {x1 y1} $coords break
# Since the canvas coordinate system is upside
# down we must flip back to get the image right.
# We do this by adjusting y and y scale.
switch $opts(-anchor) {
nw { set dx 0.0 ; set dy 1.0 }
n { set dx 0.5 ; set dy 1.0 }
ne { set dx 1.0 ; set dy 1.0 }
e { set dx 1.0 ; set dy 0.5 }
se { set dx 1.0 ; set dy 0.0 }
s { set dx 0.5 ; set dy 0.0 }
sw { set dx 0.0 ; set dy 0.0 }
w { set dx 0.0 ; set dy 0.5 }
default { set dx 0.5 ; set dy 0.5 }
}
set x [expr {$x1 - $width * $dx}]
set y [expr {$y1 + $height * $dy}]
set bg $opts(-background)
if {$bg eq ""} {
# Dummy background to see if masking fails
set bg $opts(-foreground)
}
# Build a two-color palette
set colors [concat [my GetColor $bg] \
[my GetColor $opts(-foreground)]]
set PaletteHex ""
foreach color $colors {
append PaletteHex [format %02x \
[expr {int(round($color * 255.0))}]]
}
if {$pdf(cmyk)} {
set paletteX "\[ /Indexed /DeviceCMYK "
} else {
set paletteX "\[ /Indexed /DeviceRGB "
}
append paletteX "1 < "
append paletteX $PaletteHex
append paletteX " > \]"
# An image object for this bitmap+color
set xobject "<<\n/Type /XObject\n"
append xobject "/Subtype /Image\n"
append xobject "/Width $width\n/Height $height\n"
append xobject "/ColorSpace $paletteX\n"
append xobject "/BitsPerComponent 1\n"
append xobject "/Length [string length $stream]\n"
if {$opts(-background) eq ""} {
append xobject "/Mask $imoid 0 R\n"
}
append xobject ">>\n"
append xobject "stream\n"
append xobject $stream
append xobject "\nendstream"
set newoid [my AddObject $xobject]
set newid image$newoid
set images($newid) [list $width $height $newoid 0]
# Put the image on the page
my Pdfoutcmd $width 0 0 [expr {-$height}] $x $y "cm"
my Pdfout "/$newid Do\n"
}
image {
set image $opts(-image)
if {$image eq ""} {
return
}
set id image_canvas_$image
if {![info exists images($id)]} {
my addRawImage [$image data] -id $id
}
foreach {width height oid} $images($id) break
foreach {x1 y1} $coords break
# Since the canvas coordinate system is upside
# down we must flip back to get the image right.
# We do this by adjusting y and y scale.
switch $opts(-anchor) {
nw { set dx 0.0 ; set dy 1.0 }
n { set dx 0.5 ; set dy 1.0 }
ne { set dx 1.0 ; set dy 1.0 }
e { set dx 1.0 ; set dy 0.5 }
se { set dx 1.0 ; set dy 0.0 }
s { set dx 0.5 ; set dy 0.0 }
sw { set dx 0.0 ; set dy 0.0 }
w { set dx 0.0 ; set dy 0.5 }
default { set dx 0.5 ; set dy 0.5 }
}
set x [expr {$x1 - $width * $dx}]
set y [expr {$y1 + $height * $dy}]
my Pdfoutcmd $width 0 0 [expr {-$height}] $x $y "cm"
my Pdfout "/$id Do\n"
}
window {
catch {package require Img}
if {[catch {
image create photo -format window -data $opts(-window)
} image]} {
set image ""
}
if {$image eq ""} {
# Get a size even if it is unmapped
foreach width [list [winfo width $opts(-window)] \
$opts(-width) \
[winfo reqwidth $opts(-window)]] {
if {$width > 1} break
}
foreach height [list [winfo height $opts(-window)] \
$opts(-height) \
[winfo reqheight $opts(-window)]] {
if {$height > 1} break
}
} else {
set id [my addRawImage [$image data]]
foreach {width height oid} $images($id) break
}
foreach {x1 y1} $coords break
# Since the canvas coordinate system is upside
# down we must flip back to get the image right.
# We do this by adjusting y and y scale.
switch $opts(-anchor) {
nw { set dx 0.0 ; set dy 1.0 }
n { set dx 0.5 ; set dy 1.0 }
ne { set dx 1.0 ; set dy 1.0 }
e { set dx 1.0 ; set dy 0.5 }
se { set dx 1.0 ; set dy 0.0 }
s { set dx 0.5 ; set dy 0.0 }
sw { set dx 0.0 ; set dy 0.0 }
w { set dx 0.0 ; set dy 0.5 }
default { set dx 0.5 ; set dy 0.5 }
}
set x [expr {$x1 - $width * $dx}]
set y [expr {$y1 + $height * $dy}]
if {$image eq ""} {
# Draw a black box
my Pdfoutcmd $x [expr {$y - $height}] \
$width $height "re"
my Pdfoutcmd "f"
} else {
my Pdfoutcmd $width 0 0 [expr {-$height}] $x $y "cm"
my Pdfout "/$id Do\n"
}
}
} ;# End of switch over item type
# Note: Any item above may return early if needed, so
# there should not be any code here.
}
method CanvasBezier {coords} {
# Is it a closed curve?
if {[lindex $coords 0] == [lindex $coords end-1] && \
[lindex $coords 1] == [lindex $coords end]} {
set closed 1
set x0 [expr {0.5 * [lindex $coords end-3] + 0.5 *[lindex $coords 0]}]
set y0 [expr {0.5 * [lindex $coords end-2] + 0.5 *[lindex $coords 1]}]
set x1 [expr {0.167* [lindex $coords end-3] + 0.833*[lindex $coords 0]}]
set y1 [expr {0.167* [lindex $coords end-2] + 0.833*[lindex $coords 1]}]
set x2 [expr {0.833* [lindex $coords 0] + 0.167*[lindex $coords 2]}]
set y2 [expr {0.833* [lindex $coords 1] + 0.167*[lindex $coords 3]}]
set x3 [expr {0.5 * [lindex $coords 0] + 0.5 *[lindex $coords 2]}]
set y3 [expr {0.5 * [lindex $coords 1] + 0.5 *[lindex $coords 3]}]
my Pdfoutcmd $x0 $y0 "m"
my Pdfoutcmd $x1 $y1 $x2 $y2 $x3 $y3 "c"
} else {
set closed 0
set x3 [lindex $coords 0]
set y3 [lindex $coords 1]
my Pdfoutcmd $x3 $y3 "m"
}
set len [llength $coords]
for {set i 2} {$i < ($len - 2)} {incr i 2} {
foreach {px1 py1 px2 py2} [lrange $coords $i [expr {$i + 3}]] break
set x1 [expr {0.333*$x3 + 0.667*$px1}]
set y1 [expr {0.333*$y3 + 0.667*$py1}]
if {!$closed && $i == ($len - 4)} {
# Last of an open curve
set x3 $px2
set y3 $py2
} else {
set x3 [expr {0.5 * $px1 + 0.5 * $px2}]
set y3 [expr {0.5 * $py1 + 0.5 * $py2}]
}
set x2 [expr {0.333 * $x3 + 0.667 * $px1}]
set y2 [expr {0.333 * $y3 + 0.667 * $py1}]
my Pdfoutcmd $x1 $y1 $x2 $y2 $x3 $y3 "c"
}
}
method CanvasRawCurve {coords} {
set x3 [lindex $coords 0]
set y3 [lindex $coords 1]
my Pdfoutcmd $x3 $y3 "m"
set len [llength $coords]
# Is there a complete set of segments in the list?
set add [expr {($len - 2) % 6}]
if {$add != 0} {
eval lappend coords [lrange $coords 0 [expr {$add - 1}]]
}
for {set i 0} {$i < ($len - 8)} {incr i 6} {
foreach {px1 py1 px2 py2 px3 py3 px4 py4} \
[lrange $coords $i [expr {$i + 7}]] break
if {$px1 == $px2 && $py1 == $py2 && $px3 == $px4 && $py3 == $py4} {
# Straight line
my Pdfoutcmd $px4 $py4 "l"
} else {
my Pdfoutcmd $px2 $py2 $px3 $py3 $px4 $py4 "c"
}
}
}
method CanvasGetBitmap {bitmap offset} {
# The pattern is unique for the scale for this canvas
foreach {xscale yscale xoffset yoffset} $pdf(canvasscale) break
# Adapt to offset
if {[regexp {^(\#?)(.*),(.*)$} $offset -> pre ox oy]} {
set xoffset [expr {$xoffset + $ox * $xscale}]
set yoffset [expr {$yoffset - $oy * $yscale}]
} else {
# Not supported yet
}
set scale [list $xscale $yscale $xoffset $yoffset]
set tail [string map {. x} [join $scale _]]
set id pattern_canvas_[file rootname [file tail $bitmap]]_$tail
if {![info exists patterns($id)]} {
my AddBitmap $bitmap -id $id -pattern $scale
}
return $id
}
# Utility for translating dash patterns - if needed
proc ::pdf4tcl::CanvasMakeDashPattern {pattern linewidth} {
# If numeric, return the same
if { ! [regexp {[.,-_]} $pattern] } {
return $pattern
}
# A pattern adapts to line width
set linewidth [expr {int($linewidth + 0.5)}]
if {$linewidth < 1} {
set linewidth 1
}
set lw2 [expr {2 * $linewidth}]
set lw4 [expr {4 * $linewidth}]
set lw6 [expr {6 * $linewidth}]
set lw8 [expr {8 * $linewidth}]
# Translate each character
set newPattern {}
foreach c [split $pattern ""] {
switch $c {
" " {
if { [llength $newPattern] > 0 } {
set lastNumber [expr {$lw4 + [lindex $newPattern end]}]
set newPattern [lreplace $newPattern end end $lastNumber]
}
}
"." {
lappend newPattern $lw2 $lw4
}
"," {
lappend newPattern $lw4 $lw4
}
"-" {
lappend newPattern $lw6 $lw4
}
"_" {
lappend newPattern $lw8 $lw4
}
}
}
return $newPattern
}
# Setup the graphics state from standard options
method CanvasStdOpts {optsName} {
upvar 1 $optsName opts
# Stipple for fill color
set fillstippleid ""
if {[info exists opts(-stipple)] && $opts(-stipple) ne ""} {
set fillstippleid [my CanvasGetBitmap $opts(-stipple) \
$opts(-offset)]
}
# Stipple for stroke color
set strokestippleid ""
if {[info exists opts(-outlinestipple)] && \
$opts(-outlinestipple) ne ""} {
set strokestippleid [my CanvasGetBitmap $opts(-outlinestipple) \
$opts(-outlineoffset)]
}
# Outline controls stroke color
if {[info exists opts(-outline)] && $opts(-outline) ne ""} {
my CanvasStrokeColor $opts(-outline) $strokestippleid
}
# Fill controls fill color
if {[info exists opts(-fill)] && $opts(-fill) ne ""} {
my CanvasFillColor $opts(-fill) $fillstippleid
}
# Line width
if {[info exists opts(-width)]} {
my Pdfoutcmd $opts(-width) "w"
}
# Dash pattern and offset
if {[info exists opts(-dash)] && $opts(-dash) ne ""} {
set dashPattern [CanvasMakeDashPattern $opts(-dash) $opts(-width)]
my Pdfout "\[$dashPattern\] $opts(-dashoffset) d\n"
}
# Cap style
if {[info exists opts(-capstyle)] && $opts(-capstyle) ne "butt"} {
switch $opts(-capstyle) {
projecting {
my Pdfoutcmd 2 "J"
}
round {
my Pdfoutcmd 1 "J"
}
}
}
# Join style
if {[info exists opts(-joinstyle)] && $opts(-joinstyle) ne "miter"} {
switch $opts(-joinstyle) {
bevel {
my Pdfoutcmd 2 "j"
}
round {
my Pdfoutcmd 1 "j"
}
}
}
}
# Set the fill color from a Tk color
method CanvasFillColor {color {bitmapid ""}} {
set cList [my GetColor $color]
if {$bitmapid eq ""} {
my SetFillColor $cList
} else {
foreach {red green blue k} $cList break
my Pdfout "/Cs1 cs\n"
if {$pdf(cmyk)} {
my Pdfoutcmd $red $green $blue $k "/$bitmapid scn"
} else {
my Pdfoutcmd $red $green $blue "/$bitmapid scn"
}
}
}
# Set the stroke color from a Tk color
method CanvasStrokeColor {color {bitmapid ""}} {
set cList [my GetColor $color]
if {$bitmapid eq ""} {
my SetStrokeColor $cList
} else {
foreach {red green blue k} $cList break
my Pdfout "/Cs1 CS\n"
if {$pdf(cmyk)} {
my Pdfoutcmd $red $green $blue $k "/$bitmapid SCN"
} else {
my Pdfoutcmd $red $green $blue "/$bitmapid SCN"
}
}
}
# Helper to extract configuration from a canvas item
proc ::pdf4tcl::CanvasGetOpts {path id arrName} {
upvar 1 $arrName arr
array unset arr
foreach item [$path itemconfigure $id] {
set arr([lindex $item 0]) [lindex $item 4]
}
if {![info exists arr(-state)]} {
return
}
if {$arr(-state) eq "" || $arr(-state) eq "normal"} {
return
}
# Translate options depending on state
set state $arr(-state)
foreach item [array names arr] {
if {[regexp -- "^-${state}(.*)\$" $item -> orig]} {
if {[info exists arr(-$orig)]} {
set arr(-$orig) $arr($item)
}
}
}
}
# Get the text from a text item, as a list of lines
# This takes and line wrapping into account
proc ::pdf4tcl::CanvasGetWrappedText {w item ulName} {
upvar 1 $ulName underline
set text [$w itemcget $item -text]
set width [$w itemcget $item -width]
set underline [$w itemcget $item -underline]
# Simple non-wrapping case. Only divide on newlines.
if {$width == 0} {
set lines [split $text \n]
if {$underline != -1} {
set isum 0
set lineNo 0
foreach line $lines {
set iend [expr {$isum + [string length $line]}]
if {$underline < $iend} {
set underline [list $lineNo [expr {$underline - $isum}]]
break
}
incr lineNo
set isum [expr {$iend + 1}]
}
}
return $lines
}
# Run across the text's left side and look for all indexes
# that start a line.
foreach {x1 y1 x2 y2} [$w bbox $item] break
set firsts {}
for {set y $y1} {$y < $y2} {incr y} {
lappend firsts [$w index $item @$x1,$y]
}
set firsts [lsort -integer -unique $firsts]
# Extract each displayed line
set prev 0
set res {}
foreach index $firsts {
if {$prev != $index} {
set line [string range $text $prev [expr {$index - 1}]]
if {[string index $line end] eq "\n"} {
set line [string trimright $line \n]
} else {
# If the line does not end with \n it is wrapped.
# Then spaces should be discarded
set line [string trimright $line]
}
lappend res $line
}
set prev $index
}
# The last chunk
lappend res [string range $text $prev end]
if {$underline != -1} {
set lineNo -1
set prev 0
foreach index $firsts {
if {$underline < $index} {
set underline [lindex $lineNo [expr {$underline - $prev}]]
break
}
set prev $index
incr lineNo
}
}
return $res
}
# Given a Tk font, figure out a reasonable font to use and set it
# as current font.
# A dict mapping from Tk font name to PDF font family name can be given
method CanvasSetFont {font {userMapping {}}} {
array unset fontinfo
array set fontinfo [font actual $font]
array set fontinfo [font metrics $font]
# Any fixed font maps to courier
if {$fontinfo(-fixed)} {
set fontinfo(-family) courier
}
set bold [expr {$fontinfo(-weight) eq "bold"}]
set italic [expr {$fontinfo(-slant) eq "italic"}]
switch -glob [string tolower $fontinfo(-family)] {
*courier* - *fixed* {
set family Courier
if {$bold && $italic} {
append family -BoldOblique
} elseif {$bold} {
append family -Bold
} elseif {$italic} {
append family -BoldOblique
}
}
*times* - {*nimbus roman*} {
if {$bold && $italic} {
set family Times-BoldItalic
} elseif {$bold} {
set family Times-Bold
} elseif {$italic} {
set family Times-Italic
} else {
set family Times-Roman
}
}
*helvetica* - *arial* - {*nimbus sans*} - default {
set family Helvetica
if {$bold && $italic} {
append family -BoldOblique
} elseif {$bold} {
append family -Bold
} elseif {$italic} {
append family -BoldOblique
}
}
}
array set userMappingArr $userMapping
if {[info exists userMappingArr($font)]} {
set family $userMappingArr($font)
}
set fontsize $fontinfo(-linespace)
my BeginTextObj
my setFont $fontsize $family 1
}
#######################################################################
# Helper functions
#######################################################################
# helper function: mask parentheses and backslash
proc ::pdf4tcl::CleanText {in fn} {
variable ::pdf4tcl::FontsAttrs
if {$FontsAttrs($fn,specialencoding)} {
# Convert using special encoding of font subset:
set out ""
foreach uchar [split $in {}] {
append out [dict get $FontsAttrs($fn,encoding) $uchar]
}
} else {
set out [encoding convertto $FontsAttrs($fn,encoding) $in]
}
# map special characters
return [string map {
\n "\\n" \r "\\r" \t "\\t" \b "\\b" \f "\\f" ( "\\(" ) "\\)" \\ "\\\\"
} $out]
}
# helper function: correctly quote string with parentheses
proc ::pdf4tcl::QuoteString {string} {
# map special characters
return ([string map {
\n "\\n" \r "\\r" \t "\\t" \b "\\b" \f "\\f" ( "\\(" ) "\\)" \\ "\\\\"
} $string])
}
# helper function: consume and return an object id
method GetOid {{noxref 0}} {
if {!$noxref} {
my StoreXref
}
set res $pdf(pdf_obj)
incr pdf(pdf_obj)
return $res
}
# helper function: return next object id (without incrementing)
method NextOid {} {
return $pdf(pdf_obj)
}
# helper function: set xref of (current) oid to current out_pos
method StoreXref {{oid {}}} {
if {$oid eq ""} {
set oid $pdf(pdf_obj)
}
set pdf(xref,$oid) $pdf(out_pos)
}
# helper function for formatting floating point numbers
proc ::pdf4tcl::Nf {n {deci 3}} {
# Up to 3 decimals
set num [format %.*f $deci $n]
# Remove surplus decimals
set num [string trimright [string trimright $num "0"] "."]
# Small negative numbers might become -0
if {$num eq "-0"} {
set num "0"
}
return $num
}
} ;# end of class pdf4tcl::pdf4tcl
#######################################################################
# Implementation of pdf4tcl::catPdf resides below
#######################################################################
# Put all helpers in a namespace
namespace eval pdf4tcl::cat {}
# Parse a PDF dictionary in <<>> and put its elements and values in a tcl dict
proc pdf4tcl::cat::PdfDictToTclDict {dict} {
# Remove surrounding <<>>
regexp {^\s*<<\s*(.*?)\s*>>\s*$} $dict -> values
if {![info exists values]} {
#puts DICT??
return {}
}
# Parser
set state none
set key ""
set value ""
set result {}
set i 0
set len [string length $values]
while {$i < $len} {
set c [string index $values $i]
switch $state {
none {
if {$c eq "/"} {
set key $c
set state name
incr i
}
}
name {
if {[string is alnum $c]} {
append key $c
incr i
} elseif {[string is space $c]} {
set state space
incr i
} else {
set value $c
incr i
set state val
}
}
space {
if {[string is space $c]} {
incr i
} else {
set value $c
incr i
set state val
}
}
val {
if {$c eq "/"} {
# Start of a new key
dict set result $key [string trim $value]
set key $c
set value ""
set state name
incr i
} elseif {0} {
# TODO: take care of << [ ( etc.
} else {
append value $c
incr i
}
}
}
}
if {$key ne ""} {
dict set result $key $value
}
return $result
}
# Parse a PDF object's dictionary and put its elements and values in a
# tcl dict
proc pdf4tcl::cat::PdfObjToTclDict {obj} {
#set apa $dict
# Remove surrounding obj
regexp {^\s*\d+\s+0\s+obj\s*(.*)$} $obj -> obj
set obj [string trim $obj]
# Remove endobj
set dict [string range $obj 0 end-6]
# TODO: remove any stream?
return [PdfDictToTclDict $dict]
}
# Make a tcl dict into a PDF dictionary in <<>>
proc pdf4tcl::cat::TclDictToPdfDict {dict} {
set res "<<"
foreach {key val} $dict {
append res $key " " $val \n
}
append res ">>"
return $res
}
# Read a PDF and organise its data into a dict with the following elements
# N : Number of objects + 1 (i.e. they go from 1 to N-1)
# trailer: trailer dictionary defining e.g. Root object
# root: Dictionary from root object
# rootid : Object number of root object
# info: Dictionary from info object, if any
# infoid : Object number of info object, if any
# <n> : Object <n> from "n 0 obj" through "endobj". A dict with keys:
# full: entire object
# dict: main dictionary, if any, converted to tcl dict
# stream: any stream
proc pdf4tcl::cat::ReadPdf {file} {
set ch [open $file rb]
set data [read $ch]
close $ch
# Locate xref table
regexp {startxref\s+(\d+)\s+%%EOF\s*$} $data -> startxref
set endpart [string range $data $startxref end]
set objs [string range $data 0 [expr {$startxref - 1}]]
# Extract trailer
regexp {trailer\s+(.*?)\s+startxref} $endpart -> trailertxt
set trailer [PdfDictToTclDict $trailertxt]
# Extract xrefs
set obj 1
set xrefs {}
foreach line [split $endpart \n] {
if {[string match *trailer* $line]} break
if {[regexp {(\d+) \d+ n} $line -> index]} {
lappend xrefs [list $obj [string trimleft $index 0]]
incr obj
}
}
dict set pdfdata N $obj
dict set pdfdata "trailer" $trailer
# Cut out objects, from the end
set xrefs [lsort -integer -decreasing -index 1 $xrefs]
foreach xref $xrefs {
foreach {obj index} $xref break
dict set pdfdata $obj full [string trim [string range $objs $index end]]
set objs [string range $objs 0 [expr {$index - 1}]]
}
# Get root object
set rval [dict get $trailer /Root]
set rootid [lindex $rval 0]
dict set pdfdata "rootid" $rootid
dict set pdfdata root [PdfObjToTclDict [dict get $pdfdata $rootid full]]
# Any info object?
if {[dict exists $trailer /Info]} {
set rval [dict get $trailer /Info]
set infoid [lindex $rval 0]
dict set pdfdata "infoid" $infoid
dict set pdfdata info [PdfObjToTclDict [dict get $pdfdata $infoid full]]
}
return $pdfdata
}
# Debug
proc pdf4tcl::cat::Dump {pdfdata} {
array set d $pdfdata
parray d {[a-zA-Z]*}
# lowest id
parray d [lindex [lsort -dictionary [dict keys $pdfdata]] 0]
parray d 6
parray d 285
}
# Write to an output stream, keep track of number of chars
proc pdf4tcl::cat::WriteCh {ch str cntName} {
upvar 1 $cntName cnt
incr cnt [string length $str]
puts -nonewline $ch $str
}
# Given a dictionary like the one from ReadPdf, create a PDF
proc pdf4tcl::cat::WritePdf {filename pdfd} {
set ch [open $filename wb]
set pos 0
set xref {}
WriteCh $ch "%PDF-1.4\n" pos
WriteCh $ch "%\xE5\xE4\xF6\n" pos
foreach obj [lreverse [dict keys $pdfd]] {
if {![string is digit -strict $obj]} continue
dict set xref $obj $pos
# TODO: do not take the full if parts exist
WriteCh $ch [dict get $pdfd $obj full]\n pos
}
set xref_pos $pos
set N [dict get $pdfd N]
WriteCh $ch "xref\n" pos
WriteCh $ch "0 $N\n" pos
WriteCh $ch "0000000000 65535 f \n" pos
for {set a 1} {$a < $N} {incr a} {
WriteCh $ch [format "%010ld 00000 n \n" [dict get $xref $a]] pos
}
WriteCh $ch "trailer\n" pos
WriteCh $ch [TclDictToPdfDict [dict get $pdfd trailer]]\n pos
WriteCh $ch "startxref\n" pos
WriteCh $ch "$xref_pos\n" pos
WriteCh $ch "%%EOF\n" po
close $ch
}
# renumber any " N 0 R" reference found
# TODO: detect stream in an object??
proc pdf4tcl::cat::RenumberRef {val delta {refmapping {}}} {
set rest $val
set result ""
while {$rest ne ""} {
# Locate first reference
if {[regexp -indices {^\d+ 0 R} $rest ixs]} {
lassign $ixs is ie
incr is -1
} elseif {[regexp -indices {\W\d+ 0 R} $rest ixs]} {
lassign $ixs is ie
} else {
append result $rest
break
}
append result [string range $rest 0 $is]
incr is
set ref [string range $rest $is $ie]
incr ie
set rest [string range $rest $ie end]
set ref [lindex $ref 0]
set new [expr {$ref + $delta}]
if {[dict exists $refmapping $ref]} {
set new [dict get $refmapping $ref]
}
append result "$new 0 R"
}
return $result
}
# renumber Tcl dict version of a dict
proc pdf4tcl::cat::RenumberDict {d delta {refmapping {}}} {
foreach {key val} $d {
dict set d $key [RenumberRef $val $delta]
}
return $d
}
# Renumber a complete object
proc pdf4tcl::cat::RenumberObj {obj delta {refmapping {}}} {
# Extract initial obj part
if {![regexp {^\s*(\d+)\s+0\s+obj\s*(.*)$} $obj -> objid objbody]} {
#puts OBJ??
#puts '$obj'
return $obj
}
# TODO, remove any stream before passing it to RenumberRef
set objbody [RenumberRef $objbody $delta $refmapping]
set objid [expr {$objid + $delta}]
set result "$objid 0 obj\n$objbody"
return $result
}
proc pdf4tcl::cat::RenumberPdf {pdfd delta {refmapping {}}} {
set newd {}
foreach {key val} $pdfd {
if {[string is digit $key]} {
set val [dict get $val full] ;# TBD if stream identified?
dict set newd [expr {$key + $delta}] \
full [RenumberObj $val $delta $refmapping]
continue
}
switch $key {
N {
# N will represent end of object numbers
dict set newd $key [expr {$val + $delta}]
}
trailer - root - info {# Dictionary
dict set newd $key [RenumberDict $val $delta]
}
rootid - infoid {
dict set newd $key [expr {$val + $delta}]
}
}
}
return $newd
}
# Add one pdf's contents to another
proc pdf4tcl::cat::AppendPdf {pdf1 pdf2} {
# Get the pages from first pdf
set pages1id [lindex [dict get $pdf1 root /Pages] 0]
regexp {/Kids\s*\[([^\]]*)\]} [dict get $pdf1 $pages1id full] -> kids1vec
# Get the pages id from second pdf
set pages2id [lindex [dict get $pdf2 root /Pages] 0]
# References in pdf2 to its Pages object should be redirected
# to pdf1's Pages object instead,
set refmapping [list $pages2id $pages1id]
# Now, renumber all objects in pdf2 to put them after all objs in pdf1
set delta [expr {[dict get $pdf1 N] - 1}]
set pdf2 [RenumberPdf $pdf2 $delta $refmapping]
#Dump $pdf2
# Get the list of pages from second pdf, after renumbering
set pages2id [lindex [dict get $pdf2 root /Pages] 0]
regexp {/Kids\s*\[([^\]]*)\]} [dict get $pdf2 $pages2id full] -> kids2vec
#puts "PAGE2 $pages2id $kids2vec"
# Recreate the pages object and replace it in pdf1
set kids "$kids1vec $kids2vec"
set count [expr {[llength $kids] / 3}]
set newobj "$pages1id 0 obj\n<<\n"
append newobj "/Type /Pages\n"
append newobj "/Count $count\n"
append newobj "/Kids \[ $kids \]\n"
append newobj ">>\nendobj"
dict set pdf1 $pages1id full $newobj
# TODO: Merge other stuff in Catalog, like AcroForm or Metadata
# Transfer all objects from 2 to 1
foreach {key val} $pdf2 {
if {[string is digit $key]} {
dict set pdf1 $key full [dict get $val full]
}
}
# Update size in trailer
dict set pdf1 trailer /Size [dict get $pdf2 N]
dict set pdf1 N [dict get $pdf2 N]
return $pdf1
}
# Concatenate PDFs.
# Currently the implementation limits the PDFs a lot since not all details
# are taken care of yet. Straightforward ones like those created with pdf4tcl
# or ps2pdf should work mostly ok.
proc pdf4tcl::catPdf {args} {
if {[llength $args] < 3} {
throw "PDF4TCL" "wrong # args: should be \"catPdf infile ?infile ...? outfile\""
}
set outfile [lindex $args end]
set infile1 [lindex $args 0]
set infiles [lrange $args 1 end-1]
set pdf1 [pdf4tcl::cat::ReadPdf $infile1]
#pdf4tcl::cat::Dump $pdf1
foreach f $infiles {
set pdf2 [pdf4tcl::cat::ReadPdf $f]
#pdf4tcl::cat::Dump $pdf2
set pdf1 [pdf4tcl::cat::AppendPdf $pdf1 $pdf2]
}
pdf4tcl::cat::WritePdf $outfile $pdf1
}
# vim: tw=0
|
Added src/packages/pdf4tcl091/pkgIndex.tcl.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded pdf4tcl 0.9.1 [list source [file join $dir pdf4tcl.tcl]] package ifneeded pdf4tcl::stdmetrics 0.1 [list source [file join $dir stdmetrics.tcl]] package ifneeded pdf4tcl::glyph2unicode 0.1 [list source [file join $dir glyph2uni.tcl]] |
Added src/packages/pdf4tcl091/stdmetrics.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
package provide pdf4tcl::stdmetrics 0.1
# this file is auto-generated, please do NOT edit!
namespace eval pdf4tcl {
variable BFA
variable Fonts
variable FontsAttrs
set Fonts [list Courier Courier-Bold Courier-BoldOblique Courier-Oblique Helvetica Helvetica-Bold Helvetica-BoldOblique Helvetica-Oblique Symbol Times-Bold Times-BoldItalic Times-Italic Times-Roman ZapfDingbats]
foreach fontname $Fonts {
set FontsAttrs($fontname,type) std
set FontsAttrs($fontname,encoding) cp1252
set FontsAttrs($fontname,specialencoding) 0
set FontsAttrs($fontname,basefontname) $fontname
set BFA($fontname,ascend) 0
set BFA($fontname,descend) 0
set BFA($fontname,fixed) 0
}
set BFA(Courier,fixed) 1
set BFA(Courier-Bold,fixed) 1
set BFA(Courier-BoldOblique,fixed) 1
set BFA(Courier-Oblique,fixed) 1
set BFA(Courier,ascend) 629
set BFA(Courier-Bold,ascend) 629
set BFA(Courier-BoldOblique,ascend) 629
set BFA(Courier-Oblique,ascend) 629
set BFA(Helvetica,ascend) 718
set BFA(Helvetica-Bold,ascend) 718
set BFA(Helvetica-BoldOblique,ascend) 718
set BFA(Helvetica-Oblique,ascend) 718
set BFA(Times-Bold,ascend) 683
set BFA(Times-BoldItalic,ascend) 683
set BFA(Times-Italic,ascend) 683
set BFA(Times-Roman,ascend) 683
set BFA(Courier,descend) -157
set BFA(Courier-Bold,descend) -157
set BFA(Courier-BoldOblique,descend) -157
set BFA(Courier-Oblique,descend) -157
set BFA(Helvetica,descend) -207
set BFA(Helvetica-Bold,descend) -207
set BFA(Helvetica-BoldOblique,descend) -207
set BFA(Helvetica-Oblique,descend) -207
set BFA(Times-Bold,descend) -217
set BFA(Times-BoldItalic,descend) -217
set BFA(Times-Italic,descend) -217
set BFA(Times-Roman,descend) -217
set BFA(Courier-Bold,charWidths) {32 600 33 600 34 600 35 600 36 600 37 600 38 600 39 600 40 600 41 600 42 600 43 600 44 600 45 600 46 600 47 600 48 600 49 600 50 600 51 600 52 600 53 600 54 600 55 600 56 600 57 600 58 600 59 600 60 600 61 600 62 600 63 600 64 600 65 600 66 600 67 600 68 600 69 600 70 600 71 600 72 600 73 600 74 600 75 600 76 600 77 600 78 600 79 600 80 600 81 600 82 600 83 600 84 600 85 600 86 600 87 600 88 600 89 600 90 600 91 600 92 600 93 600 94 600 95 600 96 600 97 600 98 600 99 600 100 600 101 600 102 600 103 600 104 600 105 600 106 600 107 600 108 600 109 600 110 600 111 600 112 600 113 600 114 600 115 600 116 600 117 600 118 600 119 600 120 600 121 600 122 600 123 600 124 600 125 600 126 600 161 600 162 600 163 600 164 600 165 600 166 600 167 600 168 600 169 600 170 600 171 600 172 600 174 600 175 600 176 600 177 600 178 600 179 600 180 600 181 600 182 600 183 600 184 600 185 600 186 600 187 600 188 600 189 600 190 600 191 600 192 600 193 600 194 600 195 600 196 600 197 600 198 600 199 600 200 600 201 600 202 600 203 600 204 600 205 600 206 600 207 600 208 600 209 600 210 600 211 600 212 600 213 600 214 600 215 600 216 600 217 600 218 600 219 600 220 600 221 600 222 600 223 600 224 600 225 600 226 600 227 600 228 600 229 600 230 600 231 600 232 600 233 600 234 600 235 600 236 600 237 600 238 600 239 600 240 600 241 600 242 600 243 600 244 600 245 600 246 600 247 600 248 600 249 600 250 600 251 600 252 600 253 600 254 600 255 600 256 600 257 600 258 600 259 600 260 600 261 600 262 600 263 600 268 600 269 600 270 600 271 600 272 600 273 600 274 600 275 600 278 600 279 600 280 600 281 600 282 600 283 600 286 600 287 600 290 600 291 600 298 600 299 600 302 600 303 600 304 600 305 600 310 600 311 600 313 600 314 600 315 600 316 600 317 600 318 600 321 600 322 600 323 600 324 600 325 600 326 600 327 600 328 600 332 600 333 600 336 600 337 600 338 600 339 600 340 600 341 600 342 600 343 600 344 600 345 600 346 600 347 600 350 600 351 600 352 600 353 600 354 600 355 600 356 600 357 600 362 600 363 600 366 600 367 600 368 600 369 600 370 600 371 600 376 600 377 600 378 600 379 600 380 600 381 600 382 600 402 600 536 600 537 600 710 600 711 600 728 600 729 600 730 600 731 600 732 600 733 600 8211 600 8212 600 8216 600 8217 600 8218 600 8220 600 8221 600 8222 600 8224 600 8225 600 8226 600 8230 600 8240 600 8249 600 8250 600 8260 600 8364 600 8482 600 8706 600 8710 600 8721 600 8722 600 8730 600 8800 600 8804 600 8805 600 9674 600 63171 600 64257 600 64258 600}
set BFA(Courier-Bold,bbox) [list -113 -250 749 801]
set BFA(Courier-BoldOblique,charWidths) {32 600 33 600 34 600 35 600 36 600 37 600 38 600 39 600 40 600 41 600 42 600 43 600 44 600 45 600 46 600 47 600 48 600 49 600 50 600 51 600 52 600 53 600 54 600 55 600 56 600 57 600 58 600 59 600 60 600 61 600 62 600 63 600 64 600 65 600 66 600 67 600 68 600 69 600 70 600 71 600 72 600 73 600 74 600 75 600 76 600 77 600 78 600 79 600 80 600 81 600 82 600 83 600 84 600 85 600 86 600 87 600 88 600 89 600 90 600 91 600 92 600 93 600 94 600 95 600 96 600 97 600 98 600 99 600 100 600 101 600 102 600 103 600 104 600 105 600 106 600 107 600 108 600 109 600 110 600 111 600 112 600 113 600 114 600 115 600 116 600 117 600 118 600 119 600 120 600 121 600 122 600 123 600 124 600 125 600 126 600 161 600 162 600 163 600 164 600 165 600 166 600 167 600 168 600 169 600 170 600 171 600 172 600 174 600 175 600 176 600 177 600 178 600 179 600 180 600 181 600 182 600 183 600 184 600 185 600 186 600 187 600 188 600 189 600 190 600 191 600 192 600 193 600 194 600 195 600 196 600 197 600 198 600 199 600 200 600 201 600 202 600 203 600 204 600 205 600 206 600 207 600 208 600 209 600 210 600 211 600 212 600 213 600 214 600 215 600 216 600 217 600 218 600 219 600 220 600 221 600 222 600 223 600 224 600 225 600 226 600 227 600 228 600 229 600 230 600 231 600 232 600 233 600 234 600 235 600 236 600 237 600 238 600 239 600 240 600 241 600 242 600 243 600 244 600 245 600 246 600 247 600 248 600 249 600 250 600 251 600 252 600 253 600 254 600 255 600 256 600 257 600 258 600 259 600 260 600 261 600 262 600 263 600 268 600 269 600 270 600 271 600 272 600 273 600 274 600 275 600 278 600 279 600 280 600 281 600 282 600 283 600 286 600 287 600 290 600 291 600 298 600 299 600 302 600 303 600 304 600 305 600 310 600 311 600 313 600 314 600 315 600 316 600 317 600 318 600 321 600 322 600 323 600 324 600 325 600 326 600 327 600 328 600 332 600 333 600 336 600 337 600 338 600 339 600 340 600 341 600 342 600 343 600 344 600 345 600 346 600 347 600 350 600 351 600 352 600 353 600 354 600 355 600 356 600 357 600 362 600 363 600 366 600 367 600 368 600 369 600 370 600 371 600 376 600 377 600 378 600 379 600 380 600 381 600 382 600 402 600 536 600 537 600 710 600 711 600 728 600 729 600 730 600 731 600 732 600 733 600 8211 600 8212 600 8216 600 8217 600 8218 600 8220 600 8221 600 8222 600 8224 600 8225 600 8226 600 8230 600 8240 600 8249 600 8250 600 8260 600 8364 600 8482 600 8706 600 8710 600 8721 600 8722 600 8730 600 8800 600 8804 600 8805 600 9674 600 63171 600 64257 600 64258 600}
set BFA(Courier-BoldOblique,bbox) [list -57 -250 869 801]
set BFA(Courier-Oblique,charWidths) {32 600 33 600 34 600 35 600 36 600 37 600 38 600 39 600 40 600 41 600 42 600 43 600 44 600 45 600 46 600 47 600 48 600 49 600 50 600 51 600 52 600 53 600 54 600 55 600 56 600 57 600 58 600 59 600 60 600 61 600 62 600 63 600 64 600 65 600 66 600 67 600 68 600 69 600 70 600 71 600 72 600 73 600 74 600 75 600 76 600 77 600 78 600 79 600 80 600 81 600 82 600 83 600 84 600 85 600 86 600 87 600 88 600 89 600 90 600 91 600 92 600 93 600 94 600 95 600 96 600 97 600 98 600 99 600 100 600 101 600 102 600 103 600 104 600 105 600 106 600 107 600 108 600 109 600 110 600 111 600 112 600 113 600 114 600 115 600 116 600 117 600 118 600 119 600 120 600 121 600 122 600 123 600 124 600 125 600 126 600 161 600 162 600 163 600 164 600 165 600 166 600 167 600 168 600 169 600 170 600 171 600 172 600 174 600 175 600 176 600 177 600 178 600 179 600 180 600 181 600 182 600 183 600 184 600 185 600 186 600 187 600 188 600 189 600 190 600 191 600 192 600 193 600 194 600 195 600 196 600 197 600 198 600 199 600 200 600 201 600 202 600 203 600 204 600 205 600 206 600 207 600 208 600 209 600 210 600 211 600 212 600 213 600 214 600 215 600 216 600 217 600 218 600 219 600 220 600 221 600 222 600 223 600 224 600 225 600 226 600 227 600 228 600 229 600 230 600 231 600 232 600 233 600 234 600 235 600 236 600 237 600 238 600 239 600 240 600 241 600 242 600 243 600 244 600 245 600 246 600 247 600 248 600 249 600 250 600 251 600 252 600 253 600 254 600 255 600 256 600 257 600 258 600 259 600 260 600 261 600 262 600 263 600 268 600 269 600 270 600 271 600 272 600 273 600 274 600 275 600 278 600 279 600 280 600 281 600 282 600 283 600 286 600 287 600 290 600 291 600 298 600 299 600 302 600 303 600 304 600 305 600 310 600 311 600 313 600 314 600 315 600 316 600 317 600 318 600 321 600 322 600 323 600 324 600 325 600 326 600 327 600 328 600 332 600 333 600 336 600 337 600 338 600 339 600 340 600 341 600 342 600 343 600 344 600 345 600 346 600 347 600 350 600 351 600 352 600 353 600 354 600 355 600 356 600 357 600 362 600 363 600 366 600 367 600 368 600 369 600 370 600 371 600 376 600 377 600 378 600 379 600 380 600 381 600 382 600 402 600 536 600 537 600 710 600 711 600 728 600 729 600 730 600 731 600 732 600 733 600 8211 600 8212 600 8216 600 8217 600 8218 600 8220 600 8221 600 8222 600 8224 600 8225 600 8226 600 8230 600 8240 600 8249 600 8250 600 8260 600 8364 600 8482 600 8706 600 8710 600 8721 600 8722 600 8730 600 8800 600 8804 600 8805 600 9674 600 63171 600 64257 600 64258 600}
set BFA(Courier-Oblique,bbox) [list -27 -250 849 805]
set BFA(Courier,charWidths) {32 600 33 600 34 600 35 600 36 600 37 600 38 600 39 600 40 600 41 600 42 600 43 600 44 600 45 600 46 600 47 600 48 600 49 600 50 600 51 600 52 600 53 600 54 600 55 600 56 600 57 600 58 600 59 600 60 600 61 600 62 600 63 600 64 600 65 600 66 600 67 600 68 600 69 600 70 600 71 600 72 600 73 600 74 600 75 600 76 600 77 600 78 600 79 600 80 600 81 600 82 600 83 600 84 600 85 600 86 600 87 600 88 600 89 600 90 600 91 600 92 600 93 600 94 600 95 600 96 600 97 600 98 600 99 600 100 600 101 600 102 600 103 600 104 600 105 600 106 600 107 600 108 600 109 600 110 600 111 600 112 600 113 600 114 600 115 600 116 600 117 600 118 600 119 600 120 600 121 600 122 600 123 600 124 600 125 600 126 600 161 600 162 600 163 600 164 600 165 600 166 600 167 600 168 600 169 600 170 600 171 600 172 600 174 600 175 600 176 600 177 600 178 600 179 600 180 600 181 600 182 600 183 600 184 600 185 600 186 600 187 600 188 600 189 600 190 600 191 600 192 600 193 600 194 600 195 600 196 600 197 600 198 600 199 600 200 600 201 600 202 600 203 600 204 600 205 600 206 600 207 600 208 600 209 600 210 600 211 600 212 600 213 600 214 600 215 600 216 600 217 600 218 600 219 600 220 600 221 600 222 600 223 600 224 600 225 600 226 600 227 600 228 600 229 600 230 600 231 600 232 600 233 600 234 600 235 600 236 600 237 600 238 600 239 600 240 600 241 600 242 600 243 600 244 600 245 600 246 600 247 600 248 600 249 600 250 600 251 600 252 600 253 600 254 600 255 600 256 600 257 600 258 600 259 600 260 600 261 600 262 600 263 600 268 600 269 600 270 600 271 600 272 600 273 600 274 600 275 600 278 600 279 600 280 600 281 600 282 600 283 600 286 600 287 600 290 600 291 600 298 600 299 600 302 600 303 600 304 600 305 600 310 600 311 600 313 600 314 600 315 600 316 600 317 600 318 600 321 600 322 600 323 600 324 600 325 600 326 600 327 600 328 600 332 600 333 600 336 600 337 600 338 600 339 600 340 600 341 600 342 600 343 600 344 600 345 600 346 600 347 600 350 600 351 600 352 600 353 600 354 600 355 600 356 600 357 600 362 600 363 600 366 600 367 600 368 600 369 600 370 600 371 600 376 600 377 600 378 600 379 600 380 600 381 600 382 600 402 600 536 600 537 600 710 600 711 600 728 600 729 600 730 600 731 600 732 600 733 600 8211 600 8212 600 8216 600 8217 600 8218 600 8220 600 8221 600 8222 600 8224 600 8225 600 8226 600 8230 600 8240 600 8249 600 8250 600 8260 600 8364 600 8482 600 8706 600 8710 600 8721 600 8722 600 8730 600 8800 600 8804 600 8805 600 9674 600 63171 600 64257 600 64258 600}
set BFA(Courier,bbox) [list -23 -250 715 805]
set BFA(Helvetica-Bold,charWidths) {32 278 33 333 34 474 35 556 36 556 37 889 38 722 39 238 40 333 41 333 42 389 43 584 44 278 45 333 46 278 47 278 48 556 49 556 50 556 51 556 52 556 53 556 54 556 55 556 56 556 57 556 58 333 59 333 60 584 61 584 62 584 63 611 64 975 65 722 66 722 67 722 68 722 69 667 70 611 71 778 72 722 73 278 74 556 75 722 76 611 77 833 78 722 79 778 80 667 81 778 82 722 83 667 84 611 85 722 86 667 87 944 88 667 89 667 90 611 91 333 92 278 93 333 94 584 95 556 96 333 97 556 98 611 99 556 100 611 101 556 102 333 103 611 104 611 105 278 106 278 107 556 108 278 109 889 110 611 111 611 112 611 113 611 114 389 115 556 116 333 117 611 118 556 119 778 120 556 121 556 122 500 123 389 124 280 125 389 126 584 161 333 162 556 163 556 164 556 165 556 166 280 167 556 168 333 169 737 170 370 171 556 172 584 174 737 175 333 176 400 177 584 178 333 179 333 180 333 181 611 182 556 183 278 184 333 185 333 186 365 187 556 188 834 189 834 190 834 191 611 192 722 193 722 194 722 195 722 196 722 197 722 198 1000 199 722 200 667 201 667 202 667 203 667 204 278 205 278 206 278 207 278 208 722 209 722 210 778 211 778 212 778 213 778 214 778 215 584 216 778 217 722 218 722 219 722 220 722 221 667 222 667 223 611 224 556 225 556 226 556 227 556 228 556 229 556 230 889 231 556 232 556 233 556 234 556 235 556 236 278 237 278 238 278 239 278 240 611 241 611 242 611 243 611 244 611 245 611 246 611 247 584 248 611 249 611 250 611 251 611 252 611 253 556 254 611 255 556 256 722 257 556 258 722 259 556 260 722 261 556 262 722 263 556 268 722 269 556 270 722 271 743 272 722 273 611 274 667 275 556 278 667 279 556 280 667 281 556 282 667 283 556 286 778 287 611 290 778 291 611 298 278 299 278 302 278 303 278 304 278 305 278 310 722 311 556 313 611 314 278 315 611 316 278 317 611 318 400 321 611 322 278 323 722 324 611 325 722 326 611 327 722 328 611 332 778 333 611 336 778 337 611 338 1000 339 944 340 722 341 389 342 722 343 389 344 722 345 389 346 667 347 556 350 667 351 556 352 667 353 556 354 611 355 333 356 611 357 389 362 722 363 611 366 722 367 611 368 722 369 611 370 722 371 611 376 667 377 611 378 500 379 611 380 500 381 611 382 500 402 556 536 667 537 556 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 556 8212 1000 8216 278 8217 278 8218 278 8220 500 8221 500 8222 500 8224 556 8225 556 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 556 8482 1000 8706 494 8710 612 8721 600 8722 584 8730 549 8800 549 8804 549 8805 549 9674 494 63171 250 64257 611 64258 611}
set BFA(Helvetica-Bold,bbox) [list -170 -228 1003 962]
set BFA(Helvetica-BoldOblique,charWidths) {32 278 33 333 34 474 35 556 36 556 37 889 38 722 39 238 40 333 41 333 42 389 43 584 44 278 45 333 46 278 47 278 48 556 49 556 50 556 51 556 52 556 53 556 54 556 55 556 56 556 57 556 58 333 59 333 60 584 61 584 62 584 63 611 64 975 65 722 66 722 67 722 68 722 69 667 70 611 71 778 72 722 73 278 74 556 75 722 76 611 77 833 78 722 79 778 80 667 81 778 82 722 83 667 84 611 85 722 86 667 87 944 88 667 89 667 90 611 91 333 92 278 93 333 94 584 95 556 96 333 97 556 98 611 99 556 100 611 101 556 102 333 103 611 104 611 105 278 106 278 107 556 108 278 109 889 110 611 111 611 112 611 113 611 114 389 115 556 116 333 117 611 118 556 119 778 120 556 121 556 122 500 123 389 124 280 125 389 126 584 161 333 162 556 163 556 164 556 165 556 166 280 167 556 168 333 169 737 170 370 171 556 172 584 174 737 175 333 176 400 177 584 178 333 179 333 180 333 181 611 182 556 183 278 184 333 185 333 186 365 187 556 188 834 189 834 190 834 191 611 192 722 193 722 194 722 195 722 196 722 197 722 198 1000 199 722 200 667 201 667 202 667 203 667 204 278 205 278 206 278 207 278 208 722 209 722 210 778 211 778 212 778 213 778 214 778 215 584 216 778 217 722 218 722 219 722 220 722 221 667 222 667 223 611 224 556 225 556 226 556 227 556 228 556 229 556 230 889 231 556 232 556 233 556 234 556 235 556 236 278 237 278 238 278 239 278 240 611 241 611 242 611 243 611 244 611 245 611 246 611 247 584 248 611 249 611 250 611 251 611 252 611 253 556 254 611 255 556 256 722 257 556 258 722 259 556 260 722 261 556 262 722 263 556 268 722 269 556 270 722 271 743 272 722 273 611 274 667 275 556 278 667 279 556 280 667 281 556 282 667 283 556 286 778 287 611 290 778 291 611 298 278 299 278 302 278 303 278 304 278 305 278 310 722 311 556 313 611 314 278 315 611 316 278 317 611 318 400 321 611 322 278 323 722 324 611 325 722 326 611 327 722 328 611 332 778 333 611 336 778 337 611 338 1000 339 944 340 722 341 389 342 722 343 389 344 722 345 389 346 667 347 556 350 667 351 556 352 667 353 556 354 611 355 333 356 611 357 389 362 722 363 611 366 722 367 611 368 722 369 611 370 722 371 611 376 667 377 611 378 500 379 611 380 500 381 611 382 500 402 556 536 667 537 556 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 556 8212 1000 8216 278 8217 278 8218 278 8220 500 8221 500 8222 500 8224 556 8225 556 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 556 8482 1000 8706 494 8710 612 8721 600 8722 584 8730 549 8800 549 8804 549 8805 549 9674 494 63171 250 64257 611 64258 611}
set BFA(Helvetica-BoldOblique,bbox) [list -174 -228 1114 962]
set BFA(Helvetica-Oblique,charWidths) {32 278 33 278 34 355 35 556 36 556 37 889 38 667 39 191 40 333 41 333 42 389 43 584 44 278 45 333 46 278 47 278 48 556 49 556 50 556 51 556 52 556 53 556 54 556 55 556 56 556 57 556 58 278 59 278 60 584 61 584 62 584 63 556 64 1015 65 667 66 667 67 722 68 722 69 667 70 611 71 778 72 722 73 278 74 500 75 667 76 556 77 833 78 722 79 778 80 667 81 778 82 722 83 667 84 611 85 722 86 667 87 944 88 667 89 667 90 611 91 278 92 278 93 278 94 469 95 556 96 333 97 556 98 556 99 500 100 556 101 556 102 278 103 556 104 556 105 222 106 222 107 500 108 222 109 833 110 556 111 556 112 556 113 556 114 333 115 500 116 278 117 556 118 500 119 722 120 500 121 500 122 500 123 334 124 260 125 334 126 584 161 333 162 556 163 556 164 556 165 556 166 260 167 556 168 333 169 737 170 370 171 556 172 584 174 737 175 333 176 400 177 584 178 333 179 333 180 333 181 556 182 537 183 278 184 333 185 333 186 365 187 556 188 834 189 834 190 834 191 611 192 667 193 667 194 667 195 667 196 667 197 667 198 1000 199 722 200 667 201 667 202 667 203 667 204 278 205 278 206 278 207 278 208 722 209 722 210 778 211 778 212 778 213 778 214 778 215 584 216 778 217 722 218 722 219 722 220 722 221 667 222 667 223 611 224 556 225 556 226 556 227 556 228 556 229 556 230 889 231 500 232 556 233 556 234 556 235 556 236 278 237 278 238 278 239 278 240 556 241 556 242 556 243 556 244 556 245 556 246 556 247 584 248 611 249 556 250 556 251 556 252 556 253 500 254 556 255 500 256 667 257 556 258 667 259 556 260 667 261 556 262 722 263 500 268 722 269 500 270 722 271 643 272 722 273 556 274 667 275 556 278 667 279 556 280 667 281 556 282 667 283 556 286 778 287 556 290 778 291 556 298 278 299 278 302 278 303 222 304 278 305 278 310 667 311 500 313 556 314 222 315 556 316 222 317 556 318 299 321 556 322 222 323 722 324 556 325 722 326 556 327 722 328 556 332 778 333 556 336 778 337 556 338 1000 339 944 340 722 341 333 342 722 343 333 344 722 345 333 346 667 347 500 350 667 351 500 352 667 353 500 354 611 355 278 356 611 357 317 362 722 363 556 366 722 367 556 368 722 369 556 370 722 371 556 376 667 377 611 378 500 379 611 380 500 381 611 382 500 402 556 536 667 537 500 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 556 8212 1000 8216 222 8217 222 8218 222 8220 333 8221 333 8222 333 8224 556 8225 556 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 556 8482 1000 8706 476 8710 612 8721 600 8722 584 8730 453 8800 549 8804 549 8805 549 9674 471 63171 250 64257 500 64258 500}
set BFA(Helvetica-Oblique,bbox) [list -170 -225 1116 931]
set BFA(Helvetica,charWidths) {32 278 33 278 34 355 35 556 36 556 37 889 38 667 39 191 40 333 41 333 42 389 43 584 44 278 45 333 46 278 47 278 48 556 49 556 50 556 51 556 52 556 53 556 54 556 55 556 56 556 57 556 58 278 59 278 60 584 61 584 62 584 63 556 64 1015 65 667 66 667 67 722 68 722 69 667 70 611 71 778 72 722 73 278 74 500 75 667 76 556 77 833 78 722 79 778 80 667 81 778 82 722 83 667 84 611 85 722 86 667 87 944 88 667 89 667 90 611 91 278 92 278 93 278 94 469 95 556 96 333 97 556 98 556 99 500 100 556 101 556 102 278 103 556 104 556 105 222 106 222 107 500 108 222 109 833 110 556 111 556 112 556 113 556 114 333 115 500 116 278 117 556 118 500 119 722 120 500 121 500 122 500 123 334 124 260 125 334 126 584 161 333 162 556 163 556 164 556 165 556 166 260 167 556 168 333 169 737 170 370 171 556 172 584 174 737 175 333 176 400 177 584 178 333 179 333 180 333 181 556 182 537 183 278 184 333 185 333 186 365 187 556 188 834 189 834 190 834 191 611 192 667 193 667 194 667 195 667 196 667 197 667 198 1000 199 722 200 667 201 667 202 667 203 667 204 278 205 278 206 278 207 278 208 722 209 722 210 778 211 778 212 778 213 778 214 778 215 584 216 778 217 722 218 722 219 722 220 722 221 667 222 667 223 611 224 556 225 556 226 556 227 556 228 556 229 556 230 889 231 500 232 556 233 556 234 556 235 556 236 278 237 278 238 278 239 278 240 556 241 556 242 556 243 556 244 556 245 556 246 556 247 584 248 611 249 556 250 556 251 556 252 556 253 500 254 556 255 500 256 667 257 556 258 667 259 556 260 667 261 556 262 722 263 500 268 722 269 500 270 722 271 643 272 722 273 556 274 667 275 556 278 667 279 556 280 667 281 556 282 667 283 556 286 778 287 556 290 778 291 556 298 278 299 278 302 278 303 222 304 278 305 278 310 667 311 500 313 556 314 222 315 556 316 222 317 556 318 299 321 556 322 222 323 722 324 556 325 722 326 556 327 722 328 556 332 778 333 556 336 778 337 556 338 1000 339 944 340 722 341 333 342 722 343 333 344 722 345 333 346 667 347 500 350 667 351 500 352 667 353 500 354 611 355 278 356 611 357 317 362 722 363 556 366 722 367 556 368 722 369 556 370 722 371 556 376 667 377 611 378 500 379 611 380 500 381 611 382 500 402 556 536 667 537 500 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 556 8212 1000 8216 222 8217 222 8218 222 8220 333 8221 333 8222 333 8224 556 8225 556 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 556 8482 1000 8706 476 8710 612 8721 600 8722 584 8730 453 8800 549 8804 549 8805 549 9674 471 63171 250 64257 500 64258 500}
set BFA(Helvetica,bbox) [list -166 -225 1000 931]
set BFA(Symbol,charWidths) {32 250 33 333 35 500 37 833 38 778 40 333 41 333 43 549 44 250 46 250 47 278 48 500 49 500 50 500 51 500 52 500 53 500 54 500 55 500 56 500 57 500 58 278 59 278 60 549 61 549 62 549 63 444 91 333 93 333 95 500 123 480 124 200 125 480 172 713 176 400 177 549 181 576 215 549 247 549 402 500 913 722 914 667 915 603 917 611 918 611 919 722 920 741 921 333 922 722 923 686 924 889 925 722 926 645 927 722 928 768 929 556 931 592 932 611 933 690 934 763 935 722 936 795 945 631 946 549 947 411 948 494 949 439 950 494 951 603 952 521 953 329 954 549 955 549 957 521 958 493 959 549 960 549 961 549 962 439 963 603 964 439 965 576 966 521 967 549 968 686 969 686 977 631 978 620 981 603 982 713 8226 460 8230 1000 8242 247 8243 411 8260 167 8364 750 8465 686 8472 987 8476 795 8486 768 8501 823 8592 987 8593 603 8594 987 8595 603 8596 1042 8629 658 8656 987 8657 603 8658 987 8659 603 8660 1042 8704 713 8706 494 8707 549 8709 823 8710 612 8711 713 8712 713 8713 713 8715 439 8719 823 8721 713 8722 549 8727 500 8730 549 8733 713 8734 713 8736 768 8743 603 8744 603 8745 768 8746 768 8747 274 8756 863 8764 549 8773 549 8776 549 8800 549 8801 549 8804 549 8805 549 8834 713 8835 713 8836 713 8838 713 8839 713 8853 768 8855 768 8869 658 8901 250 8992 686 8993 686 9001 329 9002 329 9674 494 9824 753 9827 753 9829 753 9830 753 63193 790 63194 790 63195 890 63717 500 63718 603 63719 1000 63720 790 63721 790 63722 786 63723 384 63724 384 63725 384 63726 384 63727 384 63728 384 63729 494 63730 494 63731 494 63732 494 63733 686 63734 384 63735 384 63736 384 63737 384 63738 384 63739 384 63740 494 63741 494 63742 494 63743 790}
set BFA(Symbol,bbox) [list -180 -293 1090 1010]
set BFA(Times-Bold,charWidths) {32 250 33 333 34 555 35 500 36 500 37 1000 38 833 39 278 40 333 41 333 42 500 43 570 44 250 45 333 46 250 47 278 48 500 49 500 50 500 51 500 52 500 53 500 54 500 55 500 56 500 57 500 58 333 59 333 60 570 61 570 62 570 63 500 64 930 65 722 66 667 67 722 68 722 69 667 70 611 71 778 72 778 73 389 74 500 75 778 76 667 77 944 78 722 79 778 80 611 81 778 82 722 83 556 84 667 85 722 86 722 87 1000 88 722 89 722 90 667 91 333 92 278 93 333 94 581 95 500 96 333 97 500 98 556 99 444 100 556 101 444 102 333 103 500 104 556 105 278 106 333 107 556 108 278 109 833 110 556 111 500 112 556 113 556 114 444 115 389 116 333 117 556 118 500 119 722 120 500 121 500 122 444 123 394 124 220 125 394 126 520 161 333 162 500 163 500 164 500 165 500 166 220 167 500 168 333 169 747 170 300 171 500 172 570 174 747 175 333 176 400 177 570 178 300 179 300 180 333 181 556 182 540 183 250 184 333 185 300 186 330 187 500 188 750 189 750 190 750 191 500 192 722 193 722 194 722 195 722 196 722 197 722 198 1000 199 722 200 667 201 667 202 667 203 667 204 389 205 389 206 389 207 389 208 722 209 722 210 778 211 778 212 778 213 778 214 778 215 570 216 778 217 722 218 722 219 722 220 722 221 722 222 611 223 556 224 500 225 500 226 500 227 500 228 500 229 500 230 722 231 444 232 444 233 444 234 444 235 444 236 278 237 278 238 278 239 278 240 500 241 556 242 500 243 500 244 500 245 500 246 500 247 570 248 500 249 556 250 556 251 556 252 556 253 500 254 556 255 500 256 722 257 500 258 722 259 500 260 722 261 500 262 722 263 444 268 722 269 444 270 722 271 672 272 722 273 556 274 667 275 444 278 667 279 444 280 667 281 444 282 667 283 444 286 778 287 500 290 778 291 500 298 389 299 278 302 389 303 278 304 389 305 278 310 778 311 556 313 667 314 278 315 667 316 278 317 667 318 394 321 667 322 278 323 722 324 556 325 722 326 556 327 722 328 556 332 778 333 500 336 778 337 500 338 1000 339 722 340 722 341 444 342 722 343 444 344 722 345 444 346 556 347 389 350 556 351 389 352 556 353 389 354 667 355 333 356 667 357 416 362 722 363 556 366 722 367 556 368 722 369 556 370 722 371 556 376 722 377 667 378 444 379 667 380 444 381 667 382 444 402 500 536 556 537 389 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 500 8212 1000 8216 333 8217 333 8218 333 8220 500 8221 500 8222 500 8224 500 8225 500 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 500 8482 1000 8706 494 8710 612 8721 600 8722 570 8730 549 8800 549 8804 549 8805 549 9674 494 63171 250 64257 556 64258 556}
set BFA(Times-Bold,bbox) [list -168 -218 1000 935]
set BFA(Times-BoldItalic,charWidths) {32 250 33 389 34 555 35 500 36 500 37 833 38 778 39 278 40 333 41 333 42 500 43 570 44 250 45 333 46 250 47 278 48 500 49 500 50 500 51 500 52 500 53 500 54 500 55 500 56 500 57 500 58 333 59 333 60 570 61 570 62 570 63 500 64 832 65 667 66 667 67 667 68 722 69 667 70 667 71 722 72 778 73 389 74 500 75 667 76 611 77 889 78 722 79 722 80 611 81 722 82 667 83 556 84 611 85 722 86 667 87 889 88 667 89 611 90 611 91 333 92 278 93 333 94 570 95 500 96 333 97 500 98 500 99 444 100 500 101 444 102 333 103 500 104 556 105 278 106 278 107 500 108 278 109 778 110 556 111 500 112 500 113 500 114 389 115 389 116 278 117 556 118 444 119 667 120 500 121 444 122 389 123 348 124 220 125 348 126 570 161 389 162 500 163 500 164 500 165 500 166 220 167 500 168 333 169 747 170 266 171 500 172 606 174 747 175 333 176 400 177 570 178 300 179 300 180 333 181 576 182 500 183 250 184 333 185 300 186 300 187 500 188 750 189 750 190 750 191 500 192 667 193 667 194 667 195 667 196 667 197 667 198 944 199 667 200 667 201 667 202 667 203 667 204 389 205 389 206 389 207 389 208 722 209 722 210 722 211 722 212 722 213 722 214 722 215 570 216 722 217 722 218 722 219 722 220 722 221 611 222 611 223 500 224 500 225 500 226 500 227 500 228 500 229 500 230 722 231 444 232 444 233 444 234 444 235 444 236 278 237 278 238 278 239 278 240 500 241 556 242 500 243 500 244 500 245 500 246 500 247 570 248 500 249 556 250 556 251 556 252 556 253 444 254 500 255 444 256 667 257 500 258 667 259 500 260 667 261 500 262 667 263 444 268 667 269 444 270 722 271 608 272 722 273 500 274 667 275 444 278 667 279 444 280 667 281 444 282 667 283 444 286 722 287 500 290 722 291 500 298 389 299 278 302 389 303 278 304 389 305 278 310 667 311 500 313 611 314 278 315 611 316 278 317 611 318 382 321 611 322 278 323 722 324 556 325 722 326 556 327 722 328 556 332 722 333 500 336 722 337 500 338 944 339 722 340 667 341 389 342 667 343 389 344 667 345 389 346 556 347 389 350 556 351 389 352 556 353 389 354 611 355 278 356 611 357 366 362 722 363 556 366 722 367 556 368 722 369 556 370 722 371 556 376 611 377 611 378 389 379 611 380 389 381 611 382 389 402 500 536 556 537 389 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 500 8212 1000 8216 333 8217 333 8218 333 8220 500 8221 500 8222 500 8224 500 8225 500 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 500 8482 1000 8706 494 8710 612 8721 600 8722 606 8730 549 8800 549 8804 549 8805 549 9674 494 63171 250 64257 556 64258 556}
set BFA(Times-BoldItalic,bbox) [list -200 -218 996 921]
set BFA(Times-Italic,charWidths) {32 250 33 333 34 420 35 500 36 500 37 833 38 778 39 214 40 333 41 333 42 500 43 675 44 250 45 333 46 250 47 278 48 500 49 500 50 500 51 500 52 500 53 500 54 500 55 500 56 500 57 500 58 333 59 333 60 675 61 675 62 675 63 500 64 920 65 611 66 611 67 667 68 722 69 611 70 611 71 722 72 722 73 333 74 444 75 667 76 556 77 833 78 667 79 722 80 611 81 722 82 611 83 500 84 556 85 722 86 611 87 833 88 611 89 556 90 556 91 389 92 278 93 389 94 422 95 500 96 333 97 500 98 500 99 444 100 500 101 444 102 278 103 500 104 500 105 278 106 278 107 444 108 278 109 722 110 500 111 500 112 500 113 500 114 389 115 389 116 278 117 500 118 444 119 667 120 444 121 444 122 389 123 400 124 275 125 400 126 541 161 389 162 500 163 500 164 500 165 500 166 275 167 500 168 333 169 760 170 276 171 500 172 675 174 760 175 333 176 400 177 675 178 300 179 300 180 333 181 500 182 523 183 250 184 333 185 300 186 310 187 500 188 750 189 750 190 750 191 500 192 611 193 611 194 611 195 611 196 611 197 611 198 889 199 667 200 611 201 611 202 611 203 611 204 333 205 333 206 333 207 333 208 722 209 667 210 722 211 722 212 722 213 722 214 722 215 675 216 722 217 722 218 722 219 722 220 722 221 556 222 611 223 500 224 500 225 500 226 500 227 500 228 500 229 500 230 667 231 444 232 444 233 444 234 444 235 444 236 278 237 278 238 278 239 278 240 500 241 500 242 500 243 500 244 500 245 500 246 500 247 675 248 500 249 500 250 500 251 500 252 500 253 444 254 500 255 444 256 611 257 500 258 611 259 500 260 611 261 500 262 667 263 444 268 667 269 444 270 722 271 544 272 722 273 500 274 611 275 444 278 611 279 444 280 611 281 444 282 611 283 444 286 722 287 500 290 722 291 500 298 333 299 278 302 333 303 278 304 333 305 278 310 667 311 444 313 556 314 278 315 556 316 278 317 611 318 300 321 556 322 278 323 667 324 500 325 667 326 500 327 667 328 500 332 722 333 500 336 722 337 500 338 944 339 667 340 611 341 389 342 611 343 389 344 611 345 389 346 500 347 389 350 500 351 389 352 500 353 389 354 556 355 278 356 556 357 300 362 722 363 500 366 722 367 500 368 722 369 500 370 722 371 500 376 556 377 556 378 389 379 556 380 389 381 556 382 389 402 500 536 500 537 389 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 500 8212 889 8216 333 8217 333 8218 333 8220 556 8221 556 8222 556 8224 500 8225 500 8226 350 8230 889 8240 1000 8249 333 8250 333 8260 167 8364 500 8482 980 8706 476 8710 612 8721 600 8722 675 8730 453 8800 549 8804 549 8805 549 9674 471 63171 250 64257 500 64258 500}
set BFA(Times-Italic,bbox) [list -169 -217 1010 883]
set BFA(Times-Roman,charWidths) {32 250 33 333 34 408 35 500 36 500 37 833 38 778 39 180 40 333 41 333 42 500 43 564 44 250 45 333 46 250 47 278 48 500 49 500 50 500 51 500 52 500 53 500 54 500 55 500 56 500 57 500 58 278 59 278 60 564 61 564 62 564 63 444 64 921 65 722 66 667 67 667 68 722 69 611 70 556 71 722 72 722 73 333 74 389 75 722 76 611 77 889 78 722 79 722 80 556 81 722 82 667 83 556 84 611 85 722 86 722 87 944 88 722 89 722 90 611 91 333 92 278 93 333 94 469 95 500 96 333 97 444 98 500 99 444 100 500 101 444 102 333 103 500 104 500 105 278 106 278 107 500 108 278 109 778 110 500 111 500 112 500 113 500 114 333 115 389 116 278 117 500 118 500 119 722 120 500 121 500 122 444 123 480 124 200 125 480 126 541 161 333 162 500 163 500 164 500 165 500 166 200 167 500 168 333 169 760 170 276 171 500 172 564 174 760 175 333 176 400 177 564 178 300 179 300 180 333 181 500 182 453 183 250 184 333 185 300 186 310 187 500 188 750 189 750 190 750 191 444 192 722 193 722 194 722 195 722 196 722 197 722 198 889 199 667 200 611 201 611 202 611 203 611 204 333 205 333 206 333 207 333 208 722 209 722 210 722 211 722 212 722 213 722 214 722 215 564 216 722 217 722 218 722 219 722 220 722 221 722 222 556 223 500 224 444 225 444 226 444 227 444 228 444 229 444 230 667 231 444 232 444 233 444 234 444 235 444 236 278 237 278 238 278 239 278 240 500 241 500 242 500 243 500 244 500 245 500 246 500 247 564 248 500 249 500 250 500 251 500 252 500 253 500 254 500 255 500 256 722 257 444 258 722 259 444 260 722 261 444 262 667 263 444 268 667 269 444 270 722 271 588 272 722 273 500 274 611 275 444 278 611 279 444 280 611 281 444 282 611 283 444 286 722 287 500 290 722 291 500 298 333 299 278 302 333 303 278 304 333 305 278 310 722 311 500 313 611 314 278 315 611 316 278 317 611 318 344 321 611 322 278 323 722 324 500 325 722 326 500 327 722 328 500 332 722 333 500 336 722 337 500 338 889 339 722 340 667 341 333 342 667 343 333 344 667 345 333 346 556 347 389 350 556 351 389 352 556 353 389 354 611 355 278 356 611 357 326 362 722 363 500 366 722 367 500 368 722 369 500 370 722 371 500 376 722 377 611 378 444 379 611 380 444 381 611 382 444 402 500 536 556 537 389 710 333 711 333 728 333 729 333 730 333 731 333 732 333 733 333 8211 500 8212 1000 8216 333 8217 333 8218 333 8220 444 8221 444 8222 444 8224 500 8225 500 8226 350 8230 1000 8240 1000 8249 333 8250 333 8260 167 8364 500 8482 980 8706 476 8710 612 8721 600 8722 564 8730 453 8800 549 8804 549 8805 549 9674 471 63171 250 64257 556 64258 556}
set BFA(Times-Roman,bbox) [list -168 -218 1000 898]
set BFA(ZapfDingbats,charWidths) {32 278 8594 838 8596 1016 8597 458 9312 788 9313 788 9314 788 9315 788 9316 788 9317 788 9318 788 9319 788 9320 788 9321 788 9632 761 9650 892 9660 892 9670 788 9679 791 9687 438 9733 816 9742 719 9755 960 9758 939 9824 626 9827 776 9829 694 9830 595 9985 974 9986 961 9987 974 9988 980 9990 789 9991 790 9992 791 9993 690 9996 549 9997 855 9998 911 9999 933 10000 911 10001 945 10002 974 10003 755 10004 846 10005 762 10006 761 10007 571 10008 677 10009 763 10010 760 10011 759 10012 754 10013 494 10014 552 10015 537 10016 577 10017 692 10018 786 10019 788 10020 788 10021 790 10022 793 10023 794 10025 823 10026 789 10027 841 10028 823 10029 833 10030 816 10031 831 10032 923 10033 744 10034 723 10035 749 10036 790 10037 792 10038 695 10039 776 10040 768 10041 792 10042 759 10043 707 10044 708 10045 682 10046 701 10047 826 10048 815 10049 789 10050 789 10051 707 10052 687 10053 696 10054 689 10055 786 10056 787 10057 713 10058 791 10059 785 10061 873 10063 762 10064 762 10065 759 10066 759 10070 784 10072 138 10073 277 10074 415 10075 392 10076 392 10077 668 10078 668 10081 732 10082 544 10083 544 10084 910 10085 667 10086 760 10087 760 10088 390 10089 390 10090 317 10091 317 10092 276 10093 276 10094 509 10095 509 10096 410 10097 410 10098 234 10099 234 10100 334 10101 334 10102 788 10103 788 10104 788 10105 788 10106 788 10107 788 10108 788 10109 788 10110 788 10111 788 10112 788 10113 788 10114 788 10115 788 10116 788 10117 788 10118 788 10119 788 10120 788 10121 788 10122 788 10123 788 10124 788 10125 788 10126 788 10127 788 10128 788 10129 788 10130 788 10131 788 10132 894 10136 748 10137 924 10138 748 10139 918 10140 927 10141 928 10142 928 10143 834 10144 873 10145 828 10146 924 10147 924 10148 917 10149 930 10150 931 10151 463 10152 883 10153 836 10154 836 10155 867 10156 867 10157 696 10158 696 10159 874 10161 874 10162 760 10163 946 10164 771 10165 865 10166 771 10167 888 10168 967 10169 888 10170 831 10171 873 10172 927 10173 970 10174 918}
set BFA(ZapfDingbats,bbox) [list -1 -143 981 820]
}
|