/** * Yudit Unicode Editor Source File * * GNU Copyright (C) 1997-2006 Gaspar Sinai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * dated June 1991. See file COPYYING for details. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "stoolkit/SString.h" #include "swindow/SPrinter.h" #include "swidget/STextView.h" #include "swidget/SUniPrint.h" /** * This is a stoolkit printer. * Currently it only prints on A4 portrait. */ SUniPrint::SUniPrint (const SPrinter& _printer, const SString& headerFontName, double headerFontSize, const SString& bodyFontName, double bodyFontSize) : printer (_printer) { pageCount = 0; printheader = (headerFontSize > 1.0); SLocation l = SLocation (printer.getX(), printer.getY()); SDimension d = SDimension (printer.getWidth(), printer.getHeight()); headerLeft.setFont (headerFontName, headerFontSize); headerCenter.setFont (headerFontName, headerFontSize); headerRight.setFont (headerFontName, headerFontSize); int headerHeight = (int)headerCenter.lineHeight; int gap0 = 20; // Between top and header. int gap1 = 10; // between header and body int gap2 = 20; // between bottom and body end. body.setFont (bodyFontName, bodyFontSize); SLocation hl = SLocation (l.x, l.y + gap0); SDimension hd (d.width, headerHeight); /* we will move and resize them again later. now they are max wide.*/ headerLeft.resize(hd); headerLeft.move (hl); headerLeft.setMultiline (false); headerCenter.resize(hd); headerCenter.move (hl); headerCenter.setMultiline (false); headerRight.resize(hd); headerRight.move (hl); headerRight.setMultiline (false); SLocation bl = SLocation (hl.x, hl.y + (int) hd.height + gap1); int bodyHeight = (int) d.height-bl.y-gap2; if (bodyHeight < (int)body.lineHeight) { fprintf (stderr, "Too large font.\n"); pageHeight = body.lineHeight; } else /* should be multiples of lineheight. */ { pageHeight = body.lineHeight * (bodyHeight/body.lineHeight+1); } if (pageHeight<2) pageHeight=2; body.move (bl); SDimension bd (d.width, pageHeight-1); body.resize (bd); } SUniPrint::~SUniPrint() { } unsigned int SUniPrint::getPageCount () const { return pageCount; } /** * print. * @param header will be displayed on thee header * @param buffer will be the data to print * @param evt true = handle events */ bool SUniPrint::print (const SString& header, const SString& buffer, bool evt) { pageCount = 0; if (!printer.open(evt)) return false; SString dt = printer.getCreationDate (); //fprintf (stderr, "DATE=%*.*s\n", SSARGS(dt)); headerLeft.setText(dt); body.setText (buffer); /* FIXME: break it into pages, and set the viewport */ /* first print to cache. */ /* cahce the top line */ SLocation l (body.getLocation().x, body.getLocation().y); SDimension d = body.getSize(); if (!printer.newpath (l.x, l.y, "UPPERLINE")) { printer.moveto (l.x, l.y-9); printer.lineto (l.x + (int)d.width, l.y-9); printer.lineto (l.x + (int)d.width, l.y-8); printer.lineto (l.x, l.y-8 ); printer.closepath (); } printer.fill (); SDimension ld = headerLeft.getPreferredSize (); headerLeft.resize (ld); /* left can be drawn already */ if (printheader) { headerLeft.redraw (&printer, headerLeft.getLocation().x, headerLeft.getLocation().y, headerLeft.getSize().width, headerLeft.getSize().height); } unsigned int pmaMax = 1; /** * go through body and right */ unsigned int heightCount = 0; while (heightCount < body.getDocumentHeight()) { printer.newPage(); body.redraw (&printer, body.getLocation().x, body.getLocation().y, body.getSize().width, body.getSize().height); pageCount++; char a[64]; /* we are not much off using current page */ sprintf (a, "Page %u of %u", pageCount, pageCount); headerRight.setText (a); SDimension rd = headerRight.getPreferredSize (); headerRight.resize (rd); if (printheader) { headerRight.redraw (&printer, headerRight.getLocation().x, headerRight.getLocation().y, headerRight.getSize().width, headerRight.getSize().height); } if (rd.width > pmaMax) pmaMax = rd.width; heightCount += pageHeight; body.setViewPort (SLocation (0, -(int) heightCount)); } /* nove we have the maximum size of right header */ headerRight.resize (SDimension ((unsigned int) pmaMax, headerRight.getSize().height)); /* now lets see how much is left for the center guy */ int full = (int) body.getSize().width; int center = full - (int) pmaMax - (int)ld.width; if (center < 0) center = 1; if (printheader && header.size()) { SString testBegin = "file:"; SString testEnd = header; testBegin.append (testEnd); headerCenter.setText (testBegin); SDimension cd = headerCenter.getPreferredSize(); /* reduce it */ if ((int)cd.width > center) { testEnd.insert (0, "..."); } /* remove glyphs till it fits. */ while ((int)cd.width > center && testEnd.size()>3) { testEnd.remove (3); testBegin = "file:"; testBegin.append (testEnd); headerCenter.setText (testBegin); cd = headerCenter.getPreferredSize(); } headerCenter.resize (cd); /* poor man's centering */ //fprintf (stderr, "center=%u cd=%u\n", center, cd.width); //fprintf (stderr, "full=%u pmamax=%u ldwidth=%u\n", full, pmaMax, ld.width); headerCenter.move (SLocation ( body.getLocation().x + (int)ld.width + ((int)center - (int)cd.width)/2, headerCenter.getLocation().y)); if (printheader) { headerCenter.redraw (&printer, headerCenter.getLocation().x, headerCenter.getLocation().y, headerCenter.getSize().width, headerCenter.getSize().height); } } /*----- print - really using cached images ------------ */ printer.cacheOn (false); unsigned int fullPageCount = pageCount; pageCount = 0; body.setViewPort (SLocation (0, 0)); heightCount = 0; while (heightCount < body.getDocumentHeight()) { /* upper line */ printer.newPage(); if (printheader) { printer.newpath (l.x, l.y, "UPPERLINE"); printer.fill(); } /* body */ body.redraw (&printer, body.getLocation().x, body.getLocation().y, body.getSize().width, body.getSize().height-1); /* left */ if (printheader) { headerLeft.redraw (&printer, headerLeft.getLocation().x, headerLeft.getLocation().y, headerLeft.getSize().width, headerLeft.getSize().height); } /* center */ if (printheader && header.size()) { headerCenter.redraw (&printer, headerCenter.getLocation().x, headerCenter.getLocation().y, headerCenter.getSize().width, headerCenter.getSize().height); } /* right aligned header */ pageCount++; char a[64]; sprintf (a, "Page %u of %u", pageCount, fullPageCount); headerRight.setText (a); SDimension rd = headerRight.getPreferredSize (); //fprintf (stderr, "Right ps=%u %u\n", rd.width, rd.height); headerRight.move ( SLocation ( full - (int)rd.width + body.getLocation().x, headerRight.getLocation().y ) ); headerRight.resize (SDimension (rd.width, rd.height)); if (printheader) { headerRight.redraw (&printer, headerRight.getLocation().x, headerRight.getLocation().y, headerRight.getSize().width, headerRight.getSize().height); } heightCount += pageHeight; body.setViewPort (SLocation (0, -(int) heightCount)); } headerLeft.textData.clear(); headerRight.textData.clear(); headerCenter.textData.clear(); body.textData.clear(); //fprintf (stderr, "closing printer...\n"); bool status = printer.close(); //fprintf (stderr, "closed printer...\n"); return status; } void SUniPrint::setLineEndMark (bool brk) { body.setLineEndMark (brk); } void SUniPrint::setWordWrap (bool brk) { body.setWordWrap (brk); } void SUniPrint::setDocumentEmbedding (SS_Embedding e) { body.textData.setDocumentEmbedding (e); } bool SUniPrint::hasNative () { return printer.hasNative(); }