1 //========================================================================
2 //
3 // This file comes from pdftohtml project
4 // http://pdftohtml.sourceforge.net
5 //
6 // Copyright from:
7 // Gueorgui Ovtcharov
8 // Rainer Dorsch <http://www.ra.informatik.uni-stuttgart.de/~rainer/>
9 // Mikhail Kruk <meshko@cs.brandeis.edu>
10 //
11 //========================================================================
12
13 //========================================================================
14 //
15 // Modified under the Poppler project - http://poppler.freedesktop.org
16 //
17 // All changes made under the Poppler project to this file are licensed
18 // under GPL version 2 or later
19 //
20 // Copyright (C) 2007, 2010 Albert Astals Cid <aacid@kde.org>
21 // Copyright (C) 2008 Boris Toloknov <tlknv@yandex.ru>
22 // Copyright (C) 2008 Tomas Are Haavet <tomasare@gmail.com>
23 // Copyright (C) 2010 OSSD CDAC Mumbai by Leena Chourey (leenac@cdacmumbai.in) and Onkar Potdar (onkar@cdacmumbai.in)
24 //
25 // To see a description of the changes please see the Changelog file that
26 // came with your tarball or type make ChangeLog if you are building from git
27 //
28 //========================================================================
29
30 #include "HtmlFonts.h"
31 #include "GlobalParams.h"
32 #include "UnicodeMap.h"
33 #include <stdio.h>
34
35 struct Fonts{
36 char *Fontname;
37 char *name;
38 };
39
40 const int font_num=13;
41
42 static Fonts fonts[font_num+1]={
43 {"Courier", "Courier" },
44 {"Courier-Bold", "Courier"},
45 {"Courier-BoldOblique", "Courier"},
46 {"Courier-Oblique", "Courier"},
47 {"Helvetica", "Helvetica"},
48 {"Helvetica-Bold", "Helvetica"},
49 {"Helvetica-BoldOblique", "Helvetica"},
50 {"Helvetica-Oblique", "Helvetica"},
51 {"Symbol", "Symbol" },
52 {"Times-Bold", "Times" },
53 {"Times-BoldItalic", "Times" },
54 {"Times-Italic", "Times" },
55 {"Times-Roman", "Times" },
56 {" " , "Times" },
57 };
58
59 #define xoutRound(x) ((int)(x + 0.5))
60 extern GBool xml;
61
62 GooString* HtmlFont::DefaultFont=new GooString("Times"); // Arial,Helvetica,sans-serif
63
HtmlFontColor(GfxRGB rgb)64 HtmlFontColor::HtmlFontColor(GfxRGB rgb){
65 r=static_cast<int>(rgb.r/65535.0*255.0);
66 g=static_cast<int>(rgb.g/65535.0*255.0);
67 b=static_cast<int>(rgb.b/65535.0*255.0);
68 if (!(Ok(r)&&Ok(b)&&Ok(g))) {
69 if (!globalParams->getErrQuiet()) fprintf(stderr, "Error : Bad color (%d,%d,%d) reset to (0,0,0)\n", r, g, b);
70 r=0;g=0;b=0;
71 }
72 }
73
convtoX(unsigned int xcol) const74 GooString *HtmlFontColor::convtoX(unsigned int xcol) const{
75 GooString *xret=new GooString();
76 char tmp;
77 unsigned int k;
78 k = (xcol/16);
79 if ((k>=0)&&(k<10)) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10);
80 xret->append(tmp);
81 k = (xcol%16);
82 if ((k>=0)&&(k<10)) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10);
83 xret->append(tmp);
84 return xret;
85 }
86
toString() const87 GooString *HtmlFontColor::toString() const{
88 GooString *tmp=new GooString("#");
89 GooString *tmpr=convtoX(r);
90 GooString *tmpg=convtoX(g);
91 GooString *tmpb=convtoX(b);
92 tmp->append(tmpr);
93 tmp->append(tmpg);
94 tmp->append(tmpb);
95 delete tmpr;
96 delete tmpg;
97 delete tmpb;
98 return tmp;
99 }
100
HtmlFont(GooString * ftname,int _size,GfxRGB rgb)101 HtmlFont::HtmlFont(GooString* ftname,int _size, GfxRGB rgb){
102 //if (col) color=HtmlFontColor(col);
103 //else color=HtmlFontColor();
104 color=HtmlFontColor(rgb);
105
106 GooString *fontname = NULL;
107
108 if( ftname ){
109 fontname = new GooString(ftname);
110 FontName=new GooString(ftname);
111 }
112 else {
113 fontname = NULL;
114 FontName = NULL;
115 }
116
117 lineSize = -1;
118
119 size=(_size-1);
120 italic = gFalse;
121 bold = gFalse;
122
123 if (fontname){
124 if (strstr(fontname->lowerCase()->getCString(),"bold")) bold=gTrue;
125
126 if (strstr(fontname->lowerCase()->getCString(),"italic")||
127 strstr(fontname->lowerCase()->getCString(),"oblique")) italic=gTrue;
128
129 int i=0;
130 while (strcmp(ftname->getCString(),fonts[i].Fontname)&&(i<font_num))
131 {
132 i++;
133 }
134 pos=i;
135 delete fontname;
136 } else
137 pos = font_num;
138 if (!DefaultFont) DefaultFont=new GooString(fonts[font_num].name);
139
140 }
141
HtmlFont(const HtmlFont & x)142 HtmlFont::HtmlFont(const HtmlFont& x){
143 size=x.size;
144 lineSize=x.lineSize;
145 italic=x.italic;
146 bold=x.bold;
147 pos=x.pos;
148 color=x.color;
149 if (x.FontName) FontName=new GooString(x.FontName);
150 }
151
152
~HtmlFont()153 HtmlFont::~HtmlFont(){
154 if (FontName) delete FontName;
155 }
156
operator =(const HtmlFont & x)157 HtmlFont& HtmlFont::operator=(const HtmlFont& x){
158 if (this==&x) return *this;
159 size=x.size;
160 lineSize=x.lineSize;
161 italic=x.italic;
162 bold=x.bold;
163 pos=x.pos;
164 color=x.color;
165 if (FontName) delete FontName;
166 if (x.FontName) FontName=new GooString(x.FontName);
167 return *this;
168 }
169
clear()170 void HtmlFont::clear(){
171 if(DefaultFont) delete DefaultFont;
172 DefaultFont = NULL;
173 }
174
175
176
177 /*
178 This function is used to compare font uniquily for insertion into
179 the list of all encountered fonts
180 */
isEqual(const HtmlFont & x) const181 GBool HtmlFont::isEqual(const HtmlFont& x) const{
182 return ((size==x.size) &&
183 (lineSize==x.lineSize) &&
184 (pos==x.pos) && (bold==x.bold) && (italic==x.italic) &&
185 (color.isEqual(x.getColor())));
186 }
187
188 /*
189 This one is used to decide whether two pieces of text can be joined together
190 and therefore we don't care about bold/italics properties
191 */
isEqualIgnoreBold(const HtmlFont & x) const192 GBool HtmlFont::isEqualIgnoreBold(const HtmlFont& x) const{
193 return ((size==x.size) &&
194 (!strcmp(fonts[pos].name, fonts[x.pos].name)) &&
195 (color.isEqual(x.getColor())));
196 }
197
getFontName()198 GooString* HtmlFont::getFontName(){
199 if (pos!=font_num) return new GooString(fonts[pos].name);
200 else return new GooString(DefaultFont);
201 }
202
getFullName()203 GooString* HtmlFont::getFullName(){
204 if (FontName)
205 return new GooString(FontName);
206 else return new GooString(DefaultFont);
207 }
208
setDefaultFont(GooString * defaultFont)209 void HtmlFont::setDefaultFont(GooString* defaultFont){
210 if (DefaultFont) delete DefaultFont;
211 DefaultFont=new GooString(defaultFont);
212 }
213
214
getDefaultFont()215 GooString* HtmlFont::getDefaultFont(){
216 return DefaultFont;
217 }
218
219 // this method if plain wrong todo
HtmlFilter(Unicode * u,int uLen)220 GooString* HtmlFont::HtmlFilter(Unicode* u, int uLen) {
221 GooString *tmp = new GooString();
222 UnicodeMap *uMap;
223 char buf[8];
224 int n;
225
226 // get the output encoding
227 if (!(uMap = globalParams->getTextEncoding())) {
228 return tmp;
229 }
230
231 for (int i = 0; i < uLen; ++i) {
232 switch (u[i])
233 {
234 case '"': tmp->append("""); break;
235 case '&': tmp->append("&"); break;
236 case '<': tmp->append("<"); break;
237 case '>': tmp->append(">"); break;
238 case ' ': tmp->append( !xml && ( i+1 >= uLen || !tmp->getLength() || tmp->getChar( tmp->getLength()-1 ) == ' ' ) ? " " : " " );
239 break;
240 default:
241 {
242 // convert unicode to string
243 if ((n = uMap->mapUnicode(u[i], buf, sizeof(buf))) > 0) {
244 tmp->append(buf, n);
245 }
246 }
247 }
248 }
249
250 uMap->decRefCnt();
251 return tmp;
252 }
253
simple(HtmlFont * font,Unicode * content,int uLen)254 GooString* HtmlFont::simple(HtmlFont* font, Unicode* content, int uLen){
255 GooString *cont=HtmlFilter (content, uLen);
256
257 /*if (font.isBold()) {
258 cont->insert(0,"<b>",3);
259 cont->append("</b>",4);
260 }
261 if (font.isItalic()) {
262 cont->insert(0,"<i>",3);
263 cont->append("</i>",4);
264 } */
265
266 return cont;
267 }
268
HtmlFontAccu()269 HtmlFontAccu::HtmlFontAccu(){
270 accu=new std::vector<HtmlFont>();
271 }
272
~HtmlFontAccu()273 HtmlFontAccu::~HtmlFontAccu(){
274 if (accu) delete accu;
275 }
276
AddFont(const HtmlFont & font)277 int HtmlFontAccu::AddFont(const HtmlFont& font){
278 std::vector<HtmlFont>::iterator i;
279 for (i=accu->begin();i!=accu->end();i++)
280 {
281 if (font.isEqual(*i))
282 {
283 return (int)(i-(accu->begin()));
284 }
285 }
286
287 accu->push_back(font);
288 return (accu->size()-1);
289 }
290
291 // get CSS font name for font #i
getCSStyle(int i,GooString * content,int j)292 GooString* HtmlFontAccu::getCSStyle(int i, GooString* content, int j){
293 GooString *tmp;
294 GooString *iStr=GooString::fromInt(i);
295 GooString *jStr=GooString::fromInt(j);
296
297 if (!xml) {
298 tmp = new GooString("<span class=\"ft");
299 tmp->append(jStr);
300 tmp->append(iStr);
301 tmp->append("\">");
302 tmp->append(content);
303 tmp->append("</span>");
304 } else {
305 tmp = new GooString("");
306 tmp->append(content);
307 }
308
309 delete jStr;
310 delete iStr;
311 return tmp;
312 }
313
314 // get CSS font definition for font #i
CSStyle(int i,int j)315 GooString* HtmlFontAccu::CSStyle(int i, int j){
316 GooString *tmp=new GooString();
317 GooString *iStr=GooString::fromInt(i);
318 GooString *jStr=GooString::fromInt(j);
319
320 std::vector<HtmlFont>::iterator g=accu->begin();
321 g+=i;
322 HtmlFont font=*g;
323 GooString *Size=GooString::fromInt(font.getSize());
324 GooString *colorStr=font.getColor().toString();
325 GooString *fontName=font.getFontName();
326 GooString *lSize;
327
328 if(!xml){
329 tmp->append(".ft");
330 tmp->append(jStr);
331 tmp->append(iStr);
332 tmp->append("{font-size:");
333 tmp->append(Size);
334 if( font.getLineSize() != -1 )
335 {
336 lSize = GooString::fromInt(font.getLineSize());
337 tmp->append("px;line-height:");
338 tmp->append(lSize);
339 delete lSize;
340 }
341 tmp->append("px;font-family:");
342 tmp->append(fontName); //font.getFontName());
343 tmp->append(";color:");
344 tmp->append(colorStr);
345 tmp->append(";}");
346 }
347 if (xml) {
348 tmp->append("<fontspec id=\"");
349 tmp->append(iStr);
350 tmp->append("\" size=\"");
351 tmp->append(Size);
352 tmp->append("\" family=\"");
353 tmp->append(fontName); //font.getFontName());
354 tmp->append("\" color=\"");
355 tmp->append(colorStr);
356 tmp->append("\"/>");
357 }
358
359 delete fontName;
360 delete colorStr;
361 delete jStr;
362 delete iStr;
363 delete Size;
364 return tmp;
365 }
366
367
368