/* Some code Copyright (C) 2002 John Wyrwas * * Based on the KWord Exporter * * AbiWord * Copyright (C) 2001 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * */ /* PDF code based loosely on HTMLDOC * * Copyright 1997-2002 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal * copyright law. Distribution and use rights are outlined in the file * "COPYING.txt" which should have been included with this file. If this * file is missing or damaged please contact Easy Software Products * at: * * Attn: ESP Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 * Hollywood, Maryland 20636-3111 USA * * Voice: (301) 373-9600 * EMail: info@easysw.com * WWW: http://www.easysw.com * */ #include #include #include #include #include #include "md5.c" #include "ut_string.h" #include "ut_types.h" #include "ut_misc.h" #include "ut_units.h" #include "ut_bytebuf.h" #include "ut_base64.h" #include "ut_debugmsg.h" #include "ut_vector.h" #include "pt_Types.h" #include "pd_Document.h" #include "pp_AttrProp.h" #include "px_ChangeRecord.h" #include "px_CR_Object.h" #include "px_CR_Span.h" #include "px_CR_Strux.h" #include "pp_Property.h" #include "ap_Prefs.h" #include "pd_Style.h" #include "fd_Field.h" #include "xap_EncodingManager.h" #include "fl_AutoNum.h" #include "fp_PageSize.h" #include "ut_string_class.h" #include "ie_exp_PDF.h" void IE_Exp_PDF::add_to_buffer(const char * sz, UT_uint32 length) { if (!sz || !length) return; m_file_buffer.append((UT_Byte *)sz,length); return; } void IE_Exp_PDF::add_to_buffer(const char * sz) { if (!sz) return; m_file_buffer.append((UT_Byte *)sz,strlen(sz)); return; } void IE_Exp_PDF::pdf_start_stream() { // Write the "/Length " string, get the position, and then write 10 // zeroes to cover the maximum size of a stream. add_to_buffer("/Length "); pdf_stream_length = current_file_size(); add_to_buffer("0000000000>>stream\n"); pdf_stream_start = current_file_size(); } // 'flate_open_stream()' - Open a deflated output stream. void IE_Exp_PDF::flate_open_stream() { compressor_active = 1; compressor.zalloc = (alloc_func)0; compressor.zfree = (free_func)0; compressor.opaque = (voidpf)0; deflateInit(&compressor, 1); compressor.next_out = (Bytef *)comp_buffer; compressor.avail_out = sizeof(comp_buffer); } // 'flate_close_stream()' - Close a deflated output stream. void IE_Exp_PDF::flate_close_stream() { while (deflate(&compressor, Z_FINISH) != Z_STREAM_END) { add_to_buffer((const char *)comp_buffer, (UT_Byte *)compressor.next_out - (UT_Byte *)comp_buffer); compressor.next_out = (Bytef *)comp_buffer; compressor.avail_out = sizeof(comp_buffer); } if ((UT_Byte *)compressor.next_out > (UT_Byte *)comp_buffer) add_to_buffer((const char *)(comp_buffer), (UT_Byte *)compressor.next_out - (UT_Byte *)comp_buffer); deflateEnd(&compressor); compressor_active = 0; } //flate_puts()' - Write a character string to a compressed stream. void IE_Exp_PDF::flate_puts(const char *s) { flate_write((UT_Byte *)s, strlen(s)); } //'flate_write()' - Write data to a compressed stream. void IE_Exp_PDF::flate_write(UT_Byte *buf,int length) { int flush = 0; if (compressor_active) { compressor.next_in = buf; compressor.avail_in = length; while (compressor.avail_in > 0) { if (compressor.avail_out < (int)(sizeof(comp_buffer) / 8)) { add_to_buffer((const char *)comp_buffer, (UT_Byte *)compressor.next_out - (UT_Byte *)comp_buffer); compressor.next_out = (Bytef *)comp_buffer; compressor.avail_out = sizeof(comp_buffer); } deflate(&compressor, flush ? Z_FULL_FLUSH : Z_NO_FLUSH); flush = 0; } } else add_to_buffer((const char *)buf, length); } // Writes a text entry void IE_Exp_PDF::write_string(UT_Byte *s,int compress) /* I - Compress output? */ { if (compress) flate_write((UT_Byte *)"(", 1); else add_to_buffer("("); while (*s != '\0') { // This section changes invalid characters if (*s == 160) { /*   */ if (compress) flate_write((UT_Byte *)" ", 1); else add_to_buffer(" "); } else if (*s < 32 || *s > 126) { if (compress) { flate_printf("\\%o", *s); } else { doc_printf("\\%o", *s); } } else if (compress) { if (*s == '(' || *s == ')' || *s == '\\') flate_write((UT_Byte *)"\\", 1); flate_write(s, 1); } else { if (*s == '(' || *s == ')' || *s == '\\') add_to_buffer("\\"); add_to_buffer((const char *)(*s)); } s ++; } if (compress) flate_write((UT_Byte *)")", 1); else add_to_buffer(")"); } int IE_Exp_PDF::pdf_start_object() { int * temp = new int; *temp = current_file_size(); m_num_objects++; m_objects.addItem(temp); doc_printf( "%d 0 obj", m_num_objects); pdf_object_type = 0; add_to_buffer(pdf_object_type ? "[" : "<<"); return (m_num_objects); // Object number } void IE_Exp_PDF::pdf_end_object() { int length; // Total length of stream int write_size; /* Length of output string */ char buf[10240]; /* Output buffer */ if (pdf_stream_start) { // For streams, go back and update the length field in the // object dictionary... length = current_file_size() - pdf_stream_start; write_size = snprintf(buf, sizeof(buf),"%-10d", length); m_file_buffer.overwrite(pdf_stream_length, (UT_Byte *)buf, write_size); pdf_stream_start = 0; add_to_buffer("endstream\n"); } else add_to_buffer(pdf_object_type ? "]" : ">>"); add_to_buffer("endobj\n"); } void IE_Exp_PDF::set_font(int typeface,float size) { char sizes[255], // Formatted string for size *s; // Pointer to end of string if (typeface == render_typeface && size == render_size) return; // Format size and strip trailing 0's and decimals... sprintf(sizes, "%.1f", size); for (s = sizes + strlen(sizes) - 1; s > sizes && *s == '0'; s --) *s = '\0'; if (*s == '.') *s = '\0'; // Set the new typeface, style, and size. flate_printf("/F%x ", typeface); flate_printf("%s Tf ", sizes); render_typeface = typeface; render_size = size; } void IE_Exp_PDF::set_pos(float x,float y) { char xs[255], // Formatted string for X... ys[255], // Formatted string for Y. *s; // Pointer to end of string if (fabs(render_x - x) < 0.1 && fabs(render_y - y) < 0.1) return; if (render_x == -1.0) { sprintf(xs, "%.3f", x); sprintf(ys, "%.3f", y); } else { sprintf(xs, "%.3f", x - render_startx); sprintf(ys, "%.3f", y - render_y); } //Strip trailing 0's and decimals... for (s = xs + strlen(xs) - 1; s > xs && *s == '0'; s --) *s = '\0'; if (*s == '.') *s = '\0'; for (s = ys + strlen(ys) - 1; s > ys && *s == '0'; s --) *s = '\0'; if (*s == '.') *s = '\0'; flate_printf("%s ", xs); flate_printf("%s Td", ys); render_x = render_startx = x; render_y = y; } //'set_color()' - Set the current text color... void IE_Exp_PDF::set_color(float *rgb) /* I - RGB color */ { if (rgb[0] == render_rgb[0] && rgb[1] == render_rgb[1] && rgb[2] == render_rgb[2]) return; render_rgb[0] = rgb[0]; render_rgb[1] = rgb[1]; render_rgb[2] = rgb[2]; flate_printf("%.2f ",rgb[0]); flate_printf("%.2f ",rgb[1]); flate_printf("%.2f rg ",rgb[2]); } /* end file */