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 "XMLOutputDev.h"
23 #include "GfxState.h"
24 #include "popplercompat.h"
25 #ifndef HAVE_POPPLER
26   #include "gfile.h"
27 #endif
28 
XMLOutputDev(char * filename)29 XMLOutputDev::XMLOutputDev(char*filename)
30 :TextOutputDev(mktmpname(0), false, false, false)
31 {
32   out = fopen(filename, "wb");
33   if(!out) {
34       perror(filename);
35       exit(-1);
36   }
37   fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
38   fprintf(out, "<document>\n");
39 }
40 
~XMLOutputDev()41 XMLOutputDev::~XMLOutputDev()
42 {
43   fprintf(out, "</document>\n");
44   fclose(out);
45 }
46 
startPage(int pageNum,GfxState * state)47 void XMLOutputDev::startPage(int pageNum, GfxState *state)
48 {
49     TextOutputDev::startPage(pageNum, state);
50     fprintf(out, "<page nr=\"%d\" width=\"%.0f\" height=\"%.0f\">\n", pageNum,
51 	state->getPageWidth(), state->getPageHeight());
52 }
53 
endPage()54 void XMLOutputDev::endPage()
55 {
56     TextOutputDev::endPage();
57     TextWordList* list = makeWordList();
58     int len = list->getLength();
59     int i;
60 
61     char textTag = 0;
62     GString*fontname = new GString();
63     double fontsize = -99999;
64     double base = -9999;
65     double color_r = -1;
66     double color_g = -1;
67     double color_b = -1;
68     for(i=0;i<len;i++) {
69 	TextWord*word = list->get(i);
70 	GString*newfont = word->getFontName();
71 	double newsize = word->getFontSize();
72 #ifdef HAVE_POPPLER
73 	double newbase = word->getBaseline();
74 #else
75 	double newbase = word->base;
76 #endif
77 	double newcolor_r;
78 	double newcolor_g;
79 	double newcolor_b;
80   word->getColor(&newcolor_r, &newcolor_g, &newcolor_b);
81 
82 	if((newfont && newfont->cmp(fontname)) ||
83 	   newsize != fontsize ||
84 	   newbase != base ||
85 	   newcolor_r != color_r ||
86 	   newcolor_g != color_g ||
87 	   newcolor_b != color_b
88 	   )
89 	{
90 	    TextFontInfo*info = word->getFontInfo();
91 	    if(textTag)
92 		fprintf(out, "</t>\n");
93 	    textTag = 1;
94 	    GBool italic = gFalse;
95 	    GBool bold = gFalse;
96 	    GBool serif = gFalse;
97 
98 	    if(info->isItalic()) italic = gTrue;
99 	    if(info->isBold()) bold = gTrue;
100 	    if(info->isSerif()) serif = gTrue;
101 	    char*name = (char*)"";
102 	    if(newfont) {
103 		name = newfont->lowerCase()->getCString();
104 		if(strlen(name)>7 && name[6]=='+')
105 		    name += 7;
106 		if(strstr(name, "ital")) italic = gTrue;
107 		if(strstr(name, "slan")) italic = gTrue;
108 		if(strstr(name, "obli")) italic = gTrue;
109 		if(strstr(name, "bold")) bold = gTrue;
110 		if(strstr(name, "heav")) bold = gTrue;
111 		if(strstr(name, "medi")) bold = gTrue;
112 		if(strstr(name, "serif")) serif = gTrue;
113 	    }
114 
115     double xMin,yMin,xMax,yMax;
116     word->getBBox(&xMin, &yMin, &xMax, &yMax);
117 
118     int rot = word->getRotation();
119 
120 	    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\">",
121 		    name,
122 		    newbase,
123 		    (rot&1)?yMin:xMin,
124 		    (rot&1)?yMin:xMin,
125 		    (rot&1)?xMin:yMin,
126 		    (rot&1)?yMax:xMax,
127 		    (rot&1)?xMax:yMax,
128 		    info->isFixedWidth()?"fixed;":"",
129 		    serif?"serif;":"",
130 		    italic?"italic;":"",
131 		    bold?"bold;":"",
132 		    newsize,
133 		    ((int)(newcolor_r*255))&0xff,
134 		    ((int)(newcolor_g*255))&0xff,
135 		    ((int)(newcolor_b*255))&0xff
136 		    );
137 	    fontname = newfont->copy();
138 	    fontsize = newsize;
139 	    base = newbase;
140 	    color_r = newcolor_r;
141 	    color_g = newcolor_g;
142 	    color_b = newcolor_b;
143 	}
144 	char*s = word->getText()->getCString();
145 	while(*s) {
146 	    switch(*s) {
147 		case '<': fprintf(out, "&lt;");break;
148 		case '>': fprintf(out, "&gt;");break;
149 		case '&': fprintf(out, "&amp;");break;
150 		default: fwrite(s, 1, 1, out);
151 	    }
152 	    s++;
153 	}
154 	if(word->getSpaceAfter())
155 	    fprintf(out, " ");
156     }
157     if(textTag) fprintf(out, "</t>\n");
158     fprintf(out, "</page>\n");
159 }
160 
161