Files
harbour-core/extras/hbvpdf/core.prg
vszakats 9687850865 2013-03-16 02:10 UTC+0100 Viktor Szakats (harbour syenar.net)
* (all files)
    * stripped svn header
    * minor cleanups
    ; use following command to find out the history of files:
       git log
       git log --follow
       git blame
       git annotate
2013-03-16 02:11:42 +01:00

2589 lines
86 KiB
Plaintext

#include "hbvpdf.ch"
#include "fileio.ch"
#define CRLF ( Chr( 13 ) + Chr( 10 ) )
THREAD STATIC t_aReport
// ---------------
FUNCTION pdfInit()
t_aReport := Array( PARAMLEN )
RETURN t_aReport
// -------------------------
FUNCTION pdfWidth( _nWidth )
t_aReport[ REPORTWIDTH ] := _nWidth
RETURN NIL
// --------------------------
FUNCTION pdfTextWidth( cStr )
RETURN pdfLen( cStr ) / 25.4
// ----------------------------------------------------------
FUNCTION pdfAtSay( cString, nRow, nCol, cUnits, lExact, cId )
LOCAL _nFont, lReverse, nAt
__defaultNIL( @nRow, t_aReport[ REPORTLINE ] )
__defaultNIL( @cUnits, "R" )
__defaultNIL( @lExact, .F. )
__defaultNIL( @cId, "" )
IF t_aReport[ HEADEREDIT ]
RETURN pdfHeader( "PDFATSAY", cId, { cString, nRow, nCol, cUnits, lExact } )
ENDIF
IF ( nAt := At( "#pagenumber#", cString ) ) > 0
cString := Left( cString, nAt - 1 ) + hb_ntos( pdfPageNumber() ) + SubStr( cString, nAt + 12 )
ENDIF
lReverse := .F.
IF cUnits == "M"
nRow := pdfM2Y( nRow )
nCol := pdfM2X( nCol )
ELSEIF cUnits == "R"
IF ! lExact
pdfCheckLine( nRow )
nRow := nRow + t_aReport[ PDFTOP ]
ENDIF
nRow := pdfR2D( nRow )
nCol := pdfM2X( t_aReport[ PDFLEFT ] ) + ;
nCol * 100.00 / t_aReport[ REPORTWIDTH ] * ;
( t_aReport[ PAGEX ] - pdfM2X( t_aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00
ENDIF
IF ! Empty( cString )
cString := pdfStringB( cString )
IF Right( cString, 1 ) == Chr( 255 ) // reverse
cString := Left( cString, Len( cString ) - 1 )
pdfBox( t_aReport[ PAGEY ] - nRow - t_aReport[ FONTSIZE ] + 2.0, nCol, t_aReport[ PAGEY ] - nRow + 2.0, nCol + pdfM2X( pdfLen( cString ) ) + 1,, 100, "D" )
t_aReport[ PAGEBUFFER ] += " 1 g "
lReverse := .T.
ELSEIF Right( cString, 1 ) == Chr( 254 ) // underline
cString := Left( cString, Len( cString ) - 1 )
pdfBox( t_aReport[ PAGEY ] - nRow + 0.5, nCol, t_aReport[ PAGEY ] - nRow + 1, nCol + pdfM2X( pdfLen( cString ) ) + 1,, 100, "D" )
ENDIF
// version 0.01
IF ( nAt := At( Chr( 253 ), cString ) ) > 0 // some color text inside
t_aReport[ PAGEBUFFER ] += CRLF + ;
Chr_RGB( SubStr( cString, nAt + 1, 1 ) ) + " " + ;
Chr_RGB( SubStr( cString, nAt + 2, 1 ) ) + " " + ;
Chr_RGB( SubStr( cString, nAt + 3, 1 ) ) + " rg "
cString := Stuff( cString, nAt, 4, "" )
ENDIF
// version 0.01
_nFont := AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ FONTNAME ] } )
IF !( t_aReport[ FONTNAME ] == t_aReport[ FONTNAMEPREV ] )
t_aReport[ FONTNAMEPREV ] := t_aReport[ FONTNAME ]
t_aReport[ PAGEBUFFER ] += CRLF + "BT /Fo" + hb_ntos( _nFont ) + " " + LTrim( Transform( t_aReport[ FONTSIZE ], "999.99" ) ) + " Tf " + LTrim( Transform( nCol, "9999.99" ) ) + " " + LTrim( Transform( nRow, "9999.99" ) ) + " Td (" + cString + ") Tj ET"
ELSEIF t_aReport[ FONTSIZE ] != t_aReport[ FONTSIZEPREV ]
t_aReport[ FONTSIZEPREV ] := t_aReport[ FONTSIZE ]
t_aReport[ PAGEBUFFER ] += CRLF + "BT /Fo" + hb_ntos( _nFont ) + " " + LTrim( Transform( t_aReport[ FONTSIZE ], "999.99" ) ) + " Tf " + LTrim( Transform( nCol, "9999.99" ) ) + " " + LTrim( Transform( nRow, "9999.99" ) ) + " Td (" + cString + ") Tj ET"
ELSE
t_aReport[ PAGEBUFFER ] += CRLF + "BT " + LTrim( Transform( nCol, "9999.99" ) ) + " " + LTrim( Transform( nRow, "9999.99" ) ) + " Td (" + cString + ") Tj ET"
ENDIF
IF lReverse
t_aReport[ PAGEBUFFER ] += " 0 g "
ENDIF
ENDIF
RETURN NIL
// ---------------
FUNCTION pdfBold()
IF pdfGetFontInfo( "NAME" ) == "Times"
t_aReport[ FONTNAME ] := 2
ELSEIF pdfGetFontInfo( "NAME" ) == "Helvetica"
t_aReport[ FONTNAME ] := 6
ELSE
t_aReport[ FONTNAME ] := 10 // Courier // 0.04
ENDIF
AAdd( t_aReport[ PAGEFONTS ], t_aReport[ FONTNAME ] )
IF AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ FONTNAME ] } ) == 0
AAdd( t_aReport[ FONTS ], { t_aReport[ FONTNAME ], ++t_aReport[ NEXTOBJ ] } )
ENDIF
RETURN NIL
// ---------------------
FUNCTION pdfBoldItalic()
IF pdfGetFontInfo( "NAME" ) == "Times"
t_aReport[ FONTNAME ] := 4
ELSEIF pdfGetFontInfo( "NAME" ) == "Helvetica"
t_aReport[ FONTNAME ] := 8
ELSE
t_aReport[ FONTNAME ] := 12 // 0.04
ENDIF
AAdd( t_aReport[ PAGEFONTS ], t_aReport[ FONTNAME ] )
IF AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ FONTNAME ] } ) == 0
AAdd( t_aReport[ FONTS ], { t_aReport[ FONTNAME ], ++t_aReport[ NEXTOBJ ] } )
ENDIF
RETURN NIL
// ------------------------------------------------
FUNCTION pdfBookAdd( cTitle, nLevel, nPage, nLine )
AAdd( t_aReport[ BOOKMARK ], { nLevel, AllTrim( cTitle ), 0, 0, 0, 0, 0, 0, nPage, iif( nLevel == 1, t_aReport[ PAGEY ], t_aReport[ PAGEY ] - nLine * 72 / t_aReport[ LPI ] ) } )
RETURN NIL
// ---------------------
FUNCTION pdfBookClose()
t_aReport[ BOOKMARK ] := nil
RETURN NIL
// ----------------------------------------------
STATIC FUNCTION pdfBookCount( nRecno, nCurLevel )
LOCAL nTempLevel, nCount := 0, nLen := Len( t_aReport[ BOOKMARK ] )
++nRecno
WHILE nRecno <= nLen
nTempLevel := t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
IF nTempLevel <= nCurLevel
EXIT
ELSE
IF nCurLevel + 1 == nTempLevel
++nCount
ENDIF
ENDIF
++nRecno
ENDDO
RETURN -1 * nCount
// ----------------------------------------------------
STATIC FUNCTION pdfBookFirst( nRecno, nCurLevel, nObj )
LOCAL nFirst := 0, nLen := Len( t_aReport[ BOOKMARK ] )
++nRecno
IF nRecno <= nLen
IF nCurLevel + 1 == t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
nFirst := nRecno
ENDIF
ENDIF
RETURN iif( nFirst == 0, nFirst, nObj + nFirst )
// ---------------------------------------------------
STATIC FUNCTION pdfBookLast( nRecno, nCurLevel, nObj )
LOCAL nLast := 0, nLen := Len( t_aReport[ BOOKMARK ] )
++nRecno
IF nRecno <= nLen
IF nCurLevel + 1 == t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
WHILE nRecno <= nLen .AND. nCurLevel + 1 <= t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
IF nCurLevel + 1 == t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
nLast := nRecno
ENDIF
++nRecno
ENDDO
ENDIF
ENDIF
RETURN iif( nLast == 0, nLast, nObj + nLast )
// ---------------------------------------------------
STATIC FUNCTION pdfBookNext( nRecno, nCurLevel, nObj )
LOCAL nTempLevel, nNext := 0, nLen := Len( t_aReport[ BOOKMARK ] )
++nRecno
WHILE nRecno <= nLen
nTempLevel := t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
IF nCurLevel > nTempLevel
EXIT
ELSEIF nCurLevel == nTempLevel
nNext := nRecno
EXIT
ELSE
// keep going
ENDIF
++nRecno
ENDDO
RETURN iif( nNext == 0, nNext, nObj + nNext )
// --------------------
FUNCTION pdfBookOpen()
t_aReport[ BOOKMARK ] := {}
RETURN NIL
// -----------------------------------------------------
STATIC FUNCTION pdfBookParent( nRecno, nCurLevel, nObj )
LOCAL nTempLevel
LOCAL nParent := 0
--nRecno
WHILE nRecno > 0
nTempLevel := t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
IF nTempLevel < nCurLevel
nParent := nRecno
EXIT
ENDIF
--nRecno
ENDDO
RETURN iif( nParent == 0, nObj - 1, nObj + nParent )
// ---------------------------------------------------
STATIC FUNCTION pdfBookPrev( nRecno, nCurLevel, nObj )
LOCAL nTempLevel
LOCAL nPrev := 0
--nRecno
WHILE nRecno > 0
nTempLevel := t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
IF nCurLevel > nTempLevel
EXIT
ELSEIF nCurLevel == nTempLevel
nPrev := nRecno
EXIT
ELSE
// keep going
ENDIF
--nRecno
ENDDO
RETURN iif( nPrev == 0, nPrev, nObj + nPrev )
// ------------------------------------------------------------
FUNCTION pdfBox( x1, y1, x2, y2, nBorder, nShade, cUnits, cColor, cId )
LOCAL cBoxColor
__defaultNIL( @nBorder, 0 )
__defaultNIL( @nShade, 0 )
__defaultNIL( @cUnits, "M" )
__defaultNIL( @cColor, "" )
// version 0.02
cBoxColor := ""
IF ! Empty( cColor )
cBoxColor := " " + Chr_RGB( SubStr( cColor, 2, 1 ) ) + " " + ;
Chr_RGB( SubStr( cColor, 3, 1 ) ) + " " + ;
Chr_RGB( SubStr( cColor, 4, 1 ) ) + " rg "
IF Empty( AllTrim( cBoxColor ) )
cBoxColor := ""
ENDIF
ENDIF
// version 0.02
IF t_aReport[ HEADEREDIT ]
RETURN pdfHeader( "PDFBOX", cId, { x1, y1, x2, y2, nBorder, nShade, cUnits } )
ENDIF
IF cUnits == "M"
y1 += 0.5
y2 += 0.5
IF nShade > 0
// version 0.02
t_aReport[ PAGEBUFFER ] += CRLF + Transform( 1.00 - nShade / 100.00, "9.99" ) + " g " + cBoxColor + hb_ntos( pdfM2X( y1 ) ) + " " + hb_ntos( pdfM2Y( x1 ) ) + " " + hb_ntos( pdfM2X( y2 - y1 ) ) + " -" + hb_ntos( pdfM2X( x2 - x1 ) ) + " re f 0 g"
ENDIF
IF nBorder > 0
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( pdfM2X( y1 ) ) + " " + hb_ntos( pdfM2Y( x1 ) ) + " " + hb_ntos( pdfM2X( y2 - y1 ) ) + " -" + hb_ntos( pdfM2X( nBorder ) ) + " re f"
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( pdfM2X( y2 - nBorder ) ) + " " + hb_ntos( pdfM2Y( x1 ) ) + " " + hb_ntos( pdfM2X( nBorder ) ) + " -" + hb_ntos( pdfM2X( x2 - x1 ) ) + " re f"
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( pdfM2X( y1 ) ) + " " + hb_ntos( pdfM2Y( x2 - nBorder ) ) + " " + hb_ntos( pdfM2X( y2 - y1 ) ) + " -" + hb_ntos( pdfM2X( nBorder ) ) + " re f"
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( pdfM2X( y1 ) ) + " " + hb_ntos( pdfM2Y( x1 ) ) + " " + hb_ntos( pdfM2X( nBorder ) ) + " -" + hb_ntos( pdfM2X( x2 - x1 ) ) + " re f"
ENDIF
ELSEIF cUnits == "D"// "Dots"
// x1, y1, x2, y2 - nTop, nLeft, nBottom, nRight
IF nShade > 0
// version 0.02
t_aReport[ PAGEBUFFER ] += CRLF + Transform( 1.00 - nShade / 100.00, "9.99" ) + " g " + cBoxColor + hb_ntos( y1 ) + " " + hb_ntos( t_aReport[ PAGEY ] - x1 ) + " " + hb_ntos( y2 - y1 ) + " -" + hb_ntos( x2 - x1 ) + " re f 0 g"
ENDIF
IF nBorder > 0
/*
1
+-----+
4 | | 2
+-----+
3
*/
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( y1 ) + " " + hb_ntos( t_aReport[ PAGEY ] - x1 ) + " " + hb_ntos( y2 - y1 ) + " -" + hb_ntos( nBorder ) + " re f"
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( y2 - nBorder ) + " " + hb_ntos( t_aReport[ PAGEY ] - x1 ) + " " + hb_ntos( nBorder ) + " -" + hb_ntos( x2 - x1 ) + " re f"
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( y1 ) + " " + hb_ntos( t_aReport[ PAGEY ] - x2 + nBorder ) + " " + hb_ntos( y2 - y1 ) + " -" + hb_ntos( nBorder ) + " re f"
t_aReport[ PAGEBUFFER ] += CRLF + "0 g " + hb_ntos( y1 ) + " " + hb_ntos( t_aReport[ PAGEY ] - x1 ) + " " + hb_ntos( nBorder ) + " -" + hb_ntos( x2 - x1 ) + " re f"
ENDIF
ENDIF
RETURN NIL
// ------------------------------------------------------------
FUNCTION pdfBox1( nTop, nLeft, nBottom, nRight, nBorderWidth, cBorderColor, cBoxColor )
__defaultNIL( @nBorderWidth, 0.5 )
__defaultNIL( @cBorderColor, Chr( 0 ) + Chr( 0 ) + Chr( 0 ) )
__defaultNIL( @cBoxColor, Chr( 255 ) + Chr( 255 ) + Chr( 255 ) )
t_aReport[ PAGEBUFFER ] += CRLF + ;
Chr_RGB( SubStr( cBorderColor, 1, 1 ) ) + " " + ;
Chr_RGB( SubStr( cBorderColor, 2, 1 ) ) + " " + ;
Chr_RGB( SubStr( cBorderColor, 3, 1 ) ) + ;
" RG" + ;
CRLF + ;
Chr_RGB( SubStr( cBoxColor, 1, 1 ) ) + " " + ;
Chr_RGB( SubStr( cBoxColor, 2, 1 ) ) + " " + ;
Chr_RGB( SubStr( cBoxColor, 3, 1 ) ) + ;
" rg" + ;
CRLF + hb_ntos( nBorderWidth ) + " w" + ;
CRLF + hb_ntos( nLeft + nBorderWidth / 2 ) + " " + ;
CRLF + hb_ntos( t_aReport[ PAGEY ] - nBottom + nBorderWidth / 2 ) + " " + ;
CRLF + hb_ntos( nRight - nLeft - nBorderWidth ) + ;
CRLF + hb_ntos( nBottom - nTop - nBorderWidth ) + " " + ;
" re" + ;
CRLF + "B"
RETURN NIL
// -----------------------------------------------------------
FUNCTION pdfCenter( cString, nRow, nCol, cUnits, lExact, cId )
LOCAL nLen, nAt
__defaultNIL( @nRow, t_aReport[ REPORTLINE ] )
__defaultNIL( @cUnits, "R" )
__defaultNIL( @lExact, .F. )
__defaultNIL( @nCol, iif( cUnits == "R", t_aReport[ REPORTWIDTH ] / 2, t_aReport[ PAGEX ] / 72 * 25.4 / 2 ) )
IF t_aReport[ HEADEREDIT ]
RETURN pdfHeader( "PDFCENTER", cId, { cString, nRow, nCol, cUnits, lExact } )
ENDIF
IF ( nAt := At( "#pagenumber#", cString ) ) > 0
cString := Left( cString, nAt - 1 ) + hb_ntos( pdfPageNumber() ) + SubStr( cString, nAt + 12 )
ENDIF
nLen := pdfLen( cString ) / 2
IF cUnits == "R"
IF ! lExact
pdfCheckLine( nRow )
nRow := nRow + t_aReport[ PDFTOP ]
ENDIF
ENDIF
pdfAtSay( cString, pdfR2M( nRow ), iif( cUnits == "R", t_aReport[ PDFLEFT ] + ( t_aReport[ PAGEX ] / 72 * 25.4 - 2 * t_aReport[ PDFLEFT ] ) * nCol / t_aReport[ REPORTWIDTH ], nCol ) - nLen, "M", lExact )
RETURN NIL
// ---------------------------------
STATIC FUNCTION pdfCheckLine( nRow )
IF nRow + t_aReport[ PDFTOP ] > t_aReport[ PDFBOTTOM ]
pdfNewPage()
nRow := t_aReport[ REPORTLINE ]
ENDIF
t_aReport[ REPORTLINE ] := nRow
RETURN NIL
// ----------------
FUNCTION pdfClose()
LOCAL nI, cTemp, nCurLevel, nObj1, nLast, nCount, nFirst, nRecno, nBooklen
FIELD FIRST, PREV, NEXT, LAST, COUNT, PARENT, PAGE, COORD, TITLE, LEVEL
pdfClosePage()
// kids
t_aReport[ REFS ][ 2 ] := t_aReport[ DOCLEN ]
cTemp := ;
"1 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/Type /Pages /Count " + hb_ntos( t_aReport[ REPORTPAGE ] ) + CRLF + ;
"/Kids ["
FOR nI := 1 TO t_aReport[ REPORTPAGE ]
cTemp += " " + hb_ntos( t_aReport[ PAGES ][ nI ] ) + " 0 R"
NEXT
cTemp += " ]" + CRLF + ;
">>" + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
// info
++t_aReport[ REPORTOBJ ]
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
cTemp := hb_ntos( t_aReport[ REPORTOBJ ] ) + " 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/Producer ()" + CRLF + ;
"/Title ()" + CRLF + ;
"/Author ()" + CRLF + ;
"/Creator ()" + CRLF + ;
"/Subject ()" + CRLF + ;
"/Keywords ()" + CRLF + ;
"/CreationDate (D:" + Str( Year( Date() ), 4 ) + PadL( Month( Date() ), 2, "0" ) + PadL( Day( Date() ), 2, "0" ) + SubStr( Time(), 1, 2 ) + SubStr( Time(), 4, 2 ) + SubStr( Time(), 7, 2 ) + ")" + CRLF + ;
">>" + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
// root
++t_aReport[ REPORTOBJ ]
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
cTemp := hb_ntos( t_aReport[ REPORTOBJ ] ) + " 0 obj" + CRLF + ;
"<< /Type /Catalog /Pages 1 0 R /Outlines " + hb_ntos( t_aReport[ REPORTOBJ ] + 1 ) + " 0 R" + iif( ( nBookLen := Len( t_aReport[ BOOKMARK ] ) ) > 0, " /PageMode /UseOutlines", "" ) + " >>" + CRLF + "endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
++t_aReport[ REPORTOBJ ]
nObj1 := t_aReport[ REPORTOBJ ]
IF nBookLen > 0
nRecno := 1
nFirst := t_aReport[ REPORTOBJ ] + 1
nLast := 0
nCount := 0
WHILE nRecno <= nBookLen
nCurLevel := t_aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ]
t_aReport[ BOOKMARK ][ nRecno ][ BOOKPARENT ] := pdfBookParent( nRecno, nCurLevel, t_aReport[ REPORTOBJ ] )
t_aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] := pdfBookPrev( nRecno, nCurLevel, t_aReport[ REPORTOBJ ] )
t_aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] := pdfBookNext( nRecno, nCurLevel, t_aReport[ REPORTOBJ ] )
t_aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] := pdfBookFirst( nRecno, nCurLevel, t_aReport[ REPORTOBJ ] )
t_aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] := pdfBookLast( nRecno, nCurLevel, t_aReport[ REPORTOBJ ] )
t_aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] := pdfBookCount( nRecno, nCurLevel )
IF nCurLevel == 1
nLast := nRecno
++nCount
ENDIF
++nRecno
ENDDO
nLast += t_aReport[ REPORTOBJ ]
cTemp := hb_ntos( t_aReport[ REPORTOBJ ] ) + " 0 obj" + CRLF + "<< /Type /Outlines /Count " + hb_ntos( nCount ) + " /First " + hb_ntos( nFirst ) + " 0 R /Last " + hb_ntos( nLast ) + " 0 R >>" + CRLF + "endobj" // + CRLF
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
++t_aReport[ REPORTOBJ ]
nRecno := 1
FOR nI := 1 TO nBookLen
cTemp := CRLF + hb_ntos( t_aReport[ REPORTOBJ ] + nI - 1 ) + " 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/Parent " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKPARENT ] ) + " 0 R" + CRLF + ;
"/Dest [" + hb_ntos( t_aReport[ PAGES ][ t_aReport[ BOOKMARK ][ nRecno ][ BOOKPAGE ] ] ) + " 0 R /XYZ 0 " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ] ) + " 0]" + CRLF + ;
"/Title (" + AllTrim( t_aReport[ BOOKMARK ][ nRecno ][ BOOKTITLE ] ) + ")" + CRLF + ;
iif( t_aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] > 0, "/Prev " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] ) + " 0 R" + CRLF, "" ) + ;
iif( t_aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] > 0, "/Next " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] ) + " 0 R" + CRLF, "" ) + ;
iif( t_aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] > 0, "/First " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] ) + " 0 R" + CRLF, "" ) + ;
iif( t_aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] > 0, "/Last " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] ) + " 0 R" + CRLF, "" ) + ;
iif( t_aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] != 0, "/Count " + hb_ntos( t_aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] ) + CRLF, "" ) + ;
">>" + CRLF + "endobj" + CRLF
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] + 2 )
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
++nRecno
NEXT
pdfBookClose()
t_aReport[ REPORTOBJ ] += nBookLen - 1
ELSE
cTemp := hb_ntos( t_aReport[ REPORTOBJ ] ) + " 0 obj" + CRLF + "<< /Type /Outlines /Count 0 >>" + CRLF + "endobj" + CRLF
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
ENDIF
cTemp := CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
++t_aReport[ REPORTOBJ ]
cTemp += "xref" + CRLF + ;
"0 " + hb_ntos( t_aReport[ REPORTOBJ ] ) + CRLF + ;
PadL( t_aReport[ REFS ][ 1 ], 10, "0" ) + " 65535 f" + CRLF
FOR nI := 2 TO Len( t_aReport[ REFS ] )
cTemp += PadL( t_aReport[ REFS ][ nI ], 10, "0" ) + " 00000 n" + CRLF
NEXT
cTemp += "trailer << /Size " + hb_ntos( t_aReport[ REPORTOBJ ] ) + " /Root " + hb_ntos( nObj1 - 1 ) + " 0 R /Info " + hb_ntos( nObj1 - 2 ) + " 0 R >>" + CRLF + ;
"startxref" + CRLF + ;
hb_ntos( t_aReport[ DOCLEN ] ) + CRLF + ;
"%%EOF" + CRLF
FWrite( t_aReport[ HANDLE ], cTemp )
/*
IF t_aReport[ OPTIMIZE ]
pdfOptimize( ) coming !
ENDIF
*/
FClose( t_aReport[ HANDLE ] )
t_aReport := nil
RETURN NIL
// ---------------------------
STATIC FUNCTION pdfClosePage()
LOCAL cTemp, cBuffer, nBuffer, nRead, nI, k, nImage, nFont, nImageHandle
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
AAdd( t_aReport[ PAGES ], t_aReport[ REPORTOBJ ] + 1 )
cTemp := ;
hb_ntos( ++t_aReport[ REPORTOBJ ] ) + " 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/Type /Page /Parent 1 0 R" + CRLF + ;
"/Resources " + hb_ntos( ++t_aReport[ REPORTOBJ ] ) + " 0 R" + CRLF + ;
"/MediaBox [ 0 0 " + LTrim( Transform( t_aReport[ PAGEX ], "9999.99" ) ) + " " + ;
LTrim( Transform( t_aReport[ PAGEY ], "9999.99" ) ) + " ]" + CRLF + ;
"/Contents " + hb_ntos( ++t_aReport[ REPORTOBJ ] ) + " 0 R" + CRLF + ;
">>" + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
cTemp := ;
hb_ntos( t_aReport[ REPORTOBJ ] - 1 ) + " 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/ColorSpace << /DeviceRGB /DeviceGray >>" + CRLF + ; // version 0.01
"/ProcSet [ /PDF /Text /ImageB /ImageC ]"
IF Len( t_aReport[ PAGEFONTS ] ) > 0
cTemp += CRLF + ;
"/Font" + CRLF + ;
"<<"
FOR nI := 1 TO Len( t_aReport[ PAGEFONTS ] )
nFont := AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ PAGEFONTS ][ nI ] } )
cTemp += CRLF + "/Fo" + hb_ntos( nFont ) + " " + hb_ntos( t_aReport[ FONTS ][ nFont ][ 2 ] ) + " 0 R"
NEXT
cTemp += CRLF + ">>"
ENDIF
IF Len( t_aReport[ PAGEIMAGES ] ) > 0
cTemp += CRLF + "/XObject" + CRLF + "<<"
FOR nI := 1 TO Len( t_aReport[ PAGEIMAGES ] )
nImage := AScan( t_aReport[ IMAGES ], {| arr | arr[ 1 ] == t_aReport[ PAGEIMAGES ][ nI ][ 1 ] } )
IF nImage == 0
AAdd( t_aReport[ IMAGES ], { t_aReport[ PAGEIMAGES ][ nI ][ 1 ], ++t_aReport[ NEXTOBJ ], pdfImageInfo( t_aReport[ PAGEIMAGES ][ nI ][ 1 ] ) } )
nImage := Len( t_aReport[ IMAGES ] )
ENDIF
cTemp += CRLF + "/Image" + hb_ntos( nImage ) + " " + hb_ntos( t_aReport[ IMAGES ][ nImage ][ 2 ] ) + " 0 R"
NEXT
cTemp += CRLF + ">>"
ENDIF
cTemp += CRLF + ">>" + CRLF + "endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
cTemp := hb_ntos( t_aReport[ REPORTOBJ ] ) + " 0 obj << /Length " + ;
hb_ntos( t_aReport[ REPORTOBJ ] + 1 ) + " 0 R >>" + CRLF + ;
"stream"
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
IF Len( t_aReport[ PAGEIMAGES ] ) > 0
cTemp := ""
FOR nI := 1 TO Len( t_aReport[ PAGEIMAGES ] )
cTemp += CRLF + "q"
nImage := AScan( t_aReport[ IMAGES ], {| arr | arr[ 1 ] == t_aReport[ PAGEIMAGES ][ nI ][ 1 ] } )
cTemp += CRLF + hb_ntos( iif( t_aReport[ PAGEIMAGES ][ nI ][ 5 ] == 0, pdfM2X( t_aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_WIDTH ] / t_aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_XRES ] * 25.4 ), t_aReport[ PAGEIMAGES ][ nI ][ 5 ] ) ) + ;
" 0 0 " + ;
hb_ntos( iif( t_aReport[ PAGEIMAGES ][ nI ][ 4 ] == 0, pdfM2X( t_aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_HEIGHT ] / t_aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_YRES ] * 25.4 ), t_aReport[ PAGEIMAGES ][ nI ][ 4 ] ) ) + ;
" " + hb_ntos( t_aReport[ PAGEIMAGES ][ nI ][ 3 ] ) + ;
" " + hb_ntos( t_aReport[ PAGEY ] - t_aReport[ PAGEIMAGES ][ nI ][ 2 ] - ;
iif( t_aReport[ PAGEIMAGES ][ nI ][ 4 ] == 0, pdfM2X( t_aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_HEIGHT ] / t_aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_YRES ] * 25.4 ), t_aReport[ PAGEIMAGES ][ nI ][ 4 ] ) ) + " cm"
cTemp += CRLF + "/Image" + hb_ntos( nImage ) + " Do"
cTemp += CRLF + "Q"
NEXT
t_aReport[ PAGEBUFFER ] := cTemp + t_aReport[ PAGEBUFFER ]
ENDIF
cTemp := t_aReport[ PAGEBUFFER ]
cTemp += CRLF + "endstream" + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
cTemp := hb_ntos( ++t_aReport[ REPORTOBJ ] ) + " 0 obj" + CRLF + ;
hb_ntos( Len( t_aReport[ PAGEBUFFER ] ) ) + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
FOR nI := 1 TO Len( t_aReport[ FONTS ] )
IF t_aReport[ FONTS ][ nI ][ 2 ] > t_aReport[ REPORTOBJ ]
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
cTemp := ;
hb_ntos( t_aReport[ FONTS ][ nI ][ 2 ] ) + " 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/Type /Font" + CRLF + ;
"/Subtype /Type1" + CRLF + ;
"/Name /Fo" + hb_ntos( nI ) + CRLF + ;
"/BaseFont /" + t_aReport[ TYPE1 ][ t_aReport[ FONTS ][ nI ][ 1 ] ] + CRLF + ;
"/Encoding /WinAnsiEncoding" + CRLF + ;
">>" + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
ENDIF
NEXT
FOR nI := 1 TO Len( t_aReport[ IMAGES ] )
IF t_aReport[ IMAGES ][ nI ][ 2 ] > t_aReport[ REPORTOBJ ]
AAdd( t_aReport[ REFS ], t_aReport[ DOCLEN ] )
// "/Filter /CCITTFaxDecode" for B&W only ?
cTemp := ;
hb_ntos( t_aReport[ IMAGES ][ nI ][ 2 ] ) + " 0 obj" + CRLF + ;
"<<" + CRLF + ;
"/Type /XObject" + CRLF + ;
"/Subtype /Image" + CRLF + ;
"/Name /Image" + hb_ntos( nI ) + CRLF + ;
"/Filter [" + iif( At( ".jpg", Lower( t_aReport[ IMAGES ][ nI ][ 1 ] ) ) > 0, " /DCTDecode", "" ) + " ]" + CRLF + ;
"/Width " + hb_ntos( t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_WIDTH ] ) + CRLF + ;
"/Height " + hb_ntos( t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_HEIGHT ] ) + CRLF + ;
"/BitsPerComponent " + hb_ntos( t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_BITS ] ) + CRLF + ;
"/ColorSpace /" + iif( t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_SPACE ] == 1, "DeviceGray", "DeviceRGB" ) + CRLF + ;
"/Length " + hb_ntos( t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] ) + CRLF + ;
">>" + CRLF + ;
"stream" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
nImageHandle := FOpen( t_aReport[ IMAGES ][ nI ][ 1 ] )
FSeek( nImageHandle, t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_FROM ] )
nBuffer := 8192
cBuffer := Space( nBuffer )
k := 0
WHILE k < t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ]
IF k + nBuffer <= t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ]
nRead := nBuffer
ELSE
nRead := t_aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] - k
ENDIF
FRead( nImageHandle, @cBuffer, nRead )
t_aReport[ DOCLEN ] += nRead
FWrite( t_aReport[ HANDLE ], cBuffer, nRead )
k += nRead
ENDDO
FClose( nImageHandle )
cTemp := CRLF + "endstream" + CRLF + ;
"endobj" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
ENDIF
NEXT
t_aReport[ REPORTOBJ ] := t_aReport[ NEXTOBJ ]
t_aReport[ NEXTOBJ ] := t_aReport[ REPORTOBJ ] + 4
t_aReport[ PAGEBUFFER ] := ""
RETURN NIL
// -------------------------------------
STATIC FUNCTION pdfGetFontInfo( cParam )
LOCAL cRet
IF cParam == "NAME"
IF Left( t_aReport[ TYPE1 ][ t_aReport[ FONTNAME ] ], 5 ) == "Times"
cRet := "Times"
ELSEIF Left( t_aReport[ TYPE1 ][ t_aReport[ FONTNAME ] ], 9 ) == "Helvetica"
cRet := "Helvetica"
ELSE
cRet := "Courier" // 0.04
ENDIF
ELSE // size
cRet := Int( ( t_aReport[ FONTNAME ] - 1 ) % 4 )
ENDIF
RETURN cRet
// -----------------------------------------------------------------
FUNCTION pdfImage( cFile, nRow, nCol, cUnits, nHeight, nWidth, cId )
__defaultNIL( @nRow, t_aReport[ REPORTLINE ] )
__defaultNIL( @nCol, 0 )
__defaultNIL( @nHeight, 0 )
__defaultNIL( @nWidth, 0 )
__defaultNIL( @cUnits, "R" )
__defaultNIL( @cId, "" )
IF t_aReport[ HEADEREDIT ]
RETURN pdfHeader( "PDFIMAGE", cId, { cFile, nRow, nCol, cUnits, nHeight, nWidth } )
ENDIF
IF cUnits == "M"
nRow := t_aReport[ PAGEY ] - pdfM2Y( nRow )
nCol := pdfM2X( nCol )
nHeight := t_aReport[ PAGEY ] - pdfM2Y( nHeight )
nWidth := pdfM2X( nWidth )
ELSEIF cUnits == "R"
nRow := t_aReport[ PAGEY ] - pdfR2D( nRow )
nCol := pdfM2X( t_aReport[ PDFLEFT ] ) + ;
nCol * 100.00 / t_aReport[ REPORTWIDTH ] * ;
( t_aReport[ PAGEX ] - pdfM2X( t_aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00
nHeight := t_aReport[ PAGEY ] - pdfR2D( nHeight )
nWidth := pdfM2X( t_aReport[ PDFLEFT ] ) + ;
nWidth * 100.00 / t_aReport[ REPORTWIDTH ] * ;
( t_aReport[ PAGEX ] - pdfM2X( t_aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00
ELSEIF cUnits == "D"
ENDIF
AAdd( t_aReport[ PAGEIMAGES ], { cFile, nRow, nCol, nHeight, nWidth } )
RETURN NIL
// -----------------
FUNCTION pdfItalic()
IF pdfGetFontInfo( "NAME" ) == "Times"
t_aReport[ FONTNAME ] := 3
ELSEIF pdfGetFontInfo( "NAME" ) == "Helvetica"
t_aReport[ FONTNAME ] := 7
ELSE
t_aReport[ FONTNAME ] := 11 // 0.04
ENDIF
AAdd( t_aReport[ PAGEFONTS ], t_aReport[ FONTNAME ] )
IF AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ FONTNAME ] } ) == 0
AAdd( t_aReport[ FONTS ], { t_aReport[ FONTNAME ], ++t_aReport[ NEXTOBJ ] } )
ENDIF
RETURN NIL
// -----------------------
FUNCTION pdfLen( cString )
LOCAL nWidth := 0.00, nI, nLen, nArr, nAdd := ( t_aReport[ FONTNAME ] - 1 ) % 4
nLen := Len( cString )
IF Right( cString, 1 ) == Chr( 255 ) .OR. Right( cString, 1 ) == Chr( 254 ) // reverse or underline
--nLen
ENDIF
IF pdfGetFontInfo( "NAME" ) == "Times"
nArr := 1
ELSEIF pdfGetFontInfo( "NAME" ) == "Helvetica"
nArr := 2
ELSE
nArr := 3 // 0.04
ENDIF
IF ! Empty( t_aReport[ FONTWIDTH ] )
FOR nI := 1 TO nLen
nWidth += t_aReport[ FONTWIDTH ][ nArr ][ ( Asc( SubStr( cString, nI, 1 ) ) - 32 ) * 4 + 1 + nAdd ] * 25.4 * t_aReport[ FONTSIZE ] / 720.00 / 100.00
NEXT
ENDIF
RETURN nWidth
// -------------------------
STATIC FUNCTION pdfM2R( mm )
RETURN Int( t_aReport[ LPI ] * mm / 25.4 )
// ------------------------
STATIC FUNCTION pdfM2X( n )
RETURN n * 72 / 25.4
// ------------------------
STATIC FUNCTION pdfM2Y( n )
RETURN t_aReport[ PAGEY ] - n * 72 / 25.4
// ---------------------
FUNCTION pdfNewLine( n )
__defaultNIL( @n, 1 )
IF t_aReport[ REPORTLINE ] + n + t_aReport[ PDFTOP ] > t_aReport[ PDFBOTTOM ]
pdfNewPage()
t_aReport[ REPORTLINE ] += 1
ELSE
t_aReport[ REPORTLINE ] += n
ENDIF
RETURN t_aReport[ REPORTLINE ]
// ---------------------------------------------------------------------------------------
FUNCTION pdfNewPage( _cPageSize, _cPageOrient, _nLpi, _cFontName, _nFontType, _nFontSize )
__defaultNIL( @_cPageSize, t_aReport[ PAGESIZE ] )
__defaultNIL( @_cPageOrient, t_aReport[ PAGEORIENT ] )
__defaultNIL( @_nLpi, t_aReport[ LPI ] )
__defaultNIL( @_cFontName, pdfGetFontInfo( "NAME" ) )
__defaultNIL( @_nFontType, pdfGetFontInfo( "TYPE" ) )
__defaultNIL( @_nFontSize, t_aReport[ FONTSIZE ] )
IF ! Empty( t_aReport[ PAGEBUFFER ] )
pdfClosePage()
ENDIF
t_aReport[ PAGEFONTS ] := {}
t_aReport[ PAGEIMAGES ] := {}
++t_aReport[ REPORTPAGE ] // NEW !!!
pdfPageSize( _cPageSize )
pdfPageOrient( _cPageOrient )
pdfSetLPI( _nLpi )
pdfSetFont( _cFontName, _nFontType, _nFontSize )
pdfDrawHeader()
t_aReport[ REPORTLINE ] := 0// 5
t_aReport[ FONTNAMEPREV ] := 0
t_aReport[ FONTSIZEPREV ] := 0
RETURN NIL
// -----------------
FUNCTION pdfNormal()
IF pdfGetFontInfo( "NAME" ) == "Times"
t_aReport[ FONTNAME ] := 1
ELSEIF pdfGetFontInfo( "NAME" ) == "Helvetica"
t_aReport[ FONTNAME ] := 5
ELSE
t_aReport[ FONTNAME ] := 9 // 0.04
ENDIF
AAdd( t_aReport[ PAGEFONTS ], t_aReport[ FONTNAME ] )
IF AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ FONTNAME ] } ) == 0
AAdd( t_aReport[ FONTS ], { t_aReport[ FONTNAME ], ++t_aReport[ NEXTOBJ ] } )
ENDIF
RETURN NIL
// ---------------------------------------
FUNCTION pdfOpen( cFile, nLen, lOptimize )
LOCAL cTemp, nI, nJ, n1, n2 := 896, n12
__defaultNIL( @nLen, 200 )
__defaultNIL( @lOptimize, .F. )
t_aReport[ FONTNAME ] := 1
t_aReport[ FONTSIZE ] := 10
t_aReport[ LPI ] := 6
t_aReport[ PAGESIZE ] := "LETTER"
t_aReport[ PAGEORIENT ] := "P"
t_aReport[ PAGEX ] := 8.5 * 72
t_aReport[ PAGEY ] := 11.0 * 72
t_aReport[ REPORTWIDTH ] := nLen // 200 // should be as parameter
t_aReport[ REPORTPAGE ] := 0
t_aReport[ REPORTLINE ] := 0// 5
t_aReport[ FONTNAMEPREV ] := 0
t_aReport[ FONTSIZEPREV ] := 0
t_aReport[ PAGEBUFFER ] := ""
t_aReport[ REPORTOBJ ] := 1// 2
t_aReport[ DOCLEN ] := 0
t_aReport[ TYPE1 ] := { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" } // 0.04
t_aReport[ MARGINS ] := .T.
t_aReport[ HEADEREDIT ] := .F.
t_aReport[ NEXTOBJ ] := 0
t_aReport[ PDFTOP ] := 1 // top
t_aReport[ PDFLEFT ] := 10 // left & right
t_aReport[ PDFBOTTOM ] := t_aReport[ PAGEY ] / 72 * t_aReport[ LPI ] - 1 // bottom, default "LETTER", "P", 6
t_aReport[ HANDLE ] := FCreate( cFile )
t_aReport[ PAGES ] := {}
t_aReport[ REFS ] := { 0, 0 }
t_aReport[ BOOKMARK ] := {}
t_aReport[ HEADER ] := {}
t_aReport[ FONTS ] := {}
t_aReport[ IMAGES ] := {}
t_aReport[ PAGEIMAGES ] := {}
t_aReport[ PAGEFONTS ] := {}
// TOFIX: This external file dependency should be removed.
cTemp := __pdf_fontsdat() // times, times-bold, times-italic, times-bolditalic, helvetica..., courier... // 0.04
n1 := Len( cTemp ) / ( 2 * n2 )
t_aReport[ FONTWIDTH ] := Array( n1, n2 )
t_aReport[ OPTIMIZE ] := lOptimize
t_aReport[ NEXTOBJ ] := t_aReport[ REPORTOBJ ] + 4
n12 := 2 * n2 // 0.04
FOR nI := 1 TO n1
FOR nJ := 1 TO n2
t_aReport[ FONTWIDTH ][ nI ][ nJ ] := Bin2I( SubStr( cTemp, ( nI - 1 ) * n12 + ( nJ - 1 ) * 2 + 1, 2 ) )
NEXT
NEXT
t_aReport[ DOCLEN ] := 0
cTemp := "%PDF-1.3" + CRLF
t_aReport[ DOCLEN ] += Len( cTemp )
FWrite( t_aReport[ HANDLE ], cTemp )
RETURN NIL
// -------------------------------
FUNCTION pdfPageSize( _cPageSize, _nWidth, _nHeight )
LOCAL nSize, aSize, nWidth, nHeight
aSize := { ;
{ "LETTER", 8.50, 11.00 }, ;
{ "LEGAL", 8.50, 14.00 }, ;
{ "LEDGER", 11.00, 17.00 }, ;
{ "EXECUTIVE" , 7.25, 10.50 }, ;
{ "A4", 8.27, 11.69 }, ;
{ "A3", 11.69, 16.54 }, ;
{ "JIS B4", 10.12, 14.33 }, ;
{ "JIS B5", 7.16, 10.12 }, ;
{ "JPOST", 3.94, 5.83 }, ;
{ "JPOSTD", 5.83, 7.87 }, ;
{ "COM10", 4.12, 9.50 }, ;
{ "MONARCH", 3.87, 7.50 }, ;
{ "C5", 6.38, 9.01 }, ;
{ "DL", 4.33, 8.66 }, ;
{ "B5", 6.93, 9.84 }, ;
{ "USSTDFOLD", 14.87, 11.00 } }
__defaultNIL( @_cPageSize, "LETTER" )
IF Empty( _nWidth ) .OR. Empty( _nHeight )
nSize := AScan( aSize, {| arr | arr[ 1 ] == _cPageSize } )
IF nSize == 0
nSize := 1
ENDIF
t_aReport[ PAGESIZE ] := aSize[ nSize ][ 1 ]
nWidth := aSize[ nSize ][ 2 ]
nHeight := aSize[ nSize ][ 3 ]
ELSE
_nWidth := Val( Str( _nWidth ) )
_nHeight := Val( Str( _nHeight ) )
nSize := AScan( aSize, {| arr | ( arr[ 2 ] == _nWidth ) .AND. ( arr[ 3 ] == _nHeight ) } )
IF nSize == 0
nSize := AScan( aSize, {| arr | ( arr[ 3 ] == _nWidth ) .AND. ( arr[ 2 ] == _nHeight ) } )
ENDIF
IF nSize == 0
nSize := 1
ENDIF
t_aReport[ PAGESIZE ] := aSize[ nSize ][ 1 ]
nWidth := _nWidth
nHeight := _nHeight
ENDIF
IF t_aReport[ PAGEORIENT ] == "P"
t_aReport[ PAGEX ] := nWidth * 72
t_aReport[ PAGEY ] := nHeight * 72
ELSE
t_aReport[ PAGEX ] := nHeight * 72
t_aReport[ PAGEY ] := nWidth * 72
ENDIF
RETURN NIL
// -----------------------------------
FUNCTION pdfPageOrient( _cPageOrient )
__defaultNIL( @_cPageOrient, "P" )
t_aReport[ PAGEORIENT ] := _cPageOrient
pdfPageSize( t_aReport[ PAGESIZE ] )
RETURN NIL
// ---------------------------
STATIC FUNCTION pdfR2D( nRow )
RETURN t_aReport[ PAGEY ] - nRow * 72 / t_aReport[ LPI ]
// ---------------------------
STATIC FUNCTION pdfR2M( nRow )
RETURN 25.4 * nRow / t_aReport[ LPI ]
// ------------------------
FUNCTION pdfPageNumber( n )
__defaultNIL( @n, 0 )
IF n > 0
t_aReport[ REPORTPAGE ] := n // NEW !!!
ENDIF
RETURN t_aReport[ REPORTPAGE ]
// ---------------------------
FUNCTION pdfReverse( cString )
RETURN cString + Chr( 255 )
// ----------------------------------------------------------
FUNCTION pdfRJust( cString, nRow, nCol, cUnits, lExact, cId )
LOCAL nLen, nAdj := 1.0, nAt
__defaultNIL( @nRow, t_aReport[ REPORTLINE ] )
__defaultNIL( @cUnits, "R" )
__defaultNIL( @lExact, .F. )
IF t_aReport[ HEADEREDIT ]
RETURN pdfHeader( "PDFRJUST", cId, { cString, nRow, nCol, cUnits, lExact } )
ENDIF
IF ( nAt := At( "#pagenumber#", cString ) ) > 0
cString := Left( cString, nAt - 1 ) + hb_ntos( pdfPageNumber() ) + SubStr( cString, nAt + 12 )
ENDIF
nLen := pdfLen( cString )
IF cUnits == "R"
IF ! lExact
pdfCheckLine( nRow )
nRow := nRow + t_aReport[ PDFTOP ]
ENDIF
ENDIF
pdfAtSay( cString, pdfR2M( nRow ), iif( cUnits == "R", t_aReport[ PDFLEFT ] + ( t_aReport[ PAGEX ] / 72 * 25.4 - 2 * t_aReport[ PDFLEFT ] ) * nCol / t_aReport[ REPORTWIDTH ] - nAdj, nCol ) - nLen, "M", lExact )
RETURN NIL
// -----------------------------------------------
FUNCTION pdfSetFont( _cFont, _nType, _nSize, cId )
__defaultNIL( @_cFont, "Times" )
__defaultNIL( @_nType, 0 )
__defaultNIL( @_nSize, 10 )
IF t_aReport[ HEADEREDIT ]
RETURN pdfHeader( "PDFSETFONT", cId, { _cFont, _nType, _nSize } )
ENDIF
_cFont := Upper( _cFont )
t_aReport[ FONTSIZE ] := _nSize
IF _cFont == "TIMES"
t_aReport[ FONTNAME ] := _nType + 1
ELSEIF _cFont == "HELVETICA"
t_aReport[ FONTNAME ] := _nType + 5
ELSE
t_aReport[ FONTNAME ] := _nType + 9 // 0.04
ENDIF
AAdd( t_aReport[ PAGEFONTS ], t_aReport[ FONTNAME ] )
IF AScan( t_aReport[ FONTS ], {| arr | arr[ 1 ] == t_aReport[ FONTNAME ] } ) == 0
AAdd( t_aReport[ FONTS ], { t_aReport[ FONTNAME ], ++t_aReport[ NEXTOBJ ] } )
ENDIF
RETURN NIL
// ----------------------
FUNCTION pdfSetLPI( _nLpi )
LOCAL cLpi := hb_ntos( _nLpi )
__defaultNIL( @_nLpi, 6 )
cLpi := iif( cLpi $ "1;2;3;4;6;8;12;16;24;48", cLpi, "6" )
t_aReport[ LPI ] := Val( cLpi )
pdfPageSize( t_aReport[ PAGESIZE ] )
RETURN NIL
// ---------------------------
FUNCTION pdfStringB( cString )
cString := StrTran( cString, "(", "\(" )
cString := StrTran( cString, ")", "\)" )
RETURN cString
// ---------------------------------------------------------------------------
FUNCTION pdfTextCount( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits )
RETURN pdfText( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits, .F. )
// ------------------------------------------------------------------------------
FUNCTION pdfText( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits, cColor, lPrint )
LOCAL cDelim := Chr( 0 ) + Chr( 9 ) + Chr( 10 ) + Chr( 13 ) + Chr( 26 ) + Chr( 32 ) + Chr( 138 ) + Chr( 141 )
LOCAL nI, cTemp, cToken, k, nL, nRow, nLines, nLineLen, nStart
LOCAL lParagraph, nSpace, nNew, nTokenLen, nCRLF, nTokens, nLen
__defaultNIL( @nTab, -1 )
__defaultNIL( @cUnits, "R" )
__defaultNIL( @nJustify, 4 ) // justify
__defaultNIL( @lPrint, .T. )
__defaultNIL( @cColor, "" )
IF cUnits == "M"
nTop := pdfM2R( nTop )
ELSEIF cUnits == "R"
nLeft := pdfX2M( pdfM2X( t_aReport[ PDFLEFT ] ) + ;
nLeft * 100.00 / t_aReport[ REPORTWIDTH ] * ;
( t_aReport[ PAGEX ] - pdfM2X( t_aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 )
ENDIF
t_aReport[ REPORTLINE ] := nTop - 1
nSpace := pdfLen( " " )
nLines := 0
nCRLF := 0
nNew := nTab
cString := AllTrim( cString )
nTokens := NumToken( cString, cDelim )
nStart := 1
IF nJustify == 1 .OR. nJustify == 4
nLeft := nLeft
ELSEIF nJustify == 2
nLeft := nLeft - nLength / 2
ELSEIF nJustify == 3
nLeft := nLeft - nLength
ENDIF
nL := nLeft
nL += nNew * nSpace // first always paragraph
nLineLen := nSpace * nNew - nSpace
lParagraph := .T.
nI := 1
WHILE nI <= nTokens
cToken := Token( cString, cDelim, nI )
nTokenLen := pdfLen( cToken )
nLen := Len( cToken )
IF nLineLen + nSpace + nTokenLen > nLength
IF nStart == nI // single word > nLength
k := 1
WHILE k <= nLen
cTemp := ""
nLineLen := 0.00
nL := nLeft
IF lParagraph
nLineLen += nSpace * nNew
IF nJustify != 2
nL += nSpace * nNew
ENDIF
lParagraph := .F.
ENDIF
IF nJustify == 2
nL := nLeft + ( nLength - pdfLen( cTemp ) ) / 2
ELSEIF nJustify == 3
nL := nLeft + nLength - pdfLen( cTemp )
ENDIF
WHILE k <= nLen .AND. ( ( nLineLen += pdfLen( SubStr( cToken, k, 1 ) ) ) <= nLength )
nLineLen += pdfLen( SubStr( cToken, k, 1 ) )
cTemp += SubStr( cToken, k, 1 )
++k
ENDDO
IF Empty( cTemp ) // single character > nlength
cTemp := SubStr( cToken, k, 1 )
++k
ENDIF
++nLines
IF lPrint
nRow := pdfNewLine( 1 )
// version 0.02
pdfAtSay( cColor + cTemp, pdfR2M( nRow + t_aReport[ PDFTOP ] ), nL, "M" )
ENDIF
ENDDO
++nI
nStart := nI
ELSE
pdfTextPrint( nI - 1, nLeft, @lParagraph, nJustify, nSpace, nNew, nLength, @nLineLen, @nLines, @nStart, cString, cDelim, cColor, lPrint )
ENDIF
ELSEIF ( nI == nTokens ) .OR. ( nI < nTokens .AND. ( nCRLF := pdfTextNextPara( cString, cDelim, nI ) ) > 0 )
IF nI == nTokens
nLineLen += nSpace + nTokenLen
ENDIF
pdfTextPrint( nI, nLeft, @lParagraph, nJustify, nSpace, nNew, nLength, @nLineLen, @nLines, @nStart, cString, cDelim, cColor, lPrint )
++nI
IF nCRLF > 1
nLines += nCRLF - 1
ENDIF
IF lPrint
/* nRow := */pdfNewLine( nCRLF - 1 )
ENDIF
ELSE
nLineLen += nSpace + nTokenLen
++nI
ENDIF
ENDDO
RETURN nLines
// --------------------------------------------------------------------------------------------------------------------------------------
STATIC FUNCTION pdfTextPrint( nI, nLeft, lParagraph, nJustify, nSpace, nNew, nLength, nLineLen, nLines, nStart, cString, cDelim, cColor, lPrint )
LOCAL nFinish, nL, nB, nJ, cToken, nRow
nFinish := nI
nL := nLeft
IF lParagraph
IF nJustify != 2
nL += nSpace * nNew
ENDIF
ENDIF
IF nJustify == 3 // right
nL += nLength - nLineLen
ELSEIF nJustify == 2 // center
nL += ( nLength - nLineLen ) / 2
ENDIF
++nLines
IF lPrint
nRow := pdfNewLine( 1 )
ENDIF
nB := nSpace
IF nJustify == 4
nB := ( nLength - nLineLen + ( nFinish - nStart ) * nSpace ) / ( nFinish - nStart )
ENDIF
FOR nJ := nStart TO nFinish
cToken := Token( cString, cDelim, nJ )
IF lPrint
// version 0.02
pdfAtSay( cColor + cToken, pdfR2M( nRow + t_aReport[ PDFTOP ] ), nL, "M" )
ENDIF
nL += pdfLen ( cToken ) + nB
NEXT
nStart := nFinish + 1
lParagraph := .F.
nLineLen := 0.00
nLineLen += nSpace * nNew
RETURN NIL
// ---------------------------------------------------
STATIC FUNCTION pdfTextNextPara( cString, cDelim, nI )
LOCAL nAt, cAt, nCRLF, nNew, nRat, nRet := 0
// check if next spaces paragraph(s)
nAt := AtToken( cString, cDelim, nI ) + Len( Token( cString, cDelim, nI ) )
cAt := SubStr( cString, nAt, AtToken( cString, cDelim, nI + 1 ) - nAt )
nCRLF := NumAt( Chr( 13 ) + Chr( 10 ), cAt )
nRat := RAt( Chr( 13 ) + Chr( 10 ), cAt )
nNew := Len( cAt ) - nRat - iif( nRat > 0, 1, 0 )
IF nCRLF > 1 .OR. ( nCRLF == 1 .AND. nNew > 0 )
nRet := nCRLF
ENDIF
RETURN nRet
// -----------------------------
FUNCTION pdfUnderline( cString )
RETURN cString + Chr( 254 )
// ------------------------
STATIC FUNCTION pdfX2M( n )
RETURN n * 25.4 / 72
// --------------------------------
STATIC FUNCTION TimeAsAMPM( cTime )
IF Val( cTime ) < 12
cTime += " am"
ELSEIF Val( cTime ) == 12
cTime += " pm"
ELSE
cTime := Str( Val( cTime ) - 12, 2 ) + SubStr( cTime, 3 ) + " pm"
ENDIF
cTime := Left( cTime, 5 ) + SubStr( cTime, 10 )
RETURN cTime
FUNCTION pdfOpenHeader( cFile )
LOCAL nAt // , nErrorCode:=0
__defaultNIL( @cFile, "" )
IF ! Empty( cFile )
cFile := AllTrim( cFile )
IF Len( cFile ) > 12 .OR. ;
At( " ", cFile ) > 0 .OR. ;
( At( " ", cFile ) == 0 .AND. Len( cFile ) > 8 ) .OR. ;
( ( nAt := At( ".", cFile ) ) > 0 .AND. Len( SubStr( cFile, nAt + 1 ) ) > 3 )
COPY File ( cFile ) TO temp.tmp
cFile := "temp.tmp"
ENDIF
// t_aReport[ HEADER ] := ft_RestArr( cFile, @nErrorCode )
t_aReport[ HEADER ] := File2Array( cFile )
ELSE
t_aReport[ HEADER ] := {}
ENDIF
t_aReport[ MARGINS ] := .T.
RETURN NIL
FUNCTION pdfEditOnHeader()
t_aReport[ HEADEREDIT ] := .T.
t_aReport[ MARGINS ] := .T.
RETURN NIL
FUNCTION pdfEditOffHeader()
t_aReport[ HEADEREDIT ] := .F.
t_aReport[ MARGINS ] := .T.
RETURN NIL
FUNCTION pdfCloseHeader()
t_aReport[ HEADER ] := {}
t_aReport[ MARGINS ] := .F.
RETURN NIL
FUNCTION pdfDeleteHeader( cId )
LOCAL nRet := -1, nId
cId := Upper( cId )
nId := AScan( t_aReport[ HEADER ], {| arr | arr[ 3 ] == cId } )
IF nId > 0
nRet := Len( t_aReport[ HEADER ] ) - 1
ADel( t_aReport[ HEADER ], nId )
ASize( t_aReport[ HEADER ], nRet )
t_aReport[ MARGINS ] := .T.
ENDIF
RETURN nRet
FUNCTION pdfEnableHeader( cId )
LOCAL nId
cId := Upper( cId )
nId := AScan( t_aReport[ HEADER ], {| arr | arr[ 3 ] == cId } )
IF nId > 0
t_aReport[ HEADER ][ nId ][ 1 ] := .T.
t_aReport[ MARGINS ] := .T.
ENDIF
RETURN NIL
FUNCTION pdfDisableHeader( cId )
LOCAL nId
cId := Upper( cId )
nId := AScan( t_aReport[ HEADER ], {| arr | arr[ 3 ] == cId } )
IF nId > 0
t_aReport[ HEADER ][ nId ][ 1 ] := .F.
t_aReport[ MARGINS ] := .T.
ENDIF
RETURN NIL
FUNCTION pdfSaveHeader( cFile )
Array2File( "temp.tmp", t_aReport[ HEADER ] )
COPY file temp.tmp to ( cFile )
RETURN NIL
FUNCTION pdfHeader( cFunction, cId, arr )
LOCAL nId, nI, nLen, nIdLen
nId := 0
IF ! Empty( cId )
cId := Upper( cId )
nId := AScan( t_aReport[ HEADER ], {| arr | arr[ 3 ] == cId } )
ENDIF
IF nId == 0
nLen := Len( t_aReport[ HEADER ] )
IF Empty( cId )
cId := cFunction
nIdLen := Len( cId )
FOR nI := 1 TO nLen
IF t_aReport[ HEADER ][ nI ][ 2 ] == cId
IF Val( SubStr( t_aReport[ HEADER ][ nI ][ 3 ], nIdLen + 1 ) ) > nId
nId := Val( SubStr( t_aReport[ HEADER ][ nI ][ 3 ], nIdLen + 1 ) )
ENDIF
ENDIF
NEXT
++nId
cId += hb_ntos( nId )
ENDIF
AAdd( t_aReport[ HEADER ], { .T., cFunction, cId } )
++nLen
FOR nI := 1 TO Len( arr )
AAdd( t_aReport[ HEADER ][ nLen ], arr[ nI ] )
NEXT
ELSE
ASize( t_aReport[ HEADER ][ nId ], 3 )
FOR nI := 1 TO Len( arr )
AAdd( t_aReport[ HEADER ][ nId ], arr[ nI ] )
NEXT
ENDIF
RETURN cId
FUNCTION pdfDrawHeader()
LOCAL nI, _nFont, _nSize, nLen := Len( t_aReport[ HEADER ] )
IF nLen > 0
// save font
_nFont := t_aReport[ FONTNAME ]
_nSize := t_aReport[ FONTSIZE ]
FOR nI := 1 TO nLen
IF t_aReport[ HEADER ][ nI ][ 1 ] // enabled
DO CASE
CASE t_aReport[ HEADER ][ nI ][ 2 ] == "PDFATSAY"
pdfAtSay( t_aReport[ HEADER ][ nI ][ 4 ], t_aReport[ HEADER ][ nI ][ 5 ], t_aReport[ HEADER ][ nI ][ 6 ], t_aReport[ HEADER ][ nI ][ 7 ], t_aReport[ HEADER ][ nI ][ 8 ], t_aReport[ HEADER ][ nI ][ 3 ] )
CASE t_aReport[ HEADER ][ nI ][ 2 ] == "PDFCENTER"
pdfCenter( t_aReport[ HEADER ][ nI ][ 4 ], t_aReport[ HEADER ][ nI ][ 5 ], t_aReport[ HEADER ][ nI ][ 6 ], t_aReport[ HEADER ][ nI ][ 7 ], t_aReport[ HEADER ][ nI ][ 8 ], t_aReport[ HEADER ][ nI ][ 3 ] )
CASE t_aReport[ HEADER ][ nI ][ 2 ] == "PDFRJUST"
pdfRJust( t_aReport[ HEADER ][ nI ][ 4 ], t_aReport[ HEADER ][ nI ][ 5 ], t_aReport[ HEADER ][ nI ][ 6 ], t_aReport[ HEADER ][ nI ][ 7 ], t_aReport[ HEADER ][ nI ][ 8 ], t_aReport[ HEADER ][ nI ][ 3 ] )
CASE t_aReport[ HEADER ][ nI ][ 2 ] == "PDFBOX"
pdfBox( t_aReport[ HEADER ][ nI ][ 4 ], t_aReport[ HEADER ][ nI ][ 5 ], t_aReport[ HEADER ][ nI ][ 6 ], t_aReport[ HEADER ][ nI ][ 7 ], t_aReport[ HEADER ][ nI ][ 8 ], t_aReport[ HEADER ][ nI ][ 9 ], t_aReport[ HEADER ][ nI ][ 10 ], t_aReport[ HEADER ][ nI ][ 3 ] )
CASE t_aReport[ HEADER ][ nI ][ 2 ] == "PDFSETFONT"
pdfSetFont( t_aReport[ HEADER ][ nI ][ 4 ], t_aReport[ HEADER ][ nI ][ 5 ], t_aReport[ HEADER ][ nI ][ 6 ], t_aReport[ HEADER ][ nI ][ 3 ] )
CASE t_aReport[ HEADER ][ nI ][ 2 ] == "PDFIMAGE"
pdfImage( t_aReport[ HEADER ][ nI ][ 4 ], t_aReport[ HEADER ][ nI ][ 5 ], t_aReport[ HEADER ][ nI ][ 6 ], t_aReport[ HEADER ][ nI ][ 7 ], t_aReport[ HEADER ][ nI ][ 8 ], t_aReport[ HEADER ][ nI ][ 9 ], t_aReport[ HEADER ][ nI ][ 3 ] )
ENDCASE
ENDIF
NEXT
t_aReport[ FONTNAME ] := _nFont
t_aReport[ FONTSIZE ] := _nSize
IF t_aReport[ MARGINS ]
pdfMargins()
ENDIF
ELSE
IF t_aReport[ MARGINS ]
t_aReport[ PDFTOP ] := 1 // top
t_aReport[ PDFLEFT ] := 10 // left & right
t_aReport[ PDFBOTTOM ] := t_aReport[ PAGEY ] / 72 * t_aReport[ LPI ] - 1 // bottom, default "LETTER", "P", 6
t_aReport[ MARGINS ] := .F.
ENDIF
ENDIF
RETURN NIL
FUNCTION pdfMargins( nTop, nLeft, nBottom )
LOCAL nI, nLen := Len( t_aReport[ HEADER ] ), nTemp, aTemp, nHeight
// version 0.07 begin
__defaultNIL( @nTop, 1 )
__defaultNIL( @nLeft, 10 )
// bottom, default "LETTER", "P", 6
__defaultNIL( @nBottom, t_aReport[ PAGEY ] / 72 * t_aReport[ LPI ] - 1 )
t_aReport[ PDFTOP ] := nTop
t_aReport[ PDFLEFT ] := nLeft
t_aReport[ PDFBOTTOM ] := nBottom
// version 0.07 end
FOR nI := 1 TO nLen
IF t_aReport[ HEADER ][ nI ][ 1 ] // enabled
IF t_aReport[ HEADER ][ nI ][ 2 ] == "PDFSETFONT"
ELSEIF t_aReport[ HEADER ][ nI ][ 2 ] == "PDFIMAGE"
IF t_aReport[ HEADER ][ nI ][ 8 ] == 0 // picture in header, first at all, not at any page yet
aTemp := pdfImageInfo( t_aReport[ HEADER ][ nI ][ 4 ] )
nHeight := aTemp[ IMAGE_HEIGHT ] / aTemp[ IMAGE_YRES ] * 25.4
IF t_aReport[ HEADER ][ nI ][ 7 ] == "D"
nHeight := pdfM2X( nHeight )
ENDIF
ELSE
nHeight := t_aReport[ HEADER ][ nI ][ 8 ]
ENDIF
IF t_aReport[ HEADER ][ nI ][ 7 ] == "M"
nTemp := t_aReport[ PAGEY ] / 72 * 25.4 / 2
IF t_aReport[ HEADER ][ nI ][ 5 ] < nTemp
nTemp := ( t_aReport[ HEADER ][ nI ][ 5 ] + nHeight ) * t_aReport[ LPI ] / 25.4 // top
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ELSE
nTemp := t_aReport[ HEADER ][ nI ][ 5 ] * t_aReport[ LPI ] / 25.4 // top
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 7 ] == "D"
nTemp := t_aReport[ PAGEY ] / 2
IF t_aReport[ HEADER ][ nI ][ 5 ] < nTemp
nTemp := ( t_aReport[ HEADER ][ nI ][ 5 ] + nHeight ) * t_aReport[ LPI ] / 72 // top
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ELSE
nTemp := t_aReport[ HEADER ][ nI ][ 5 ] * t_aReport[ LPI ] / 72 // top
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ENDIF
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 2 ] == "PDFBOX"
IF t_aReport[ HEADER ][ nI ][ 10 ] == "M"
nTemp := t_aReport[ PAGEY ] / 72 * 25.4 / 2
IF t_aReport[ HEADER ][ nI ][ 4 ] < nTemp .AND. ;
t_aReport[ HEADER ][ nI ][ 6 ] < nTemp
nTemp := t_aReport[ HEADER ][ nI ][ 6 ] * t_aReport[ LPI ] / 25.4 // top
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 4 ] < nTemp .AND. ;
t_aReport[ HEADER ][ nI ][ 6 ] > nTemp
nTemp := ( t_aReport[ HEADER ][ nI ][ 4 ] + t_aReport[ HEADER ][ nI ][ 8 ] ) * t_aReport[ LPI ] / 25.4 // top
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
nTemp := ( t_aReport[ HEADER ][ nI ][ 6 ] - t_aReport[ HEADER ][ nI ][ 8 ] ) * t_aReport[ LPI ] / 25.4 // top
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 4 ] > nTemp .AND. ;
t_aReport[ HEADER ][ nI ][ 6 ] > nTemp
nTemp := t_aReport[ HEADER ][ nI ][ 4 ] * t_aReport[ LPI ] / 25.4 // top
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 10 ] == "D"
nTemp := t_aReport[ PAGEY ] / 2
IF t_aReport[ HEADER ][ nI ][ 4 ] < nTemp .AND. ;
t_aReport[ HEADER ][ nI ][ 6 ] < nTemp
nTemp := t_aReport[ HEADER ][ nI ][ 6 ] / t_aReport[ LPI ] // top
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 4 ] < nTemp .AND. ;
t_aReport[ HEADER ][ nI ][ 6 ] > nTemp
nTemp := ( t_aReport[ HEADER ][ nI ][ 4 ] + t_aReport[ HEADER ][ nI ][ 8 ] ) / t_aReport[ LPI ] // top
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
nTemp := ( t_aReport[ HEADER ][ nI ][ 6 ] - t_aReport[ HEADER ][ nI ][ 8 ] ) / t_aReport[ LPI ] // top
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 4 ] > nTemp .AND. ;
t_aReport[ HEADER ][ nI ][ 6 ] > nTemp
nTemp := t_aReport[ HEADER ][ nI ][ 4 ] / t_aReport[ LPI ] // top
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ENDIF
ENDIF
ELSE
IF t_aReport[ HEADER ][ nI ][ 7 ] == "R"
nTemp := t_aReport[ HEADER ][ nI ][ 5 ] // top
IF t_aReport[ HEADER ][ nI ][ 5 ] > t_aReport[ PAGEY ] / 72 * t_aReport[ LPI ] / 2
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ELSE
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 7 ] == "M"
nTemp := t_aReport[ HEADER ][ nI ][ 5 ] * t_aReport[ LPI ] / 25.4 // top
IF t_aReport[ HEADER ][ nI ][ 5 ] > t_aReport[ PAGEY ] / 72 * 25.4 / 2
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ELSE
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ENDIF
ELSEIF t_aReport[ HEADER ][ nI ][ 7 ] == "D"
nTemp := t_aReport[ HEADER ][ nI ][ 5 ] / t_aReport[ LPI ] // top
IF t_aReport[ HEADER ][ nI ][ 5 ] > t_aReport[ PAGEY ] / 2
IF nTemp < t_aReport[ PDFBOTTOM ]
t_aReport[ PDFBOTTOM ] := nTemp
ENDIF
ELSE
IF nTemp > t_aReport[ PDFTOP ]
t_aReport[ PDFTOP ] := nTemp
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
NEXT
t_aReport[ MARGINS ] := .F.
RETURN NIL
FUNCTION pdfCreateHeader( _file, _size, _orient, _lpi, _width )
LOCAL t_aReportStyle := { ;
{ 1 , 2 , 3 , 4 , 5 , 6 }, ; // "Default"
{ 2.475, 4.0, 4.9, 6.4, 7.5, 64.0 }, ; // "P6"
{ 3.3 , 5.4, 6.5, 8.6, 10.0, 85.35 }, ; // "P8"
{ 2.475, 4.0, 4.9, 6.4, 7.5, 48.9 }, ; // "L6"
{ 3.3 , 5.4, 6.5, 8.6, 10.0, 65.2 }, ; // "L8"
{ 2.475, 4.0, 4.9, 6.4, 7.5, 82.0 }, ; // "P6"
{ 3.3 , 5.4, 6.5, 8.6, 10.0, 109.35 } } // "P8"
LOCAL nStyle := 1, nAdd := 0.00
__defaultNIL( @_size, t_aReport[ PAGESIZE ] )
__defaultNIL( @_orient, t_aReport[ PAGEORIENT ] )
__defaultNIL( @_lpi, t_aReport[ LPI ] )
__defaultNIL( @_width, 200 )
IF _size == "LETTER"
IF _orient == "P"
IF _lpi == 6
nStyle := 2
ELSEIF _lpi == 8
nStyle := 3
ENDIF
ELSEIF _orient == "L"
IF _lpi == 6
nStyle := 4
ELSEIF _lpi == 8
nStyle := 5
ENDIF
ENDIF
ELSEIF _size == "LEGAL"
IF _orient == "P"
IF _lpi == 6
nStyle := 6
ELSEIF _lpi == 8
nStyle := 7
ENDIF
ELSEIF _orient == "L"
IF _lpi == 6
nStyle := 4
ELSEIF _lpi == 8
nStyle := 5
ENDIF
ENDIF
ENDIF
pdfEditOnHeader()
IF _size == "LEGAL"
nAdd := 76.2
ENDIF
IF _orient == "P"
pdfBox( 5.0, 5.0, 274.0 + nAdd, 210.0, 1.0 )
pdfBox( 6.5, 6.5, 272.5 + nAdd, 208.5, 0.5 )
pdfBox( 11.5, 9.5, 22.0, 205.5, 0.5, 5 )
pdfBox( 23.0, 9.5, 33.5, 205.5, 0.5, 5 )
pdfBox( 34.5, 9.5, 267.5 + nAdd, 205.5, 0.5 )
ELSE
pdfBox( 5.0, 5.0, 210.0, 274.0 + nAdd, 1.0 )
pdfBox( 6.5, 6.5, 208.5, 272.5 + nAdd, 0.5 )
pdfBox( 11.5, 9.5, 22.0, 269.5 + nAdd, 0.5, 5 )
pdfBox( 23.0, 9.5, 33.5, 269.5 + nAdd, 0.5, 5 )
pdfBox( 34.5, 9.5, 203.5, 269.5 + nAdd, 0.5 )
ENDIF
pdfSetFont( "Helvetica", BOLD, 10 ) // 0.04
pdfAtSay( "Test Line 1", t_aReportStyle[ nStyle ][ 1 ], 1, "R", .T. )
pdfSetFont( "Times", BOLD, 18 )
pdfCenter( "Test Line 2", t_aReportStyle[ nStyle ][ 2 ],, "R", .T. )
pdfSetFont( "Times", BOLD, 12 )
pdfCenter( "Test Line 3", t_aReportStyle[ nStyle ][ 3 ],, "R", .T. )
pdfSetFont( "Helvetica", BOLD, 10 ) // 0.04
pdfAtSay( "Test Line 4", t_aReportStyle[ nStyle ][ 4 ], 1, "R", .T. )
pdfSetFont( "Helvetica", BOLD, 10 ) // 0.04
pdfAtSay( "Test Line 5", t_aReportStyle[ nStyle ][ 5 ], 1, "R", .T. )
pdfAtSay( DToC( Date() ) + " " + TimeAsAMPM( Time() ), t_aReportStyle[ nStyle ][ 6 ], 1, "R", .T. )
pdfRJust( "Page: #pagenumber#", t_aReportStyle[ nStyle ][ 6 ], t_aReport[ REPORTWIDTH ], "R", .T. )
pdfEditOffHeader()
pdfSaveHeader( _file )
RETURN NIL
FUNCTION pdfImageInfo( cFile )
LOCAL cTemp := Upper( SubStr( cFile, RAt( ".", cFile ) + 1 ) ), aTemp := {}
DO CASE
CASE cTemp == "TIF"
aTemp := pdfTIFFInfo( cFile )
CASE cTemp == "JPG"
aTemp := pdfJPEGInfo( cFile )
ENDCASE
RETURN aTemp
FUNCTION pdfTIFFInfo( cFile )
LOCAL c40 := Chr( 0 ) + Chr( 0 ) + Chr( 0 ) + Chr( 0 )
// local aType := {"BYTE","ASCII","SHORT","LONG","RATIONAL","SBYTE","UNDEFINED","SSHORT","SLONG","SRATIONAL","FLOAT","DOUBLE"}
LOCAL aCount := { 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 }
LOCAL nTemp, nHandle, cValues, c2, nFieldType, nCount, nPos, nTag, nValues
LOCAL nOffset, cTemp, cIFDNext, nIFD, nFields, nn// , cTag, nPages
LOCAL nWidth := 0, nHeight := 0, nBits := 0, nFrom := 0, nLength := 0, xRes := 0, yRes := 0, aTemp := {}, nSpace
nHandle := FOpen( cFile )
c2 := " "
FRead( nHandle, @c2, 2 )
FRead( nHandle, @c2, 2 )
cIFDNext := " "
FRead( nHandle, @cIFDNext, 4 )
cTemp := Space( 12 )
// nPages := 0
WHILE !( cIFDNext == c40 ) // read IFD's
nIFD := Bin2L( cIFDNext )
FSeek( nHandle, nIFD )
// ? "*** IFD " + hb_ntos( ++nPages )
FRead( nHandle, @c2, 2 )
nFields := Bin2I( c2 )
FOR nn := 1 TO nFields
FRead( nHandle, @cTemp, 12 )
nTag := Bin2W( SubStr( cTemp, 1, 2 ) )
nFieldType := Bin2W( SubStr( cTemp, 3, 2 ) )
/*
1 = BYTE 8-bit unsigned integer.
2 = ASCII 8-bit byte that contains a 7-bit ASCII code; the last byte
must be NUL (binary zero).
3 = SHORT 16-bit (2-byte) unsigned integer.
4 = LONG 32-bit (4-byte) unsigned integer.
5 = RATIONAL Two LONGs: the first represents the numerator of a
fraction; the second, the denominator.
In TIFF 6.0, some new field types have been defined:
6 = SBYTE An 8-bit signed (twos-complement) integer.
7 = UNDEFINED An 8-bit byte that may contain anything, depending on
the definition of the field.
8 = SSHORT A 16-bit (2-byte) signed (twos-complement) integer.
9 = SLONG A 32-bit (4-byte) signed (twos-complement) integer.
10 = SRATIONAL Two SLONG's: the first represents the numerator of a
fraction, the second the denominator.
11 = FLOAT Single precision (4-byte) IEEE format.
12 = DOUBLE Double precision (8-byte) IEEE format.
*/
nCount := Bin2L( SubStr( cTemp, 5, 4 ) )
nOffset := Bin2L( SubStr( cTemp, 9, 4 ) )
IF nCount > 1 .OR. nFieldType == RATIONAL .OR. nFieldType == SRATIONAL
nPos := filepos( nHandle )
FSeek( nHandle, nOffset )
nValues := nCount * aCount[ nFieldType ]
cValues := Space( nValues )
FRead( nHandle, @cValues, nValues )
FSeek( nHandle, nPos )
ELSE
cValues := SubStr( cTemp, 9, 4 )
ENDIF
IF nFieldType == ASCII
--nCount
ENDIF
// ? "Tag"
// ?? " " + PadR( nTag, 10 )
// cTag := ""
DO CASE
CASE nTag == 256
/*
ImageWidth
Tag = 256 (100.H)
Type = SHORT or LONG
The number of columns in the image, i.e., the number of pixels per scanline.
*/
// ?? "ImageWidth"
// cTag := "ImageWidth"
#if 0
IF nFieldType != SHORT .AND. nFieldType != LONG
Alert( "Wrong Type for ImageWidth" )
ENDIF
#endif
IF nFieldType == SHORT
nWidth := Bin2W( SubStr( cValues, 1, 2 ) )
ELSEIF nFieldType == LONG
nWidth := Bin2L( SubStr( cValues, 1, 4 ) )
ENDIF
CASE nTag == 257
/*
ImageLength
Tag = 257 (101.H)
Type = SHORT or LONG
The number of rows (sometimes described as scanlines) in the image.
*/
// ?? "ImageLength"
// cTag := "ImageLength"
#if 0
IF nFieldType != SHORT .AND. nFieldType != LONG
Alert( "Wrong Type for ImageLength" )
ENDIF
#endif
IF nFieldType == SHORT
nHeight := Bin2W( SubStr( cValues, 1, 2 ) )
ELSEIF nFieldType == LONG
nHeight := Bin2L( SubStr( cValues, 1, 4 ) )
ENDIF
CASE nTag == 258
/*
BitsPerSample
Tag = 258 (102.H)
Type = SHORT
The number of bits per component.
Allowable values for Baseline TIFF grayscale images are 4 and 8, allowing either
16 or 256 distinct shades of gray.
*/
// ?? "BitsPerSample"
// cTag := "BitsPerSample"
nTemp := 0
IF nFieldType == SHORT
nTemp := Bin2W( cValues )
ELSE
// Alert( "Wrong Type for BitsPerSample" )
ENDIF
nBits := nTemp
// IF nTemp != 4 .AND. nTemp != 8
// Alert( "Wrong Value for BitsPerSample" )
// ENDIF
CASE nTag == 259
/*
Compression
Tag = 259 (103.H)
Type = SHORT
Values:
1 = No compression, but pack data into bytes as tightly as possible, leaving no unused
bits (except at the end of a row). The component values are stored as an array of
type BYTE. Each scan line (row) is padded to the next BYTE boundary.
2 = CCITT Group 3 1-Dimensional Modified Huffman run length encoding. See
Section 10 for a description of Modified Huffman Compression.
32773 = PackBits compression, a simple byte-oriented run length scheme. See the
PackBits section for details.
Data compression applies only to raster image data. All other TIFF fields are
unaffected.
Baseline TIFF readers must handle all three compression schemes.
*/
// ?? "Compression"
// cTag := "Compression"
/*nTemp := 0
IF nFieldType == SHORT
nTemp := Bin2W( cValues )
ELSE
// Alert( "Wrong Type for Compression" )
ENDIF*/
// IF nTemp != 1 .AND. nTemp != 2 .AND. nTemp != 32773
// Alert( "Wrong Value for Compression" )
// ENDIF
CASE nTag == 262
/*
PhotometricInterpretation
Tag = 262 (106.H)
Type = SHORT
Values:
0 = WhiteIsZero. For bilevel and grayscale images: 0 is imaged as white. The maxi-mum
value is imaged as black. This is the normal value for Compression=2.
1 = BlackIsZero. For bilevel and grayscale images: 0 is imaged as black. The maxi-mum
value is imaged as white. If this value is specified for Compression=2, the
image should display and print reversed.
*/
// ?? "PhotometricInterpretation"
// cTag := "PhotometricInterpretation"
nTemp := -1
IF nFieldType == SHORT
nTemp := Bin2W( cValues )
ELSE
// Alert( "Wrong Type for PhotometricInterpretation" )
ENDIF
IF nTemp != 0 .AND. nTemp != 1 .AND. nTemp != 2 .AND. nTemp != 3
// Alert( "Wrong Value for PhotometricInterpretation" )
ENDIF
CASE nTag == 264
/*
CellWidth
The width of the dithering or halftoning matrix used to create a dithered or
halftoned bilevel file.Tag = 264 (108.H)
Type = SHORT
N = 1
No default. See also Threshholding.
*/
// ?? "CellWidth"
// cTag := "CellWidth"
IF nFieldType != SHORT
// Alert( "Wrong Type for CellWidth" )
ENDIF
CASE nTag == 265
/*
CellLength
The length of the dithering or halftoning matrix used to create a dithered or
halftoned bilevel file.
Tag = 265 (109.H)
Type = SHORT
N = 1
This field should only be present if Threshholding = 2
No default. See also Threshholding.
*/
// ?? "CellLength"
// cTag := "CellLength"
IF nFieldType != SHORT
// Alert( "Wrong Type for CellLength" )
ENDIF
CASE nTag == 266
/*
FillOrder
The logical order of bits within a byte.
Tag = 266 (10A.H)
Type = SHORT
N = 1
*/
// ?? "FillOrder"
// cTag := "FillOrder"
IF nFieldType != SHORT
// Alert( "Wrong Type for FillOrder" )
ENDIF
CASE nTag == 273
/*
StripOffsets
Tag = 273 (111.H)
Type = SHORT or LONG
For each strip, the byte offset of that strip.
*/
// ?? "StripOffsets"
// cTag := "StripOffsets"
IF nFieldType != SHORT .AND. nFieldType != LONG
// Alert( "Wrong Type for StripOffsets" )
ENDIF
IF nFieldType == SHORT
nFrom := Bin2W( SubStr( cValues, 1, 2 ) )
ELSEIF nFieldType == LONG
nFrom := Bin2L( SubStr( cValues, 1, 4 ) )
ENDIF
CASE nTag == 277
/*
SamplesPerPixel
Tag = 277 (115.H)
Type = SHORT
The number of components per pixel. This number is 3 for RGB images, unless
extra samples are present. See the ExtraSamples field for further information.
*/
// ?? "SamplesPerPixel"
// cTag := "SamplesPerPixel"
IF nFieldType != SHORT
// Alert( "Wrong Type for SamplesPerPixel" )
ENDIF
CASE nTag == 278
/*
RowsPerStrip
Tag = 278 (116.H)
Type = SHORT or LONG
The number of rows in each strip (except possibly the last strip.)
For example, if ImageLength is 24, and RowsPerStrip is 10, then there are 3
strips, with 10 rows in the first strip, 10 rows in the second strip, and 4 rows in the
third strip. (The data in the last strip is not padded with 6 extra rows of dummy
data.)
*/
// ?? "RowsPerStrip"
// cTag := "RowsPerStrip"
IF nFieldType != SHORT .AND. nFieldType != LONG
// Alert( "Wrong Type for RowsPerStrip" )
ENDIF
CASE nTag == 279
/*
StripByteCounts
Tag = 279 (117.H)
Type = SHORT or LONG
For each strip, the number of bytes in that strip after any compression.
*/
// ?? "StripByteCounts"
// cTag := "StripByteCounts"
IF nFieldType != SHORT .AND. nFieldType != LONG
// Alert( "Wrong Type for StripByteCounts" )
ENDIF
IF nFieldType == SHORT
nLength := Bin2W( SubStr( cValues, 1, 2 ) )
ELSEIF nFieldType == LONG
nLength := Bin2L( SubStr( cValues, 1, 4 ) )
ENDIF
nLength *= nCount // Count all strips !!!
CASE nTag == 282
/*
XResolution
Tag = 282 (11A.H)
Type = RATIONAL
The number of pixels per ResolutionUnit in the ImageWidth (typically, horizontal
- see Orientation) direction.
*/
// ?? "XResolution"
// cTag := "XResolution"
IF nFieldType != RATIONAL
// Alert( "Wrong Type for XResolution" )
ENDIF
xRes := Bin2L( SubStr( cValues, 1, 4 ) )
CASE nTag == 283
/*
YResolution
Tag = 283 (11B.H)
Type = RATIONAL
The number of pixels per ResolutionUnit in the ImageLength (typically, vertical)
direction.
*/
// ?? "YResolution"
// cTag := "YResolution"
IF nFieldType != RATIONAL
// Alert( "Wrong Type for YResolution" )
ENDIF
yRes := Bin2L( SubStr( cValues, 1, 4 ) )
CASE nTag == 284
// ?? "PlanarConfiguration"
// cTag := "PlanarConfiguration"
IF nFieldType != SHORT
// Alert( "Wrong Type for PlanarConfiguration" )
ENDIF
CASE nTag == 288
/*
FreeOffsets
For each string of contiguous unused bytes in a TIFF file, the byte offset of the
string.
Tag = 288 (120.H)
Type = LONG
Not recommended for general interchange.
See also FreeByteCounts.
*/
// ?? "FreeOffsets"
// cTag := "FreeOffsets"
IF nFieldType != LONG
// Alert( "Wrong Type for FreeOffsets" )
ENDIF
CASE nTag == 289
/*
FreeByteCounts
For each string of contiguous unused bytes in a TIFF file, the number of bytes in
the string.
Tag = 289 (121.H)
Type = LONG
Not recommended for general interchange.
See also FreeOffsets.
*/
// ?? "FreeByteCounts"
// cTag := "FreeByteCounts"
IF nFieldType != LONG
// Alert( "Wrong Type for FreeByteCounts" )
ENDIF
CASE nTag == 296
/*
ResolutionUnit
Tag = 296 (128.H)
Type = SHORT
Values:
1 = No absolute unit of measurement. Used for images that may have a non-square
aspect ratio but no meaningful absolute dimensions.
2 = Inch.
3 = Centimeter.
Default = 2 (inch).
*/
// ?? "ResolutionUnit"
// cTag := "ResolutionUnit"
nTemp := 0
IF nFieldType == SHORT
nTemp := Bin2W( cValues )
ELSE
// Alert( "Wrong Type for ResolutionUnit" )
ENDIF
IF nTemp != 1 .AND. nTemp != 2 .AND. nTemp != 3
// Alert( "Wrong Value for ResolutionUnit" )
ENDIF
CASE nTag == 305
// ?? "Software"
// cTag := "Software"
IF nFieldType != ASCII
// Alert( "Wrong Type for Software" )
ENDIF
CASE nTag == 306
/*
DateTime
Date and time of image creation.
Tag = 306 (132.H)
Type = ASCII
N = 2 0
The format is: YYYY:MM:DD HH:MM:SS, with hours like those on a 24-hour
clock, and one space character between the date and the time. The length of the
string, including the terminating NUL, is 20 bytes.
*/
// ?? "DateTime"
// cTag := "DateTime"
IF nFieldType != ASCII
// Alert( "Wrong Type for DateTime" )
ENDIF
CASE nTag == 315
/*
Artist
Person who created the image.
Tag = 315 (13B.H)
Type = ASCII
Note: some older TIFF files used this tag for storing Copyright information.
*/
// ?? "Artist"
// cTag := "Artist"
IF nFieldType != ASCII
// Alert( "Wrong Type for Artist" )
ENDIF
CASE nTag == 320
/*
ColorMap
Tag = 320 (140.H)
Type = SHORT
N = 3 * (2**BitsPerSample)
This field defines a Red-Green-Blue color map (often called a lookup table) for
palette color images. In a palette-color image, a pixel value is used to index into an
RGB-lookup table. For example, a palette-color pixel having a value of 0 would
be displayed according to the 0th Red, Green, Blue triplet.
In a TIFF ColorMap, all the Red values come first, followed by the Green values,
then the Blue values. In the ColorMap, black is represented by 0,0,0 and white is
represented by 65535, 65535, 65535.
*/
// ?? "ColorMap"
// cTag := "ColorMap"
IF nFieldType != SHORT
// Alert( "Wrong Type for ColorMap" )
ENDIF
CASE nTag == 338
/*
ExtraSamples
Description of extra components.
Tag = 338 (152.H)
Type = SHORT
N = m
*/
// ?? "ExtraSamples"
// cTag := "ExtraSamples"
IF nFieldType != SHORT
// Alert( "Wrong Type for ExtraSamples" )
ENDIF
CASE nTag == 33432
/*
Copyright
Copyright notice.
Tag = 33432 (8298.H)
Type = ASCII
Copyright notice of the person or organization that claims the copyright to the
image. The complete copyright statement should be listed in this field including
any dates and statements of claims. For example, Copyright, John Smith, 19xx.
All rights reserved.
*/
// ?? "Copyright"
// cTag := "Copyright"
IF nFieldType != ASCII
// Alert( "Wrong Type for Copyright" )
ENDIF
OTHERWISE
// ?? "Unknown"
// cTag := "Unknown"
ENDCASE
#if 0
?? PadR( cTag, 30 )
?? " type " + PadR( aType[ nFieldType ], 10 ) + " count " + hb_ntos( nCount ) + " <"
DO CASE
CASE nFieldType == BYTE
FOR nI := 1 TO nCount
?? " " + hb_ntos( Asc( SubStr( cValues, nI, 1 ) ) )
NEXT
CASE nFieldType == ASCII
?? " "
FOR nI := 1 TO nCount
?? SubStr( cValues, nI, 1 )
NEXT
CASE nFieldType == SHORT
FOR nI := 1 TO nCount
?? " " + hb_ntos( Bin2W( SubStr( cValues, ( nI - 1 ) * 2 + 1, 2 ) ) )
NEXT
CASE nFieldType == LONG
FOR nI := 1 TO nCount
?? " " + hb_ntos( Bin2L( SubStr( cValues, ( nI - 1 ) * 4 + 1, 4 ) ) )
NEXT
CASE nFieldType == RATIONAL
FOR nI := 1 TO nCount
?? " " + hb_ntos( Bin2L( SubStr( cValues, ( nI - 1 ) * 8 + 1, 4 ) ) ) + "/" + hb_ntos( Bin2L( SubStr( cValues, nI + 4, 4 ) ) )
NEXT
CASE nFieldType == SBYTE
FOR nI := 1 TO nCount
?? " " + hb_ntos( Asc( SubStr( cValues, nI, 1 ) ) )
NEXT
CASE nFieldType == UNDEFINED
FOR nI := 1 TO nCount
?? " " + SubStr( cValues, nI, 1 )
NEXT
CASE nFieldType == SSHORT
FOR nI := 1 TO nCount
?? " " + hb_ntos( Bin2I( SubStr( cValues, ( nI - 1 ) * 2 + 1, 2 ) ) )
NEXT
CASE nFieldType == SLONG
FOR nI := 1 TO nCount
?? " " + hb_ntos( Bin2L( SubStr( cValues, ( nI - 1 ) * 4 + 1, 4 ) ) )
NEXT
CASE nFieldType == SRATIONAL
FOR nI := 1 TO nCount
?? " " + hb_ntos( Bin2L( SubStr( cValues, ( nI - 1 ) * 8 + 1, 4 ) ) ) + "/" + hb_ntos( Bin2L( SubStr( cValues, nI + 4, 4 ) ) )
NEXT
CASE nFieldType == FLOAT
CASE nFieldType == DOUBLE
FOR nI := 1 TO nCount
?? " " + hb_ntos( CToF( SubStr( cValues, ( nI - 1 ) * 8 + 1, 8 ) ) )
NEXT
ENDCASE
?? " >"
#endif
NEXT
FRead( nHandle, @cIFDNext, 4 )
ENDDO
FClose( nHandle )
AAdd( aTemp, nWidth )
AAdd( aTemp, nHeight )
AAdd( aTemp, xRes )
AAdd( aTemp, yRes )
AAdd( aTemp, nBits )
AAdd( aTemp, nFrom )
AAdd( aTemp, nLength )
nSpace := 0
AAdd( aTemp, nSpace )
RETURN aTemp
FUNCTION pdfJPEGInfo( cFile )
LOCAL c255, nAt, nHandle
LOCAL nWidth, nHeight, nBits := 8, nFrom := 0, nLength, xRes, yRes, aTemp := {}
LOCAL nBuffer := 20000
LOCAL nSpace // := 3 // 3 - RGB, 1 - GREY, 4 - CMYK
nHandle := FOpen( cFile )
c255 := Space( nBuffer )
FRead( nHandle, @c255, nBuffer )
xRes := Asc( SubStr( c255, 15, 1 ) ) * 256 + Asc( SubStr( c255, 16, 1 ) )
yRes := Asc( SubStr( c255, 17, 1 ) ) * 256 + Asc( SubStr( c255, 18, 1 ) )
nAt := RAt( Chr( 255 ) + Chr( 192 ), c255 ) + 5
nHeight := Asc( SubStr( c255, nAt, 1 ) ) * 256 + Asc( SubStr( c255, nAt + 1, 1 ) )
nWidth := Asc( SubStr( c255, nAt + 2, 1 ) ) * 256 + Asc( SubStr( c255, nAt + 3, 1 ) )
nSpace := Asc( SubStr( c255, nAt + 4, 1 ) )
nLength := FileSize( nHandle )
FClose( nHandle )
AAdd( aTemp, nWidth )
AAdd( aTemp, nHeight )
AAdd( aTemp, xRes )
AAdd( aTemp, yRes )
AAdd( aTemp, nBits )
AAdd( aTemp, nFrom )
AAdd( aTemp, nLength )
AAdd( aTemp, nSpace )
RETURN aTemp
STATIC FUNCTION FilePos( nHandle )
RETURN FSeek( nHandle, 0, FS_RELATIVE )
STATIC FUNCTION Chr_RGB( cChar )
RETURN Str( Asc( cChar ) / 255, 4, 2 )
STATIC FUNCTION NumToken( cString, cDelimiter )
RETURN AllToken( cString, cDelimiter )
STATIC FUNCTION Token( cString, cDelimiter, nPointer )
RETURN AllToken( cString, cDelimiter, nPointer, 1 )
STATIC FUNCTION AtToken( cString, cDelimiter, nPointer )
RETURN AllToken( cString, cDelimiter, nPointer, 2 )
STATIC FUNCTION AllToken( cString, cDelimiter, nPointer, nAction )
LOCAL nTokens := 0, nPos := 1, nLen := Len( cString ), nStart, cRet
__defaultNIL( @cDelimiter, Chr( 0 ) + Chr( 9 ) + Chr( 10 ) + Chr( 13 ) + Chr( 26 ) + Chr( 32 ) + Chr( 138 ) + Chr( 141 ) )
__defaultNIL( @nAction, 0 )
// nAction == 0 - numtoken
// nAction == 1 - token
// nAction == 2 - attoken
WHILE nPos <= nLen
IF ! SubStr( cString, nPos, 1 ) $ cDelimiter
nStart := nPos
WHILE nPos <= nLen .AND. ! SubStr( cString, nPos, 1 ) $ cDelimiter
++nPos
ENDDO
++nTokens
IF nAction > 0
IF nPointer == nTokens
IF nAction == 1
cRet := SubStr( cString, nStart, nPos - nStart )
ELSE
cRet := nStart
ENDIF
EXIT
ENDIF
ENDIF
ENDIF
IF SubStr( cString, nPos, 1 ) $ cDelimiter
WHILE nPos <= nLen .AND. SubStr( cString, nPos, 1 ) $ cDelimiter
++nPos
ENDDO
ENDIF
cRet := nTokens
ENDDO
RETURN cRet
STATIC FUNCTION NumAt( cSearch, cString )
LOCAL n := 0, nAt, nPos := 0
WHILE ( nAt := At( cSearch, SubStr( cString, nPos + 1 ) ) ) > 0
nPos += nAt
++n
ENDDO
RETURN n
STATIC FUNCTION FileSize( nHandle )
LOCAL nCurrent
LOCAL nLength
// Get file position
nCurrent := FilePos( nHandle )
// Get file length
nLength := FSeek( nHandle, 0, FS_END )
// nLength := FilePos( nHandle )
// Reset file position
FSeek( nHandle, nCurrent )
RETURN nLength
// next 3 function written by Peter Kulek
// modified DATE processing by V.K.
STATIC FUNCTION Array2File( cFile, aRay, nDepth, hFile )
LOCAL nBytes := 0
LOCAL i
nDepth := iif( HB_ISNUMERIC( nDepth ), nDepth, 0 )
IF hFile == NIL
IF ( hFile := FCreate( cFile, FC_NORMAL ) ) == F_ERROR
RETURN nBytes
ENDIF
ENDIF
nDepth++
nBytes += WriteData( hFile, aRay )
IF HB_ISARRAY( aRay )
FOR i := 1 TO Len( aRay )
nBytes += Array2File( cFile, aRay[ i ], nDepth, hFile )
NEXT
ENDIF
nDepth--
IF nDepth == 0
FClose( hFile )
ENDIF
RETURN nBytes
STATIC FUNCTION WriteData( hFile, xData )
LOCAL cData := ValType( xData )
IF HB_ISSTRING( xData )
cData += I2Bin( Len( xData ) ) + xData
ELSEIF HB_ISNUMERIC( xData )
cData += I2Bin( Len( hb_ntos( xData ) ) ) + hb_ntos( xData )
ELSEIF HB_ISDATE( xData )
cData += I2Bin( 8 ) + DToS( xData )
ELSEIF HB_ISLOGICAL( xData )
cData += I2Bin( 1 ) + iif( xData, "T", "F" )
ELSEIF HB_ISARRAY( xData )
cData += I2Bin( Len( xData ) )
ELSE
cData += I2Bin( 0 ) // NIL
ENDIF
RETURN FWrite( hFile, cData, Len( cData ) )
STATIC FUNCTION File2Array( cFile, nLen, hFile )
LOCAL cData, cType, nDataLen, nBytes
LOCAL nDepth := 0
LOCAL aRay := {}
IF hFile == NIL
IF ( hFile := FOpen( cFile, FO_READ ) ) == F_ERROR
RETURN aRay
ENDIF
cData := Space( 3 )
FRead( hFile, @cData, 3 )
IF !( Left( cData, 1 ) == "A" )
RETURN aRay
ENDIF
nLen := Bin2I( Right( cData, 2 ) )
ENDIF
DO WHILE nDepth < nLen
cData := Space( 3 )
nBytes := FRead( hFile, @cData, 3 )
IF nBytes < 3
EXIT
ENDIF
cType := PadL( cData, 1 )
nDataLen := Bin2I( Right( cData, 2 ) )
IF !( cType == "A" )
cData := Space( nDataLen )
nBytes := FRead( hFile, @cData, nDataLen )
IF nBytes < nDataLen
EXIT
ENDIF
ENDIF
nDepth++
AAdd( aRay, NIL )
IF cType == "C"
aRay[ nDepth ] := cData
ELSEIF cType == "N"
aRay[ nDepth ] := Val( cData )
ELSEIF cType == "D"
aRay[ nDepth ] := hb_SToD( cData )
ELSEIF cType == "L"
aRay[ nDepth ] := ( cData == "T" )
ELSEIF cType == "A"
aRay[ nDepth ] := File2Array(, nDataLen, hFile )
ENDIF
ENDDO
IF cFile != NIL
FClose( hFile )
ENDIF
RETURN aRay
// end of 3rd function written by Peter Kulek