compile pdf2swf with xpdf's wordlist support
[swftools.git] / lib / pdf / XMLOutputDev.cc
1 /* XMLOutputDev.cc
2
3    This file is part of swftools.
4
5    Swftools is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    Swftools is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with swftools; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
18
19 #include "../../config.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "gfile.h"
23 #include "XMLOutputDev.h"
24 #include "GfxState.h"
25
26 XMLOutputDev::XMLOutputDev(char*filename)
27 :TextOutputDev(mktmpname(0), false, false, false)
28 {
29   out = fopen(filename, "wb");
30   if(!out) {
31       perror(filename);
32       exit(-1);
33   }
34   fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
35   fprintf(out, "<document>\n");
36 }
37
38 XMLOutputDev::~XMLOutputDev()
39 {
40   fprintf(out, "</document>\n");
41   fclose(out);
42 }
43
44 void XMLOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2)
45 {
46     TextOutputDev::startPage(pageNum, state, x1, y1, x2, y2);
47     fprintf(out, "<page nr=\"%d\" width=\"%.0f\" height=\"%.0f\">\n", pageNum,
48         state->getPageWidth(), state->getPageHeight());
49 }
50
51 void XMLOutputDev::endPage()
52 {
53     TextOutputDev::endPage();
54     TextWordList* list = makeWordList();
55     int len = list->getLength();
56     int i;
57
58     char textTag = 0;
59     GString*fontname = new GString();
60     double fontsize = -99999;
61     double base = -9999;
62     for(i=0;i<len;i++) {
63         TextWord*word = list->get(i);
64         GString*newfont = word->getFontName();
65         double newsize = word->getFontSize();
66         double newbase = word->base;
67
68         if((newfont && newfont->cmp(fontname)) || 
69            newsize != fontsize ||
70            newbase != base) 
71         {
72             TextFontInfo*info = word->getFontInfo();
73             if(textTag)
74                 fprintf(out, "</t>\n");
75             textTag = 1;
76             GBool italic = gFalse;
77             GBool bold = gFalse;
78             GBool serif = gFalse;
79
80             if(info->isItalic()) italic = gTrue;
81             if(info->isBold()) bold = gTrue;
82             if(info->isSerif()) serif = gTrue;
83             char*name = (char*)"";
84             if(newfont) {
85                 name = newfont->lowerCase()->getCString();
86                 if(strlen(name)>7 && name[6]=='+')
87                     name += 7;
88                 if(strstr(name, "ital")) italic = gTrue;
89                 if(strstr(name, "slan")) italic = gTrue;
90                 if(strstr(name, "obli")) italic = gTrue;
91                 if(strstr(name, "bold")) bold = gTrue;
92                 if(strstr(name, "heav")) bold = gTrue;
93                 if(strstr(name, "medi")) bold = gTrue;
94                 if(strstr(name, "serif")) serif = gTrue;
95             }
96             
97             fprintf(out, "<t font=\"%s\" y=\"%f\" x=\"%f\" style=\"%s%s%s%s\" fontsize=\"%.0fpt\">", 
98                     name,
99                     newbase,
100                     (word->rot&1)?word->yMin:word->xMin,
101                     info->isFixedWidth()?"fixed;":"",
102                     serif?"serif;":"",
103                     italic?"italic;":"",
104                     bold?"bold;":"",
105                     newsize);
106             fontname = newfont->copy();
107             fontsize = newsize;
108             base = newbase;
109         }
110         char*s = word->getText()->getCString();
111         while(*s) {
112             switch(*s) {
113                 case '<': fprintf(out, "&lt;");break;
114                 case '>': fprintf(out, "&gt;");break;
115                 case '&': fprintf(out, "&amp;");break;
116                 default: fwrite(s, 1, 1, out);
117             }
118             s++;
119         }
120         if(word->spaceAfter)
121             fprintf(out, " ");
122     }
123     if(textTag) fprintf(out, "</t>\n");
124     fprintf(out, "</page>\n");
125 }
126