new parameter addspacechars
[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     double color_r = -1;
63     double color_g = -1;
64     double color_b = -1;
65     for(i=0;i<len;i++) {
66         TextWord*word = list->get(i);
67         GString*newfont = word->getFontName();
68         double newsize = word->getFontSize();
69         double newbase = word->base;
70         double newcolor_r = word->colorR;
71         double newcolor_g = word->colorG;
72         double newcolor_b = word->colorB;
73
74         if((newfont && newfont->cmp(fontname)) || 
75            newsize != fontsize ||
76            newbase != base ||
77            newcolor_r != color_r ||
78            newcolor_g != color_g ||
79            newcolor_b != color_b
80            ) 
81         {
82             TextFontInfo*info = word->getFontInfo();
83             if(textTag)
84                 fprintf(out, "</t>\n");
85             textTag = 1;
86             GBool italic = gFalse;
87             GBool bold = gFalse;
88             GBool serif = gFalse;
89
90             if(info->isItalic()) italic = gTrue;
91             if(info->isBold()) bold = gTrue;
92             if(info->isSerif()) serif = gTrue;
93             char*name = (char*)"";
94             if(newfont) {
95                 name = newfont->lowerCase()->getCString();
96                 if(strlen(name)>7 && name[6]=='+')
97                     name += 7;
98                 if(strstr(name, "ital")) italic = gTrue;
99                 if(strstr(name, "slan")) italic = gTrue;
100                 if(strstr(name, "obli")) italic = gTrue;
101                 if(strstr(name, "bold")) bold = gTrue;
102                 if(strstr(name, "heav")) bold = gTrue;
103                 if(strstr(name, "medi")) bold = gTrue;
104                 if(strstr(name, "serif")) serif = gTrue;
105             }
106             
107             fprintf(out, "<t font=\"%s\" y=\"%f\" x=\"%f\" bbox=\"%f:%f:%f:%f\" style=\"%s%s%s%s\" fontsize=\"%.0fpt\" color=\"%02x%02x%02x\">", 
108                     name,
109                     newbase,
110                     (word->rot&1)?word->yMin:word->xMin,
111                     (word->rot&1)?word->yMin:word->xMin,
112                     (word->rot&1)?word->xMin:word->yMin,
113                     (word->rot&1)?word->yMax:word->xMax,
114                     (word->rot&1)?word->xMax:word->yMax,
115                     info->isFixedWidth()?"fixed;":"",
116                     serif?"serif;":"",
117                     italic?"italic;":"",
118                     bold?"bold;":"",
119                     newsize,
120                     ((int)(newcolor_r*255))&0xff,
121                     ((int)(newcolor_g*255))&0xff,
122                     ((int)(newcolor_b*255))&0xff
123                     );
124             fontname = newfont->copy();
125             fontsize = newsize;
126             base = newbase;
127             color_r = newcolor_r;
128             color_g = newcolor_g;
129             color_b = newcolor_b;
130         }
131         char*s = word->getText()->getCString();
132         while(*s) {
133             switch(*s) {
134                 case '<': fprintf(out, "&lt;");break;
135                 case '>': fprintf(out, "&gt;");break;
136                 case '&': fprintf(out, "&amp;");break;
137                 default: fwrite(s, 1, 1, out);
138             }
139             s++;
140         }
141         if(word->spaceAfter)
142             fprintf(out, " ");
143     }
144     if(textTag) fprintf(out, "</t>\n");
145     fprintf(out, "</page>\n");
146 }
147