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("&quot;");  break;
235 	case '&': tmp->append("&amp;");  break;
236 	case '<': tmp->append("&lt;");  break;
237 	case '>': tmp->append("&gt;");  break;
238 	case ' ': tmp->append( !xml && ( i+1 >= uLen || !tmp->getLength() || tmp->getChar( tmp->getLength()-1 ) == ' ' ) ? "&nbsp;" : " " );
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