diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 4d521fb745..cca76b8ed0 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,48 @@ 2008-12-31 13:59 UTC+0100 Foo Bar */ +2008-05-20 13:30 UTC+0100 Viktor Szakats (harbour.01 syenar hu) + + contrib/hbvpdf + + contrib/hbvpdf/common.mak + + contrib/hbvpdf/hbvpdf.prg + + contrib/hbvpdf/hbvpdf.ch + + contrib/hbvpdf/make_gcc.sh + + contrib/hbvpdf/tests + + contrib/hbvpdf/tests/fonts.dat + + contrib/hbvpdf/tests/files + + contrib/hbvpdf/tests/files/color.tif + + contrib/hbvpdf/tests/files/test.txt + + contrib/hbvpdf/tests/files/color.jpg + + contrib/hbvpdf/tests/pdf_demo.prg + + contrib/hbvpdf/tests/tstpdf.prg + + contrib/hbvpdf/tests/bld_b32.bat + + contrib/hbvpdf/tests/bld_vc.bat + + contrib/hbvpdf/hbvpdft.prg + + contrib/hbvpdf/make_b32.bat + + contrib/hbvpdf/make_vc.bat + + contrib/hbvpdf/Makefile + + Added Viktor K's pure Clipper pdf lib. + + Added Pritpal's OOP version. + + Added make files, reorged dir layout, named + files to avoid collision. + + Added minor #define tweak to compile as-is. + * Renamed pdf.ch to hbvpdf.ch for above reasons, + if this hurts anybody, I will correct it. + ! Fixed unused vars and a few other things. + ; TOFIX: - ShellExecute(), GetDeskTopWindow() + dependencies commented out. + - fonts.dat dependency is a PITA, so + this file should be moved inside + the .prg somehow. + - There are some hard-wired non porable + things like acrobat executable path. + + * contrib/Makefile + * contrib/make_b32_all.bat + * contrib/make_gcc_all.sh + * contrib/make_vc_all.bat + + hbvpdf added to make systems. + 2008-05-20 09:30 UTC+0100 Viktor Szakats (harbour.01 syenar hu) * contrib/hbwhat32/wincorec.c ! Removed old-style Clipper comment from C code. diff --git a/harbour/contrib/Makefile b/harbour/contrib/Makefile index 37b4f91796..40e9308621 100644 --- a/harbour/contrib/Makefile +++ b/harbour/contrib/Makefile @@ -11,6 +11,7 @@ DIRS=\ hbmisc \ hbnf \ hbclipsm \ + hbvpdf \ xhb \ # examples \ # hbzlib \ diff --git a/harbour/contrib/hbvpdf/Makefile b/harbour/contrib/hbvpdf/Makefile new file mode 100644 index 0000000000..1e6df9b80e --- /dev/null +++ b/harbour/contrib/hbvpdf/Makefile @@ -0,0 +1,16 @@ +# +# $Id$ +# + +ROOT = ../../ + +PRG_SOURCES=\ + hbvpdf.prg \ + hbvpdft.prg \ + +PRG_HEADERS=\ + hbvpdf.ch \ + +LIBNAME=hbvpdf + +include $(TOP)$(ROOT)config/lib.cf diff --git a/harbour/contrib/hbvpdf/common.mak b/harbour/contrib/hbvpdf/common.mak new file mode 100644 index 0000000000..f9df38606b --- /dev/null +++ b/harbour/contrib/hbvpdf/common.mak @@ -0,0 +1,17 @@ +# +# $Id$ +# + +LIBNAME = $(LIBPREF)hbvpdf + +LIB_PATH = $(LIB_DIR)$(LIBNAME)$(LIBEXT) + +PRG_HEADERS = \ + hbvpdf.ch \ + +LIB_OBJS = \ + $(OBJ_DIR)hbvpdf$(OBJEXT) \ + $(OBJ_DIR)hbvpdft$(OBJEXT) \ + +all: \ + $(LIB_PATH) \ diff --git a/harbour/contrib/hbvpdf/hbvpdf.ch b/harbour/contrib/hbvpdf/hbvpdf.ch new file mode 100644 index 0000000000..4081063d1c --- /dev/null +++ b/harbour/contrib/hbvpdf/hbvpdf.ch @@ -0,0 +1,223 @@ +#include "fileio.ch" +#include "common.ch" + +#define CRLF chr(13)+chr(10) + +#define NORMAL 0 +#define BOLD 1 +#define ITALIC 2 +#define BOLDITALIC 3 + +#define BOOKLEVEL 1 +#define BOOKTITLE 2 +#define BOOKPARENT 3 +#define BOOKPREV 4 +#define BOOKNEXT 5 +#define BOOKFIRST 6 +#define BOOKLAST 7 +#define BOOKCOUNT 8 +#define BOOKPAGE 9 +#define BOOKCOORD 10 + +#define FONTNAME 1 // font name +#define FONTSIZE 2 // font size +#define LPI 3 // lines per inch +#define PAGESIZE 4 // page size +#define PAGEORIENT 5 // page orientation +#define PAGEX 6 +#define PAGEY 7 +#define REPORTWIDTH 8 // report width +#define REPORTPAGE 9 // report page +#define REPORTLINE 10 // report line +#define FONTNAMEPREV 11 // prev font name +#define FONTSIZEPREV 12 // prev font size +#define PAGEBUFFER 13 // page buffer +#define REPORTOBJ 14 // current obj +#define DOCLEN 15 // document length +#define TYPE1 16 // array of type 1 fonts +#define MARGINS 17 // recalc margins ? +#define HEADEREDIT 18 // edit header ? +#define NEXTOBJ 19 // next obj +#define PDFTOP 20 // top row +#define PDFLEFT 21 // left & right margin in mm +#define PDFBOTTOM 22 // bottom row +#define HANDLE 23 // handle +#define PAGES 24 // array of pages +#define REFS 25 // array of references +#define BOOKMARK 26 // array of bookmarks +#define HEADER 27 // array of headers +#define FONTS 28 // array of report fonts +#define IMAGES 29 // array of report images +#define PAGEIMAGES 30 // array of current page images +#define PAGEFONTS 31 // array of current page fonts +#define FONTWIDTH 32 // array of fonts width's +#define OPTIMIZE 33 // optimized ? +#define PARAMLEN 33 // number of report elements + +#define ALIGN_LEFT 1 +#define ALIGN_CENTER 2 +#define ALIGN_RIGHT 3 +#define ALIGN_JUSTIFY 4 + +#define IMAGE_WIDTH 1 +#define IMAGE_HEIGHT 2 +#define IMAGE_XRES 3 +#define IMAGE_YRES 4 +#define IMAGE_BITS 5 +#define IMAGE_FROM 6 +#define IMAGE_LENGTH 7 + +#define BYTE 1 +#define ASCII 2 +#define SHORT 3 +#define LONG 4 +#define RATIONAL 5 +#define SBYTE 6 +#define UNDEFINED 7 +#define SSHORT 8 +#define SLONG 9 +#define SRATIONAL 10 +#define FLOAT 11 +#define DOUBLE 12 + +#define pdf_ALICEBLUE "F0F8FF" +#define pdf_ANTIQUEWHITE "FAEBD7" +#define pdf_AQUA "00FFFF" +#define pdf_AQUAMARINE "7FFFD4" +#define pdf_AZURE "F0FFFF" +#define pdf_BEIGE "F5F5DC" +#define pdf_BISQUE "FFE4C4" +#define pdf_BLACK "000000" +#define pdf_BLANCHEDALMOND "FFEBCD" +#define pdf_BLUE "0000FF" +#define pdf_BLUEVIOLET "8A2BE2" +#define pdf_BROWN "A52A2A" +#define pdf_BURLYWOOD "DEB887" +#define pdf_CADETBLUE "5F9EA0" +#define pdf_CHARTREUSE "7FFF00" +#define pdf_CHOCOLATE "D2691E" +#define pdf_CORAL "FF7F50" +#define pdf_CORNFLOWERBLUE "6495ED" +#define pdf_CORNSILK "FFF8DC" +#define pdf_CRIMSON "DC143C" +#define pdf_CYAN "00FFFF" +#define pdf_DARKBLUE "00008B" +#define pdf_DARKCYAN "008B8B" +#define pdf_DARKGOLDENROD "B8860B" +#define pdf_DARKGRAY "A9A9A9" +#define pdf_DARKGREEN "006400" +#define pdf_DARKKHAKI "BDB76B" +#define pdf_DARKMAGENTA "8B008B" +#define pdf_DARKOLIVEGREEN "556B2F" +#define pdf_DARKORANGE "FF8C00" +#define pdf_DARKORCHID "9932CC" +#define pdf_DARKRED "8B0000" +#define pdf_DARKSALMON "E9967A" +#define pdf_DARKSEAGREEN "8FBC8F" +#define pdf_DARKSLATEBLUE "483D8B" +#define pdf_DARKSLATEGRAY "2F4F4F" +#define pdf_DARKTURQUOISE "00CED1" +#define pdf_DARKVIOLET "9400D3" +#define pdf_DEEPPINK "FF1493" +#define pdf_DEEPSKYBLUE "00BFFF" +#define pdf_DIMGRAY "696969" +#define pdf_DODGERBLUE "1E90FF" +#define pdf_FIREBRICK "B22222" +#define pdf_FLORALWHITE "FFFAF0" +#define pdf_FORESTGREEN "228B22" +#define pdf_FUCHSIA "FF00FF" +#define pdf_GAINSBORO "DCDCDC" +#define pdf_GHOSTWHITE "F8F8FF" +#define pdf_GOLD "FFD700" +#define pdf_GOLDENROD "DAA520" +#define pdf_GRAY "808080" +#define pdf_GREEN "008000" +#define pdf_GREENYELLOW "ADFF2F" +#define pdf_HONEYDEW "F0FFF0" +#define pdf_HOTPINK "FF69B4" +#define pdf_INDIANRED "CD5C5C" +#define pdf_INDIGO "4B0082" +#define pdf_IVORY "FFFFF0" +#define pdf_KHAKI "F0E68C" +#define pdf_LAVENDER "E6E6FA" +#define pdf_LAVENDERBLUSH "FFF0F5" +#define pdf_LAWNGREEN "7CFC00" +#define pdf_LEMONCHIFFON "FFFACD" +#define pdf_LIGHTBLUE "ADD8E6" +#define pdf_LIGHTCORAL "F08080" +#define pdf_LIGHTCYAN "E0FFFF" +#define pdf_LIGHTGOLDENRODYELLOW "FAFAD2" +#define pdf_LIGHTGREEN "90EE90" +#define pdf_LIGHTGREY "D3D3D3" +#define pdf_LIGHTPINK "FFB6C1" +#define pdf_LIGHTSALMON "FFA07A" +#define pdf_LIGHTSEAGREEN "20B2AA" +#define pdf_LIGHTSKYBLUE "87CEFA" +#define pdf_LIGHTSLATEGRAY "778899" +#define pdf_LIGHTSTEELBLUE "B0C4DE" +#define pdf_LIGHTYELLOW "FFFFE0" +#define pdf_LIME "00FF00" +#define pdf_LIMEGREEN "32CD32" +#define pdf_LINEN "FAF0E6" +#define pdf_MAGENTA "FF00FF" +#define pdf_MAROON "800000" +#define pdf_MEDIUMAQUAMARINE "66CDAA" +#define pdf_MEDIUMBLUE "0000CD" +#define pdf_MEDIUMORCHID "BA55D3" +#define pdf_MEDIUMPURPLE "9370DB" +#define pdf_MEDIUMSEAGREEN "3CB371" +#define pdf_MEDIUMSLATEBLUE "7B68EE" +#define pdf_MEDIUMSPRINGGREEN "00FA9A" +#define pdf_MEDIUMTURQUOISE "48D1CC" +#define pdf_MEDIUMVIOLETRED "C71585" +#define pdf_MIDNIGHTBLUE "191970" +#define pdf_MINTCREAM "F5FFFA" +#define pdf_MISTYROSE "FFE4E1" +#define pdf_MOCCASIN "FFE4B5" +#define pdf_NAVAJOWHITE "FFDEAD" +#define pdf_NAVY "000080" +#define pdf_OLDLACE "FDF5E6" +#define pdf_OLIVE "808000" +#define pdf_OLIVEDRAB "6B8E23" +#define pdf_ORANGE "FFA500" +#define pdf_ORANGERED "FF4500" +#define pdf_ORCHID "DA70D6" +#define pdf_PALEGOLDENROD "EEE8AA" +#define pdf_PALEGREEN "98FB98" +#define pdf_PALETURQUOISE "AFEEEE" +#define pdf_PALEVIOLETRED "DB7093" +#define pdf_PAPAYAWHIP "FFEFD5" +#define pdf_PEACHPUFF "FFDAB9" +#define pdf_PERU "CD853F" +#define pdf_PINK "FFC0CB" +#define pdf_PLUM "DDADDD" +#define pdf_POWDERBLUE "B0E0E6" +#define pdf_PURPLE "800080" +#define pdf_RED "FF0000" +#define pdf_ROSYBROWN "BC8F8F" +#define pdf_ROYALBLUE "4169E1" +#define pdf_SADDLEBROWN "8B4513" +#define pdf_SALMON "FA8072" +#define pdf_SANDYBROWN "F4A460" +#define pdf_SEAGREEN "2E8B57" +#define pdf_SEASHELL "FFF5EE" +#define pdf_SIENNA "A0522D" +#define pdf_SILVER "C0C0C0" +#define pdf_SKYBLUE "87CEEB" +#define pdf_SLATEBLUE "6A5ACD" +#define pdf_SLATEGRAY "708090" +#define pdf_SNOW "FFFAFA" +#define pdf_SPRINGGREEN "00FF7F" +#define pdf_STEELBLUE "4682B4" +#define pdf_TAN "D2B48C" +#define pdf_TEAL "008080" +#define pdf_THISTLE "D8BFD8" +#define pdf_TOMATO "FF6347" +#define pdf_TURQUOISE "40E0D0" +#define pdf_VIOLET "EE82EE" +#define pdf_WHEAT "F5DEB3" +#define pdf_WHITE "FFFFFF" +#define pdf_WHITESMOKE "F5F5F5" +#define pdf_YELLOW "FFFF00" +#define pdf_YELLOWGREEN "9ACD32" + diff --git a/harbour/contrib/hbvpdf/hbvpdf.prg b/harbour/contrib/hbvpdf/hbvpdf.prg new file mode 100644 index 0000000000..3d227df6ed --- /dev/null +++ b/harbour/contrib/hbvpdf/hbvpdf.prg @@ -0,0 +1,2624 @@ +/* + * $Id$ + */ + +#include "hbvpdf.ch" + +memvar aReport + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfAtSay( cString, nRow, nCol, cUnits, lExact, cId ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local _nFont, lReverse, nAt + +DEFAULT nRow to aReport[ REPORTLINE ] +DEFAULT cUnits to "R" +DEFAULT lExact to .f. +DEFAULT cId to "" + + IF aReport[ HEADEREDIT ] + return pdfHeader( "PDFATSAY", cId, { cString, nRow, nCol, cUnits, lExact } ) + ENDIF + + IF ( nAt := at( "#pagenumber#", cString ) ) > 0 + cString := left( cString, nAt - 1 ) + ltrim(str( pdfPageNumber())) + substr( cString, nAt + 12 ) + ENDIF + + lReverse = .f. + IF cUnits == "M" + nRow := pdfM2Y( nRow ) + nCol := pdfM2X( nCol ) + ELSEIF cUnits == "R" + IF .not. lExact + pdfCheckLine( nRow ) + nRow := nRow + aReport[ PDFTOP ] + ENDIF + nRow := pdfR2D( nRow ) + nCol := pdfM2X( aReport[ PDFLEFT ] ) + ; + nCol * 100.00 / aReport[ REPORTWIDTH ] * ; + ( aReport[ PAGEX ] - pdfM2X( 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( nCol, nRow + aReport[ FONTSIZE ] - 2.0, nCol + pdfM2X( pdfLen( cString )) + 1, nRow + 2 * aReport[ FONTSIZE ] - 1.5,,100, "D") + pdfBox( aReport[ PAGEY ] - nRow - aReport[ FONTSIZE ] + 2.0 , nCol, aReport[ PAGEY ] - nRow + 2.0, nCol + pdfM2X( pdfLen( cString )) + 1,,100, "D") + aReport[ PAGEBUFFER ] += " 1 g " + lReverse = .t. + ELSEIF right( cString, 1 ) == chr(254) //underline + cString := left( cString, len( cString ) - 1 ) + //pdfBox( nCol, nRow - 1.5, nCol + pdfM2X( pdfLen( cString )) + 1, nRow - 1,,100, "D") + pdfBox( aReport[ PAGEY ] - nRow + 0.5, nCol, 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 + 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( aReport[ FONTS ], {|arr| arr[1] == aReport[ FONTNAME ]} ) + IF aReport[ FONTNAME ] <> aReport[ FONTNAMEPREV ] + aReport[ FONTNAMEPREV ] := aReport[ FONTNAME ] + aReport[ PAGEBUFFER ] += CRLF + "BT /Fo" + ltrim(str( _nFont )) + " " + ltrim(transform( aReport[ FONTSIZE ], "999.99")) + " Tf " + ltrim(transform( nCol, "9999.99" )) + " " + ltrim(transform( nRow, "9999.99" )) + " Td (" + cString + ") Tj ET" + ELSEIF aReport[ FONTSIZE ] <> aReport[ FONTSIZEPREV ] + aReport[ FONTSIZEPREV ] := aReport[ FONTSIZE ] + aReport[ PAGEBUFFER ] += CRLF + "BT /Fo" + ltrim(str( _nFont )) + " " + ltrim(transform( aReport[ FONTSIZE ], "999.99")) + " Tf " + ltrim(transform( nCol, "9999.99" )) + " " + ltrim(transform( nRow, "9999.99" )) + " Td (" + cString + ") Tj ET" + ELSE + aReport[ PAGEBUFFER ] += CRLF + "BT " + ltrim(transform( nCol, "9999.99" )) + " " + ltrim(transform( nRow, "9999.99" )) + " Td (" + cString + ") Tj ET" + ENDIF + IF lReverse + aReport[ PAGEBUFFER ] += " 0 g " + ENDIF + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfBold() /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + IF pdfGetFontInfo("NAME") = "Times" + aReport[ FONTNAME ] := 2 + ELSEIF pdfGetFontInfo("NAME") = "Helvetica" + aReport[ FONTNAME ] := 6 + ELSE + aReport[ FONTNAME ] := 10 // Courier // 0.04 + ENDIF + aadd( aReport[ PAGEFONTS ], aReport[ FONTNAME ] ) + IF ascan( aReport[ FONTS ], { |arr| arr[1] == aReport[ FONTNAME ] } ) == 0 + aadd( aReport[ FONTS ], { aReport[ FONTNAME ], ++aReport[ NEXTOBJ ] } ) + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfBoldItalic() /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + IF pdfGetFontInfo("NAME") = "Times" + aReport[ FONTNAME ] := 4 + ELSEIF pdfGetFontInfo("NAME") = "Helvetica" + aReport[ FONTNAME ] := 8 + ELSE + aReport[ FONTNAME ] := 12 // 0.04 + ENDIF + aadd( aReport[ PAGEFONTS ], aReport[ FONTNAME ] ) + IF ascan( aReport[ FONTS ], { |arr| arr[1] == aReport[ FONTNAME ] } ) == 0 + aadd( aReport[ FONTS ], { aReport[ FONTNAME ], ++aReport[ NEXTOBJ ] } ) + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfBookAdd( cTitle, nLevel, nPage, nLine ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + aadd( aReport[ BOOKMARK ], { nLevel, alltrim( cTitle ), 0, 0, 0, 0, 0, 0, nPage, IIF( nLevel == 1, aReport[ PAGEY ], aReport[ PAGEY ] - nLine * 72 / aReport[ LPI ] ) }) +return Nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfBookClose( ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + aReport[ BOOKMARK ] := nil +return Nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfBookCount( nRecno, nCurLevel ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local nTempLevel := 0, nCount := 0, nLen := len( aReport[ BOOKMARK ] ) + ++nRecno + while nRecno <= nLen + nTempLevel := 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( aReport[ BOOKMARK ] ) + ++nRecno + IF nRecno <= nLen + IF nCurLevel + 1 == 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( aReport[ BOOKMARK ] ) + ++nRecno + IF nRecno <= nLen + IF nCurLevel + 1 == aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + while nRecno <= nLen .and. nCurLevel + 1 <= aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + IF nCurLevel + 1 == 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 := 0, nNext := 0, nLen := len( aReport[ BOOKMARK ] ) + ++nRecno + while nRecno <= nLen + nTempLevel := 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( ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + aReport[ BOOKMARK ] := {} +return Nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfBookParent( nRecno, nCurLevel, nObj ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local nTempLevel := 0 +local nParent := 0 + --nRecno + while nRecno > 0 + nTempLevel := 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 := 0 +local nPrev := 0 + --nRecno + while nRecno > 0 + nTempLevel := 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 +DEFAULT nBorder to 0 +DEFAULT nShade to 0 +DEFAULT cUnits to "M" +DEFAULT cColor to "" + + // 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 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 + aReport[ PAGEBUFFER ] += CRLF + transform( 1.00 - nShade / 100.00, "9.99") + " g " + cBoxColor + ltrim(str(pdfM2X( y1 ))) + " " + ltrim(str(pdfM2Y( x1 ))) + " " + ltrim(str(pdfM2X( y2 - y1 ))) + " -" + ltrim(str(pdfM2X( x2 - x1 ))) + " re f 0 g" + ENDIF + + IF nBorder > 0 + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(pdfM2X( y1 ))) + " " + ltrim(str(pdfM2Y( x1 ))) + " " + ltrim(str(pdfM2X( y2 - y1 ))) + " -" + ltrim(str(pdfM2X( nBorder ))) + " re f" + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(pdfM2X( y2 - nBorder ))) + " " + ltrim(str(pdfM2Y( x1 ))) + " " + ltrim(str(pdfM2X( nBorder ))) + " -" + ltrim(str(pdfM2X( x2 - x1 ))) + " re f" + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(pdfM2X( y1 ))) + " " + ltrim(str(pdfM2Y( x2 - nBorder ))) + " " + ltrim(str(pdfM2X( y2 - y1 ))) + " -" + ltrim(str(pdfM2X( nBorder ))) + " re f" + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(pdfM2X( y1 ))) + " " + ltrim(str(pdfM2Y( x1 ))) + " " + ltrim(str(pdfM2X( nBorder ))) + " -" + ltrim(str(pdfM2X( x2 - x1 ))) + " re f" + ENDIF + ELSEIF cUnits == "D"// "Dots" + //x1, y1, x2, y2 - nTop, nLeft, nBottom, nRight + IF nShade > 0 + // version 0.02 + aReport[ PAGEBUFFER ] += CRLF + transform( 1.00 - nShade / 100.00, "9.99") + " g " + cBoxColor + ltrim(str( y1 )) + " " + ltrim(str( aReport[ PAGEY ] - x1 )) + " " + ltrim(str( y2 - y1 )) + " -" + ltrim(str( x2 - x1 )) + " re f 0 g" + ENDIF + + IF nBorder > 0 +/* + 1 + ÚÄÄÄÄÄ¿ + 4 ³ ³ 2 + ÀÄÄÄÄÄÙ + 3 +*/ + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y1 )) + " " + ltrim(str( aReport[ PAGEY ] - x1 )) + " " + ltrim(str( y2 - y1 )) + " -" + ltrim(str( nBorder )) + " re f" + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y2 - nBorder )) + " " + ltrim(str( aReport[ PAGEY ] - x1 )) + " " + ltrim(str( nBorder )) + " -" + ltrim(str( x2 - x1 )) + " re f" + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y1 )) + " " + ltrim(str( aReport[ PAGEY ] - x2 + nBorder )) + " " + ltrim(str( y2 - y1 )) + " -" + ltrim(str( nBorder )) + " re f" + aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y1 )) + " " + ltrim(str( aReport[ PAGEY ] - x1 )) + " " + ltrim(str( nBorder )) + " -" + ltrim(str( x2 - x1 )) + " re f" + ENDIF + ENDIF + +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfBox1( nTop, nLeft, nBottom, nRight, nBorderWidth, cBorderColor, cBoxColor ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +DEFAULT nBorderWidth to 0.5 +DEFAULT cBorderColor to chr(0) + chr(0) + chr(0) +DEFAULT cBoxColor to chr(255) + chr(255) + chr(255) + + 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 + ltrim(str( nBorderWidth )) + " w" + ; + CRLF + ltrim( str ( nLeft + nBorderWidth / 2 )) + " " + ; + CRLF + ltrim( str ( aReport[ PAGEY ] - nBottom + nBorderWidth / 2)) + " " + ; + CRLF + ltrim( str ( nRight - nLeft - nBorderWidth )) + ; + CRLF + ltrim( str ( nBottom - nTop - nBorderWidth )) + " " + ; + " re" + ; + CRLF + "B" +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfCenter( cString, nRow, nCol, cUnits, lExact, cId ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local nLen, nAt +DEFAULT nRow to aReport[ REPORTLINE ] +DEFAULT cUnits to "R" +DEFAULT lExact to .f. +DEFAULT nCol to IIF( cUnits == "R", aReport[ REPORTWIDTH ] / 2, aReport[ PAGEX ] / 72 * 25.4 / 2 ) + + IF aReport[ HEADEREDIT ] + return pdfHeader( "PDFCENTER", cId, { cString, nRow, nCol, cUnits, lExact } ) + ENDIF + + IF ( nAt := at( "#pagenumber#", cString ) ) > 0 + cString := left( cString, nAt - 1 ) + ltrim(str( pdfPageNumber())) + substr( cString, nAt + 12 ) + ENDIF + + nLen := pdfLen( cString ) / 2 + IF cUnits == "R" + IF .not. lExact + pdfCheckLine( nRow ) + nRow := nRow + aReport[ PDFTOP ] + ENDIF + ENDIF + pdfAtSay( cString, pdfR2M( nRow ), IIF( cUnits == "R", aReport[ PDFLEFT ] + ( aReport[ PAGEX ] / 72 * 25.4 - 2 * aReport[ PDFLEFT ] ) * nCol / aReport[ REPORTWIDTH ], nCol ) - nLen, "M", lExact ) +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfCheckLine( nRow ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + IF nRow + aReport[ PDFTOP ] > aReport[ PDFBOTTOM ] + pdfNewPage() + nRow := aReport[ REPORTLINE ] + ENDIF + 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 + aReport[ REFS ][ 2 ] := aReport[ DOCLEN ] + cTemp := ; + "1 0 obj"+CRLF+; + "<<"+CRLF+; + "/Type /Pages /Count " + ltrim(str(aReport[ REPORTPAGE ])) + CRLF +; + "/Kids [" + + for nI := 1 to aReport[ REPORTPAGE ] + cTemp += " " + ltrim(str( aReport[ PAGES ][ nI ] )) + " 0 R" + next + + cTemp += " ]" + CRLF + ; + ">>" + CRLF + ; + "endobj" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + // info + ++aReport[ REPORTOBJ ] + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + cTemp := ltrim(str( 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 + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + // root + ++aReport[ REPORTOBJ ] + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + cTemp := ltrim(str( aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + ; + "<< /Type /Catalog /Pages 1 0 R /Outlines " + ltrim(str( aReport[ REPORTOBJ ] + 1 )) + " 0 R" + IIF( ( nBookLen := len( aReport[ BOOKMARK ] )) > 0, " /PageMode /UseOutlines", "") + " >>" + CRLF + "endobj" + CRLF + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + ++aReport[ REPORTOBJ ] + nObj1 := aReport[ REPORTOBJ ] + + IF nBookLen > 0 + + nRecno := 1 + nFirst := aReport[ REPORTOBJ ] + 1 + nLast := 0 + nCount := 0 + while nRecno <= nBookLen + nCurLevel := aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + aReport[ BOOKMARK ][ nRecno ][ BOOKPARENT ] := pdfBookParent( nRecno, nCurLevel, aReport[ REPORTOBJ ] ) + aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] := pdfBookPrev( nRecno, nCurLevel, aReport[ REPORTOBJ ] ) + aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] := pdfBookNext( nRecno, nCurLevel, aReport[ REPORTOBJ ] ) + aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] := pdfBookFirst( nRecno, nCurLevel, aReport[ REPORTOBJ ] ) + aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] := pdfBookLast( nRecno, nCurLevel, aReport[ REPORTOBJ ] ) + aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] := pdfBookCount( nRecno, nCurLevel ) + IF nCurLevel == 1 + nLast := nRecno + ++nCount + ENDIF + ++nRecno + enddo + + nLast += aReport[ REPORTOBJ ] + + cTemp := ltrim(str( aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + "<< /Type /Outlines /Count " + ltrim(str( nCount )) + " /First " + ltrim(str( nFirst )) + " 0 R /Last " + ltrim(str( nLast )) + " 0 R >>" + CRLF + "endobj" //+ CRLF + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + ++aReport[ REPORTOBJ ] + nRecno := 1 + FOR nI := 1 to nBookLen + //cTemp := IIF ( nI > 1, CRLF, "") + ltrim(str( aReport[ REPORTOBJ ] + nI - 1)) + " 0 obj" + CRLF + ; + cTemp := CRLF + ltrim(str( aReport[ REPORTOBJ ] + nI - 1)) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Parent " + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKPARENT ])) + " 0 R" + CRLF + ; + "/Dest [" + ltrim(str( aReport[ PAGES ][ aReport[ BOOKMARK ][ nRecno ][ BOOKPAGE ] ] )) + " 0 R /XYZ 0 " + ltrim( str( aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ])) + " 0]" + CRLF + ; + "/Title (" + alltrim( aReport[ BOOKMARK ][ nRecno ][ BOOKTITLE ]) + ")" + CRLF + ; + IIF( aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] > 0, "/Prev " + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ])) + " 0 R" + CRLF, "") + ; + IIF( aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] > 0, "/Next " + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ])) + " 0 R" + CRLF, "") + ; + IIF( aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] > 0, "/First " + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ])) + " 0 R" + CRLF, "") + ; + IIF( aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] > 0, "/Last " + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ])) + " 0 R" + CRLF, "") + ; + IIF( aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] <> 0, "/Count " + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ])) + CRLF, "") + ; + ">>" + CRLF + "endobj" + CRLF +// "/Dest [" + ltrim(str( aReport[ BOOKMARK ][ nRecno ][ BOOKPAGE ] * 3 )) + " 0 R /XYZ 0 " + ltrim( str( aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ])) + " 0]" + CRLF + ; +// "/Dest [" + ltrim(str( aReport[ PAGES ][ nRecno ] )) + " 0 R /XYZ 0 " + ltrim( str( aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ])) + " 0]" + CRLF + ; + + aadd( aReport[ REFS ], aReport[ DOCLEN ] + 2 ) + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + ++nRecno + NEXT + pdfBookClose() + + aReport[ REPORTOBJ ] += nBookLen - 1 + ELSE + cTemp := ltrim(str( aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + "<< /Type /Outlines /Count 0 >>" + CRLF + "endobj" + CRLF + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + ENDIF + + cTemp := CRLF + aReport[ DOCLEN ] += len( cTemp ) + + ++aReport[ REPORTOBJ ] + cTemp += "xref" + CRLF + ; + "0 " + ltrim(str( aReport[ REPORTOBJ ] )) + CRLF +; + padl( aReport[ REFS ][ 1 ], 10, "0") + " 65535 f" + CRLF + + for nI := 2 to len( aReport[ REFS ] ) + cTemp += padl( aReport[ REFS ][ nI ], 10, "0") + " 00000 n" + CRLF + next + + cTemp += "trailer << /Size " + ltrim(str( aReport[ REPORTOBJ ] )) + " /Root " + ltrim(str( nObj1 - 1 )) + " 0 R /Info " + ltrim(str( nObj1 - 2 )) + " 0 R >>" + CRLF + ; + "startxref" + CRLF + ; + ltrim(str( aReport[ DOCLEN ] )) + CRLF + ; + "%%EOF" + CRLF + fwrite( aReport[ HANDLE ], cTemp ) +/* + IF aReport[ OPTIMIZE ] + pdfOptimize( ) coming ! + ENDIF +*/ + fclose( aReport[ HANDLE ] ) + + aReport := nil + +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfClosePage() /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local cTemp, cBuffer, nBuffer, nRead, nI, k, nImage, nFont, nImageHandle + + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + + aadd( aReport[ PAGES ], aReport[ REPORTOBJ ] + 1 ) + + cTemp := ; + ltrim(str( ++aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Type /Page /Parent 1 0 R" + CRLF + ; + "/Resources " + ltrim(str( ++aReport[ REPORTOBJ ] )) + " 0 R" + CRLF + ; + "/MediaBox [ 0 0 " + ltrim(transform( aReport[ PAGEX ], "9999.99")) + " " + ; + ltrim(transform(aReport[ PAGEY ], "9999.99")) + " ]" + CRLF + ; + "/Contents " + ltrim(str( ++aReport[ REPORTOBJ ] )) + " 0 R" + CRLF + ; + ">>" + CRLF + ; + "endobj" + CRLF +// "/Contents [ " + ltrim(str( ++aReport[ REPORTOBJ ] )) + " 0 R ]" + CRLF + ; + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + cTemp := ; + ltrim(str(aReport[ REPORTOBJ ] - 1)) + " 0 obj" + CRLF + ; + "<<"+CRLF+; + "/ColorSpace << /DeviceRGB /DeviceGray >>" + CRLF + ; //version 0.01 + "/ProcSet [ /PDF /Text /ImageB /ImageC ]" + + IF len( aReport[ PAGEFONTS ] ) > 0 + cTemp += CRLF + ; + "/Font" + CRLF + ; + "<<" + + for nI := 1 to len( aReport[ PAGEFONTS ] ) + nFont := ascan( aReport[ FONTS ], { |arr| arr[1] == aReport[ PAGEFONTS ][ nI ] } ) + //IF nFont == 0 + // alert("New font after!!!") + //ENDIF + cTemp += CRLF + "/Fo" + ltrim(str( nFont )) + " " + ltrim(str( aReport[ FONTS ][ nFont ][ 2 ])) + " 0 R" + next + + cTemp += CRLF + ">>" + ENDIF + + IF len( aReport[ PAGEIMAGES ] ) > 0 + cTemp += CRLF + "/XObject" + CRLF + "<<" + for nI := 1 to len( aReport[ PAGEIMAGES ] ) + nImage := ascan( aReport[ IMAGES ], { |arr| arr[1] == aReport[ PAGEIMAGES ][ nI ][ 1 ] } ) + IF nImage == 0 + aadd( aReport[ IMAGES ], { aReport[ PAGEIMAGES ][ nI ][ 1 ], ++aReport[ NEXTOBJ ], pdfImageInfo( aReport[ PAGEIMAGES ][ nI ][ 1 ] ) } ) + nImage := len( aReport[ IMAGES ] ) + ENDIF + cTemp += CRLF + "/Image" + ltrim(str( nImage )) + " " + ltrim(str( aReport[ IMAGES ][ nImage ][ 2 ])) + " 0 R" + next + cTemp += CRLF + ">>" + ENDIF + + cTemp += CRLF + ">>" + CRLF + "endobj" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + cTemp := ltrim(str( aReport[ REPORTOBJ ] )) + " 0 obj << /Length " + ; + ltrim(str( aReport[ REPORTOBJ ] + 1 )) + " 0 R >>" + CRLF +; + "stream" + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + IF len( aReport[ PAGEIMAGES ] ) > 0 + cTemp := "" + for nI := 1 to len( aReport[ PAGEIMAGES ] ) + cTemp += CRLF + "q" + nImage := ascan( aReport[ IMAGES ], { |arr| arr[1] == aReport[ PAGEIMAGES ][ nI ][ 1 ] } ) + cTemp += CRLF + ltrim(str( IIF( aReport[ PAGEIMAGES ][ nI ][ 5 ] == 0, pdfM2X( aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_WIDTH ] / aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_XRES ] * 25.4 ), aReport[ PAGEIMAGES ][ nI ][ 5 ]))) + ; + " 0 0 " + ; + ltrim(str( IIF( aReport[ PAGEIMAGES ][ nI ][ 4 ] == 0, pdfM2X( aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_HEIGHT ] / aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_YRES ] * 25.4 ), aReport[ PAGEIMAGES ][ nI ][ 4 ]))) + ; + " " + ltrim(str( aReport[ PAGEIMAGES ][ nI ][ 3 ] )) + ; + " " + ltrim(str( aReport[ PAGEY ] - aReport[ PAGEIMAGES ][ nI ][ 2 ] - ; + IIF( aReport[ PAGEIMAGES ][ nI ][ 4 ] == 0, pdfM2X( aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_HEIGHT ] / aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_YRES ] * 25.4 ), aReport[ PAGEIMAGES ][ nI ][ 4 ]))) + " cm" + cTemp += CRLF + "/Image" + ltrim(str( nImage )) + " Do" + cTemp += CRLF + "Q" + next + aReport[ PAGEBUFFER ] := cTemp + aReport[ PAGEBUFFER ] + ENDIF + + cTemp := aReport[ PAGEBUFFER ] + + cTemp += CRLF + "endstream" + CRLF + ; + "endobj" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + cTemp := ltrim(str( ++aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + ; + ltrim(str(len( aReport[ PAGEBUFFER ] ))) + CRLF + ; + "endobj" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + for nI := 1 to len( aReport[ FONTS ] ) + IF aReport[ FONTS ][ nI ][ 2 ] > aReport[ REPORTOBJ ] + + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + + cTemp := ; + ltrim(str( aReport[ FONTS ][ nI ][ 2 ] )) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Type /Font" + CRLF + ; + "/Subtype /Type1" + CRLF + ; + "/Name /Fo" + ltrim(str( nI )) + CRLF + ; + "/BaseFont /" + aReport[ TYPE1 ][ aReport[ FONTS ][ nI ][ 1 ] ] + CRLF + ; + "/Encoding /WinAnsiEncoding" + CRLF + ; + ">>" + CRLF + ; + "endobj" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + ENDIF + next + + for nI := 1 to len( aReport[ IMAGES ] ) + IF aReport[ IMAGES ][ nI ][ 2 ] > aReport[ REPORTOBJ ] + + aadd( aReport[ REFS ], aReport[ DOCLEN ] ) + + // "/Filter /CCITTFaxDecode" for B&W only ? + cTemp := ; + ltrim(str( aReport[ IMAGES ][ nI ][ 2 ] )) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Type /XObject" + CRLF + ; + "/Subtype /Image" + CRLF + ; + "/Name /Image" + ltrim(str(nI)) + CRLF + ; + "/Filter [" + IIF( at( ".JPG", upper( aReport[ IMAGES ][ nI ][ 1 ]) ) > 0, " /DCTDecode", "" ) + " ]" + CRLF + ; + "/Width " + ltrim(str( aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_WIDTH ] )) + CRLF + ; + "/Height " + ltrim(str( aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_HEIGHT ] )) + CRLF + ; + "/BitsPerComponent " + ltrim(str( aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_BITS ] )) + CRLF + ; + "/ColorSpace /" + IIF( aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_BITS ] == 1, "DeviceGray", "DeviceRGB") + CRLF + ; + "/Length " + ltrim(str( aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ])) + CRLF + ; + ">>" + CRLF + ; + "stream" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + nImageHandle := fopen( aReport[ IMAGES ][ nI ][ 1 ] ) + fseek( nImageHandle, aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_FROM ] ) + + nBuffer := 8192 + cBuffer := space( nBuffer ) + k := 0 + while k < aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] + IF k + nBuffer <= aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] + nRead := nBuffer + ELSE + nRead := aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] - k + ENDIF + fread( nImageHandle, @cBuffer, nRead ) + + aReport[ DOCLEN ] += nRead + fwrite( aReport[ HANDLE ], cBuffer, nRead ) + k += nRead + enddo + + cTemp := CRLF + "endstream" + CRLF + ; + "endobj" + CRLF + + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + ENDIF + next + + aReport[ REPORTOBJ ] := aReport[ NEXTOBJ ] + + aReport[ NEXTOBJ ] := aReport[ REPORTOBJ ] + 4 + + aReport[ PAGEBUFFER ] := "" + +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfGetFontInfo( cParam ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local cRet + IF cParam == "NAME" + IF left( aReport[ TYPE1 ][ aReport[ FONTNAME ] ], 5 ) == "Times" + cRet := "Times" + ELSEIF left( aReport[ TYPE1 ][ aReport[ FONTNAME ] ], 9 ) == "Helvetica" + cRet := "Helvetica" + ELSE + cRet := "Courier" // 0.04 + ENDIF + ELSE // size + cRet := int(( aReport[ FONTNAME ] - 1 ) % 4) + ENDIF +return cRet + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfImage( cFile, nRow, nCol, cUnits, nHeight, nWidth, cId ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + +DEFAULT nRow to aReport[ REPORTLINE ] +DEFAULT nCol to 0 +DEFAULT nHeight to 0 +DEFAULT nWidth to 0 +DEFAULT cUnits to "R" +DEFAULT cId to "" + + IF aReport[ HEADEREDIT ] + return pdfHeader( "PDFIMAGE", cId, { cFile, nRow, nCol, cUnits, nHeight, nWidth } ) + ENDIF + + IF cUnits == "M" + nRow := aReport[ PAGEY ] - pdfM2Y( nRow ) + nCol := pdfM2X( nCol ) + nHeight := aReport[ PAGEY ] - pdfM2Y( nHeight ) + nWidth := pdfM2X( nWidth ) + ELSEIF cUnits == "R" + //IF .not. lExact + // pdfCheckLine( nRow ) + // nRow := nRow + aReportStyle[ PDFTOP ] + //ENDIF + nRow := aReport[ PAGEY ] - pdfR2D( nRow ) + nCol := pdfM2X( aReport[ PDFLEFT ] ) + ; + nCol * 100.00 / aReport[ REPORTWIDTH ] * ; + ( aReport[ PAGEX ] - pdfM2X( aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 + nHeight := aReport[ PAGEY ] - pdfR2D( nHeight ) + nWidth := pdfM2X( aReport[ PDFLEFT ] ) + ; + nWidth * 100.00 / aReport[ REPORTWIDTH ] * ; + ( aReport[ PAGEX ] - pdfM2X( aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 + ELSEIF cUnits == "D" + ENDIF + + aadd( aReport[ PAGEIMAGES ], { cFile, nRow, nCol, nHeight, nWidth } ) + +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfItalic() /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + IF pdfGetFontInfo("NAME") = "Times" + aReport[ FONTNAME ] := 3 + ELSEIF pdfGetFontInfo("NAME") = "Helvetica" + aReport[ FONTNAME ] := 7 + ELSE + aReport[ FONTNAME ] := 11 // 0.04 + ENDIF + aadd( aReport[ PAGEFONTS ], aReport[ FONTNAME ] ) + IF ascan( aReport[ FONTS ], { |arr| arr[1] == aReport[ FONTNAME ] } ) == 0 + aadd( aReport[ FONTS ], { aReport[ FONTNAME ], ++aReport[ NEXTOBJ ] } ) + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfLen( cString ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local nWidth := 0.00, nI, nLen, nArr, nAdd := ( 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 + For nI:= 1 To nLen + nWidth += aReport[ FONTWIDTH ][ nArr ][ ( asc( substr( cString, nI, 1 )) - 32 ) * 4 + 1 + nAdd ] * 25.4 * aReport[ FONTSIZE ] / 720.00 / 100.00 + Next +return nWidth + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfM2R( mm ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +return int( aReport[ LPI ] * mm / 25.4 ) + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfM2X( n ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +return n * 72 / 25.4 + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfM2Y( n ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +return aReport[ PAGEY ] - n * 72 / 25.4 + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfNewLine( n ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +DEFAULT n to 1 + IF aReport[ REPORTLINE ] + n + aReport[ PDFTOP ] > aReport[ PDFBOTTOM ] + pdfNewPage() + aReport[ REPORTLINE ] += 1 + ELSE + aReport[ REPORTLINE ] += n + ENDIF +return aReport[ REPORTLINE ] + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ*/ +function pdfNewPage( _cPageSize, _cPageOrient, _nLpi, _cFontName, _nFontType, _nFontSize )/* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ*/ +local nAdd := 76.2 +DEFAULT _cPageSize to aReport[ PAGESIZE ] +DEFAULT _cPageOrient to aReport[ PAGEORIENT ] +DEFAULT _nLpi to aReport[ LPI ] +DEFAULT _cFontName to pdfGetFontInfo("NAME") +DEFAULT _nFontType to pdfGetFontInfo("TYPE") +DEFAULT _nFontSize to aReport[ FONTSIZE ] + + IF !empty(aReport[ PAGEBUFFER ]) + pdfClosePage() + ENDIF + + aReport[ PAGEFONTS ] := {} + aReport[ PAGEIMAGES ] := {} + + ++aReport[ REPORTPAGE ] // NEW !!! + + pdfPageSize( _cPageSize ) + pdfPageOrient( _cPageOrient ) + pdfSetLPI( _nLpi ) + + pdfSetFont( _cFontName, _nFontType, _nFontSize ) + + pdfDrawHeader() + + aReport[ REPORTLINE ] := 0//5 + aReport[ FONTNAMEPREV ] := 0 + aReport[ FONTSIZEPREV ] := 0 +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfNormal() /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + IF pdfGetFontInfo("NAME") = "Times" + aReport[ FONTNAME ] := 1 + ELSEIF pdfGetFontInfo("NAME") = "Helvetica" + aReport[ FONTNAME ] := 5 + ELSE + aReport[ FONTNAME ] := 9 // 0.04 + ENDIF + aadd( aReport[ PAGEFONTS ], aReport[ FONTNAME ] ) + IF ascan( aReport[ FONTS ], { |arr| arr[1] == aReport[ FONTNAME ] } ) == 0 + aadd( aReport[ FONTS ], { aReport[ FONTNAME ], ++aReport[ NEXTOBJ ] } ) + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfOpen( cFile, nLen, lOptimize ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local cTemp, nI, nJ, n1, n2 := 896, n12 +DEFAULT nLen to 200 +DEFAULT lOptimize to .f. + + aReport[ FONTNAME ] := 1 + aReport[ FONTSIZE ] := 10 + aReport[ LPI ] := 6 + aReport[ PAGESIZE ] := "LETTER" + aReport[ PAGEORIENT ] := "P" + aReport[ PAGEX ] := 8.5 * 72 + aReport[ PAGEY ] := 11.0 * 72 + aReport[ REPORTWIDTH ] := nLen // 200 // should be as parameter + aReport[ REPORTPAGE ] := 0 + aReport[ REPORTLINE ] := 0 //5 + aReport[ FONTNAMEPREV ] := 0 + aReport[ FONTSIZEPREV ] := 0 + aReport[ PAGEBUFFER ] := "" + aReport[ REPORTOBJ ] := 1 //2 + aReport[ DOCLEN ] := 0 + 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 + aReport[ MARGINS ] := .t. + aReport[ HEADEREDIT ] := .f. + aReport[ NEXTOBJ ] := 0 + aReport[ PDFTOP ] := 1 // top + aReport[ PDFLEFT ] := 10 // left & right + aReport[ PDFBOTTOM ] := aReport[ PAGEY ] / 72 * aReport[ LPI ] - 1 // bottom, default "LETTER", "P", 6 + aReport[ HANDLE ] := fcreate( cFile ) + aReport[ PAGES ] := {} + aReport[ REFS ] := { 0, 0 } + aReport[ BOOKMARK ] := {} + aReport[ HEADER ] := {} + aReport[ FONTS ] := {} + aReport[ IMAGES ] := {} + aReport[ PAGEIMAGES ] := {} + aReport[ PAGEFONTS ] := {} + + // TOFIX: This external file dependency should be removed. + + cTemp := memoread("fonts.dat") // times, times-bold, times-italic, times-bolditalic, helvetica..., courier... // 0.04 + n1 := len( cTemp ) / ( 2 * n2 ) + aReport[ FONTWIDTH ] := array( n1, n2 ) + + aReport[ OPTIMIZE ] := lOptimize + + aReport[ NEXTOBJ ] := aReport[ REPORTOBJ ] + 4 + + n12 := 2 * n2 // 0.04 + for nI := 1 to n1 + for nJ := 1 to n2 + aReport[ FONTWIDTH ][ nI ][ nJ ] := bin2i(substr( cTemp, ( nI - 1 ) * n12 + ( nJ - 1 ) * 2 + 1, 2 )) + next + next + +/* + aReportStyle := { ; + { 2.475, 4.0, 4.9, 6.4, 7.5, 3 , 64.0 , "P6", 60, 10 }, ; + { 3.3 , 5.4, 6.5, 8.6, 10.0, 6 , 85.35, "P8", 78, 10 }, ; + { 2.475, 4.0, 4.9, 6.4, 7.5, 2.9, 48.9 , "L6", 45, 10 }, ; + { 3.3 , 5.4, 6.5, 8.6, 10.0, 5.85, 65.2 , "L8", 58, 10 }, ; + { 2.475, 4.0, 4.9, 6.4, 7.5, 2.9, 82.0 , "P6", 78, 10 }, ; + { 3.3 , 5.4, 6.5, 8.6, 10.0, 6 , 109.35 , "P8", 102, 10 } ; + } +*/ + + aReport[ DOCLEN ] := 0 + cTemp := "%PDF-1.3" + CRLF + aReport[ DOCLEN ] += len( cTemp ) + fwrite( aReport[ HANDLE ], cTemp ) + + //pdfNewPage( "LETTER", "P", 6 ) + +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfPageSize( _cPageSize ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local nSize, 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 } } + +DEFAULT _cPageSize to "LETTER" + + nSize := ascan( aSize, { |arr| arr[ 1 ] = _cPageSize } ) + + IF nSize = 0 //.or. nSize > 2 //0.05 + nSize := 1 + ENDIF + + aReport[ PAGESIZE ] := aSize[ nSize ][ 1 ] + + IF aReport[ PAGEORIENT ] = "P" + aReport[ PAGEX ] := aSize[ nSize ][ 2 ] * 72 + aReport[ PAGEY ] := aSize[ nSize ][ 3 ] * 72 + ELSE + aReport[ PAGEX ] := aSize[ nSize ][ 3 ] * 72 + aReport[ PAGEY ] := aSize[ nSize ][ 2 ] * 72 + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfPageOrient( _cPageOrient ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +DEFAULT _cPageOrient to "P" + + aReport[ PAGEORIENT ] := _cPageOrient + pdfPageSize( aReport[ PAGESIZE ] ) +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfR2D( nRow ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +return aReport[ PAGEY ] - nRow * 72 / aReport[ LPI ] + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +static function pdfR2M( nRow ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +return 25.4 * nRow / aReport[ LPI ] + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfPageNumber( n ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +DEFAULT n to 0 + IF n > 0 + aReport[ REPORTPAGE ] := n // NEW !!! + ENDIF +return aReport[ REPORTPAGE ] + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfReverse( cString ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +return cString + chr(255) + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfRJust( cString, nRow, nCol, cUnits, lExact, cId ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local nLen, nAdj := 1.0, nAt +DEFAULT nRow to aReport[ REPORTLINE ] +DEFAULT cUnits to "R" +DEFAULT lExact to .f. + + IF aReport[ HEADEREDIT ] + return pdfHeader( "PDFRJUST", cId, { cString, nRow, nCol, cUnits, lExact } ) + ENDIF + + IF ( nAt := at( "#pagenumber#", cString ) ) > 0 + cString := left( cString, nAt - 1 ) + ltrim(str( pdfPageNumber())) + substr( cString, nAt + 12 ) + ENDIF + + nLen := pdfLen( cString ) + + IF cUnits == "R" + IF .not. lExact + pdfCheckLine( nRow ) + nRow := nRow + aReport[ PDFTOP ] + ENDIF + ENDIF + pdfAtSay( cString, pdfR2M( nRow ), IIF( cUnits == "R", aReport[ PDFLEFT ] + ( aReport[ PAGEX ] / 72 * 25.4 - 2 * aReport[ PDFLEFT ] ) * nCol / aReport[ REPORTWIDTH ] - nAdj, nCol ) - nLen, "M", lExact ) +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfSetFont( _cFont, _nType, _nSize, cId ) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ + +DEFAULT _cFont to "Times" +DEFAULT _nType to 0 +DEFAULT _nSize to 10 + + IF aReport[ HEADEREDIT ] + return pdfHeader( "PDFSETFONT", cId, { _cFont, _nType, _nSize } ) + ENDIF + + _cFont := upper( _cFont ) + aReport[ FONTSIZE ] := _nSize + + IF _cFont == "TIMES" + aReport[ FONTNAME ] := _nType + 1 + ELSEIF _cFont == "HELVETICA" + aReport[ FONTNAME ] := _nType + 5 + ELSE + aReport[ FONTNAME ] := _nType + 9 // 0.04 + ENDIF + + aadd( aReport[ PAGEFONTS ], aReport[ FONTNAME ] ) + + IF ascan( aReport[ FONTS ], { |arr| arr[1] == aReport[ FONTNAME ] } ) == 0 + aadd( aReport[ FONTS ], { aReport[ FONTNAME ], ++aReport[ NEXTOBJ ] } ) + ENDIF +return nil + /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +function pdfSetLPI(_nLpi) /* +ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ */ +local cLpi := alltrim(str(_nLpi)) +DEFAULT _nLpi to 6 + + cLpi := iif(cLpi$"1;2;3;4;6;8;12;16;24;48",cLpi,"6") + aReport[ LPI ] := val( cLpi ) + + pdfPageSize( 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 +DEFAULT nTab to -1 +DEFAULT cUnits to 'R' +DEFAULT nJustify to 4 // justify +DEFAULT lPrint to .t. +DEFAULT cColor to "" + + IF cUnits == "M" + nTop := pdfM2R( nTop ) + ELSEIF cUnits == "R" + nLeft := pdfX2M( pdfM2X( aReport[ PDFLEFT ] ) + ; + nLeft * 100.00 / aReport[ REPORTWIDTH ] * ; + ( aReport[ PAGEX ] - pdfM2X( aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 ) + ENDIF + + aReport[ REPORTLINE ] := nTop - 1 + + nSpace := pdfLen( " " ) + nLines := 0 + nCRLF := 0 + + nNew := nTab + + cString := alltrim( cString ) + nTokens := numtoken( cString, cDelim ) + nTokenLen := 0.00 + 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 + 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 +/* + nFinish := nI - 1 + + 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 + pdfAtSay( cToken, pdfR2M( nRow + aReportStyle[ aReport[ REPORTSTYLE ] ][ 6 ] ), nL, "M" ) + ENDIF + nL += pdfLen ( cToken ) + nB + next + nStart := nFinish + 1 + ENDIF + + lParagraph := .f. + + nLineLen := 0.00 + nLineLen += nSpace * nNew +*/ + 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 ) + /* + 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 - 1 - nStart ) + ENDIF + for nJ := nStart to nFinish + cToken := token( cString, cDelim, nJ ) + IF lPrint + pdfAtSay( cToken, pdfR2M( nRow + aReportStyle[ aReport[ REPORTSTYLE ] ][ 6 ] ), nL, "M" ) + ENDIF + nL += pdfLen ( cToken ) + nB + next + nStart := nFinish + 1 + + lParagraph := .f. + + nLineLen := 0.00 + nLineLen += nSpace * nNew + */ + ++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 + 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 nErrorCode := 0, nAt +DEFAULT cFile to "" + 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 ) + SWPRUNCMD( "copy " + cFile + " temp.tmp > nul", 0, "", "") + cFile := "temp.tmp" + ENDIF + //aReport[ HEADER ] := FT_RestArr( cFile, @nErrorCode ) + aReport[ HEADER ] := File2Array( cFile ) + ELSE + aReport[ HEADER ] := {} + ENDIF + aReport[ MARGINS ] := .t. +return nil + +function pdfEditOnHeader() + aReport[ HEADEREDIT ] := .t. + aReport[ MARGINS ] := .t. +return nil + +function pdfEditOffHeader() + aReport[ HEADEREDIT ] := .f. + aReport[ MARGINS ] := .t. +return nil + +function pdfCloseHeader() + aReport[ HEADER ] := {} + aReport[ MARGINS ] := .f. +return nil + +function pdfDeleteHeader( cId ) +local nRet := -1, nId + cId := upper( cId ) + nId := ascan( aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + IF nId > 0 + nRet := len( aReport[ HEADER ] ) - 1 + aDel( aReport[ HEADER ], nId ) + aSize( aReport[ HEADER ], nRet ) + aReport[ MARGINS ] := .t. + ENDIF +return nRet + +function pdfEnableHeader( cId ) +local nId + cId := upper( cId ) + nId := ascan( aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + IF nId > 0 + aReport[ HEADER ][ nId ][ 1 ] := .t. + aReport[ MARGINS ] := .t. + ENDIF +return nil + +function pdfDisableHeader( cId ) +local nId + cId := upper( cId ) + nId := ascan( aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + IF nId > 0 + aReport[ HEADER ][ nId ][ 1 ] := .f. + aReport[ MARGINS ] := .t. + ENDIF +return nil + +function pdfSaveHeader( cFile ) +local nErrorCode := 0 + //FT_SaveArr( aReport[ HEADER ], 'temp.tmp', @nErrorCode ) + Array2File( 'temp.tmp', aReport[ HEADER ] ) + SWPRUNCMD( "copy temp.tmp " + cFile + " > nul", 0, "", "") +return nil + +function pdfHeader( cFunction, cId, arr ) +local nId, nI, nLen, nIdLen + nId := 0 + IF !empty( cId ) + cId := upper( cId ) + nId := ascan( aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + ENDIF + IF nId == 0 + nLen := len( aReport[ HEADER ] ) + IF empty( cId ) + cId := cFunction + nIdLen := len( cId ) + for nI := 1 to nLen + IF aReport[ HEADER ][ nI ][ 2 ] == cId + IF val( substr( aReport[ HEADER ][ nI ][ 3 ], nIdLen + 1 ) ) > nId + nId := val( substr( aReport[ HEADER ][ nI ][ 3 ], nIdLen + 1 ) ) + ENDIF + ENDIF + next + ++nId + cId += ltrim(str(nId)) + ENDIF + aadd( aReport[ HEADER ], { .t., cFunction, cId } ) + ++nLen + for nI := 1 to len( arr ) + aadd( aReport[ HEADER ][ nLen ], arr[ nI ] ) + next + ELSE + aSize( aReport[ HEADER ][ nId ], 3 ) + for nI := 1 to len( arr ) + aadd( aReport[ HEADER ][ nId ], arr[ nI ] ) + next + ENDIF +return cId + +function pdfDrawHeader() +local nI, _nFont, _nSize, nLen := len( aReport[ HEADER ] ) + + IF nLen > 0 + + // save font + _nFont := aReport[ FONTNAME ] + _nSize := aReport[ FONTSIZE ] + + for nI := 1 to nLen + IF aReport[ HEADER ][ nI ][ 1 ] // enabled + do case + case aReport[ HEADER ][ nI ][ 2 ] == "PDFATSAY" + pdfAtSay( aReport[ HEADER ][ nI ][ 4 ], aReport[ HEADER ][ nI ][ 5 ], aReport[ HEADER ][ nI ][ 6 ], aReport[ HEADER ][ nI ][ 7 ], aReport[ HEADER ][ nI ][ 8 ], aReport[ HEADER ][ nI ][ 3 ] ) + + case aReport[ HEADER ][ nI ][ 2 ] == "PDFCENTER" + pdfCenter( aReport[ HEADER ][ nI ][ 4 ], aReport[ HEADER ][ nI ][ 5 ], aReport[ HEADER ][ nI ][ 6 ], aReport[ HEADER ][ nI ][ 7 ], aReport[ HEADER ][ nI ][ 8 ], aReport[ HEADER ][ nI ][ 3 ] ) + + case aReport[ HEADER ][ nI ][ 2 ] == "PDFRJUST" + pdfRJust( aReport[ HEADER ][ nI ][ 4 ], aReport[ HEADER ][ nI ][ 5 ], aReport[ HEADER ][ nI ][ 6 ], aReport[ HEADER ][ nI ][ 7 ], aReport[ HEADER ][ nI ][ 8 ], aReport[ HEADER ][ nI ][ 3 ] ) + + case aReport[ HEADER ][ nI ][ 2 ] == "PDFBOX" + pdfBox( aReport[ HEADER ][ nI ][ 4 ], aReport[ HEADER ][ nI ][ 5 ], aReport[ HEADER ][ nI ][ 6 ], aReport[ HEADER ][ nI ][ 7 ], aReport[ HEADER ][ nI ][ 8 ], aReport[ HEADER ][ nI ][ 9 ], aReport[ HEADER ][ nI ][ 10 ], aReport[ HEADER ][ nI ][ 3 ] ) + + case aReport[ HEADER ][ nI ][ 2 ] == "PDFSETFONT" + pdfSetFont( aReport[ HEADER ][ nI ][ 4 ], aReport[ HEADER ][ nI ][ 5 ], aReport[ HEADER ][ nI ][ 6 ], aReport[ HEADER ][ nI ][ 3 ] ) + + case aReport[ HEADER ][ nI ][ 2 ] == "PDFIMAGE" + pdfImage( aReport[ HEADER ][ nI ][ 4 ], aReport[ HEADER ][ nI ][ 5 ], aReport[ HEADER ][ nI ][ 6 ], aReport[ HEADER ][ nI ][ 7 ], aReport[ HEADER ][ nI ][ 8 ], aReport[ HEADER ][ nI ][ 9 ], aReport[ HEADER ][ nI ][ 3 ] ) + + endcase + ENDIF + next + aReport[ FONTNAME ] := _nFont + aReport[ FONTSIZE ] := _nSize + + IF aReport[ MARGINS ] + pdfMargins() + ENDIF + + ELSE + IF aReport[ MARGINS ] + aReport[ PDFTOP ] := 1 // top + aReport[ PDFLEFT ] := 10 // left & right + aReport[ PDFBOTTOM ] := aReport[ PAGEY ] / 72 * aReport[ LPI ] - 1 // bottom, default "LETTER", "P", 6 + + aReport[ MARGINS ] := .f. + ENDIF + ENDIF +return nil + +function pdfMargins( nTop, nLeft, nBottom ) +local nI, nLen := len( aReport[ HEADER ] ), nTemp, aTemp, nHeight + + for nI := 1 to nLen + IF aReport[ HEADER ][ nI ][ 1 ] // enabled + + IF aReport[ HEADER ][ nI ][ 2 ] == "PDFSETFONT" + + ELSEIF aReport[ HEADER ][ nI ][ 2 ] == "PDFIMAGE" + IF aReport[ HEADER ][ nI ][ 8 ] == 0 // picture in header, first at all, not at any page yet + aTemp := pdfImageInfo( aReport[ HEADER ][ nI ][ 4 ] ) + nHeight := aTemp[ IMAGE_HEIGHT ] / aTemp[ IMAGE_YRES ] * 25.4 + IF aReport[ HEADER ][ nI ][ 7 ] == "D" + nHeight := pdfM2X( nHeight ) + ENDIF + ELSE + nHeight := aReport[ HEADER ][ nI ][ 8 ] + ENDIF + + IF aReport[ HEADER ][ nI ][ 7 ] == "M" + + nTemp := aReport[ PAGEY ] / 72 * 25.4 / 2 + + IF aReport[ HEADER ][ nI ][ 5 ] < nTemp + nTemp := ( aReport[ HEADER ][ nI ][ 5 ] + nHeight ) * aReport[ LPI ] / 25.4 // top + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ELSE + nTemp := aReport[ HEADER ][ nI ][ 5 ] * aReport[ LPI ] / 25.4 // top + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + ENDIF + + ELSEIF aReport[ HEADER ][ nI ][ 7 ] == "D" + nTemp := aReport[ PAGEY ] / 2 + + IF aReport[ HEADER ][ nI ][ 5 ] < nTemp + nTemp := ( aReport[ HEADER ][ nI ][ 5 ] + nHeight ) * aReport[ LPI ] / 72 // top + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ELSE + nTemp := aReport[ HEADER ][ nI ][ 5 ] * aReport[ LPI ] / 72 // top + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + + ENDIF + + ENDIF + + ELSEIF aReport[ HEADER ][ nI ][ 2 ] == "PDFBOX" + + IF aReport[ HEADER ][ nI ][ 10 ] == "M" + + nTemp := aReport[ PAGEY ] / 72 * 25.4 / 2 + + IF aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + aReport[ HEADER ][ nI ][ 6 ] < nTemp + nTemp := aReport[ HEADER ][ nI ][ 6 ] * aReport[ LPI ] / 25.4 // top + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ELSEIF aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + aReport[ HEADER ][ nI ][ 6 ] > nTemp + + nTemp := ( aReport[ HEADER ][ nI ][ 4 ] + aReport[ HEADER ][ nI ][ 8 ] ) * aReport[ LPI ] / 25.4 // top + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + + nTemp := ( aReport[ HEADER ][ nI ][ 6 ] - aReport[ HEADER ][ nI ][ 8 ] ) * aReport[ LPI ] / 25.4 // top + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + + ELSEIF aReport[ HEADER ][ nI ][ 4 ] > nTemp .and. ; + aReport[ HEADER ][ nI ][ 6 ] > nTemp + nTemp := aReport[ HEADER ][ nI ][ 4 ] * aReport[ LPI ] / 25.4 // top + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + ENDIF + + ELSEIF aReport[ HEADER ][ nI ][ 10 ] == "D" + nTemp := aReport[ PAGEY ] / 2 + + IF aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + aReport[ HEADER ][ nI ][ 6 ] < nTemp + nTemp := aReport[ HEADER ][ nI ][ 6 ] / aReport[ LPI ] // top + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ELSEIF aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + aReport[ HEADER ][ nI ][ 6 ] > nTemp + + nTemp := ( aReport[ HEADER ][ nI ][ 4 ] + aReport[ HEADER ][ nI ][ 8 ] ) / aReport[ LPI ] // top + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + + nTemp := ( aReport[ HEADER ][ nI ][ 6 ] - aReport[ HEADER ][ nI ][ 8 ] ) / aReport[ LPI ] // top + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + + ELSEIF aReport[ HEADER ][ nI ][ 4 ] > nTemp .and. ; + aReport[ HEADER ][ nI ][ 6 ] > nTemp + nTemp := aReport[ HEADER ][ nI ][ 4 ] / aReport[ LPI ] // top + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + ENDIF + + ENDIF + + ELSE + IF aReport[ HEADER ][ nI ][ 7 ] == "R" + nTemp := aReport[ HEADER ][ nI ][ 5 ] // top + IF aReport[ HEADER ][ nI ][ 5 ] > aReport[ PAGEY ] / 72 * aReport[ LPI ] / 2 + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + ELSE + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ENDIF + ELSEIF aReport[ HEADER ][ nI ][ 7 ] == "M" + nTemp := aReport[ HEADER ][ nI ][ 5 ] * aReport[ LPI ] / 25.4 // top + IF aReport[ HEADER ][ nI ][ 5 ] > aReport[ PAGEY ] / 72 * 25.4 / 2 + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + ELSE + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ENDIF + ELSEIF aReport[ HEADER ][ nI ][ 7 ] == "D" + nTemp := aReport[ HEADER ][ nI ][ 5 ] / aReport[ LPI ] // top + IF aReport[ HEADER ][ nI ][ 5 ] > aReport[ PAGEY ] / 2 + IF nTemp < aReport[ PDFBOTTOM ] + aReport[ PDFBOTTOM ] := nTemp + ENDIF + ELSE + IF nTemp > aReport[ PDFTOP ] + aReport[ PDFTOP ] := nTemp + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + next + + IF nTop <> NIL + aReport[ PDFTOP ] := nTop + ENDIF + IF nLeft <> NIL + aReport[ PDFLEFT ] := nLeft + ENDIF + IF nBottom <> NIL + aReport[ PDFBOTTOM ] := nBottom + ENDIF + + aReport[ MARGINS ] := .f. + +return nil + +/* + aReportStyle := { ; + { 2.475, 4.0, 4.9, 6.4, 7.5, 3 , 64.0 , "P6", 60, 10 }, ; + { 3.3 , 5.4, 6.5, 8.6, 10.0, 6 , 85.35, "P8", 78, 10 }, ; + { 2.475, 4.0, 4.9, 6.4, 7.5, 2.9, 48.9 , "L6", 45, 10 }, ; + { 3.3 , 5.4, 6.5, 8.6, 10.0, 5.85, 65.2 , "L8", 58, 10 }, ; + { 2.475, 4.0, 4.9, 6.4, 7.5, 2.9, 82.0 , "P6", 78, 10 }, ; + { 3.3 , 5.4, 6.5, 8.6, 10.0, 6 , 109.35 , "P8", 102, 10 } ; + } +*/ +function pdfCreateHeader( _file, _size, _orient, _lpi, _width ) +local ; + 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 + +DEFAULT _size to aReport[ PAGESIZE ] +DEFAULT _orient to aReport[ PAGEORIENT ] +DEFAULT _lpi to aReport[ LPI ] +DEFAULT _width to 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", aReportStyle[ nStyle ][ 1 ], 1, "R", .t. ) + + pdfSetFont("Times", BOLD, 18) + pdfCenter( "Test Line 2", aReportStyle[ nStyle ][ 2 ],,"R", .t. ) + + pdfSetFont("Times", BOLD, 12) + pdfCenter( "Test Line 3", aReportStyle[ nStyle ][ 3 ],,"R", .t. ) + + pdfSetFont("Helvetica", BOLD, 10) // 0.04 + pdfAtSay( "Test Line 4", aReportStyle[ nStyle ][ 4 ], 1, "R", .t. ) + + pdfSetFont("Helvetica", BOLD, 10) // 0.04 + pdfAtSay( "Test Line 5", aReportStyle[ nStyle ][ 5 ], 1, "R", .t. ) + + pdfAtSay( dtoc( date()) + " " + TimeAsAMPM( time() ), aReportStyle[ nStyle ][ 6 ], 1, "R", .t. ) + pdfRJust( "Page: #pagenumber#", aReportStyle[ nStyle ][ 6 ], 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, cTag, nPages, nn + +local nWidth := 0, nHeight := 0, nBits := 0, nFrom := 0, nLength := 0, xRes := 0, yRes := 0, aTemp := {} + + nHandle := fopen( cFile ) + + c2 := ' ' + fread( nHandle, @c2, 2 ) +/* +if c2 == 'II' .or. c2 == 'MM' +else + alert("Not II or MM") +endif +*/ + fread( nHandle, @c2, 2 ) +/* +if c2 <> '*' + chr(0) + alert("Not *") +endif +*/ + cIFDNext := ' ' + fread( nHandle, @cIFDNext, 4 ) + + cTemp := space(12) + nPages := 0 + + while cIFDNext <> c40 //read IFD's + + nIFD := bin2l( cIFDNext ) + + fseek( nHandle, nIFD ) + //?'*** IFD ' + ltrim(str( ++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 nFieldType <> SHORT .and. nFieldType <> LONG + alert('Wrong Type for ImageWidth') + 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 nFieldType <> SHORT .and. nFieldType <> LONG + alert('Wrong Type for ImageLength') + 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 + /* + ??padr( cTag, 30 ) + ??' type ' + padr(aType[ nFieldType ], 10) + ' count ' + ltrim(str(nCount)) + ' <' + do case + case nFieldType == BYTE + for nI := 1 to nCount + ??' ' + ltrim(str(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 + ??' ' + ltrim(str(bin2w(substr( cValues, ( nI - 1 ) * 2 + 1, 2 )))) + next + case nFieldType == LONG + for nI := 1 to nCount + ??' ' + ltrim(str(bin2l(substr( cValues, ( nI - 1 ) * 4 + 1, 4 )))) + next + case nFieldType == RATIONAL + for nI := 1 to nCount + ??' ' + ltrim(str(bin2l(substr( cValues, ( nI - 1 ) * 8 + 1, 4 )))) + '/' + ltrim(str(bin2l(substr( cValues, nI + 4, 4 )))) + next + case nFieldType == SBYTE + for nI := 1 to nCount + ??' ' + ltrim(str(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 + ??' ' + ltrim(str(bin2i(substr( cValues, ( nI - 1 ) * 2 + 1, 2 )))) + next + case nFieldType == SLONG + for nI := 1 to nCount + ??' ' + ltrim(str(bin2l(substr( cValues, ( nI - 1 ) * 4 + 1, 4 )))) + next + case nFieldType == SRATIONAL + for nI := 1 to nCount + ??' ' + ltrim(str(bin2l(substr( cValues, ( nI - 1 ) * 8 + 1, 4 )))) + '/' + ltrim(str(bin2l(substr( cValues, nI + 4, 4 )))) + next + case nFieldType == FLOAT + case nFieldType == DOUBLE + for nI := 1 to nCount + ??' ' + ltrim(str(ctof(substr( cValues, ( nI - 1 ) * 8 + 1, 8 )))) + next + + endcase + ??' >' + */ + 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 ) + +return aTemp + +function pdfJPEGInfo( cFile ) +local c255, nAt, nHandle +local nWidth := 0, nHeight := 0, nBits := 8, nFrom := 0, nLength := 0, xRes := 0, yRes := 0, aTemp := {} + + nHandle := fopen( cFile ) + + c255 := space(1024) + fread( nHandle, @c255, 1024 ) + + 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 := at( 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 )) + + fclose( nHandle ) + + nLength := filesize( cFile ) + + aadd( aTemp, nWidth ) + aadd( aTemp, nHeight ) + aadd( aTemp, xRes ) + aadd( aTemp, yRes ) + aadd( aTemp, nBits ) + aadd( aTemp, nFrom ) + aadd( aTemp, nLength ) + +return aTemp + +FUNCTION FilePos( nHandle ) +RETURN ( FSEEK( nHandle, 0, FS_RELATIVE ) ) + +FUNCTION pdfFilePrint( cFile ) +LOCAL cRun := "d:\progra~2\Adobe\Acroba~2.0\Reader\AcroRd32.exe /t " + cFile + " " + chr(34) + "HP LaserJet 5/5M PostScript" + chr(34) + " " + chr(34) + "LPT1" + chr(34) + +IF (!SWPRUNCMD( cRun, 0, "", "")) + alert("Error printing to PDF reader.") + break +ENDIF +//"C:\Program Files\Adobe\Acrobat 4.0\Reader\acrord32.exe" /t "%1" +//"HP LJ4 Legal" "HP Laserjet 4 Plus" "LPT3" +RETURN nil + +/* +function pdfAtSay( cString, nRow, nCol, cUnits, lExact ) +function pdfBold() +function pdfBoldItalic() +function pdfBookAdd( cTitle, nLevel, nPage, nLine ) +function pdfBookClose( ) +function pdfBookCount( nRecno, nCurLevel ) +function pdfBookFirst( nRecno, nCurLevel, nObj ) +function pdfBookLast( nRecno, nCurLevel, nObj ) +function pdfBookNext( nRecno, nCurLevel, nObj ) +function pdfBookOpen( ) +function pdfBookParent( nRecno, nCurLevel, nObj ) +function pdfBookPrev( nRecno, nCurLevel, nObj ) +function pdfBox( x1, y1, x2, y2, nBorder, nShade, cUnits ) +function pdfCenter( cString, nRow, nCol, cUnits, lExact ) +function pdfCheckLine( nRow ) +function pdfClose() +function pdfClosePage() +function pdfGetFontInfo( cParam ) +function pdfItalic() +function pdfLen( cString ) +function pdfM2X( n ) +function pdfM2Y( n ) +function pdfNewPage( _cPageSize, _cPageOrient, _nLpi, _cFontName, _nFontType, _nFontSize ) +function pdfNormal() +function pdfOpen() +function pdfPageSize( _cPageSize ) +function pdfPageOrient( _cPageOrient ) +function pdfR2D( nRow ) +function pdfR2M( nRow ) +function pdfReverse( cString ) +function pdfRJust( cString, nRow, nCol, cUnits, lExact ) +function pdfSetFont( _cFont, _nType, _nSize ) +function pdfSetLPI(_nLpi) +function pdfStringB( cString ) +function pdfUnderLine( cString ) +function TimeAsAMPM( cTime ) +*/ + +FUNCTION Chr_RGB( cChar ) +RETURN str(asc( cChar ) / 255, 4, 2) + +FUNCTION NumToken( cString, cDelimiter ) +RETURN AllToken( cString, cDelimiter ) + +FUNCTION Token( cString, cDelimiter, nPointer ) +RETURN AllToken( cString, cDelimiter, nPointer, 1 ) + +FUNCTION AtToken( cString, cDelimiter, nPointer ) +RETURN AllToken( cString, cDelimiter, nPointer, 2 ) + +FUNCTION AllToken( cString, cDelimiter, nPointer, nAction ) +LOCAL nTokens := 0, nPos := 1, nLen := len( cString ), nStart := 0, cToken := "", cRet +DEFAULT cDelimiter to chr(0)+chr(9)+chr(10)+chr(13)+chr(26)+chr(32)+chr(138)+chr(141) +DEFAULT nAction to 0 + +// nAction == 0 - numtoken +// nAction == 1 - token +// nAction == 2 - attoken + + while nPos <= nLen + if .not. substr( cString, nPos, 1 ) $ cDelimiter + nStart := nPos + while nPos <= nLen .and. .not. 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 + +FUNCTION NumAt( cSearch, cString ) + LOCAL n := 0, nAt := 0, nPos := 0 + WHILE ( nAt := at( cSearch, substr( cString, nPos + 1 ) )) > 0 + nPos += nAt + ++n + ENDDO +RETURN n + +FUNCTION FileSize( cFile ) + + LOCAL nLength + LOCAL nHandle + + nHandle := fopen( cFile ) + nLength := FSEEK( nHandle, 0, FS_END ) + fclose( nHandle ) + +RETURN ( nLength ) + +// next 3 function written by Peter Kulek +//modified for compatibility with common.ch by V.K. +//modified DATE processing by V.K. +function Array2File(cFile,aRay,nDepth,hFile) +local nBytes := 0 +local i +nDepth := if(ISNUMBER(nDepth),nDepth,0) +if hFile == NIL + if (hFile := fCreate(cFile,FC_NORMAL)) == -1 + return(nBytes) + endif +endif +nDepth++ +nBytes += WriteData(hFile,aRay) +if 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 ISCHARACTER(xData) + cData += i2bin(len(xData))+xData + elseif ISNUMBER(xData) + cData += i2bin(len(alltrim(str(xData))) )+alltrim(str(xData)) + elseif ISDATE(xData) + cData += i2bin(8)+dtos(xData) + elseif ISLOGICAL(xData) + cData += i2bin(1)+if(xData,'T','F') + elseif ISARRAY(xData) + cData += i2bin(len(xData)) + else + cData += i2bin(0) // NIL + endif +return( fWrite(hFile,cData,len(cData)) ) + +function File2Array(cFile,nLen,hFile) +LOCAL cData,cType,nDataLen,nBytes +local nDepth := 0 +local aRay := {} +if hFile == NIL + if (hFile:=fOpen(cFile,FO_READ)) == -1 + 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 [ FROM ] => CLASS [ FROM ] + #command MESSAGE METHOD => METHOD IS + #command CLASS MESSAGE METHOD => CLASS METHOD IS +#endif + +#ifdef __CLP__ // Clipper + #include 'class(y).ch' +#endif + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#include 'hbvpdf.ch' + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +CREATE CLASS tPdf + +#ifndef __HARBOUR__ +EXPORT: +#endif + +VAR aReport + +#ifndef __HARBOUR__ +EXPORT: +#endif + +#ifdef __HARBOUR__ +METHOD Init( cFile, nLen, lOptimize ) CONSTRUCTOR +#else +METHOD Init +#endif + +METHOD AtSay +METHOD Normal +METHOD Bold +METHOD Italic +METHOD UnderLine +METHOD BoldItalic +METHOD BookAdd +METHOD BookClose +METHOD BookOpen +METHOD Box +METHOD Box1 +METHOD Center +METHOD Close +METHOD Image +METHOD Length +METHOD NewLine +METHOD NewPage +METHOD PageSize +METHOD PageOrient +METHOD PageNumber +METHOD Reverse +METHOD RJust +METHOD SetFont +METHOD SetLPI +METHOD StringB +METHOD TextCount +METHOD Text +METHOD OpenHeader +METHOD EditOnHeader +METHOD EditOffHeader +METHOD CloseHeader +METHOD DeleteHeader +METHOD EnableHeader +METHOD DisableHeader +METHOD SaveHeader +METHOD Header +METHOD DrawHeader +METHOD Margins +METHOD CreateHeader +METHOD ImageInfo +METHOD TIFFInfo +METHOD JPEGInfo +METHOD FilePrint +METHOD BookCount +METHOD BookFirst +METHOD BookLast +METHOD BookNext +METHOD BookParent +METHOD BookPrev +METHOD CheckLine +METHOD ClosePage +METHOD GetFontInfo +METHOD M2R +METHOD M2X +METHOD M2Y +METHOD R2D +METHOD R2M +METHOD X2M +METHOD TextPrint +METHOD TextNextPara +METHOD Execute + +ENDCLASS + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Init( cFile, nLen, lOptimize ) +#else +METHOD Init( cFile, nLen, lOptimize ) +#endif + +local cTemp, nI, nJ, n1, n2 := 896, n12 + +DEFAULT nLen TO 200 +DEFAULT lOptimize TO .f. + +::aReport := array( PARAMLEN ) + +::aReport[ FONTNAME ] := 1 +::aReport[ FONTSIZE ] := 10 +::aReport[ LPI ] := 6 +::aReport[ PAGESIZE ] := "LETTER" +::aReport[ PAGEORIENT ] := "P" +::aReport[ PAGEX ] := 8.5 * 72 +::aReport[ PAGEY ] := 11.0 * 72 +::aReport[ REPORTWIDTH ] := nLen // 200 // should be as parameter +::aReport[ REPORTPAGE ] := 0 +::aReport[ REPORTLINE ] := 0 // 5 +::aReport[ FONTNAMEPREV ] := 0 +::aReport[ FONTSIZEPREV ] := 0 +::aReport[ PAGEBUFFER ] := "" +::aReport[ REPORTOBJ ] := 1 //2 +::aReport[ DOCLEN ] := 0 +::aReport[ TYPE1 ] := { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", ; + "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", ; + "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" } +::aReport[ MARGINS ] := .t. +::aReport[ HEADEREDIT ] := .f. +::aReport[ NEXTOBJ ] := 0 +::aReport[ PDFTOP ] := 1 // top +::aReport[ PDFLEFT ] := 10 // left & right +::aReport[ PDFBOTTOM ] := ::aReport[ PAGEY ] / 72 * ::aReport[ LPI ] - 1 // bottom, default "LETTER", "P", 6 +::aReport[ HANDLE ] := fcreate( cFile ) +::aReport[ PAGES ] := {} +::aReport[ REFS ] := { 0, 0 } +::aReport[ BOOKMARK ] := {} +::aReport[ HEADER ] := {} +::aReport[ FONTS ] := {} +::aReport[ IMAGES ] := {} +::aReport[ PAGEIMAGES ] := {} +::aReport[ PAGEFONTS ] := {} + +// TOFIX: This external file dependency should be removed. + +cTemp := memoread( "fonts.dat" ) +n1 := len( cTemp ) / ( 2 * n2 ) +::aReport[ FONTWIDTH ] := array( n1, n2 ) + +::aReport[ OPTIMIZE ] := lOptimize +::aReport[ NEXTOBJ ] := ::aReport[ REPORTOBJ ] + 4 + +n12 := 2 * n2 +for nI := 1 to n1 + for nJ := 1 to n2 + ::aReport[ FONTWIDTH ][ nI ][ nJ ] := bin2i( substr( cTemp, ( nI - 1 ) * n12 + ( nJ - 1 ) * 2 + 1, 2 ) ) + next +next + +::aReport[ DOCLEN ] := 0 +cTemp := "%PDF-1.3" + CRLF +::aReport[ DOCLEN ] += len( cTemp ) + +fwrite( ::aReport[ HANDLE ], cTemp ) + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:AtSay( cString, nRow, nCol, cUnits, lExact, cId ) +#else +METHOD AtSay( cString, nRow, nCol, cUnits, lExact, cId ) +#endif + +local _nFont, lReverse, nAt + +DEFAULT nRow TO ::aReport[ REPORTLINE ] +DEFAULT cUnits TO "R" +DEFAULT lExact TO .f. +DEFAULT cId TO "" + + IF ::aReport[ HEADEREDIT ] + return ::Header( "PDFATSAY", cId, { cString, nRow, nCol, cUnits, lExact } ) + ENDIF + + IF ( nAt := at( "#pagenumber#", cString ) ) > 0 + cString := left( cString, nAt - 1 ) + ltrim(str( ::PageNumber())) + substr( cString, nAt + 12 ) + ENDIF + + lReverse = .f. + IF cUnits == "M" + nRow := ::M2Y( nRow ) + nCol := ::M2X( nCol ) + ELSEIF cUnits == "R" + IF .not. lExact + ::CheckLine( nRow ) + nRow := nRow + ::aReport[ PDFTOP] + ENDIF + nRow := ::R2D( nRow ) + nCol := ::M2X( ::aReport[ PDFLEFT ] ) + ; + nCol * 100.00 / ::aReport[ REPORTWIDTH ] * ; + ( ::aReport[ PAGEX ] - ::M2X( ::aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 + ENDIF + IF !empty( cString ) + cString := ::StringB( cString ) + IF right( cString, 1 ) == chr(255) //reverse + cString := left( cString, len( cString ) - 1 ) + ::Box( ::aReport[ PAGEY ] - nRow - ::aReport[ FONTSIZE ] + 2.0 , nCol, ::aReport[ PAGEY ] - nRow + 2.0, nCol + ::M2X( ::length( cString )) + 1,,100, "D") + ::aReport[ PAGEBUFFER ] += " 1 g " + lReverse = .t. + ELSEIF right( cString, 1 ) == chr(254) //underline + cString := left( cString, len( cString ) - 1 ) + ::Box( ::aReport[ PAGEY ] - nRow + 0.5, nCol, ::aReport[ PAGEY ] - nRow + 1, nCol + ::M2X( ::length( cString )) + 1,,100, "D") + ENDIF + + // version 0.01 + IF ( nAt := at( chr(253), cString )) > 0 // some color text inside + ::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( ::aReport[ FONTS ], {|arr| arr[1] == ::aReport[ FONTNAME ]} ) + IF ::aReport[ FONTNAME ] <> ::aReport[ FONTNAMEPREV ] + ::aReport[ FONTNAMEPREV ] := ::aReport[ FONTNAME ] + ::aReport[ PAGEBUFFER ] += CRLF + "BT /Fo" + ltrim(str( _nFont )) + " " + ltrim(transform( ::aReport[ FONTSIZE ], "999.99")) + " Tf " + ltrim(transform( nCol, "9999.99" )) + " " + ltrim(transform( nRow, "9999.99" )) + " Td (" + cString + ") Tj ET" + ELSEIF ::aReport[ FONTSIZE ] <> ::aReport[ FONTSIZEPREV ] + ::aReport[ FONTSIZEPREV ] := ::aReport[ FONTSIZE ] + ::aReport[ PAGEBUFFER ] += CRLF + "BT /Fo" + ltrim(str( _nFont )) + " " + ltrim(transform( ::aReport[ FONTSIZE ], "999.99")) + " Tf " + ltrim(transform( nCol, "9999.99" )) + " " + ltrim(transform( nRow, "9999.99" )) + " Td (" + cString + ") Tj ET" + ELSE + ::aReport[ PAGEBUFFER ] += CRLF + "BT " + ltrim(transform( nCol, "9999.99" )) + " " + ltrim(transform( nRow, "9999.99" )) + " Td (" + cString + ") Tj ET" + ENDIF + IF lReverse + ::aReport[ PAGEBUFFER ] += " 0 g " + ENDIF + ENDIF + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Normal() +#else +METHOD Normal() +#endif +local cName := ::GetFontInfo( "NAME" ) + + IF cName = "Times" + ::aReport[ FONTNAME ] := 1 + ELSEIF cName = "Helvetica" + ::aReport[ FONTNAME ] := 5 + ELSE + ::aReport[ FONTNAME ] := 9 + ENDIF + aadd( ::aReport[ PAGEFONTS ], ::aReport[ FONTNAME ] ) + IF ascan( ::aReport[ FONTS ], { |arr| arr[1] == ::aReport[ FONTNAME ] } ) == 0 + aadd( ::aReport[ FONTS ], { ::aReport[ FONTNAME ], ++::aReport[ NEXTOBJ ] } ) + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Italic() +#else +METHOD Italic() +#endif +local cName := ::GetFontInfo( "NAME" ) + + IF cName = "Times" + ::aReport[ FONTNAME ] := 3 + ELSEIF cName = "Helvetica" + ::aReport[ FONTNAME ] := 7 + ELSE + ::aReport[ FONTNAME ] := 11 + ENDIF + aadd( ::aReport[ PAGEFONTS ], ::aReport[ FONTNAME ] ) + IF ascan( ::aReport[ FONTS ], { |arr| arr[1] == ::aReport[ FONTNAME ] } ) == 0 + aadd( ::aReport[ FONTS ], { ::aReport[ FONTNAME ], ++::aReport[ NEXTOBJ ] } ) + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Bold() +#else +METHOD Bold() +#endif +local cName := ::GetFontInfo( "NAME" ) + + IF cName == "Times" + ::aReport[ FONTNAME ] := 2 + ELSEIF cName == "Helvetica" + ::aReport[ FONTNAME ] := 6 + ELSEIF cName == 'Courier' + ::aReport[ FONTNAME ] := 10 // Courier // 0.04 + ENDIF + + aadd( ::aReport[ PAGEFONTS ], ::aReport[ FONTNAME ] ) + IF ascan( ::aReport[ FONTS ], { |arr| arr[1] == ::aReport[ FONTNAME ] } ) == 0 + aadd( ::aReport[ FONTS ], { ::aReport[ FONTNAME ], ++::aReport[ NEXTOBJ ] } ) + ENDIF + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BoldItalic() +#else +METHOD BoldItalic() +#endif +local cName := ::GetFontInfo( "NAME" ) + +IF cName == "Times" + ::aReport[ FONTNAME ] := 4 +ELSEIF cName == "Helvetica" + ::aReport[ FONTNAME ] := 8 +ELSEIF cName == 'Courier' + ::aReport[ FONTNAME ] := 12 // 0.04 +ENDIF + +aadd( ::aReport[ PAGEFONTS ], ::aReport[ FONTNAME ] ) +IF ascan( ::aReport[ FONTS ], { |arr| arr[1] == ::aReport[ FONTNAME ] } ) == 0 + aadd( ::aReport[ FONTS ], { ::aReport[ FONTNAME ], ++::aReport[ NEXTOBJ ] } ) +ENDIF + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookAdd( cTitle, nLevel, nPage, nLine ) +#else +METHOD BookAdd( cTitle, nLevel, nPage, nLine ) +#endif + +aadd( ::aReport[ BOOKMARK ], { nLevel, alltrim( cTitle ), 0, 0, 0, 0, 0, 0, nPage, IIF( nLevel == 1, ::aReport[ PAGEY ], ::aReport[ PAGEY ] - nLine * 72 / ::aReport[ LPI ] ) }) + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookClose( ) +#else +METHOD BookClose( ) +#endif + +::aReport[ BOOKMARK ] := nil + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookOpen( ) +#else +METHOD BookOpen( ) +#endif + +::aReport[ BOOKMARK ] := {} + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Box( x1, y1, x2, y2, nBorder, nShade, cUnits, cColor, cId ) +#else +METHOD Box( x1, y1, x2, y2, nBorder, nShade, cUnits, cColor, cId ) +#endif + +local cBoxColor + +DEFAULT nBorder TO 0 +DEFAULT nShade TO 0 +DEFAULT cUnits TO "M" +DEFAULT cColor TO "" + + 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 + + IF ::aReport[ HEADEREDIT ] + return ::Header( "PDFBOX", cId, { x1, y1, x2, y2, nBorder, nShade, cUnits } ) + ENDIF + + IF cUnits == "M" + y1 += 0.5 + y2 += 0.5 + + IF nShade > 0 + ::aReport[ PAGEBUFFER ] += CRLF + transform( 1.00 - nShade / 100.00, "9.99") + " g " + cBoxColor + ltrim(str(::M2X( y1 ))) + " " + ltrim(str(::M2Y( x1 ))) + " " + ltrim(str(::M2X( y2 - y1 ))) + " -" + ltrim(str(::M2X( x2 - x1 ))) + " re f 0 g" + ENDIF + + IF nBorder > 0 + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(::M2X( y1 ))) + " " + ltrim(str(::M2Y( x1 ))) + " " + ltrim(str(::M2X( y2 - y1 ))) + " -" + ltrim(str(::M2X( nBorder ))) + " re f" + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(::M2X( y2 - nBorder ))) + " " + ltrim(str(::M2Y( x1 ))) + " " + ltrim(str(::M2X( nBorder ))) + " -" + ltrim(str(::M2X( x2 - x1 ))) + " re f" + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(::M2X( y1 ))) + " " + ltrim(str(::M2Y( x2 - nBorder ))) + " " + ltrim(str(::M2X( y2 - y1 ))) + " -" + ltrim(str(::M2X( nBorder ))) + " re f" + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str(::M2X( y1 ))) + " " + ltrim(str(::M2Y( x1 ))) + " " + ltrim(str(::M2X( nBorder ))) + " -" + ltrim(str(::M2X( x2 - x1 ))) + " re f" + ENDIF + ELSEIF cUnits == "D" // "Dots" + IF nShade > 0 + ::aReport[ PAGEBUFFER ] += CRLF + transform( 1.00 - nShade / 100.00, "9.99") + " g " + cBoxColor + ltrim(str( y1 )) + " " + ltrim(str( ::aReport[ PAGEY ] - x1 )) + " " + ltrim(str( y2 - y1 )) + " -" + ltrim(str( x2 - x1 )) + " re f 0 g" + ENDIF + + IF nBorder > 0 +/* + 1 + ÚÄÄÄÄÄ¿ + 4 ³ ³ 2 + ÀÄÄÄÄÄÙ + 3 +*/ + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y1 )) + " " + ltrim(str( ::aReport[ PAGEY ] - x1 )) + " " + ltrim(str( y2 - y1 )) + " -" + ltrim(str( nBorder )) + " re f" + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y2 - nBorder )) + " " + ltrim(str( ::aReport[ PAGEY ] - x1 )) + " " + ltrim(str( nBorder )) + " -" + ltrim(str( x2 - x1 )) + " re f" + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y1 )) + " " + ltrim(str( ::aReport[ PAGEY ] - x2 + nBorder )) + " " + ltrim(str( y2 - y1 )) + " -" + ltrim(str( nBorder )) + " re f" + ::aReport[ PAGEBUFFER ] += CRLF + "0 g " + ltrim(str( y1 )) + " " + ltrim(str( ::aReport[ PAGEY ] - x1 )) + " " + ltrim(str( nBorder )) + " -" + ltrim(str( x2 - x1 )) + " re f" + ENDIF + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Box1( nTop, nLeft, nBottom, nRight, nBorderWidth, cBorderColor, cBoxColor ) +#else +METHOD Box1( nTop, nLeft, nBottom, nRight, nBorderWidth, cBorderColor, cBoxColor ) +#endif + +DEFAULT nBorderWidth to 0.5 +DEFAULT cBorderColor to chr(0) + chr(0) + chr(0) +DEFAULT cBoxColor to chr(255) + chr(255) + chr(255) + + ::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 + ltrim(str( nBorderWidth )) + " w" + ; + CRLF + ltrim( str ( nLeft + nBorderWidth / 2 )) + " " + ; + CRLF + ltrim( str ( ::aReport[ PAGEY ] - nBottom + nBorderWidth / 2)) + " " + ; + CRLF + ltrim( str ( nRight - nLeft - nBorderWidth )) + ; + CRLF + ltrim( str ( nBottom - nTop - nBorderWidth )) + " " + ; + " re" + ; + CRLF + "B" +return nil + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Center( cString, nRow, nCol, cUnits, lExact, cId ) +#else +METHOD Center( cString, nRow, nCol, cUnits, lExact, cId ) +#endif + +local nLen, nAt +DEFAULT nRow TO ::aReport[ REPORTLINE ] +DEFAULT cUnits TO "R" +DEFAULT lExact TO .f. +DEFAULT nCol TO IIF( cUnits == "R", ::aReport[ REPORTWIDTH ] / 2, ::aReport[ PAGEX ] / 72 * 25.4 / 2 ) + + IF ::aReport[ HEADEREDIT ] + return ::Header( "PDFCENTER", cId, { cString, nRow, nCol, cUnits, lExact } ) + ENDIF + + IF ( nAt := at( "#pagenumber#", cString ) ) > 0 + cString := left( cString, nAt - 1 ) + ltrim(str( ::PageNumber())) + substr( cString, nAt + 12 ) + ENDIF + + nLen := ::length( cString ) / 2 + IF cUnits == "R" + IF .not. lExact + ::CheckLine( nRow ) + nRow := nRow + ::aReport[ PDFTOP] + ENDIF + ENDIF + ::AtSay( cString, ::R2M( nRow ), IIF( cUnits == "R", ::aReport[ PDFLEFT ] + ( ::aReport[ PAGEX ] / 72 * 25.4 - 2 * ::aReport[ PDFLEFT ] ) * nCol / ::aReport[ REPORTWIDTH ], nCol ) - nLen, "M", lExact ) +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Close() +#else +METHOD Close() +#endif + +local nI, cTemp, nCurLevel, nObj1, nLast, nCount, nFirst, nRecno, nBooklen + +// FIELD FIRST, PREV, NEXT, LAST, COUNT, PARENT, PAGE, COORD, TITLE, LEVEL + + ::ClosePage() + + // kids + ::aReport[ REFS ][ 2 ] := ::aReport[ DOCLEN ] + cTemp := ; + "1 0 obj"+CRLF+; + "<<"+CRLF+; + "/Type /Pages /Count " + ltrim(str(::aReport[ REPORTPAGE ])) + CRLF +; + "/Kids [" + + for nI := 1 to ::aReport[ REPORTPAGE ] + cTemp += " " + ltrim(str( ::aReport[ PAGES ][ nI ] )) + " 0 R" + next + + cTemp += " ]" + CRLF + ; + ">>" + CRLF + ; + "endobj" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + // info + ++::aReport[ REPORTOBJ ] + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + cTemp := ltrim(str( ::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 + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + // root + ++::aReport[ REPORTOBJ ] + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + cTemp := ltrim(str( ::aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + ; + "<< /Type /Catalog /Pages 1 0 R /Outlines " + ltrim(str( ::aReport[ REPORTOBJ ] + 1 )) + " 0 R" + IIF( ( nBookLen := len( ::aReport[ BOOKMARK ] )) > 0, " /PageMode /UseOutlines", "") + " >>" + CRLF + "endobj" + CRLF + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + ++::aReport[ REPORTOBJ ] + nObj1 := ::aReport[ REPORTOBJ ] + + IF nBookLen > 0 + + nRecno := 1 + nFirst := ::aReport[ REPORTOBJ ] + 1 + nLast := 0 + nCount := 0 + while nRecno <= nBookLen + nCurLevel := ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + ::aReport[ BOOKMARK ][ nRecno ][ BOOKPARENT ] := ::BookParent( nRecno, nCurLevel, ::aReport[ REPORTOBJ ] ) + ::aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] := ::BookPrev( nRecno, nCurLevel, ::aReport[ REPORTOBJ ] ) + ::aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] := ::BookNext( nRecno, nCurLevel, ::aReport[ REPORTOBJ ] ) + ::aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] := ::BookFirst( nRecno, nCurLevel, ::aReport[ REPORTOBJ ] ) + ::aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] := ::BookLast( nRecno, nCurLevel, ::aReport[ REPORTOBJ ] ) + ::aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] := ::BookCount( nRecno, nCurLevel ) + IF nCurLevel == 1 + nLast := nRecno + ++nCount + ENDIF + ++nRecno + enddo + + nLast += ::aReport[ REPORTOBJ ] + + cTemp := ltrim(str( ::aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + "<< /Type /Outlines /Count " + ltrim(str( nCount )) + " /First " + ltrim(str( nFirst )) + " 0 R /Last " + ltrim(str( nLast )) + " 0 R >>" + CRLF + "endobj" //+ CRLF + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + ++::aReport[ REPORTOBJ ] + nRecno := 1 + FOR nI := 1 to nBookLen + //cTemp := IIF ( nI > 1, CRLF, "") + ltrim(str( ::aReport[ REPORTOBJ ] + nI - 1)) + " 0 obj" + CRLF + ; + cTemp := CRLF + ltrim(str( ::aReport[ REPORTOBJ ] + nI - 1)) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Parent " + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKPARENT ])) + " 0 R" + CRLF + ; + "/Dest [" + ltrim(str( ::aReport[ PAGES ][ ::aReport[ BOOKMARK ][ nRecno ][ BOOKPAGE ] ] )) + " 0 R /XYZ 0 " + ltrim( str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ])) + " 0]" + CRLF + ; + "/Title (" + alltrim( ::aReport[ BOOKMARK ][ nRecno ][ BOOKTITLE ]) + ")" + CRLF + ; + IIF( ::aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ] > 0, "/Prev " + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKPREV ])) + " 0 R" + CRLF, "") + ; + IIF( ::aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ] > 0, "/Next " + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKNEXT ])) + " 0 R" + CRLF, "") + ; + IIF( ::aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ] > 0, "/First " + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKFIRST ])) + " 0 R" + CRLF, "") + ; + IIF( ::aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ] > 0, "/Last " + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKLAST ])) + " 0 R" + CRLF, "") + ; + IIF( ::aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ] <> 0, "/Count " + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKCOUNT ])) + CRLF, "") + ; + ">>" + CRLF + "endobj" + CRLF +// "/Dest [" + ltrim(str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKPAGE ] * 3 )) + " 0 R /XYZ 0 " + ltrim( str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ])) + " 0]" + CRLF + ; +// "/Dest [" + ltrim(str( ::aReport[ PAGES ][ nRecno ] )) + " 0 R /XYZ 0 " + ltrim( str( ::aReport[ BOOKMARK ][ nRecno ][ BOOKCOORD ])) + " 0]" + CRLF + ; + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] + 2 ) + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + ++nRecno + NEXT + ::BookClose() + + ::aReport[ REPORTOBJ ] += nBookLen - 1 + ELSE + cTemp := ltrim(str( ::aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + "<< /Type /Outlines /Count 0 >>" + CRLF + "endobj" + CRLF + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + ENDIF + + cTemp := CRLF + ::aReport[ DOCLEN ] += len( cTemp ) + + ++::aReport[ REPORTOBJ ] + cTemp += "xref" + CRLF + ; + "0 " + ltrim(str( ::aReport[ REPORTOBJ ] )) + CRLF +; + padl( ::aReport[ REFS ][ 1 ], 10, "0") + " 65535 f" + CRLF + + for nI := 2 to len( ::aReport[ REFS ] ) + cTemp += padl( ::aReport[ REFS ][ nI ], 10, "0") + " 00000 n" + CRLF + next + + cTemp += "trailer << /Size " + ltrim(str( ::aReport[ REPORTOBJ ] )) + " /Root " + ltrim(str( nObj1 - 1 )) + " 0 R /Info " + ltrim(str( nObj1 - 2 )) + " 0 R >>" + CRLF + ; + "startxref" + CRLF + ; + ltrim(str( ::aReport[ DOCLEN ] )) + CRLF + ; + "%%EOF" + CRLF + fwrite( ::aReport[ HANDLE ], cTemp ) + + fclose( ::aReport[ HANDLE ] ) + + ::aReport := nil + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Image( cFile, nRow, nCol, cUnits, nHeight, nWidth, cId ) +#else +METHOD Image( cFile, nRow, nCol, cUnits, nHeight, nWidth, cId ) +#endif + +DEFAULT nRow TO ::aReport[ REPORTLINE ] +DEFAULT nCol TO 0 +DEFAULT nHeight TO 0 +DEFAULT nWidth TO 0 +DEFAULT cUnits TO "R" +DEFAULT cId TO "" + + IF ::aReport[ HEADEREDIT ] + return ::Header( "PDFIMAGE", cId, { cFile, nRow, nCol, cUnits, nHeight, nWidth } ) + ENDIF + + IF cUnits == "M" + nRow := ::aReport[ PAGEY ] - ::M2Y( nRow ) + nCol := ::M2X( nCol ) + nHeight := ::aReport[ PAGEY ] - ::M2Y( nHeight ) + nWidth := ::M2X( nWidth ) + ELSEIF cUnits == "R" + //IF .not. lExact + // ::CheckLine( nRow ) + // nRow := nRow + ::aReportStyle[ PDFTOP] + //ENDIF + nRow := ::aReport[ PAGEY ] - ::R2D( nRow ) + nCol := ::M2X( ::aReport[ PDFLEFT ] ) + ; + nCol * 100.00 / ::aReport[ REPORTWIDTH ] * ; + ( ::aReport[ PAGEX ] - ::M2X( ::aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 + nHeight := ::aReport[ PAGEY ] - ::R2D( nHeight ) + nWidth := ::M2X( ::aReport[ PDFLEFT ] ) + ; + nWidth * 100.00 / ::aReport[ REPORTWIDTH ] * ; + ( ::aReport[ PAGEX ] - ::M2X( ::aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 + ELSEIF cUnits == "D" + ENDIF + + aadd( ::aReport[ PAGEIMAGES ], { cFile, nRow, nCol, nHeight, nWidth } ) + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Length( cString ) +#else +METHOD Length( cString ) +#endif + +local nWidth := 0.00, nI, nLen, nArr, nAdd := ( ::aReport[ FONTNAME ] - 1 ) % 4 + + nLen := len( cString ) + IF right( cString, 1 ) == chr( 255 ) .or. right( cString, 1 ) == chr( 254 ) + --nLen + ENDIF + IF ::GetFontInfo("NAME") = "Times" + nArr := 1 + ELSEIF ::GetFontInfo("NAME") = "Helvetica" + nArr := 2 + ELSE + nArr := 3 + ENDIF + + For nI:= 1 To nLen + nWidth += ::aReport[ FONTWIDTH ][ nArr ][ ( asc( substr( cString, nI, 1 )) - 32 ) * 4 + 1 + nAdd ] * 25.4 * ::aReport[ FONTSIZE ] / 720.00 / 100.00 + Next +RETURN nWidth + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:NewLine( n ) +#else +METHOD NewLine( n ) +#endif + +DEFAULT n TO 1 + IF ::aReport[ REPORTLINE ] + n + ::aReport[ PDFTOP] > ::aReport[ PDFBOTTOM ] + ::NewPage() + ::aReport[ REPORTLINE ] += 1 + ELSE + ::aReport[ REPORTLINE ] += n + ENDIF + +RETURN ::aReport[ REPORTLINE ] + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:NewPage( _cPageSize, _cPageOrient, _nLpi, _cFontName, _nFontType, _nFontSize ) +#else +METHOD NewPage( _cPageSize, _cPageOrient, _nLpi, _cFontName, _nFontType, _nFontSize ) +#endif + +local nAdd := 76.2 + +DEFAULT _cPageSize TO ::aReport[ PAGESIZE ] +DEFAULT _cPageOrient TO ::aReport[ PAGEORIENT ] +DEFAULT _nLpi TO ::aReport[ LPI ] +DEFAULT _cFontName TO ::GetFontInfo( "NAME" ) +DEFAULT _nFontType TO ::GetFontInfo( "TYPE" ) +DEFAULT _nFontSize TO ::aReport[ FONTSIZE ] + + IF !empty( ::aReport[ PAGEBUFFER ] ) + ::ClosePage() + ENDIF + + ::aReport[ PAGEFONTS ] := {} + ::aReport[ PAGEIMAGES ] := {} + + ++::aReport[ REPORTPAGE ] + + ::PageSize( _cPageSize ) + ::PageOrient( _cPageOrient ) + ::SetLPI( _nLpi ) + + ::SetFont( _cFontName, _nFontType, _nFontSize ) + + ::DrawHeader() + + ::aReport[ REPORTLINE ] := 0 + ::aReport[ FONTNAMEPREV ] := 0 + ::aReport[ FONTSIZEPREV ] := 0 + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:PageSize( _cPageSize ) +#else +METHOD PageSize( _cPageSize ) +#endif + +local nSize, 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 } } + +DEFAULT _cPageSize TO "LETTER" + + nSize := ascan( aSize, { |arr| arr[ 1 ] = _cPageSize } ) + + IF nSize = 0 .or. nSize > 2 + nSize := 1 + ENDIF + + ::aReport[ PAGESIZE ] := aSize[ nSize ][ 1 ] + + IF ::aReport[ PAGEORIENT ] = "P" + ::aReport[ PAGEX ] := aSize[ nSize ][ 2 ] * 72 + ::aReport[ PAGEY ] := aSize[ nSize ][ 3 ] * 72 + ELSE + ::aReport[ PAGEX ] := aSize[ nSize ][ 3 ] * 72 + ::aReport[ PAGEY ] := aSize[ nSize ][ 2 ] * 72 + ENDIF + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:PageOrient( _cPageOrient ) +#else +METHOD PageOrient( _cPageOrient ) +#endif + +DEFAULT _cPageOrient TO "P" + + ::aReport[ PAGEORIENT ] := _cPageOrient + ::PageSize( ::aReport[ PAGESIZE ] ) +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:PageNumber( n ) +#else +METHOD PageNumber( n ) +#endif + +DEFAULT n TO 0 + IF n > 0 + ::aReport[ REPORTPAGE ] := n // NEW !!! + ENDIF +RETURN ::aReport[ REPORTPAGE ] + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Reverse( cString ) +#else +METHOD Reverse( cString ) +#endif + +RETURN cString + chr(255) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:RJust( cString, nRow, nCol, cUnits, lExact, cId ) +#else +METHOD RJust( cString, nRow, nCol, cUnits, lExact, cId ) +#endif + +local nLen, nAdj := 1.0, nAt + +DEFAULT nRow TO ::aReport[ REPORTLINE ] +DEFAULT cUnits TO "R" +DEFAULT lExact TO .f. + + IF ::aReport[ HEADEREDIT ] + return ::Header( "PDFRJUST", cId, { cString, nRow, nCol, cUnits, lExact } ) + ENDIF + + IF ( nAt := at( "#pagenumber#", cString ) ) > 0 + cString := left( cString, nAt - 1 ) + ltrim(str( ::PageNumber())) + substr( cString, nAt + 12 ) + ENDIF + + nLen := ::length( cString ) + + IF cUnits == "R" + IF .not. lExact + ::CheckLine( nRow ) + nRow := nRow + ::aReport[ PDFTOP] + ENDIF + ENDIF + ::AtSay( cString, ::R2M( nRow ), IIF( cUnits == "R", ::aReport[ PDFLEFT ] + ( ::aReport[ PAGEX ] / 72 * 25.4 - 2 * ::aReport[ PDFLEFT ] ) * nCol / ::aReport[ REPORTWIDTH ] - nAdj, nCol ) - nLen, "M", lExact ) +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:SetFont( _cFont, _nType, _nSize, cId ) +#else +METHOD SetFont( _cFont, _nType, _nSize, cId ) +#endif + +DEFAULT _cFont TO "Times" +DEFAULT _nType TO 0 +DEFAULT _nSize TO 10 + + IF ::aReport[ HEADEREDIT ] + return ::Header( "PDFSETFONT", cId, { _cFont, _nType, _nSize } ) + ENDIF + + _cFont := upper( _cFont ) + ::aReport[ FONTSIZE ] := _nSize + + IF _cFont == "TIMES" + ::aReport[ FONTNAME ] := _nType + 1 + ELSEIF _cFont == "HELVETICA" + ::aReport[ FONTNAME ] := _nType + 5 + ELSE + ::aReport[ FONTNAME ] := _nType + 9 // 0.04 + ENDIF + + aadd( ::aReport[ PAGEFONTS ], ::aReport[ FONTNAME ] ) + + IF ascan( ::aReport[ FONTS ], { |arr| arr[1] == ::aReport[ FONTNAME ] } ) == 0 + aadd( ::aReport[ FONTS ], { ::aReport[ FONTNAME ], ++::aReport[ NEXTOBJ ] } ) + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:SetLPI(_nLpi) +#else +METHOD SetLPI(_nLpi) +#endif + +local cLpi := alltrim(str(_nLpi)) +DEFAULT _nLpi TO 6 + + cLpi := iif(cLpi$"1;2;3;4;6;8;12;16;24;48",cLpi,"6") + ::aReport[ LPI ] := val( cLpi ) + + ::PageSize( ::aReport[ PAGESIZE ] ) +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:StringB( cString ) +#else +METHOD StringB( cString ) +#endif + +cString := strtran( cString, "(", "\(" ) +cString := strtran( cString, ")", "\)" ) + +RETURN cString + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:TextCount( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits ) +#else +METHOD TextCount( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits ) +#endif + +RETURN ::Text( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits, .f. ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Text( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits, cColor, lPrint ) +#else +METHOD Text( cString, nTop, nLeft, nLength, nTab, nJustify, cUnits, cColor, lPrint ) +#endif + +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 + +DEFAULT nTab TO -1 +DEFAULT cUnits TO 'R' +DEFAULT nJustify TO 4 +DEFAULT lPrint TO .t. +DEFAULT cColor TO "" + + IF cUnits == "M" + nTop := ::M2R( nTop ) + ELSEIF cUnits == "R" + nLeft := ::X2M( ::M2X( ::aReport[ PDFLEFT ] ) + ; + nLeft * 100.00 / ::aReport[ REPORTWIDTH ] * ; + ( ::aReport[ PAGEX ] - ::M2X( ::aReport[ PDFLEFT ] ) * 2 - 9.0 ) / 100.00 ) + ENDIF + + ::aReport[ REPORTLINE ] := nTop - 1 + + nSpace := ::length( " " ) + nLines := 0 + nCRLF := 0 + nNew := nTab + cString := alltrim( cString ) + nTokens := numtoken( cString, cDelim ) + nTokenLen := 0.00 + 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 + nLineLen := nSpace * nNew - nSpace + + lParagraph := .t. + nI := 1 + + while nI <= nTokens + cToken := token( cString, cDelim, nI ) + nTokenLen := ::length( 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 - ::length( cTemp ) ) / 2 + ELSEIF nJustify == 3 + nL := nLeft + nLength - ::length( cTemp ) + ENDIF + while k <= nLen .and. ( ( nLineLen += ::length( substr( cToken, k, 1 ))) <= nLength ) + nLineLen += ::length( 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 := ::NewLine( 1 ) + ::AtSay( cColor + cTemp, ::R2M( nRow + ::aReport[ PDFTOP] ), nL, "M" ) + ENDIF + enddo + ++nI + nStart := nI + ELSE + ::TextPrint( nI - 1, nLeft, @lParagraph, nJustify, nSpace, nNew, nLength, @nLineLen, @nLines, @nStart, cString, cDelim, cColor, lPrint ) + ENDIF + + ELSEIF ( nI == nTokens ) .or. ( nI < nTokens .and. ( nCRLF := ::TextNextPara( cString, cDelim, nI ) ) > 0 ) + IF nI == nTokens + nLineLen += nSpace + nTokenLen + ENDIF + ::TextPrint( 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 := ::NewLine( nCRLF - 1 ) + ENDIF + + ELSE + nLineLen += nSpace + nTokenLen + ++nI + ENDIF + enddo + +RETURN nLines + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:UnderLine( cString ) +#else +METHOD UnderLine( cString ) +#endif + +RETURN cString + chr(254) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:OpenHeader( cFile ) +#else +METHOD OpenHeader( cFile ) +#endif + +local nErrorCode := 0, nAt, cCmd + +DEFAULT cFile TO '' + + 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 ) + + cCmd := "copy " + cFile + " temp.tmp > nul" + RunExternal( cCmd ) + + cFile := "temp.tmp" + ENDIF + // ::aReport[ HEADER ] := FT_RestArr( cFile, @nErrorCode ) + ::aReport[ HEADER ] := File2Array( cFile ) + ELSE + ::aReport[ HEADER ] := {} + ENDIF + ::aReport[ MARGINS ] := .t. + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:EditOnHeader() +#else +METHOD EditOnHeader() +#endif + +::aReport[ HEADEREDIT ] := .t. +::aReport[ MARGINS ] := .t. + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:EditOffHeader() +#else +METHOD EditOffHeader() +#endif + +::aReport[ HEADEREDIT ] := .f. +::aReport[ MARGINS ] := .t. + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:CloseHeader() +#else +METHOD CloseHeader() +#endif + + ::aReport[ HEADER ] := {} + ::aReport[ MARGINS ] := .f. +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:DeleteHeader( cId ) +#else +METHOD DeleteHeader( cId ) +#endif + +local nRet := -1, nId + cId := upper( cId ) + nId := ascan( ::aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + IF nId > 0 + nRet := len( ::aReport[ HEADER ] ) - 1 + aDel( ::aReport[ HEADER ], nId ) + aSize( ::aReport[ HEADER ], nRet ) + ::aReport[ MARGINS ] := .t. + ENDIF +RETURN nRet + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:EnableHeader( cId ) +#else +METHOD EnableHeader( cId ) +#endif + +local nId + cId := upper( cId ) + nId := ascan( ::aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + IF nId > 0 + ::aReport[ HEADER ][ nId ][ 1 ] := .t. + ::aReport[ MARGINS ] := .t. + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:DisableHeader( cId ) +#else +METHOD DisableHeader( cId ) +#endif + +local nId + cId := upper( cId ) + nId := ascan( ::aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + IF nId > 0 + ::aReport[ HEADER ][ nId ][ 1 ] := .f. + ::aReport[ MARGINS ] := .t. + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:SaveHeader( cFile ) +#else +METHOD SaveHeader( cFile ) +#endif + +local nErrorCode := 0, cCmd + +Array2File( 'temp.tmp', ::aReport[ HEADER ] ) + +cCmd := "copy temp.tmp " + cFile + " > nul" +RunExternal( cCmd ) + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Header( cFunction, cId, arr ) +#else +METHOD Header( cFunction, cId, arr ) +#endif + +local nId, nI, nLen, nIdLen + nId := 0 + IF !empty( cId ) + cId := upper( cId ) + nId := ascan( ::aReport[ HEADER ], {| arr | arr[ 3 ] == cId }) + ENDIF + IF nId == 0 + nLen := len( ::aReport[ HEADER ] ) + IF empty( cId ) + cId := cFunction + nIdLen := len( cId ) + for nI := 1 to nLen + IF ::aReport[ HEADER ][ nI ][ 2 ] == cId + IF val( substr( ::aReport[ HEADER ][ nI ][ 3 ], nIdLen + 1 ) ) > nId + nId := val( substr( ::aReport[ HEADER ][ nI ][ 3 ], nIdLen + 1 ) ) + ENDIF + ENDIF + next + ++nId + cId += ltrim(str(nId)) + ENDIF + aadd( ::aReport[ HEADER ], { .t., cFunction, cId } ) + ++nLen + for nI := 1 to len( arr ) + aadd( ::aReport[ HEADER ][ nLen ], arr[ nI ] ) + next + ELSE + aSize( ::aReport[ HEADER ][ nId ], 3 ) + for nI := 1 to len( arr ) + aadd( ::aReport[ HEADER ][ nId ], arr[ nI ] ) + next + ENDIF +RETURN cId + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:DrawHeader() +#else +METHOD DrawHeader() +#endif + +local nI, _nFont, _nSize, nLen := len( ::aReport[ HEADER ] ) + + IF nLen > 0 + + // save font + _nFont := ::aReport[ FONTNAME ] + _nSize := ::aReport[ FONTSIZE ] + + for nI := 1 to nLen + IF ::aReport[ HEADER ][ nI ][ 1 ] // enabled + do case + case ::aReport[ HEADER ][ nI ][ 2 ] == "PDFATSAY" + ::AtSay( ::aReport[ HEADER ][ nI ][ 4 ], ::aReport[ HEADER ][ nI ][ 5 ], ::aReport[ HEADER ][ nI ][ 6 ], ::aReport[ HEADER ][ nI ][ 7 ], ::aReport[ HEADER ][ nI ][ 8 ], ::aReport[ HEADER ][ nI ][ 3 ] ) + + case ::aReport[ HEADER ][ nI ][ 2 ] == "PDFCENTER" + ::Center( ::aReport[ HEADER ][ nI ][ 4 ], ::aReport[ HEADER ][ nI ][ 5 ], ::aReport[ HEADER ][ nI ][ 6 ], ::aReport[ HEADER ][ nI ][ 7 ], ::aReport[ HEADER ][ nI ][ 8 ], ::aReport[ HEADER ][ nI ][ 3 ] ) + + case ::aReport[ HEADER ][ nI ][ 2 ] == "PDFRJUST" + ::RJust( ::aReport[ HEADER ][ nI ][ 4 ], ::aReport[ HEADER ][ nI ][ 5 ], ::aReport[ HEADER ][ nI ][ 6 ], ::aReport[ HEADER ][ nI ][ 7 ], ::aReport[ HEADER ][ nI ][ 8 ], ::aReport[ HEADER ][ nI ][ 3 ] ) + + case ::aReport[ HEADER ][ nI ][ 2 ] == "PDFBOX" + ::Box( ::aReport[ HEADER ][ nI ][ 4 ], ::aReport[ HEADER ][ nI ][ 5 ], ::aReport[ HEADER ][ nI ][ 6 ], ::aReport[ HEADER ][ nI ][ 7 ], ::aReport[ HEADER ][ nI ][ 8 ], ::aReport[ HEADER ][ nI ][ 9 ], ::aReport[ HEADER ][ nI ][ 10 ], ::aReport[ HEADER ][ nI ][ 3 ] ) + + case ::aReport[ HEADER ][ nI ][ 2 ] == "PDFSETFONT" + ::SetFont( ::aReport[ HEADER ][ nI ][ 4 ], ::aReport[ HEADER ][ nI ][ 5 ], ::aReport[ HEADER ][ nI ][ 6 ], ::aReport[ HEADER ][ nI ][ 3 ] ) + + case ::aReport[ HEADER ][ nI ][ 2 ] == "PDFIMAGE" + ::Image( ::aReport[ HEADER ][ nI ][ 4 ], ::aReport[ HEADER ][ nI ][ 5 ], ::aReport[ HEADER ][ nI ][ 6 ], ::aReport[ HEADER ][ nI ][ 7 ], ::aReport[ HEADER ][ nI ][ 8 ], ::aReport[ HEADER ][ nI ][ 9 ], ::aReport[ HEADER ][ nI ][ 3 ] ) + + endcase + ENDIF + next + ::aReport[ FONTNAME ] := _nFont + ::aReport[ FONTSIZE ] := _nSize + + IF ::aReport[ MARGINS ] + ::Margins() + ENDIF + + ELSE + IF ::aReport[ MARGINS ] + ::aReport[ PDFTOP] := 1 // top + ::aReport[ PDFLEFT ] := 10 // left & right + ::aReport[ PDFBOTTOM ] := ::aReport[ PAGEY ] / 72 * ::aReport[ LPI ] - 1 // bottom, default "LETTER", "P", 6 + + ::aReport[ MARGINS ] := .f. + ENDIF + ENDIF +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Margins( nTop, nLeft, nBottom ) +#else +METHOD Margins( nTop, nLeft, nBottom ) +#endif + +local nI, nLen := len( ::aReport[ HEADER ] ), nTemp, aTemp, nHeight + + for nI := 1 to nLen + IF ::aReport[ HEADER ][ nI ][ 1 ] // enabled + + IF ::aReport[ HEADER ][ nI ][ 2 ] == "PDFSETFONT" + + ELSEIF ::aReport[ HEADER ][ nI ][ 2 ] == "PDFIMAGE" + IF ::aReport[ HEADER ][ nI ][ 8 ] == 0 // picture in header, first at all, not at any page yet + aTemp := ::ImageInfo( ::aReport[ HEADER ][ nI ][ 4 ] ) + nHeight := aTemp[ IMAGE_HEIGHT ] / aTemp[ IMAGE_YRES ] * 25.4 + IF ::aReport[ HEADER ][ nI ][ 7 ] == "D" + nHeight := ::M2X( nHeight ) + ENDIF + ELSE + nHeight := ::aReport[ HEADER ][ nI ][ 8 ] + ENDIF + + IF ::aReport[ HEADER ][ nI ][ 7 ] == "M" + + nTemp := ::aReport[ PAGEY ] / 72 * 25.4 / 2 + + IF ::aReport[ HEADER ][ nI ][ 5 ] < nTemp + nTemp := ( ::aReport[ HEADER ][ nI ][ 5 ] + nHeight ) * ::aReport[ LPI ] / 25.4 // top + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ELSE + nTemp := ::aReport[ HEADER ][ nI ][ 5 ] * ::aReport[ LPI ] / 25.4 // top + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + ENDIF + + ELSEIF ::aReport[ HEADER ][ nI ][ 7 ] == "D" + nTemp := ::aReport[ PAGEY ] / 2 + + IF ::aReport[ HEADER ][ nI ][ 5 ] < nTemp + nTemp := ( ::aReport[ HEADER ][ nI ][ 5 ] + nHeight ) * ::aReport[ LPI ] / 72 // top + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ELSE + nTemp := ::aReport[ HEADER ][ nI ][ 5 ] * ::aReport[ LPI ] / 72 // top + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + + ENDIF + + ENDIF + + ELSEIF ::aReport[ HEADER ][ nI ][ 2 ] == "PDFBOX" + + IF ::aReport[ HEADER ][ nI ][ 10 ] == "M" + + nTemp := ::aReport[ PAGEY ] / 72 * 25.4 / 2 + + IF ::aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + ::aReport[ HEADER ][ nI ][ 6 ] < nTemp + nTemp := ::aReport[ HEADER ][ nI ][ 6 ] * ::aReport[ LPI ] / 25.4 // top + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ELSEIF ::aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + ::aReport[ HEADER ][ nI ][ 6 ] > nTemp + + nTemp := ( ::aReport[ HEADER ][ nI ][ 4 ] + ::aReport[ HEADER ][ nI ][ 8 ] ) * ::aReport[ LPI ] / 25.4 // top + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + + nTemp := ( ::aReport[ HEADER ][ nI ][ 6 ] - ::aReport[ HEADER ][ nI ][ 8 ] ) * ::aReport[ LPI ] / 25.4 // top + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + + ELSEIF ::aReport[ HEADER ][ nI ][ 4 ] > nTemp .and. ; + ::aReport[ HEADER ][ nI ][ 6 ] > nTemp + nTemp := ::aReport[ HEADER ][ nI ][ 4 ] * ::aReport[ LPI ] / 25.4 // top + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + ENDIF + + ELSEIF ::aReport[ HEADER ][ nI ][ 10 ] == "D" + nTemp := ::aReport[ PAGEY ] / 2 + + IF ::aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + ::aReport[ HEADER ][ nI ][ 6 ] < nTemp + nTemp := ::aReport[ HEADER ][ nI ][ 6 ] / ::aReport[ LPI ] // top + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ELSEIF ::aReport[ HEADER ][ nI ][ 4 ] < nTemp .and. ; + ::aReport[ HEADER ][ nI ][ 6 ] > nTemp + + nTemp := ( ::aReport[ HEADER ][ nI ][ 4 ] + ::aReport[ HEADER ][ nI ][ 8 ] ) / ::aReport[ LPI ] // top + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + + nTemp := ( ::aReport[ HEADER ][ nI ][ 6 ] - ::aReport[ HEADER ][ nI ][ 8 ] ) / ::aReport[ LPI ] // top + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + + ELSEIF ::aReport[ HEADER ][ nI ][ 4 ] > nTemp .and. ; + ::aReport[ HEADER ][ nI ][ 6 ] > nTemp + nTemp := ::aReport[ HEADER ][ nI ][ 4 ] / ::aReport[ LPI ] // top + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + ENDIF + + ENDIF + + ELSE + IF ::aReport[ HEADER ][ nI ][ 7 ] == "R" + nTemp := ::aReport[ HEADER ][ nI ][ 5 ] // top + IF ::aReport[ HEADER ][ nI ][ 5 ] > ::aReport[ PAGEY ] / 72 * ::aReport[ LPI ] / 2 + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + ELSE + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ENDIF + ELSEIF ::aReport[ HEADER ][ nI ][ 7 ] == "M" + nTemp := ::aReport[ HEADER ][ nI ][ 5 ] * ::aReport[ LPI ] / 25.4 // top + IF ::aReport[ HEADER ][ nI ][ 5 ] > ::aReport[ PAGEY ] / 72 * 25.4 / 2 + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + ELSE + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ENDIF + ELSEIF ::aReport[ HEADER ][ nI ][ 7 ] == "D" + nTemp := ::aReport[ HEADER ][ nI ][ 5 ] / ::aReport[ LPI ] // top + IF ::aReport[ HEADER ][ nI ][ 5 ] > ::aReport[ PAGEY ] / 2 + IF nTemp < ::aReport[ PDFBOTTOM ] + ::aReport[ PDFBOTTOM ] := nTemp + ENDIF + ELSE + IF nTemp > ::aReport[ PDFTOP] + ::aReport[ PDFTOP] := nTemp + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + next + + IF nTop <> NIL + ::aReport[ PDFTOP] := nTop + ENDIF + IF nLeft <> NIL + ::aReport[ PDFLEFT ] := nLeft + ENDIF + IF nBottom <> NIL + ::aReport[ PDFBOTTOM ] := nBottom + ENDIF + + ::aReport[ MARGINS ] := .f. + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:CreateHeader( _file, _size, _orient, _lpi, _width ) +#else +METHOD CreateHeader( _file, _size, _orient, _lpi, _width ) +#endif + +local ; + 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 + +DEFAULT _size TO ::aReport[ PAGESIZE ] +DEFAULT _orient TO ::aReport[ PAGEORIENT ] +DEFAULT _lpi TO ::aReport[ LPI ] +DEFAULT _width TO 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 + + ::EditOnHeader() + + IF _size == "LEGAL" + nAdd := 76.2 + ENDIF + + IF _orient == "P" + ::Box( 5.0, 5.0, 274.0 + nAdd, 210.0, 1.0 ) + ::Box( 6.5, 6.5, 272.5 + nAdd, 208.5, 0.5 ) + + ::Box( 11.5, 9.5, 22.0 , 205.5, 0.5, 5 ) + ::Box( 23.0, 9.5, 33.5 , 205.5, 0.5, 5 ) + ::Box( 34.5, 9.5, 267.5 + nAdd, 205.5, 0.5 ) + + ELSE + ::Box( 5.0, 5.0, 210.0, 274.0 + nAdd, 1.0 ) + ::Box( 6.5, 6.5, 208.5, 272.5 + nAdd, 0.5 ) + + ::Box( 11.5, 9.5, 22.0, 269.5 + nAdd, 0.5, 5 ) + ::Box( 23.0, 9.5, 33.5, 269.5 + nAdd, 0.5, 5 ) + ::Box( 34.5, 9.5, 203.5, 269.5 + nAdd, 0.5 ) + ENDIF + + ::SetFont("Arial", BOLD, 10) + ::AtSay( "Test Line 1", aReportStyle[ nStyle ][ 1 ], 1, "R", .t. ) + + ::SetFont("Times", BOLD, 18) + ::Center( "Test Line 2", aReportStyle[ nStyle ][ 2 ],,"R", .t. ) + + ::SetFont("Times", BOLD, 12) + ::Center( "Test Line 3", aReportStyle[ nStyle ][ 3 ],,"R", .t. ) + + ::SetFont("Arial", BOLD, 10) + ::AtSay( "Test Line 4", aReportStyle[ nStyle ][ 4 ], 1, "R", .t. ) + + ::SetFont("Arial", BOLD, 10) + ::AtSay( "Test Line 5", aReportStyle[ nStyle ][ 5 ], 1, "R", .t. ) + + ::AtSay( dtoc( date()) + " " + TimeAsAMPM( time() ), aReportStyle[ nStyle ][ 6 ], 1, "R", .t. ) + ::RJust( "Page: #pagenumber#", aReportStyle[ nStyle ][ 6 ], ::aReport[ REPORTWIDTH ], "R", .t. ) + + ::EditOffHeader() + ::SaveHeader( _file ) +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:ImageInfo( cFile ) +#else +METHOD ImageInfo( cFile ) +#endif + +local cTemp := upper(substr( cFile, rat('.', cFile) + 1 )), aTemp := {} + do case + case cTemp == "TIF" + aTemp := ::TIFFInfo( cFile ) + case cTemp == "JPG" + aTemp := ::JPEGInfo( cFile ) + endcase +RETURN aTemp + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:TIFFInfo( cFile ) +#else +METHOD TIFFInfo( cFile ) +#endif + +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, cTag, nPages, nn + +local nWidth := 0, nHeight := 0, nBits := 0, nFrom := 0, nLength := 0, xRes := 0, yRes := 0, aTemp := {} + + 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 ) + + 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 ) ) + 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 + cTag := '' + do case + case nTag == 256 + cTag := 'ImageWidth' + + IF nFieldType == SHORT + nWidth := bin2w( substr( cValues, 1, 2 )) + ELSEIF nFieldType == LONG + nWidth := bin2l( substr( cValues, 1, 4 )) + ENDIF + + case nTag == 257 + cTag := 'ImageLength' + IF nFieldType == SHORT + nHeight := bin2w(substr( cValues, 1, 2 )) + ELSEIF nFieldType == LONG + nHeight := bin2l(substr( cValues, 1, 4 )) + ENDIF + + case nTag == 258 + cTag := 'BitsPerSample' + nTemp := 0 + IF nFieldType == SHORT + nTemp := bin2w( cValues ) + ENDIF + nBits := nTemp + case nTag == 259 + cTag := 'Compression' + nTemp := 0 + IF nFieldType == SHORT + nTemp := bin2w( cValues ) + ENDIF + case nTag == 262 + cTag := 'PhotometricInterpretation' + nTemp := -1 + IF nFieldType == SHORT + nTemp := bin2w( cValues ) + ENDIF + case nTag == 264 + cTag := 'CellWidth' + case nTag == 265 + cTag := 'CellLength' + case nTag == 266 + cTag := 'FillOrder' + case nTag == 273 + cTag := 'StripOffsets' + IF nFieldType == SHORT + nFrom := bin2w(substr( cValues, 1, 2 )) + ELSEIF nFieldType == LONG + nFrom := bin2l(substr( cValues, 1, 4 )) + ENDIF + + case nTag == 277 + cTag := 'SamplesPerPixel' + case nTag == 278 + cTag := 'RowsPerStrip' + case nTag == 279 + cTag := 'StripByteCounts' + 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 + cTag := 'XResolution' + xRes := bin2l(substr( cValues, 1, 4 )) + case nTag == 283 + cTag := 'YResolution' + yRes := bin2l(substr( cValues, 1, 4 )) + case nTag == 284 + cTag := 'PlanarConfiguration' + case nTag == 288 + cTag := 'FreeOffsets' + case nTag == 289 + cTag := 'FreeByteCounts' + case nTag == 296 + cTag := 'ResolutionUnit' + nTemp := 0 + IF nFieldType == SHORT + nTemp := bin2w( cValues ) + ENDIF + case nTag == 305 + cTag := 'Software' + case nTag == 306 + cTag := 'DateTime' + case nTag == 315 + cTag := 'Artist' + case nTag == 320 + cTag := 'ColorMap' + case nTag == 338 + cTag := 'ExtraSamples' + case nTag == 33432 + cTag := 'Copyright' + otherwise + cTag := 'Unknown' + endcase + 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 ) + +return aTemp + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:JPEGInfo( cFile ) +#else +METHOD JPEGInfo( cFile ) +#endif + +local c255, nAt, nHandle +local nWidth := 0, nHeight := 0, nBits := 8, nFrom := 0 +local nLength := 0, xRes := 0, yRes := 0, aTemp := {} + + nHandle := fopen( cFile ) + + c255 := space(1024) + fread( nHandle, @c255, 1024 ) + + 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 := at( 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 )) + + fclose( nHandle ) + + nLength := filesize( cFile ) + + aadd( aTemp, nWidth ) + aadd( aTemp, nHeight ) + aadd( aTemp, xRes ) + aadd( aTemp, yRes ) + aadd( aTemp, nBits ) + aadd( aTemp, nFrom ) + aadd( aTemp, nLength ) + +return aTemp + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookCount( nRecno, nCurLevel ) +#else +METHOD BookCount( nRecno, nCurLevel ) +#endif + +local nTempLevel := 0, nCount := 0, nLen := len( ::aReport[ BOOKMARK ] ) + ++nRecno + while nRecno <= nLen + nTempLevel := ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + IF nTempLevel <= nCurLevel + exit + ELSE + IF nCurLevel + 1 == nTempLevel + ++nCount + ENDIF + ENDIF + ++nRecno + enddo +return -1 * nCount + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookFirst( nRecno, nCurLevel, nObj ) +#else +METHOD BookFirst( nRecno, nCurLevel, nObj ) +#endif + +local nFirst := 0, nLen := len( ::aReport[ BOOKMARK ] ) + ++nRecno + IF nRecno <= nLen + IF nCurLevel + 1 == ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + nFirst := nRecno + ENDIF + ENDIF +return IIF( nFirst == 0, nFirst, nObj + nFirst ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookLast( nRecno, nCurLevel, nObj ) +#else +METHOD BookLast( nRecno, nCurLevel, nObj ) +#endif + +local nLast := 0, nLen := len( ::aReport[ BOOKMARK ] ) + ++nRecno + IF nRecno <= nLen + IF nCurLevel + 1 == ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + while nRecno <= nLen .and. nCurLevel + 1 <= ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + IF nCurLevel + 1 == ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + nLast := nRecno + ENDIF + ++nRecno + enddo + ENDIF + ENDIF +return IIF( nLast == 0, nLast, nObj + nLast ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookNext( nRecno, nCurLevel, nObj ) +#else +METHOD BookNext( nRecno, nCurLevel, nObj ) +#endif + +local nTempLevel := 0, nNext := 0, nLen := len( ::aReport[ BOOKMARK ] ) + ++nRecno + while nRecno <= nLen + nTempLevel := ::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 ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookParent( nRecno, nCurLevel, nObj ) +#else +METHOD BookParent( nRecno, nCurLevel, nObj ) +#endif + +local nTempLevel := 0 +local nParent := 0 + --nRecno + while nRecno > 0 + nTempLevel := ::aReport[ BOOKMARK ][ nRecno ][ BOOKLEVEL ] + IF nTempLevel < nCurLevel + nParent := nRecno + exit + ENDIF + --nRecno + enddo +return IIF( nParent == 0, nObj - 1, nObj + nParent ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:BookPrev( nRecno, nCurLevel, nObj ) +#else +METHOD BookPrev( nRecno, nCurLevel, nObj ) +#endif + +local nTempLevel := 0 +local nPrev := 0 + --nRecno + while nRecno > 0 + nTempLevel := ::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 ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:CheckLine( nRow ) +#else +METHOD CheckLine( nRow ) +#endif + + IF nRow + ::aReport[ PDFTOP] > ::aReport[ PDFBOTTOM ] + ::NewPage() + nRow := ::aReport[ REPORTLINE ] + ENDIF + ::aReport[ REPORTLINE ] := nRow +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:GetFontInfo( cParam ) +#else +METHOD GetFontInfo( cParam ) +#endif + +local cRet + IF cParam == "NAME" + IF left( ::aReport[ TYPE1 ][ ::aReport[ FONTNAME ] ], 5 ) == "Times" + cRet := "Times" + ELSEIF left( ::aReport[ TYPE1 ][ ::aReport[ FONTNAME ] ], 9 ) == "Helvetica" + cRet := "Helvetica" + ELSE + cRet := "Courier" // 0.04 + ENDIF + ELSE // size + cRet := int(( ::aReport[ FONTNAME ] - 1 ) % 4) + ENDIF + +return cRet + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:M2R( mm ) +#else +METHOD M2R( mm ) +#endif + +return int( ::aReport[ LPI ] * mm / 25.4 ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:M2X( n ) +#else +METHOD M2X( n ) +#endif + +return n * 72 / 25.4 + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:M2Y( n ) +#else +METHOD M2Y( n ) +#endif + +return ::aReport[ PAGEY ] - n * 72 / 25.4 + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:R2D( nRow ) +#else +METHOD R2D( nRow ) +#endif + +return ::aReport[ PAGEY ] - nRow * 72 / ::aReport[ LPI ] + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:R2M( nRow ) +#else +METHOD R2M( nRow ) +#endif + +return 25.4 * nRow / ::aReport[ LPI ] + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:X2M( n ) +#else +METHOD X2M( n ) +#endif + +return n * 25.4 / 72 + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:TextPrint( nI, nLeft, lParagraph, nJustify, nSpace, nNew, nLength, nLineLen, nLines, nStart, cString, cDelim, cColor, lPrint ) +#else +METHOD TextPrint( nI, nLeft, lParagraph, nJustify, nSpace, nNew, nLength, nLineLen, nLines, nStart, cString, cDelim, cColor, lPrint ) +#endif + +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 := ::NewLine( 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 + ::AtSay( cColor + cToken, ::R2M( nRow + ::aReport[ PDFTOP ] ), nL, "M" ) + ENDIF + nL += ::Length( cToken ) + nB + next + + nStart := nFinish + 1 + + lParagraph := .f. + + nLineLen := 0.00 + nLineLen += nSpace * nNew + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:TextNextPara( cString, cDelim, nI ) +#else +METHOD TextNextPara( cString, cDelim, nI ) +#endif + +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 + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:ClosePage() +#else +METHOD ClosePage() +#endif + +local cTemp, cBuffer, nBuffer, nRead, nI, k, nImage, nFont, nImageHandle + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + + aadd( ::aReport[ PAGES ], ::aReport[ REPORTOBJ ] + 1 ) + + cTemp := ; + ltrim(str( ++::aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Type /Page /Parent 1 0 R" + CRLF + ; + "/Resources " + ltrim(str( ++::aReport[ REPORTOBJ ] )) + " 0 R" + CRLF + ; + "/MediaBox [ 0 0 " + ltrim(transform( ::aReport[ PAGEX ], "9999.99")) + " " + ; + ltrim(transform(::aReport[ PAGEY ], "9999.99")) + " ]" + CRLF + ; + "/Contents " + ltrim(str( ++::aReport[ REPORTOBJ ] )) + " 0 R" + CRLF + ; + ">>" + CRLF + ; + "endobj" + CRLF + + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + cTemp := ; + ltrim(str(::aReport[ REPORTOBJ ] - 1)) + " 0 obj" + CRLF + ; + "<<"+CRLF+; + "/ColorSpace << /DeviceRGB /DeviceGray >>" + CRLF + ; //version 0.01 + "/ProcSet [ /PDF /Text /ImageB /ImageC ]" + + IF len( ::aReport[ PAGEFONTS ] ) > 0 + cTemp += CRLF + ; + "/Font" + CRLF + ; + "<<" + + for nI := 1 to len( ::aReport[ PAGEFONTS ] ) + nFont := ascan( ::aReport[ FONTS ], { |arr| arr[1] == ::aReport[ PAGEFONTS ][ nI ] } ) + cTemp += CRLF + "/Fo" + ltrim(str( nFont )) + " " + ltrim(str( ::aReport[ FONTS ][ nFont ][ 2 ])) + " 0 R" + next + + cTemp += CRLF + ">>" + ENDIF + + IF len( ::aReport[ PAGEIMAGES ] ) > 0 + cTemp += CRLF + "/XObject" + CRLF + "<<" + for nI := 1 to len( ::aReport[ PAGEIMAGES ] ) + nImage := ascan( ::aReport[ IMAGES ], { |arr| arr[1] == ::aReport[ PAGEIMAGES ][ nI ][ 1 ] } ) + IF nImage == 0 + aadd( ::aReport[ IMAGES ], { ::aReport[ PAGEIMAGES ][ nI ][ 1 ], ++::aReport[ NEXTOBJ ], ::ImageInfo( ::aReport[ PAGEIMAGES ][ nI ][ 1 ] ) } ) + nImage := len( ::aReport[ IMAGES ] ) + ENDIF + cTemp += CRLF + "/Image" + ltrim(str( nImage )) + " " + ltrim(str( ::aReport[ IMAGES ][ nImage ][ 2 ])) + " 0 R" + next + cTemp += CRLF + ">>" + ENDIF + + cTemp += CRLF + ">>" + CRLF + "endobj" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + cTemp := ltrim(str( ::aReport[ REPORTOBJ ] )) + " 0 obj << /Length " + ; + ltrim(str( ::aReport[ REPORTOBJ ] + 1 )) + " 0 R >>" + CRLF +; + "stream" + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + IF len( ::aReport[ PAGEIMAGES ] ) > 0 + cTemp := "" + for nI := 1 to len( ::aReport[ PAGEIMAGES ] ) + cTemp += CRLF + "q" + nImage := ascan( ::aReport[ IMAGES ], { |arr| arr[1] == ::aReport[ PAGEIMAGES ][ nI ][ 1 ] } ) + cTemp += CRLF + ltrim(str( IIF( ::aReport[ PAGEIMAGES ][ nI ][ 5 ] == 0, ::M2X( ::aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_WIDTH ] / ::aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_XRES ] * 25.4 ), ::aReport[ PAGEIMAGES ][ nI ][ 5 ]))) + ; + " 0 0 " + ; + ltrim(str( IIF( ::aReport[ PAGEIMAGES ][ nI ][ 4 ] == 0, ::M2X( ::aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_HEIGHT ] / ::aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_YRES ] * 25.4 ), ::aReport[ PAGEIMAGES ][ nI ][ 4 ]))) + ; + " " + ltrim(str( ::aReport[ PAGEIMAGES ][ nI ][ 3 ] )) + ; + " " + ltrim(str( ::aReport[ PAGEY ] - ::aReport[ PAGEIMAGES ][ nI ][ 2 ] - ; + IIF( ::aReport[ PAGEIMAGES ][ nI ][ 4 ] == 0, ::M2X( ::aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_HEIGHT ] / ::aReport[ IMAGES ][ nImage ][ 3 ][ IMAGE_YRES ] * 25.4 ), ::aReport[ PAGEIMAGES ][ nI ][ 4 ]))) + " cm" + cTemp += CRLF + "/Image" + ltrim(str( nImage )) + " Do" + cTemp += CRLF + "Q" + next + ::aReport[ PAGEBUFFER ] := cTemp + ::aReport[ PAGEBUFFER ] + ENDIF + + cTemp := ::aReport[ PAGEBUFFER ] + + cTemp += CRLF + "endstream" + CRLF + ; + "endobj" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + cTemp := ltrim(str( ++::aReport[ REPORTOBJ ] )) + " 0 obj" + CRLF + ; + ltrim(str(len( ::aReport[ PAGEBUFFER ] ))) + CRLF + ; + "endobj" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + for nI := 1 to len( ::aReport[ FONTS ] ) + IF ::aReport[ FONTS ][ nI ][ 2 ] > ::aReport[ REPORTOBJ ] + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + + cTemp := ; + ltrim(str( ::aReport[ FONTS ][ nI ][ 2 ] )) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Type /Font" + CRLF + ; + "/Subtype /Type1" + CRLF + ; + "/Name /Fo" + ltrim(str( nI )) + CRLF + ; + "/BaseFont /" + ::aReport[ TYPE1 ][ ::aReport[ FONTS ][ nI ][ 1 ] ] + CRLF + ; + "/Encoding /WinAnsiEncoding" + CRLF + ; + ">>" + CRLF + ; + "endobj" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + ENDIF + next + + for nI := 1 to len( ::aReport[ IMAGES ] ) + IF ::aReport[ IMAGES ][ nI ][ 2 ] > ::aReport[ REPORTOBJ ] + + aadd( ::aReport[ REFS ], ::aReport[ DOCLEN ] ) + + cTemp := ; + ltrim(str( ::aReport[ IMAGES ][ nI ][ 2 ] )) + " 0 obj" + CRLF + ; + "<<" + CRLF + ; + "/Type /XObject" + CRLF + ; + "/Subtype /Image" + CRLF + ; + "/Name /Image" + ltrim(str(nI)) + CRLF + ; + "/Filter [" + IIF( at( ".JPG", upper( ::aReport[ IMAGES ][ nI ][ 1 ]) ) > 0, " /DCTDecode", "" ) + " ]" + CRLF + ; + "/Width " + ltrim(str( ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_WIDTH ] )) + CRLF + ; + "/Height " + ltrim(str( ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_HEIGHT ] )) + CRLF + ; + "/BitsPerComponent " + ltrim(str( ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_BITS ] )) + CRLF + ; + "/ColorSpace /" + IIF( ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_BITS ] == 1, "DeviceGray", "DeviceRGB") + CRLF + ; + "/Length " + ltrim(str( ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ])) + CRLF + ; + ">>" + CRLF + ; + "stream" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + nImageHandle := fopen( ::aReport[ IMAGES ][ nI ][ 1 ] ) + fseek( nImageHandle, ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_FROM ] ) + + nBuffer := 8192 + cBuffer := space( nBuffer ) + k := 0 + while k < ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] + IF k + nBuffer <= ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] + nRead := nBuffer + ELSE + nRead := ::aReport[ IMAGES ][ nI ][ 3 ][ IMAGE_LENGTH ] - k + ENDIF + fread( nImageHandle, @cBuffer, nRead ) + + ::aReport[ DOCLEN ] += nRead + fwrite( ::aReport[ HANDLE ], cBuffer, nRead ) + k += nRead + enddo + + cTemp := CRLF + "endstream" + CRLF + "endobj" + CRLF + + ::aReport[ DOCLEN ] += len( cTemp ) + fwrite( ::aReport[ HANDLE ], cTemp ) + + fClose( nImageHandle ) + ENDIF + next + + ::aReport[ REPORTOBJ ] := ::aReport[ NEXTOBJ ] + + ::aReport[ NEXTOBJ ] := ::aReport[ REPORTOBJ ] + 4 + + ::aReport[ PAGEBUFFER ] := "" + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:FilePrint( cFile ) +#else +METHOD FilePrint( cFile ) +#endif +local cPathAcro := "c:\progra~1\Adobe\Acroba~1.0\Reader" +local cRun := cPathAcro + "\AcroRd32.exe /t " + cFile + " " + ; + chr(34) + "HP LaserJet 5/5M PostScript" + chr(34) + " " + ; + chr(34) + "LPT1" + chr(34) + +IF ( ! RunExternal( cRun, 'print' ) ) + alert( "Error printing to PDF reader." ) + break +ENDIF + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#ifdef __XPP__ +METHOD tPdf:Execute( cFile ) +#else +METHOD Execute( cFile ) +#endif +// Replace cPathAcro with the path at your system +local cPathAcro := "c:\progra~1\Adobe\Acroba~1.0\Reader" +local cRun := cPathAcro + "\AcroRd32.exe /t " + cFile + " " + chr(34) + "HP LaserJet 5/5M PostScript" + chr(34) + " " + chr(34) + "LPT1" + chr(34) + +IF (! RunExternal( cRun, 'open', cFile ) ) + alert("Error printing to PDF reader.") + break +ENDIF + +RETURN self + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +static function FilePos( nHandle ) +return ( FSEEK( nHandle, 0, FS_RELATIVE ) ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ +/* +static function stuff( cStr, nBeg, nDel, cIns ) +return PosIns( PosDel( cStr, nBeg, nDel ), cIns, nBeg ) +*/ +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +static function Chr_RGB( cChar ) +return str(asc( cChar ) / 255, 4, 2) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +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 + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +static function FileSize( cFile ) + + LOCAL nLength + LOCAL nHandle + + nHandle := fOpen( cFile ) + nLength := fSeek( nHandle, 0, FS_END ) + fClose( nHandle ) + +return ( nLength ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +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 +local nPos := 1 +local nLen := len( cString ) +local nStart := 0 +local cToken := "" +local cRet := 0 + +DEFAULT cDelimiter TO chr(0)+chr(9)+chr(10)+chr(13)+chr(26)+chr(32)+chr(138)+chr(141) +DEFAULT nAction to 0 + +// nAction == 0 - numtoken +// nAction == 1 - token +// nAction == 2 - attoken + +while nPos <= nLen + if .not. substr( cString, nPos, 1 ) $ cDelimiter + nStart := nPos + while nPos <= nLen .and. .not. 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 + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ +// +// next 3 function written by Peter Kulek +// modified for compatibility with common.ch by V.K. +// modified DATE processing by V.K. +// +static function Array2File( cFile, aRay, nDepth, hFile ) +local nBytes := 0 +local i +local lOpen := ( hFile <> nil ) + +nDepth := if( ISNUMBER( nDepth ), nDepth, 0 ) +//if hFile == NIL +if !lOpen + if ( hFile := fCreate( cFile,FC_NORMAL ) ) == -1 + return ( nBytes ) + endif +endif +nDepth++ +nBytes += WriteData( hFile,aRay ) +if ISARRAY( aRay ) + for i := 1 to len( aRay ) + nBytes += Array2File( cFile,aRay[i],nDepth,hFile ) + next +endif +nDepth-- +// if nDepth == 0 +if !lOpen + fClose(hFile) +endif + +return( nBytes ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +static function WriteData(hFile,xData) +local cData := valtype(xData) + + if ISCHARACTER(xData) + cData += i2bin( len( xData ) ) + xData + elseif ISNUMBER(xData) + cData += i2bin( len( alltrim( str( xData ) ) ) ) + alltrim( str( xData ) ) + elseif ISDATE( xData ) + cData += i2bin( 8 )+dtos(xData) + elseif ISLOGICAL(xData) + cData += i2bin( 1 )+if( xData,'T','F' ) + elseif 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 := {} +local lOpen := ( hFile <> nil ) + +if hFile == NIL // First Timer + if ( hFile := fOpen( cFile,FO_READ ) ) == -1 + return( aRay ) + endif + cData := space( 3 ) + fRead( hFile, @cData, 3 ) + if left( cData,1 ) != 'A' // If format of file <> array + fClose( hFile ) ////////// + 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 ] := ctod( left( cData, 4 ) + "/" + substr( cData, 5, 2 ) + "/" + substr( cData, 7, 2 )) //stod(cData) + elseif cType=='L' + aRay[ nDepth ] := ( cData=='T' ) + elseif cType=='A' + aRay[ nDepth ] := File2Array( , nDataLen, hFile ) + endif +enddo + +if !lOpen + fClose( hFile ) +endif + +return ( aRay ) + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +static FUNCTION NumAt( cSearch, cString ) + + LOCAL n := 0, nAt := 0, nPos := 0 + WHILE ( nAt := at( cSearch, substr( cString, nPos + 1 ) )) > 0 + nPos += nAt + ++n + ENDDO + +RETURN n + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +static function RunExternal( cCmd, cVerb, cFile ) +local lRet := .t. + +#ifdef __CLP__ + lRet := SwpRunCmd( cCmd, 0, '', '' ) +#endif + +#ifdef __HARBOUR__ + if cVerb <> nil +// TOFIX: This requires hbwhat32, which in turns requires xhb. +// This has to solved differently. +// ShellExecute( GetDeskTopWindow(), cVerb, cFile, , , 1 ) + HB_SYMBOL_UNUSED( cFile ) + else + __Run( cCmd ) + endif +#endif + +#ifdef __XPP__ + RunShell( cCmd, , .t., .t. ) +#endif + +return lRet + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ diff --git a/harbour/contrib/hbvpdf/make_b32.bat b/harbour/contrib/hbvpdf/make_b32.bat new file mode 100644 index 0000000000..c484512c4c --- /dev/null +++ b/harbour/contrib/hbvpdf/make_b32.bat @@ -0,0 +1,6 @@ +@echo off +rem +rem $Id$ +rem + +call ..\mtpl_b32.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/harbour/contrib/hbvpdf/make_gcc.sh b/harbour/contrib/hbvpdf/make_gcc.sh new file mode 100644 index 0000000000..0593942308 --- /dev/null +++ b/harbour/contrib/hbvpdf/make_gcc.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# +# $Id$ +# + +../mtpl_gcc.sh $1 $2 $3 $4 $5 $6 $7 $8 $9 diff --git a/harbour/contrib/hbvpdf/make_vc.bat b/harbour/contrib/hbvpdf/make_vc.bat new file mode 100644 index 0000000000..4ceb9b9261 --- /dev/null +++ b/harbour/contrib/hbvpdf/make_vc.bat @@ -0,0 +1,6 @@ +@echo off +rem +rem $Id$ +rem + +call ..\mtpl_vc.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/harbour/contrib/hbvpdf/tests/bld_b32.bat b/harbour/contrib/hbvpdf/tests/bld_b32.bat new file mode 100644 index 0000000000..fb0090c8f7 --- /dev/null +++ b/harbour/contrib/hbvpdf/tests/bld_b32.bat @@ -0,0 +1,22 @@ +@echo off +rem +rem $Id$ +rem + +rem --------------------------------------------------------------- +rem This is a generic template file, if it doesn't fit your own needs +rem please DON'T MODIFY IT. +rem +rem Instead, make a local copy and modify that one, or make a call to +rem this batch file from your customized one. [vszakats] +rem --------------------------------------------------------------- + +set HB_BIN_INSTALL=..\..\..\bin +set HB_INC_INSTALL=..\..\..\include +set HB_LIB_INSTALL=..\..\..\lib + +set HB_ARCHITECTURE=w32 +set HB_COMPILER=bcc32 +set HB_USER_LIBS=hbvpdf.lib + +call %HB_BIN_INSTALL%\bld.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/harbour/contrib/hbvpdf/tests/bld_vc.bat b/harbour/contrib/hbvpdf/tests/bld_vc.bat new file mode 100644 index 0000000000..ad40d03dc8 --- /dev/null +++ b/harbour/contrib/hbvpdf/tests/bld_vc.bat @@ -0,0 +1,22 @@ +@echo off +rem +rem $Id$ +rem + +rem --------------------------------------------------------------- +rem This is a generic template file, if it doesn't fit your own needs +rem please DON'T MODIFY IT. +rem +rem Instead, make a local copy and modify that one, or make a call to +rem this batch file from your customized one. [vszakats] +rem --------------------------------------------------------------- + +set HB_BIN_INSTALL=..\..\..\bin +set HB_INC_INSTALL=..\..\..\include +set HB_LIB_INSTALL=..\..\..\lib + +set HB_ARCHITECTURE=w32 +set HB_COMPILER=msvc +set HB_USER_LIBS=hbvpdf.lib + +call %HB_BIN_INSTALL%\bld.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/harbour/contrib/hbvpdf/tests/files/color.jpg b/harbour/contrib/hbvpdf/tests/files/color.jpg new file mode 100644 index 0000000000..38140c23c6 Binary files /dev/null and b/harbour/contrib/hbvpdf/tests/files/color.jpg differ diff --git a/harbour/contrib/hbvpdf/tests/files/color.tif b/harbour/contrib/hbvpdf/tests/files/color.tif new file mode 100644 index 0000000000..325513e145 Binary files /dev/null and b/harbour/contrib/hbvpdf/tests/files/color.tif differ diff --git a/harbour/contrib/hbvpdf/tests/files/test.txt b/harbour/contrib/hbvpdf/tests/files/test.txt new file mode 100644 index 0000000000..5498e372f0 --- /dev/null +++ b/harbour/contrib/hbvpdf/tests/files/test.txt @@ -0,0 +1,12 @@ +(sample text) + +THE HARBOUR PROJECT CONTRIB LICENSE +=================================== + +There is no one single license that applies to the Harbour Project +contrib files. Some files use the Harbour Project Compiler license. +Some files use the Harbour Project Library license. Some files use +the old Harbour Project Library license. Some files may even use other +types of free software or open source software licenses. Some files +have been donated to the public domain. If you use any of the contrib +files, you need to investigate the license that applies to each file. diff --git a/harbour/contrib/hbvpdf/tests/fonts.dat b/harbour/contrib/hbvpdf/tests/fonts.dat new file mode 100644 index 0000000000..37957e64ab Binary files /dev/null and b/harbour/contrib/hbvpdf/tests/fonts.dat differ diff --git a/harbour/contrib/hbvpdf/tests/pdf_demo.prg b/harbour/contrib/hbvpdf/tests/pdf_demo.prg new file mode 100644 index 0000000000..538275a56e --- /dev/null +++ b/harbour/contrib/hbvpdf/tests/pdf_demo.prg @@ -0,0 +1,224 @@ +/* + * $Id$ + */ + +#include "hbvpdf.ch" + +memvar aReport + +procedure main() + + local cRun, nWidth, nTab, nI, nJ, nK, nCol, nRow, aStyle, aFonts + local nTop, nLeft, nBottom, nRight + local aColor := { ; + "FF0000", "8B0000", "800000", "FF4500", "D2691E", "B8860B", "FF8C00", "FFA500", "DAA520", "808000", "FFD700", "FFFF00", "ADFF2F", "9ACD32", "7FFF00", "7CFC00", "00FF00", "32CD32", "008000", "006400",; + "66CDAA", "7FFFD4", "87CEFA", "87CEEB", "F0F8FF", "E0FFFF", "B0C4DE", "B0E0E6", "AFEEEE", "ADD8E6", "8FBC8F", "90EE90", "98FB98", "00FA9A", "00FF7F", "3CB371", "2E8B57", "228B22", "556B2F", "6B8E23",; + "5F9EA0", "40E0D0", "48D1CC", "00CED1", "20B2AA", "008B8B", "008080", "2F4F4F", "00BFFF", "00FFFF", "00FFFF", "0000FF", "0000CD", "00008B", "000080", "1E90FF", "4169E1", "4682B4", "6495ED", "7B68EE",; + "C71585", "FF1493", "FF00FF", "FF00FF", "9370DB", "DDADDD", "DB7093", "FF69B4", "DA70D6", "EE82EE", "BA55D3", "9932CC", "8A2BE2", "9400D3", "8B008B", "800080", "4B0082", "191970", "483D8B", "6A5ACD",; + "DC143C", "B22222", "A52A2A", "CD5C5C", "FA8072", "E9967A", "FFA07A", "F5DEB3", "FFDEAD", "EEE8AA", "FFDAB9", "FFE4C4", "FFEFD5", "FFE4E1", "FFE4B5", "D2B48C", "DEB887", "F0E68C", "BDB76B", "F4A460",; + "FDF5E6", "FFF8DC", "FAF0E6", "FAFAD2", "FFFACD", "FFEBCD", "FFFFE0", "FAEBD7", "FFF5EE", "FFF0F5", "D8BFD8", "FFC0CB", "FFB6C1", "BC8F8F", "F08080", "FF7F50", "FF6347", "8B4513", "A0522D", "CD853F",; + "FFFAFA", "FFFFF0", "E6E6FA", "FFFAF0", "F8F8FF", "F0FFF0", "F5F5DC", "F0FFFF", "F5FFFA", "708090", "778899", "F5F5F5", "DCDCDC", "D3D3D3", "C0C0C0", "A9A9A9", "808080", "696969", "000000", "FFFFFF"} + + PUBLIC aReport := array( PARAMLEN ) + + set date format "YYYY/MM/DD" // important for save/load array function!!! + + aStyle := { "Normal", "Bold", "Italic", "BoldItalic" } + + aFonts := { { "Times", .t., .t., .t., .t. },; + { "Helvetica", .t., .t., .t., .t. },; + { "Courier", .t., .t., .t., .t. } } + + pdfOpen('test.pdf', 200, .t.) + + pdfEditOnHeader() + pdfImage( 'files\color.tif', 0, 0, "M" ) // file, row, col, units, height, width + pdfEditOffHeader() + pdfSaveHeader('test.hea') + pdfCloseHeader() + + pdfBookOpen() + + /* + pdfCreateHeader( "letter_portrait_6.hea", "LETTER", "P", 6 ) + pdfCreateHeader( "letter_portrait_8.hea", "LETTER", "P", 8 ) + pdfCreateHeader( "letter_landscape_6.hea", "LETTER", "L", 6 ) + pdfCreateHeader( "letter_landscape_8.hea", "LETTER", "L", 8 ) + pdfCreateHeader( "legal_portrait_6.hea", "LEGAL", "P", 6 ) + pdfCreateHeader( "legal_portrait_8.hea", "LEGAL", "P", 8 ) + pdfCreateHeader( "legal_landscape_6.hea", "LEGAL", "L", 6 ) + pdfCreateHeader( "legal_landscape_8.hea", "LEGAL", "L", 8 ) + */ + + pdfNewPage( "LETTER", "P", 6 ) + + pdfBookAdd( "Grids & Borders", 1, aReport[ REPORTPAGE ], 0 ) + pdfBookAdd( "Simple Grid", 2, aReport[ REPORTPAGE ], 0 ) + + for nI := 0 to 792 step 36 + pdfBox( nI, 0, nI, 612, 0.01, , "D" ) + next + for nI := 0 to 612 step 36 + pdfBox( 0, nI, 792, nI, 0.01, , "D" ) + next + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "10 dots border ", 2, aReport[ REPORTPAGE ], 0 ) + pdfBox( 0, 0, 792, 612, 10, , "D" ) + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Boxes", 1, aReport[ REPORTPAGE ], 0 ) + pdfBookAdd( "Boxes", 2, aReport[ REPORTPAGE ], 0 ) + + nRow := 85 + nCol := 85 + pdfBox( nRow , ( nCol * 2 ) , ( nRow * 3 ) , ( nCol * 4 ) , 1.00, 15, "D" ) + pdfBox( nRow + 10, ( nCol * 2 ) + 10, ( nRow * 3 ) + 10, ( nCol * 4 ) + 10, 0.50, 25, "D" ) + pdfBox( nRow + 20, ( nCol * 2 ) + 20, ( nRow * 3 ) + 20, ( nCol * 4 ) + 20, 0.25, 35, "D" ) + pdfBox( nRow + 30, ( nCol * 2 ) + 30, ( nRow * 3 ) + 30, ( nCol * 4 ) + 30, 0.15, 45, "D" ) + pdfBox( nRow + 40, ( nCol * 2 ) + 40, ( nRow * 3 ) + 40, ( nCol * 4 ) + 40, 0.10, 55, "D" ) + pdfBox( nRow + 50, ( nCol * 2 ) + 50, ( nRow * 3 ) + 50, ( nCol * 4 ) + 50, 0.05, 65, "D" ) + pdfBox( nRow + 60, ( nCol * 2 ) + 60, ( nRow * 3 ) + 60, ( nCol * 4 ) + 60, 0.01, 75, "D" ) + pdfBox( nRow + 70, ( nCol * 2 ) + 70, ( nRow * 3 ) + 70, ( nCol * 4 ) + 70, 0.01, 85, "D" ) + pdfBox( nRow + 80, ( nCol * 2 ) + 80, ( nRow * 3 ) + 80, ( nCol * 4 ) + 80, 0.01, 95, "D" ) + pdfBox( nRow + 90, ( nCol * 2 ) + 90, ( nRow * 3 ) + 90, ( nCol * 4 ) + 90, 0.01, 100, "D" ) + + /* + nRow := 12 + nCol := 120 + for nI := 1 to 6 + nRow += 10 + nCol += 10 + pdfBox( nCol, nRow, nCol + 10, nRow + 10, 0.5, nI, "M" ) + next + for nI := 0 to 20 step 10 + nRow += 10 + nCol += 10 + pdfBox( nCol, nRow, nCol + 10, nRow + 10, 0.5, nI,"M" ) + next + for nI := 30 to 100 step 10 + nRow += 10 + nCol -= 10 + pdfBox( nCol, nRow, nCol + 10, nRow + 10, 0.5, nI,"M" ) + next + */ + + for nI := 1 to 7 + nRow := 150 + nI * 10 + for nJ := 1 to 20 + nCol := nJ * 10 - 3 + pdfBox( nRow, nCol, nRow + 10, nCol + 10, 0.01, nI * 10,"M", chr(253) + chr( cton( substr( aColor[ ( nI - 1 ) * 20 + nJ ], 1, 2 ), 16) ) + chr( cton( substr( aColor[ ( nI - 1 ) * 20 + nJ ], 3, 2 ), 16) ) + chr( cton( substr( aColor[ ( nI - 1 ) * 20 + nJ ], 5, 2 ), 16) ) ) + next + next + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Color Boxes ", 2, aReport[ REPORTPAGE ], 0 ) + for nI := 1 to 140 + nTop := ( nI - 1 ) * 2.4 + nLeft := ( nI - 1 ) * 2.1 + nBottom := aReport[ PAGEY ] - ( nI - 1 ) * 2.47 + nRight := aReport[ PAGEX ] - ( nI - 1 ) * 2.18 + pdfBox1( nTop, nLeft, nBottom, nRight, 10, chr( cton( substr( aColor[ nI ], 1, 2 ), 16) ) + chr( cton( substr( aColor[ nI ], 3, 2 ), 16) ) + chr( cton( substr( aColor[ nI ], 5, 2 ), 16) )) + next + + pdfNewPage( "LETTER", "P", 6 ) + pdfBox1( 0, 0, 100, 200, 10, chr(0) + chr(255) + chr(0), chr(255) + chr(255) + chr(0) ) + pdfBookAdd( "Memos", 1, aReport[ REPORTPAGE ], 0 ) + pdfBookAdd( "Different Styles & Colors", 2, aReport[ REPORTPAGE ], 0 ) + nWidth := 90 + nTab := 0 + + pdfText( memoread('files\test.txt'), 28, 107.95, nWidth, nTab, 3, 'M', chr(253) + chr(0) + chr(0) + chr(255) )//, pdfTextCount( memoread('test.txt'), 28, 107.95, nWidth, nTab, 3, 'M' ) + pdfText( memoread('files\test.txt'), 58, 107.95, nWidth, nTab, 2, 'M', chr(253) + chr(0) + chr(255) + chr(0) )//, pdfTextCount( memoread('test.txt'), 58, 107.95, nWidth, nTab, 2, 'M' ) + pdfText( memoread('files\test.txt'), 88, 107.95, nWidth, nTab, 1, 'M', chr(253) + chr(255) + chr(0) + chr(0) )//, pdfTextCount( memoread('test.txt'), 88, 107.95, nWidth, nTab, 1, 'M' ) + pdfText( memoread('files\test.txt'), 118, 107.95 - nWidth / 2, nWidth, nTab, 4, 'M', chr(253) + chr(255) + chr(255) + chr(0) )//, pdfTextCount( memoread('test.txt'), 118, 107.95 - nWidth / 2, nWidth, nTab, 4, 'M' ) + + pdfText( memoread('files\test.txt'), 34, 100, nWidth, nTab, 3, 'R', chr(253) + chr(0) + chr(128) + chr(128) )//, pdfTextCount( memoread('test.txt'), 33, 100, nWidth, nTab, 3, 'R' ) + pdfText( memoread('files\test.txt'), 41, 100, nWidth, nTab, 2, 'R', chr(253) + chr(0) + chr(191) + chr(255) )//, pdfTextCount( memoread('test.txt'), 40, 100, nWidth, nTab, 2, 'R' ) + pdfText( memoread('files\test.txt'), 48, 100, nWidth, nTab, 1, 'R', chr(253) + chr(244) + chr(164) + chr(96) )//, pdfTextCount( memoread('test.txt'), 47, 100, nWidth, nTab, 1, 'R' ) + pdfText( memoread('files\test.txt'), 55, 35, nWidth, nTab, 4, 'R', chr(253) + chr(0) + chr(0) + chr(0) )//, pdfTextCount( memoread('test.txt'), 54, 35, nWidth, nTab, 4, 'R' ) + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Fonts", 1, aReport[ REPORTPAGE ], 0 ) + pdfBookAdd( "Different Styles", 2, aReport[ REPORTPAGE ], 0 ) + nK := 6 + for nI := 1 to len( aFonts ) + ++nK + for nJ := 1 to 4 + if aFonts[ nI ][ nJ + 1 ] + pdfSetFont( aFonts[ nI ][ 1 ], nJ - 1, aReport[ FONTSIZE ] ) + pdfRJust("This is a test for " + aFonts[ nI ][ 1 ] + " " + ; + aStyle[ nJ ], nK++, aReport[ REPORTWIDTH ], "R") + endif + next + pdfRJust(pdfUnderline("Underline"), nK++, aReport[ REPORTWIDTH ], "R") + pdfRJust(pdfReverse("Test"), nK, aReport[ REPORTWIDTH ], "R") + next + + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Pictures", 1, aReport[ REPORTPAGE ], 0 ) + pdfBookAdd( "TIFF", 2, aReport[ REPORTPAGE ], 0 ) + pdfImage( 'files\color.tif', 0, 0, "M" ) // file, row, col, units, height, width + pdfRJust(pdfUnderline("TIFF"), nK++, aReport[ REPORTWIDTH ], "R") + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "JPEG", 2, aReport[ REPORTPAGE ], 0 ) + pdfImage( 'files\color.jpg', 0, 0, "M" ) // file, row, col, units, height, width + pdfRJust(pdfUnderline("JPEG"), nK++, aReport[ REPORTWIDTH ], "R") + + pdfOpenHeader('test.hea') + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Headers", 1, aReport[ REPORTPAGE ], 0 ) + pdfBookAdd( "Picture Header Page 8", 2, aReport[ REPORTPAGE ], 0 ) + + // version 0.01 + pdfAtSay( chr(253) + chr(255) + chr(0) + chr(0) + 'Red Sample of header repeating on pages 8-10', 1, 20, "R" ) + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Picture Header Page 9", 2, aReport[ REPORTPAGE ], 0 ) + + // version 0.01 + pdfAtSay( chr(253) + chr(0) + chr(255) + chr(0) + 'Green Sample of header repeating on pages 8-10', 1, 20, "R" ) + + pdfNewPage( "LETTER", "P", 6 ) + pdfBookAdd( "Picture Header Page 10", 2, aReport[ REPORTPAGE ], 0 ) + + // version 0.01 + pdfAtSay( chr(253) + chr(0) + chr(0) + chr(255) + 'Blue Sample of header repeating on pages 8-10', 1, 20, "R" ) + + pdfClose() + +// pdfFilePrint( "test.pdf" ) // print .pdf file WITHOUT opening acrobat + +/* + cRun := "d:\progra~2\Adobe\Acroba~2.0\Reader\AcroRd32.exe " + "test.pdf" + + IF (!SWPRUNCMD( cRun, 0, "", "")) + alert(" Error running Acrobat Reader.") + break + ENDIF +*/ + +static function cton( cString, nBase ) // this function called only used in pdf_demo.prg +local cTemp, nI, cChar := "", n := 0, nLen + + nLen := len( cString ) + cTemp := "" + for nI := nLen to 1 step -1 + cTemp += substr( cString, nI, 1 ) + next + cTemp = upper( cTemp ) + + for nI = 1 to nLen + cChar = substr( cTemp, nI, 1 ) + if .not. IsDigit( cChar ) + n = n + ((Asc( cChar ) - 65) + 10) * ( nBase ^ ( nI - 1 ) ) + else + n = n + (( nBase ^ ( nI - 1 )) * val( cChar )) + endif + next + +return n + diff --git a/harbour/contrib/hbvpdf/tests/tstpdf.prg b/harbour/contrib/hbvpdf/tests/tstpdf.prg new file mode 100644 index 0000000000..9fed7d7576 --- /dev/null +++ b/harbour/contrib/hbvpdf/tests/tstpdf.prg @@ -0,0 +1,191 @@ +/* + * $Id$ + */ + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +#include "hbvpdf.ch" + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + +function Main() + + local cRun, nWidth, nTab, nI, nJ, nK, nCol, nRow, aStyle, aFonts + local nTop, nLeft, nBottom, nRight, cText, oPdf + local aColor := { ; + "FF0000", "8B0000", "800000", "FF4500", "D2691E", "B8860B", "FF8C00", "FFA500", "DAA520", "808000", "FFD700", "FFFF00", "ADFF2F", "9ACD32", "7FFF00", "7CFC00", "00FF00", "32CD32", "008000", "006400",; + "66CDAA", "7FFFD4", "87CEFA", "87CEEB", "F0F8FF", "E0FFFF", "B0C4DE", "B0E0E6", "AFEEEE", "ADD8E6", "8FBC8F", "90EE90", "98FB98", "00FA9A", "00FF7F", "3CB371", "2E8B57", "228B22", "556B2F", "6B8E23",; + "5F9EA0", "40E0D0", "48D1CC", "00CED1", "20B2AA", "008B8B", "008080", "2F4F4F", "00BFFF", "00FFFF", "00FFFF", "0000FF", "0000CD", "00008B", "000080", "1E90FF", "4169E1", "4682B4", "6495ED", "7B68EE",; + "C71585", "FF1493", "FF00FF", "FF00FF", "9370DB", "DDADDD", "DB7093", "FF69B4", "DA70D6", "EE82EE", "BA55D3", "9932CC", "8A2BE2", "9400D3", "8B008B", "800080", "4B0082", "191970", "483D8B", "6A5ACD",; + "DC143C", "B22222", "A52A2A", "CD5C5C", "FA8072", "E9967A", "FFA07A", "F5DEB3", "FFDEAD", "EEE8AA", "FFDAB9", "FFE4C4", "FFEFD5", "FFE4E1", "FFE4B5", "D2B48C", "DEB887", "F0E68C", "BDB76B", "F4A460",; + "FDF5E6", "FFF8DC", "FAF0E6", "FAFAD2", "FFFACD", "FFEBCD", "FFFFE0", "FAEBD7", "FFF5EE", "FFF0F5", "D8BFD8", "FFC0CB", "FFB6C1", "BC8F8F", "F08080", "FF7F50", "FF6347", "8B4513", "A0522D", "CD853F",; + "FFFAFA", "FFFFF0", "E6E6FA", "FFFAF0", "F8F8FF", "F0FFF0", "F5F5DC", "F0FFFF", "F5FFFA", "708090", "778899", "F5F5F5", "DCDCDC", "D3D3D3", "C0C0C0", "A9A9A9", "808080", "696969", "000000", "FFFFFF"} + + set date format "YYYY/MM/DD" + + aStyle := { "Normal", "Bold", "Italic", "BoldItalic" } + + aFonts := { { "Times", .t., .t., .t., .t. }, ; + { "Helvetica", .t., .t., .t., .t. }, ; + { "Courier", .t., .t., .t., .t. } } + + oPdf := tPdf():New( 'test.pdf', 200, .t. ) + oPdf:EditOnHeader() + oPdf:Image( 'files\color.tif', 0, 0, "M" ) + oPdf:EditOffHeader() + oPdf:SaveHeader( 'test.hea' ) + oPdf:CloseHeader() + oPdf:BookOpen() + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Grids & Borders", 1, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:BookAdd( "Simple Grid", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + + for nI := 0 to 792 step 36 + oPdf:Box( nI, 0, nI, 612, 0.01, , "D" ) + next + for nI := 0 to 612 step 36 + oPdf:Box( 0, nI, 792, nI, 0.01, , "D" ) + next + + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "10 dots border ", 2, 2, 0 ) + oPdf:Box( 0, 0, 792, 612, 10, , "D" ) + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Boxes", 1, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:BookAdd( "Boxes", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + + nRow := 85 + nCol := 85 + oPdf:Box( nRow , ( nCol * 2 ) , ( nRow * 3 ) , ( nCol * 4 ) , 1.00, 15, "D" ) + oPdf:Box( nRow + 10, ( nCol * 2 ) + 10, ( nRow * 3 ) + 10, ( nCol * 4 ) + 10, 0.50, 25, "D" ) + oPdf:Box( nRow + 20, ( nCol * 2 ) + 20, ( nRow * 3 ) + 20, ( nCol * 4 ) + 20, 0.25, 35, "D" ) + oPdf:Box( nRow + 30, ( nCol * 2 ) + 30, ( nRow * 3 ) + 30, ( nCol * 4 ) + 30, 0.15, 45, "D" ) + oPdf:Box( nRow + 40, ( nCol * 2 ) + 40, ( nRow * 3 ) + 40, ( nCol * 4 ) + 40, 0.10, 55, "D" ) + oPdf:Box( nRow + 50, ( nCol * 2 ) + 50, ( nRow * 3 ) + 50, ( nCol * 4 ) + 50, 0.05, 65, "D" ) + oPdf:Box( nRow + 60, ( nCol * 2 ) + 60, ( nRow * 3 ) + 60, ( nCol * 4 ) + 60, 0.01, 75, "D" ) + oPdf:Box( nRow + 70, ( nCol * 2 ) + 70, ( nRow * 3 ) + 70, ( nCol * 4 ) + 70, 0.01, 85, "D" ) + oPdf:Box( nRow + 80, ( nCol * 2 ) + 80, ( nRow * 3 ) + 80, ( nCol * 4 ) + 80, 0.01, 95, "D" ) + oPdf:Box( nRow + 90, ( nCol * 2 ) + 90, ( nRow * 3 ) + 90, ( nCol * 4 ) + 90, 0.01, 100, "D" ) + + for nI := 1 to 7 + nRow := 150 + nI * 10 + for nJ := 1 to 20 + nCol := nJ * 10 - 3 + oPdf:Box( nRow, nCol, nRow + 10, nCol + 10, 0.01, nI * 10,"M", chr(253) + chr( cton( substr( aColor[ ( nI - 1 ) * 20 + nJ ], 1, 2 ), 16) ) + chr( cton( substr( aColor[ ( nI - 1 ) * 20 + nJ ], 3, 2 ), 16) ) + chr( cton( substr( aColor[ ( nI - 1 ) * 20 + nJ ], 5, 2 ), 16) ) ) + next + next + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Color Boxes ", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + for nI := 1 to 140 + nTop := ( nI - 1 ) * 2.4 + nLeft := ( nI - 1 ) * 2.1 + nBottom := oPdf:aReport[ PAGEY ] - ( nI - 1 ) * 2.47 + nRight := oPdf:aReport[ PAGEX ] - ( nI - 1 ) * 2.18 + oPdf:Box1( nTop, nLeft, nBottom, nRight, 10, chr( cton( substr( aColor[ nI ], 1, 2 ), 16) ) + chr( cton( substr( aColor[ nI ], 3, 2 ), 16) ) + chr( cton( substr( aColor[ nI ], 5, 2 ), 16) )) + next + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Memos", 1, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:BookAdd( "Different Styles & Colors", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + nWidth := 90 + nTab := 0 + cText := memoread('files\test.txt') + + oPdf:Text( cText, 28, 107.95, nWidth, nTab, 3, 'M', chr(253) + chr(0) + chr(0) + chr(255) ) + oPdf:Text( cText, 58, 107.95, nWidth, nTab, 2, 'M', chr(253) + chr(0) + chr(255) + chr(0) ) + oPdf:Text( cText, 88, 107.95, nWidth, nTab, 1, 'M', chr(253) + chr(255) + chr(0) + chr(0) ) + oPdf:Text( cText, 118, 107.95 - nWidth / 2, nWidth, nTab, 4, 'M', chr(253) + chr(255) + chr(255) + chr(0) ) + + oPdf:Text( cText, 34, 100, nWidth, nTab, 3, 'R', chr(253) + chr(0) + chr(128) + chr(128) )//, pdfTextCount( memoread('files\test.txt'), 33, 100, nWidth, nTab, 3, 'R' ) + oPdf:Text( cText, 41, 100, nWidth, nTab, 2, 'R', chr(253) + chr(0) + chr(191) + chr(255) )//, pdfTextCount( memoread('files\test.txt'), 40, 100, nWidth, nTab, 2, 'R' ) + oPdf:Text( cText, 48, 100, nWidth, nTab, 1, 'R', chr(253) + chr(244) + chr(164) + chr(96) )//, pdfTextCount( memoread('files\test.txt'), 47, 100, nWidth, nTab, 1, 'R' ) + oPdf:Text( cText, 55, 35, nWidth, nTab, 4, 'R', chr(253) + chr(0) + chr(0) + chr(0) )//, pdfTextCount( memoread('files\test.txt'), 54, 35, nWidth, nTab, 4, 'R' ) + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Fonts", 1, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:BookAdd( "Different Styles", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + nK := 6 + for nI := 1 to len( aFonts ) // Fonts + ++nk + for nJ := 1 to 4 // Styles + if aFonts[ nI ][ nJ + 1 ] + oPdf:SetFont( aFonts[ nI ][ 1 ], nJ - 1, oPdf:aReport[ FONTSIZE ] ) + oPdf:RJust("This is a test for " + aFonts[ nI ][ 1 ] + " " + ; + aStyle[ nJ ], nK++, oPdf:aReport[ REPORTWIDTH ], "R") + endif + next + oPdf:RJust(oPdf:Underline("Underline"), nK++, oPdf:aReport[ REPORTWIDTH ], "R") + oPdf:RJust(oPdf:Reverse("Test"), nK, oPdf:aReport[ REPORTWIDTH ], "R") + next + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Pictures", 1, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:BookAdd( "TIFF", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + // file, row, col, units, height, width + oPdf:Image( 'files\color.tif', 0, 0, "M" ) + oPdf:RJust( oPdf:Underline("TIFF"), nK++, oPdf:aReport[ REPORTWIDTH ], "R") + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "JPEG", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:Image( 'files\color.jpg', 0, 0, "M" ) // file, row, col, units, height, width + oPdf:RJust(oPdf:Underline("JPEG"), nK++, oPdf:aReport[ REPORTWIDTH ], "R") + + oPdf:OpenHeader('test.hea') + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Headers", 1, oPdf:aReport[ REPORTPAGE ], 0 ) + oPdf:BookAdd( "Picture Header Page 8", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + + oPdf:AtSay( chr(253) + chr(255) + chr(0) + chr(0) + 'Red Sample of header repeating on pages 8-10', 1, 20, "R" ) + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Picture Header Page 9", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + + oPdf:AtSay( chr(253) + chr(0) + chr(255) + chr(0) + 'Green Sample of header repeating on pages 8-10', 1, 20, "R" ) + + oPdf:NewPage( "LETTER", "P", 6 ) + oPdf:BookAdd( "Picture Header Page 10", 2, oPdf:aReport[ REPORTPAGE ], 0 ) + + oPdf:AtSay( chr(253) + chr(0) + chr(0) + chr(255) + 'Blue Sample of header repeating on pages 8-10', 1, 20, "R" ) + + oPdf:Close() + +#ifndef __XPP__ + oPdf:Execute( 'test.pdf' ) +#endif + + // oPdf:FilePrint() + +return nil + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ +// +// This function called only used in tstPdf.prg +// +static function cton( cString, nBase ) +local cTemp, nI, cChar := "", n := 0, nLen + + nLen := len( cString ) + cTemp := "" + for nI := nLen to 1 step -1 + cTemp += substr( cString, nI, 1 ) + next + cTemp = upper( cTemp ) + + for nI = 1 to nLen + cChar = substr( cTemp, nI, 1 ) + if .not. IsDigit( cChar ) + n = n + ((Asc( cChar ) - 65) + 10) * ( nBase ^ ( nI - 1 ) ) + else + n = n + (( nBase ^ ( nI - 1 )) * val( cChar )) + endif + next + +return n + +//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\\ + + diff --git a/harbour/contrib/make_b32_all.bat b/harbour/contrib/make_b32_all.bat index 4b69a14fcb..40a8cbd9fa 100644 --- a/harbour/contrib/make_b32_all.bat +++ b/harbour/contrib/make_b32_all.bat @@ -42,7 +42,7 @@ rem ******************************************************* set _HB_DIRS=rddado hbbmcdx hbbtree gtwvg hbct hbgt hbmisc hbnf hbmsql for %%n in ( %_HB_DIRS% ) do %COMSPEC% /c %__BATWORKER__% %%n %1 %2 %3 %4 %5 %6 %7 %8 %9 -set _HB_DIRS=hbole hbziparch hbodbc hbtpathy hbtip hbw32 hbwhat32 xhb +set _HB_DIRS=hbole hbziparch hbodbc hbtpathy hbtip hbvpdf hbw32 hbwhat32 xhb for %%n in ( %_HB_DIRS% ) do %COMSPEC% /c %__BATWORKER__% %%n %1 %2 %3 %4 %5 %6 %7 %8 %9 set _HB_DIRS=hbclipsm hbw32ddr diff --git a/harbour/contrib/make_gcc_all.sh b/harbour/contrib/make_gcc_all.sh index 5449b18e81..22cb916e7e 100755 --- a/harbour/contrib/make_gcc_all.sh +++ b/harbour/contrib/make_gcc_all.sh @@ -38,7 +38,7 @@ fi #************************************************************** -_HB_DIRS="hbbmcdx hbbtree hbclipsm hbct hbgt hbmisc hbmsql hbnf hbtip hbtpathy xhb" +_HB_DIRS="hbbmcdx hbbtree hbclipsm hbct hbgt hbmisc hbmsql hbnf hbtip hbtpathy hbvpdf xhb" case "$HB_ARCHITECTURE" in w32|cyg|os2) diff --git a/harbour/contrib/make_vc_all.bat b/harbour/contrib/make_vc_all.bat index 5d07ebb597..40fe3283f3 100644 --- a/harbour/contrib/make_vc_all.bat +++ b/harbour/contrib/make_vc_all.bat @@ -42,7 +42,7 @@ rem ******************************************************* set _HB_DIRS=rddado hbbmcdx hbbtree gtwvg hbct hbgt hbmisc hbnf hbmsql for %%n in ( %_HB_DIRS% ) do %COMSPEC% /c %__BATWORKER__% %%n %1 %2 %3 %4 %5 %6 %7 %8 %9 -set _HB_DIRS=hbole hbziparch hbodbc hbtpathy hbtip hbw32 hbwhat32 xhb +set _HB_DIRS=hbole hbziparch hbodbc hbtpathy hbtip hbvpdf hbw32 hbwhat32 xhb for %%n in ( %_HB_DIRS% ) do %COMSPEC% /c %__BATWORKER__% %%n %1 %2 %3 %4 %5 %6 %7 %8 %9 set _HB_DIRS=hbclipsm hbw32ddr