Commit bcc5e3af authored by Kristian Høgsberg's avatar Kristian Høgsberg

2005-12-12 Kristian Høgsberg <krh@redhat.com>

	* Makefile.am:
	* configure.ac:
	* goo/GooVector.h:
	* utils/HtmlFonts.cc:
	* utils/HtmlFonts.h:
	* utils/HtmlLinks.cc:
	* utils/HtmlLinks.h:
	* utils/HtmlOutputDev.cc:
	* utils/HtmlOutputDev.h:
	* utils/ImageOutputDev.cc:
	* utils/ImageOutputDev.h:
	* utils/Makefile.am:
	* utils/parseargs.c:
	* utils/parseargs.h:
	* utils/pdffonts.1:
	* utils/pdffonts.cc:
	* utils/pdfimages.1:
	* utils/pdfimages.cc:
	* utils/pdfinfo.1:
	* utils/pdfinfo.cc:
	* utils/pdftohtml.1:
	* utils/pdftohtml.cc:
	* utils/pdftoppm.1:
	* utils/pdftoppm.cc:
	* utils/pdftops.1:
	* utils/pdftops.cc:
	* utils/pdftotext.1:
	* utils/pdftotext.cc: Add command line utilities from xpdf.
parent 5fbded32
2005-12-12 Kristian Høgsberg <krh@redhat.com>
* Makefile.am:
* configure.ac:
* goo/GooVector.h:
* utils/HtmlFonts.cc:
* utils/HtmlFonts.h:
* utils/HtmlLinks.cc:
* utils/HtmlLinks.h:
* utils/HtmlOutputDev.cc:
* utils/HtmlOutputDev.h:
* utils/ImageOutputDev.cc:
* utils/ImageOutputDev.h:
* utils/Makefile.am:
* utils/parseargs.c:
* utils/parseargs.h:
* utils/pdffonts.1:
* utils/pdffonts.cc:
* utils/pdfimages.1:
* utils/pdfimages.cc:
* utils/pdfinfo.1:
* utils/pdfinfo.cc:
* utils/pdftohtml.1:
* utils/pdftohtml.cc:
* utils/pdftoppm.1:
* utils/pdftoppm.cc:
* utils/pdftops.1:
* utils/pdftops.cc:
* utils/pdftotext.1:
* utils/pdftotext.cc: Add command line utilities from xpdf.
2005-12-10 Albert Astals Cid <aacid@kde.org>
* qt4/src/poppler-page.cc:
......
......@@ -22,7 +22,11 @@ qt4_subdir = qt4
qt4_pc_file = poppler-qt4.pc
endif
SUBDIRS = goo fofi $(splash_subdir) poppler $(glib_subdir) $(qt_subdir) test $(qt4_subdir)
if BUILD_UTILS
utils_subdir = utils
endif
SUBDIRS = goo fofi $(splash_subdir) poppler $(utils_subdir) $(glib_subdir) $(qt_subdir) test $(qt4_subdir)
EXTRA_DIST = \
README-XPDF \
......
......@@ -479,6 +479,13 @@ fi
AM_CONDITIONAL(BUILD_GTK_TEST, test x$enable_gtk_test = xyes)
AC_ARG_ENABLE(utils,
AC_HELP_STRING([--disable-utils],
[Don't compile poppler command line utils.]),
enable_utils=$enableval,
enable_utils="yes")
AM_CONDITIONAL(BUILD_UTILS, test x$enable_utils = xyes)
AC_ARG_ENABLE(compile-warnings,
AC_HELP_STRING([--enable-compile-warnings=@<:@no/yes/kde@:>@]
[Turn on compiler warnings.]),,
......@@ -505,6 +512,7 @@ goo/Makefile
fofi/Makefile
splash/Makefile
poppler/Makefile
utils/Makefile
glib/Makefile
test/Makefile
qt/Makefile
......@@ -521,11 +529,12 @@ poppler-qt4.pc])
echo ""
echo "Building poppler with support for:"
echo " splash output: $enable_splash_output"
echo " cairo output: $enable_cairo_output"
echo " qt wrapper: $enable_poppler_qt"
echo " qt4 wrapper: $enable_poppler_qt4"
echo " qt4 unittests: $enable_poppler_qt4testlib"
echo " glib wrapper: $enable_poppler_glib"
echo " use libjpeg: $enable_libjpeg"
echo " use zlib: $enable_zlib"
echo " splash output: $enable_splash_output"
echo " cairo output: $enable_cairo_output"
echo " qt wrapper: $enable_poppler_qt"
echo " qt4 wrapper: $enable_poppler_qt4"
echo " qt4 unittests: $enable_poppler_qt4testlib"
echo " glib wrapper: $enable_poppler_glib"
echo " use libjpeg: $enable_libjpeg"
echo " use zlib: $enable_zlib"
echo " command line utils: $enable_poppler_glib"
#ifndef _VECTOR_H
#define _VECTOR_H
#include "goo/gtypes.h"
template<class T>
class GooVector{
private:
int _size;
T* last;
T* storage;
void resize(){
if (_size==0) _size=2;else _size=2*_size;
T *tmp=new T[_size];
if (storage){
last=copy(storage,last,tmp);
delete [] storage;
}
else last=tmp;
storage=tmp;
}
T* copy(T* src1,T* scr2,T* dest){
T* tmp=src1;
T* d=dest;
while(tmp!=scr2){
*d=*tmp;
d++;tmp++;
}
return d;
}
public:
typedef T* iterator;
GooVector(){
_size=0;
last=0;
storage=0;
}
virtual ~GooVector(){
delete[] storage ;
}
void reset(){
last=storage;
}
int size(){
return (last-storage);
}
void push_back(const T& elem){
if (!storage||(size() >=_size)) resize();
*last=elem;
last++;
}
T pop_back() {
if (last!=storage) last--;
return *last;
}
T operator[](unsigned int i){
return *(storage+i);
}
GBool isEmpty() const{
return !_size || (last==storage) ;
}
iterator begin() const{
return storage;
}
iterator end() const {
return last;
}
};
#endif
#include "HtmlFonts.h"
#include "GlobalParams.h"
#include "UnicodeMap.h"
#include <stdio.h>
struct Fonts{
char *Fontname;
char *name;
};
const int font_num=13;
static Fonts fonts[font_num+1]={
{"Courier", "Courier" },
{"Courier-Bold", "Courier"},
{"Courier-BoldOblique", "Courier"},
{"Courier-Oblique", "Courier"},
{"Helvetica", "Helvetica"},
{"Helvetica-Bold", "Helvetica"},
{"Helvetica-BoldOblique", "Helvetica"},
{"Helvetica-Oblique", "Helvetica"},
{"Symbol", "Symbol" },
{"Times-Bold", "Times" },
{"Times-BoldItalic", "Times" },
{"Times-Italic", "Times" },
{"Times-Roman", "Times" },
{" " , "Times" },
};
#define xoutRound(x) ((int)(x + 0.5))
extern GBool xml;
GooString* HtmlFont::DefaultFont=new GooString("Times"); // Arial,Helvetica,sans-serif
HtmlFontColor::HtmlFontColor(GfxRGB rgb){
r=static_cast<int>(255*rgb.r);
g=static_cast<int>(255*rgb.g);
b=static_cast<int>(255*rgb.b);
if (!(Ok(r)&&Ok(b)&&Ok(g))) {printf("Error : Bad color \n");r=0;g=0;b=0;}
}
GooString *HtmlFontColor::convtoX(unsigned int xcol) const{
GooString *xret=new GooString();
char tmp;
unsigned int k;
k = (xcol/16);
if ((k>=0)&&(k<10)) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10);
xret->append(tmp);
k = (xcol%16);
if ((k>=0)&&(k<10)) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10);
xret->append(tmp);
return xret;
}
GooString *HtmlFontColor::toString() const{
GooString *tmp=new GooString("#");
GooString *tmpr=convtoX(r);
GooString *tmpg=convtoX(g);
GooString *tmpb=convtoX(b);
tmp->append(tmpr);
tmp->append(tmpg);
tmp->append(tmpb);
delete tmpr;
delete tmpg;
delete tmpb;
return tmp;
}
HtmlFont::HtmlFont(GooString* ftname,int _size, GfxRGB rgb){
//if (col) color=HtmlFontColor(col);
//else color=HtmlFontColor();
color=HtmlFontColor(rgb);
GooString *fontname = NULL;
if( ftname ){
fontname = new GooString(ftname);
FontName=new GooString(ftname);
}
else {
fontname = NULL;
FontName = NULL;
}
lineSize = -1;
size=(_size-1);
italic = gFalse;
bold = gFalse;
if (fontname){
if (strstr(fontname->lowerCase()->getCString(),"bold")) bold=gTrue;
if (strstr(fontname->lowerCase()->getCString(),"italic")||
strstr(fontname->lowerCase()->getCString(),"oblique")) italic=gTrue;
int i=0;
while (strcmp(ftname->getCString(),fonts[i].Fontname)&&(i<font_num))
{
i++;
}
pos=i;
delete fontname;
}
if (!DefaultFont) DefaultFont=new GooString(fonts[font_num].name);
}
HtmlFont::HtmlFont(const HtmlFont& x){
size=x.size;
lineSize=x.lineSize;
italic=x.italic;
bold=x.bold;
pos=x.pos;
color=x.color;
if (x.FontName) FontName=new GooString(x.FontName);
}
HtmlFont::~HtmlFont(){
if (FontName) delete FontName;
}
HtmlFont& HtmlFont::operator=(const HtmlFont& x){
if (this==&x) return *this;
size=x.size;
lineSize=x.lineSize;
italic=x.italic;
bold=x.bold;
pos=x.pos;
color=x.color;
if (FontName) delete FontName;
if (x.FontName) FontName=new GooString(x.FontName);
return *this;
}
void HtmlFont::clear(){
if(DefaultFont) delete DefaultFont;
DefaultFont = NULL;
}
/*
This function is used to compare font uniquily for insertion into
the list of all encountered fonts
*/
GBool HtmlFont::isEqual(const HtmlFont& x) const{
return ((size==x.size) &&
(lineSize==x.lineSize) &&
(pos==x.pos) && (bold==x.bold) && (italic==x.italic) &&
(color.isEqual(x.getColor())));
}
/*
This one is used to decide whether two pieces of text can be joined together
and therefore we don't care about bold/italics properties
*/
GBool HtmlFont::isEqualIgnoreBold(const HtmlFont& x) const{
return ((size==x.size) &&
(!strcmp(fonts[pos].name, fonts[x.pos].name)) &&
(color.isEqual(x.getColor())));
}
GooString* HtmlFont::getFontName(){
if (pos!=font_num) return new GooString(fonts[pos].name);
else return new GooString(DefaultFont);
}
GooString* HtmlFont::getFullName(){
if (FontName)
return new GooString(FontName);
else return new GooString(DefaultFont);
}
void HtmlFont::setDefaultFont(GooString* defaultFont){
if (DefaultFont) delete DefaultFont;
DefaultFont=new GooString(defaultFont);
}
GooString* HtmlFont::getDefaultFont(){
return DefaultFont;
}
// this method if plain wrong todo
GooString* HtmlFont::HtmlFilter(Unicode* u, int uLen) {
GooString *tmp = new GooString();
UnicodeMap *uMap;
char buf[8];
int n;
// get the output encoding
if (!(uMap = globalParams->getTextEncoding())) {
return tmp;
}
for (int i = 0; i < uLen; ++i) {
switch (u[i])
{
case '"': tmp->append("&quot;"); break;
case '&': tmp->append("&amp;"); break;
case '<': tmp->append("&lt;"); break;
case '>': tmp->append("&gt;"); break;
default:
{
// convert unicode to string
if ((n = uMap->mapUnicode(u[i], buf, sizeof(buf))) > 0) {
tmp->append(buf, n);
}
}
}
}
uMap->decRefCnt();
return tmp;
}
GooString* HtmlFont::simple(HtmlFont* font, Unicode* content, int uLen){
GooString *cont=HtmlFilter (content, uLen);
/*if (font.isBold()) {
cont->insert(0,"<b>",3);
cont->append("</b>",4);
}
if (font.isItalic()) {
cont->insert(0,"<i>",3);
cont->append("</i>",4);
} */
return cont;
}
HtmlFontAccu::HtmlFontAccu(){
accu=new GooVector<HtmlFont>();
}
HtmlFontAccu::~HtmlFontAccu(){
if (accu) delete accu;
}
int HtmlFontAccu::AddFont(const HtmlFont& font){
GooVector<HtmlFont>::iterator i;
for (i=accu->begin();i!=accu->end();i++)
{
if (font.isEqual(*i))
{
return (int)(i-(accu->begin()));
}
}
accu->push_back(font);
return (accu->size()-1);
}
// get CSS font name for font #i
GooString* HtmlFontAccu::getCSStyle(int i, GooString* content){
GooString *tmp;
GooString *iStr=GooString::fromInt(i);
if (!xml) {
tmp = new GooString("<span class=\"ft");
tmp->append(iStr);
tmp->append("\">");
tmp->append(content);
tmp->append("</span>");
} else {
tmp = new GooString("");
tmp->append(content);
}
delete iStr;
return tmp;
}
// get CSS font definition for font #i
GooString* HtmlFontAccu::CSStyle(int i){
GooString *tmp=new GooString();
GooString *iStr=GooString::fromInt(i);
GooVector<HtmlFont>::iterator g=accu->begin();
g+=i;
HtmlFont font=*g;
GooString *Size=GooString::fromInt(font.getSize());
GooString *colorStr=font.getColor().toString();
GooString *fontName=font.getFontName();
GooString *lSize;
if(!xml){
tmp->append(".ft");
tmp->append(iStr);
tmp->append("{font-size:");
tmp->append(Size);
if( font.getLineSize() != -1 )
{
lSize = GooString::fromInt(font.getLineSize());
tmp->append("px;line-height:");
tmp->append(lSize);
delete lSize;
}
tmp->append("px;font-family:");
tmp->append(fontName); //font.getFontName());
tmp->append(";color:");
tmp->append(colorStr);
tmp->append(";}");
}
if (xml) {
tmp->append("<fontspec id=\"");
tmp->append(iStr);
tmp->append("\" size=\"");
tmp->append(Size);
tmp->append("\" family=\"");
tmp->append(fontName); //font.getFontName());
tmp->append("\" color=\"");
tmp->append(colorStr);
tmp->append("\"/>");
}
delete fontName;
delete colorStr;
delete iStr;
delete Size;
return tmp;
}
#ifndef _HTML_FONTS_H
#define _HTML_FONTS_H
#include "goo/GooVector.h"
#include "goo/GooString.h"
#include "GfxState.h"
#include "CharTypes.h"
class HtmlFontColor{
private:
unsigned int r;
unsigned int g;
unsigned int b;
GBool Ok(unsigned int xcol){ return ((xcol<=255)&&(xcol>=0));}
GooString *convtoX(unsigned int xcol) const;
public:
HtmlFontColor():r(0),g(0),b(0){}
HtmlFontColor(GfxRGB rgb);
HtmlFontColor(const HtmlFontColor& x){r=x.r;g=x.g;b=x.b;}
HtmlFontColor& operator=(const HtmlFontColor &x){
r=x.r;g=x.g;b=x.b;
return *this;
}
~HtmlFontColor(){};
GooString* toString() const;
GBool isEqual(const HtmlFontColor& col) const{
return ((r==col.r)&&(g==col.g)&&(b==col.b));
}
} ;
class HtmlFont{
private:
unsigned int size;
int lineSize;
GBool italic;
GBool bold;
int pos; // position of the font name in the fonts array
static GooString *DefaultFont;
GooString *FontName;
HtmlFontColor color;
static GooString* HtmlFilter(Unicode* u, int uLen); //char* s);
public:
HtmlFont(){FontName=NULL;};
HtmlFont(GooString* fontname,int _size, GfxRGB rgb);
HtmlFont(const HtmlFont& x);
HtmlFont& operator=(const HtmlFont& x);
HtmlFontColor getColor() const {return color;}
~HtmlFont();
static void clear();
GooString* getFullName();
GBool isItalic() const {return italic;}
GBool isBold() const {return bold;}
unsigned int getSize() const {return size;}
int getLineSize() const {return lineSize;}
void setLineSize(int _lineSize) { lineSize = _lineSize; }
GooString* getFontName();
static GooString* getDefaultFont();
static void setDefaultFont(GooString* defaultFont);
GBool isEqual(const HtmlFont& x) const;
GBool isEqualIgnoreBold(const HtmlFont& x) const;
static GooString* simple(HtmlFont *font, Unicode *content, int uLen);
void print() const {printf("font: %s %d %s%spos: %d\n", FontName->getCString(), size, bold ? "bold " : "", italic ? "italic " : "", pos);};
};
class HtmlFontAccu{
private:
GooVector<HtmlFont> *accu;
public:
HtmlFontAccu();
~HtmlFontAccu();
int AddFont(const HtmlFont& font);
HtmlFont* Get(int i){
GooVector<HtmlFont>::iterator g=accu->begin();
g+=i;
return g;
}
GooString* getCSStyle (int i, GooString* content);
GooString* CSStyle(int i);
int size() const {return accu->size();}
};
#endif
#include "HtmlLinks.h"
HtmlLink::HtmlLink(const HtmlLink& x){
Xmin=x.Xmin;
Ymin=x.Ymin;
Xmax=x.Xmax;
Ymax=x.Ymax;
dest=new GooString(x.dest);
}
HtmlLink::HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString * _dest)
{
if (xmin < xmax) {
Xmin=xmin;
Xmax=xmax;
} else {
Xmin=xmax;
Xmax=xmin;
}
if (ymin < ymax) {
Ymin=ymin;
Ymax=ymax;
} else {
Ymin=ymax;
Ymax=ymin;
}
dest=new GooString(_dest);
}
HtmlLink::~HtmlLink(){
if (dest) delete dest;
}
GBool HtmlLink::isEqualDest(const HtmlLink& x) const{
return (!strcmp(dest->getCString(), x.dest->getCString()));
}
GBool HtmlLink::inLink(double xmin,double ymin,double xmax,double ymax) const {
double y=(ymin+ymax)/2;
if (y>Ymax) return gFalse;
return (y>Ymin)&&(xmin<Xmax)&&(xmax>Xmin);
}
HtmlLink& HtmlLink::operator=(const HtmlLink& x){
if (this==&x) return *this;
if (dest) {delete dest;dest=NULL;}
Xmin=x.Xmin;
Ymin=x.Ymin;
Xmax=x.Xmax;
Ymax=x.Ymax;
dest=new GooString(x.dest);
return *this;
}
GooString* HtmlLink::getLinkStart() {
GooString *res = new GooString("<A href=\"");
res->append(dest);
res->append("\">");
return res;
}
/*GooString* HtmlLink::Link(GooString* content){
//GooString* _dest=new GooString(dest);
GooString *tmp=new GooString("<a href=\"");
tmp->append(dest);
tmp->append("\">");
tmp->append(content);
tmp->append("</a>");
//delete _dest;
return tmp;
}*/
HtmlLinks::HtmlLinks(){
accu=new GooVector<HtmlLink>();
}
HtmlLinks::~HtmlLinks(){
delete accu;
accu=NULL;
}
GBool HtmlLinks::inLink(double xmin,double ymin,double xmax,double ymax,int& p)const {
for(GooVector<HtmlLink>::iterator i=accu->begin();i!=accu->end();i++){
if (i->inLink(xmin,ymin,xmax,ymax)) {
p=(i - accu->begin());
return 1;
}
}
return 0;
}
HtmlLink* HtmlLinks::getLink(int i) const{
GooVector<HtmlLink>::iterator g=accu->begin();
g+=i;
return g;
}
#ifndef _HTML_LINKS
#define _HTML_LINKS
#include <stdlib.h>
#include <string.h>
#include "goo/GooVector.h"
#include "goo/GooString.h"
class HtmlLink{
private:
double Xmin;
double Ymin;
double Xmax;
double Ymax;
GooString* dest;
public:
HtmlLink(){dest=NULL;}
HtmlLink(const HtmlLink& x);
HtmlLink& operator=(const HtmlLink& x);
HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString *_dest);
~HtmlLink();
GBool isEqualDest(const HtmlLink& x) const;
GooString *getDest(){return new GooString(dest);}
double getX1() const {return Xmin;}
double getX2() const {return Xmax;}
double getY1() const {return Ymin;}
double getY2() const {return Ymax;}