Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Andi Sardina Ramos
Okular
Commits
8f4104a9
Commit
8f4104a9
authored
Jun 13, 2005
by
Enrico Ros
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merge (refactored) patch_050,051,060
svn path=/branches/kpdf/annotations/kdegraphics/kpdf/; revision=424991
parent
04122718
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
245 additions
and
12 deletions
+245
-12
TODO
TODO
+2
-0
core/document.cpp
core/document.cpp
+14
-0
core/document.h
core/document.h
+20
-3
core/generator.h
core/generator.h
+1
-0
core/generator_pdf/generator_pdf.cpp
core/generator_pdf/generator_pdf.cpp
+166
-1
core/generator_pdf/generator_pdf.h
core/generator_pdf/generator_pdf.h
+12
-4
ui/propertiesdialog.cpp
ui/propertiesdialog.cpp
+30
-4
No files found.
TODO
View file @
8f4104a9
...
...
@@ -30,6 +30,7 @@ More items (first items will enter 'In progress list' first):
-> evaluate completely handling links internally instead of asking xpdf structs
-> pageview: change document viewport after mouse scrolling ended (not every scroll frame)
this will give better mvc consistancy
-> other info on pdfs properties: number of accessed times, time spent on pdf, ...
-> part: collapsing the left panel will hide it (activate hiding action)
-> preload: add a delay when forward loading pages
-> toc: add search bar (a 'prune on type' lineedit like in thumbnails widget) (BR99349)
...
...
@@ -121,6 +122,7 @@ Done (newest features come first):
-> ADD: annotations: PDF1.6 reader (PDF's annotations -> our data structures)
-> ADD: Internal data structures for annotations handling.
-> FIX: rmb when no doc displayed to restore menu
-> ADD: Put fonts used by the document on the properties dialog
-> ADD: partial implementation of XYZ links
-> ADD: google-like search on thumbnails
-> ADD: use kde wallet for storing passwords of protected files
...
...
core/document.cpp
View file @
8f4104a9
...
...
@@ -344,6 +344,11 @@ const DocumentSynopsis * KPDFDocument::documentSynopsis() const
return
generator
?
generator
->
generateDocumentSynopsis
()
:
NULL
;
}
const
DocumentFonts
*
KPDFDocument
::
documentFonts
()
const
{
return
generator
?
generator
->
generateDocumentFonts
()
:
NULL
;
}
const
KPDFPage
*
KPDFDocument
::
page
(
uint
n
)
const
{
return
(
n
<
pages_vector
.
count
()
)
?
pages_vector
[
n
]
:
0
;
...
...
@@ -1570,4 +1575,13 @@ DocumentSynopsis::DocumentSynopsis()
// void implementation, only subclassed for naming
}
/** DocumentFonts **/
DocumentFonts
::
DocumentFonts
()
:
QDomDocument
(
"DocumentFonts"
)
{
// void implementation, only subclassed for naming
}
#include "document.moc"
core/document.h
View file @
8f4104a9
...
...
@@ -22,6 +22,7 @@ class DocumentObserver;
class
DocumentViewport
;
class
DocumentInfo
;
class
DocumentSynopsis
;
class
DocumentFonts
;
class
Generator
;
class
PixmapRequest
;
class
Annotation
;
...
...
@@ -68,6 +69,7 @@ class KPDFDocument : public QObject
bool
isOpened
()
const
;
const
DocumentInfo
*
documentInfo
()
const
;
const
DocumentSynopsis
*
documentSynopsis
()
const
;
const
DocumentFonts
*
documentFonts
()
const
;
const
KPDFPage
*
page
(
uint
page
)
const
;
const
DocumentViewport
&
viewport
()
const
;
uint
currentPage
()
const
;
...
...
@@ -168,7 +170,7 @@ class DocumentViewport
};
/**
* @short A
dom
tree containing informations about the document.
* @short A
DOM
tree containing informations about the document.
*
* The Info structure can be filled in by generators to display metadata
* about the currently opened file.
...
...
@@ -193,10 +195,10 @@ class DocumentInfo : public QDomDocument
};
/**
* @short A D
om
tree that describes the Table of Contents.
* @short A D
OM
tree that describes the Table of Contents.
*
* The Synopsis (TOC or Table Of Contents for friends) is represented via
* a dom tree where each nod has an internal name (displayed in the listview)
* a dom tree where each nod
e
has an internal name (displayed in the listview)
* and one or more attributes.
*
* In the tree the tag name is the 'screen' name of the entry. A tag can have
...
...
@@ -211,4 +213,19 @@ class DocumentSynopsis : public QDomDocument
DocumentSynopsis
();
};
/**
* @short A DOM thee describing fonts used in document.
*
* Root's childrend (if any) are font nodes with the following attributes:
* - Name
* - Type
* - Embedded (if font is shipped inside the document)
* - File (system's file that provides this font
*/
class
DocumentFonts
:
public
QDomDocument
{
public:
DocumentFonts
();
};
#endif
core/generator.h
View file @
8f4104a9
...
...
@@ -49,6 +49,7 @@ class Generator : public QObject
// Document description and Table of contents
virtual
const
DocumentInfo
*
generateDocumentInfo
()
{
return
0L
;
}
virtual
const
DocumentSynopsis
*
generateDocumentSynopsis
()
{
return
0L
;
}
virtual
const
DocumentFonts
*
generateDocumentFonts
()
{
return
0L
;
}
// DRM handling
virtual
bool
isAllowed
(
int
/*Document::Permisison(s)*/
)
{
return
true
;
}
...
...
core/generator_pdf/generator_pdf.cpp
View file @
8f4104a9
...
...
@@ -32,6 +32,7 @@
#include "xpdf/UnicodeMap.h"
#include "xpdf/Outline.h"
#include "xpdf/GfxState.h"
#include "xpdf/Annot.h" // for retrieving fonts only
#include "goo/GList.h"
// local includes
...
...
@@ -65,7 +66,8 @@
PDFGenerator
::
PDFGenerator
(
KPDFDocument
*
doc
)
:
Generator
(
doc
),
pdfdoc
(
0
),
kpdfOutputDev
(
0
),
ready
(
true
),
pixmapRequest
(
0
),
docInfoDirty
(
true
),
docSynopsisDirty
(
true
)
pixmapRequest
(
0
),
docInfoDirty
(
true
),
docSynopsisDirty
(
true
),
docFontsDirty
(
true
)
{
// generate kpdfOutputDev and cache page color
reparseConfig
();
...
...
@@ -256,6 +258,58 @@ const DocumentSynopsis * PDFGenerator::generateDocumentSynopsis()
return
&
docSyn
;
}
const
DocumentFonts
*
PDFGenerator
::
generateDocumentFonts
()
{
if
(
!
docFontsDirty
)
return
&
docFonts
;
// initialize fonts dom
docFonts
=
DocumentFonts
();
docFonts
.
appendChild
(
docFonts
.
createElement
(
"Fonts"
)
);
// fonts repository to check for duplicates
Ref
*
fonts
=
NULL
;
int
fontsLen
=
0
;
int
fontsSize
=
0
;
// temporary inner-loop xpdf objects
Object
objAnn
,
objAnnStr
,
objAnnRes
;
// loop on all pages
docLock
.
lock
();
int
pagesNumber
=
pdfdoc
->
getNumPages
();
for
(
int
pg
=
0
;
pg
<
pagesNumber
;
pg
++
)
{
// look for fonts in page's resources
Page
*
page
=
pdfdoc
->
getCatalog
()
->
getPage
(
pg
+
1
);
Dict
*
resDict
=
page
->
getResourceDict
();
if
(
resDict
)
addFonts
(
resDict
,
&
fonts
,
fontsLen
,
fontsSize
);
// look for fonts in annotation's resources
Annots
*
annots
=
new
Annots
(
pdfdoc
->
getXRef
(),
page
->
getAnnots
(
&
objAnn
)
);
objAnn
.
free
();
int
annotsNumber
=
annots
->
getNumAnnots
();
for
(
int
i
=
0
;
i
<
annotsNumber
;
i
++
)
{
if
(
annots
->
getAnnot
(
i
)
->
getAppearance
(
&
objAnnStr
)
->
isStream
()
)
{
objAnnStr
.
streamGetDict
()
->
lookup
(
"Resources"
,
&
objAnnRes
);
if
(
objAnnRes
.
isDict
()
)
addFonts
(
objAnnRes
.
getDict
(),
&
fonts
,
fontsLen
,
fontsSize
);
objAnnRes
.
free
();
}
objAnnStr
.
free
();
}
delete
annots
;
}
kdWarning
()
<<
docFonts
.
toString
()
<<
endl
;
// empty the font list and release mutex
gfree
(
fonts
);
docLock
.
unlock
();
return
&
docFonts
;
}
bool
PDFGenerator
::
isAllowed
(
int
permissions
)
{
#if !KPDF_FORCE_DRM
...
...
@@ -633,6 +687,117 @@ void PDFGenerator::addSynopsisChildren( QDomNode * parent, GList * items )
}
}
void
PDFGenerator
::
addFonts
(
Dict
*
resDict
,
Ref
**
fonts
,
int
&
fontsLen
,
int
&
fontsSize
)
{
Object
obj1
,
obj2
;
// get the Font dictionary in current resource dictionary
GfxFontDict
*
gfxFontDict
=
NULL
;
resDict
->
lookupNF
(
"Font"
,
&
obj1
);
if
(
obj1
.
isRef
()
)
{
obj1
.
fetch
(
pdfdoc
->
getXRef
(),
&
obj2
);
if
(
obj2
.
isDict
()
)
{
Ref
r
=
obj1
.
getRef
();
gfxFontDict
=
new
GfxFontDict
(
pdfdoc
->
getXRef
(),
&
r
,
obj2
.
getDict
()
);
}
obj2
.
free
();
}
else
if
(
obj1
.
isDict
()
)
gfxFontDict
=
new
GfxFontDict
(
pdfdoc
->
getXRef
(),
NULL
,
obj1
.
getDict
()
);
// add all fonts in the Font dictionary
if
(
gfxFontDict
)
{
for
(
int
i
=
0
;
i
<
gfxFontDict
->
getNumFonts
();
i
++
)
{
GfxFont
*
font
=
gfxFontDict
->
getFont
(
i
);
if
(
!
font
)
continue
;
// skip already added fonts
Ref
fontRef
=
*
font
->
getID
();
bool
alreadyIn
=
false
;
for
(
int
j
=
0
;
j
<
fontsLen
&&
!
alreadyIn
;
j
++
)
if
(
fontRef
.
num
==
(
*
fonts
)[
j
].
num
&&
fontRef
.
gen
==
(
*
fonts
)[
j
].
gen
)
alreadyIn
=
true
;
if
(
alreadyIn
)
continue
;
// 0. add font element
QDomElement
fontElem
=
docFonts
.
createElement
(
"font"
);
docFonts
.
firstChild
().
appendChild
(
fontElem
);
// 1. set Name
GString
*
name
=
font
->
getOrigName
();
fontElem
.
setAttribute
(
"Name"
,
name
?
name
->
getCString
()
:
i18n
(
"[none]"
)
);
// 2. set Type
const
QString
fontTypeNames
[
8
]
=
{
i18n
(
"unknown"
),
i18n
(
"Type 1"
),
i18n
(
"Type 1C"
),
i18n
(
"Type 3"
),
i18n
(
"TrueType"
),
i18n
(
"CID Type 0"
),
i18n
(
"CID Type 0C"
),
i18n
(
"CID TrueType"
)
};
fontElem
.
setAttribute
(
"Type"
,
fontTypeNames
[
font
->
getType
()
]
);
// 3. set Embedded
Ref
embRef
;
bool
emb
=
font
->
getType
()
==
fontType3
?
true
:
font
->
getEmbeddedFontID
(
&
embRef
);
fontElem
.
setAttribute
(
"Embedded"
,
emb
?
i18n
(
"Yes"
)
:
i18n
(
"No"
)
);
// 4. set Path
QString
sPath
=
i18n
(
"-"
);
if
(
name
&&
!
emb
)
{
DisplayFontParam
*
dfp
=
globalParams
->
getDisplayFont
(
name
);
if
(
dfp
)
{
if
(
dfp
->
kind
==
displayFontT1
)
sPath
=
dfp
->
t1
.
fileName
->
getCString
();
else
sPath
=
dfp
->
tt
.
fileName
->
getCString
();
}
}
fontElem
.
setAttribute
(
"File"
,
sPath
);
// enlarge font list if needed
if
(
fontsLen
==
fontsSize
)
{
fontsSize
+=
32
;
*
fonts
=
(
Ref
*
)
grealloc
(
*
fonts
,
fontsSize
*
sizeof
(
Ref
)
);
}
// add this font to the list
(
*
fonts
)[
fontsLen
++
]
=
fontRef
;
}
delete
gfxFontDict
;
}
obj1
.
free
();
// recursively scan any resource dictionaries in objects in this dictionary
Object
xObjDict
,
xObj
,
resObj
;
resDict
->
lookup
(
"XObject"
,
&
xObjDict
);
if
(
xObjDict
.
isDict
()
)
{
for
(
int
i
=
0
;
i
<
xObjDict
.
dictGetLength
();
i
++
)
{
xObjDict
.
dictGetVal
(
i
,
&
xObj
);
if
(
xObj
.
isStream
()
)
{
xObj
.
streamGetDict
()
->
lookup
(
"Resources"
,
&
resObj
);
if
(
resObj
.
isDict
()
)
addFonts
(
resObj
.
getDict
(),
fonts
,
fontsLen
,
fontsSize
);
resObj
.
free
();
}
xObj
.
free
();
}
}
xObjDict
.
free
();
}
class
XPDFReader
{
...
...
core/generator_pdf/generator_pdf.h
View file @
8f4104a9
...
...
@@ -23,6 +23,8 @@ class PDFDoc;
class
GList
;
class
TextPage
;
class
Page
;
class
Dict
;
class
Ref
;
class
ObjectRect
;
class
KPDFOutputDev
;
...
...
@@ -54,6 +56,7 @@ class PDFGenerator : public Generator
// [INHERITED] document informations
const
DocumentInfo
*
generateDocumentInfo
();
const
DocumentSynopsis
*
generateDocumentSynopsis
();
const
DocumentFonts
*
generateDocumentFonts
();
// [INHERITED] document informations
bool
isAllowed
(
int
permissions
);
...
...
@@ -76,15 +79,18 @@ class PDFGenerator : public Generator
// friend class to access private document related variables
friend
class
PDFPixmapGeneratorThread
;
//
private functions for
access
ing
document informations
via PDFDoc
// access document informations
QString
getDocumentInfo
(
const
QString
&
data
)
const
;
QString
getDocumentDate
(
const
QString
&
data
)
const
;
//
private function for
creat
ing
the document synopsis hieracy
// creat
e
the document synopsis hieracy
void
addSynopsisChildren
(
QDomNode
*
parent
,
GList
*
items
);
// private function for adding annotations read from the pdf file
// add fonts (in resDict) to the private 'docFonts' class
void
addFonts
(
Dict
*
resDict
,
Ref
**
fonts
,
int
&
fontsLen
,
int
&
fontsSize
);
// fetch annotations from the pdf file and add they to the page
void
addAnnotations
(
Page
*
xpdfPage
,
KPDFPage
*
page
);
//
private function for creating
the transition information
//
fetch
the transition information
and add it to the page
void
addTransition
(
Page
*
xpdfPage
,
KPDFPage
*
page
);
// (async related) receive data from the generator thread
void
customEvent
(
QCustomEvent
*
);
...
...
@@ -104,6 +110,8 @@ class PDFGenerator : public Generator
DocumentInfo
docInfo
;
bool
docSynopsisDirty
;
DocumentSynopsis
docSyn
;
bool
docFontsDirty
;
DocumentFonts
docFonts
;
};
...
...
ui/propertiesdialog.cpp
View file @
8f4104a9
...
...
@@ -11,6 +11,7 @@
#include <qlayout.h>
#include <qlabel.h>
#include <klocale.h>
#include <klistview.h>
#include <ksqueezedtextlabel.h>
#include <kglobalsettings.h>
...
...
@@ -19,9 +20,10 @@
#include "core/document.h"
PropertiesDialog
::
PropertiesDialog
(
QWidget
*
parent
,
KPDFDocument
*
doc
)
:
KDialogBase
(
Plain
,
i18n
(
"Unknown File"
),
Ok
,
Ok
,
parent
,
0
,
true
,
true
)
:
KDialogBase
(
Tabbed
,
i18n
(
"Unknown File"
),
Ok
,
Ok
,
parent
,
0
,
true
,
true
)
{
QWidget
*
page
=
plainPage
();
// PROPERTIES
QFrame
*
page
=
addPage
(
i18n
(
"Properties"
));
QGridLayout
*
layout
=
new
QGridLayout
(
page
,
2
,
2
,
marginHint
(),
spacingHint
()
);
// get document info, if not present display blank data and a warning
...
...
@@ -68,10 +70,34 @@ PropertiesDialog::PropertiesDialog(QWidget *parent, KPDFDocument *doc)
layout
->
addWidget
(
value
,
row
,
1
);
}
// FONTS
QVBoxLayout
*
page2Layout
=
0
;
const
DocumentFonts
*
fonts
=
doc
->
documentFonts
();
if
(
fonts
)
{
// create fonts tab and layout it
QFrame
*
page2
=
addPage
(
i18n
(
"Fonts"
));
page2Layout
=
new
QVBoxLayout
(
page2
,
0
,
KDialog
::
spacingHint
());
// add a klistview with 4 columns
KListView
*
lv
=
new
KListView
(
page2
);
lv
->
addColumn
(
i18n
(
"Name"
)
);
lv
->
addColumn
(
i18n
(
"Type"
)
);
lv
->
addColumn
(
i18n
(
"Embedded"
)
);
lv
->
addColumn
(
i18n
(
"File"
)
);
page2Layout
->
add
(
lv
);
// populate the klistview
for
(
QDomNode
node
=
fonts
->
documentElement
().
firstChild
();
!
node
.
isNull
();
node
=
node
.
nextSibling
()
)
{
QDomElement
e
=
node
.
toElement
();
new
KListViewItem
(
lv
,
e
.
attribute
(
"Name"
),
e
.
attribute
(
"Type"
),
e
.
attribute
(
"Embedded"
),
e
.
attribute
(
"File"
)
);
}
}
// current width: left columnt + right column + dialog borders
int
width
=
layout
->
minimumSize
().
width
()
+
valMaxWidth
+
30
;
int
width
=
layout
->
minimumSize
().
width
()
+
valMaxWidth
+
2
*
marginHint
()
+
spacingHint
()
+
30
;
if
(
page2Layout
)
width
=
QMAX
(
width
,
page2Layout
->
sizeHint
().
width
()
+
marginHint
()
+
spacingHint
()
+
31
);
// stay inside the 2/3 of the screen width
QRect
screenContainer
=
KGlobalSettings
::
desktopGeometry
(
this
);
width
=
QMIN
(
width
,
2
*
screenContainer
.
width
()
/
3
);
resize
(
width
,
1
);
resize
(
width
,
1
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment