1 //========================================================================
5 // Copyright 1999-2001 Emmanuel Lesueur
7 //========================================================================
10 #pragma implementation
21 #include "PageLabel.h"
23 extern GString
*toLatin1(GString
*);
25 //------------------------------------------------------------------------
27 //------------------------------------------------------------------------
29 PageLabelLeaf::~PageLabelLeaf() {
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
38 NumberTreeLeaf
*PageLabelParser::parse(int n
, Object
*obj
) {
39 PageLabelLeaf
*r
= NULL
;
41 PageLabelLeaf::Style style
= PageLabelLeaf::StNoNum
;
42 GString
*prefix
= NULL
;
46 if (obj
->dictLookup("S", &obj2
)->isName()) {
47 if (!strcmp(obj2
.getName(), "D"))
48 style
= PageLabelLeaf::StDecimal
;
49 else if (!strcmp(obj2
.getName(), "R"))
50 style
= PageLabelLeaf::StUpperCaseRoman
;
51 else if (!strcmp(obj2
.getName(), "r"))
52 style
= PageLabelLeaf::StLowerCaseRoman
;
53 else if (!strcmp(obj2
.getName(), "A"))
54 style
= PageLabelLeaf::StUpperCaseAlpha
;
55 else if (!strcmp(obj2
.getName(), "a"))
56 style
= PageLabelLeaf::StLowerCaseAlpha
;
59 if (obj
->dictLookup("P", &obj2
)->isString())
60 prefix
= toLatin1(obj2
.getString());
62 if (obj
->dictLookup("St", &obj2
)->isInt())
63 start
= obj2
.getInt();
66 r
= new PageLabelLeaf(n
, style
, prefix
, start
, labels
);
74 //------------------------------------------------------------------------
76 //------------------------------------------------------------------------
78 PageLabels::PageLabels(Object
*dict
) : tree(dict
, &parser
) {
81 static char *addRomanDigit(char *q
, unsigned n
, char d1
, char d5
, char d10
) {
106 GString
*PageLabels::getPageLabel(int index
) {
107 PageLabelLeaf
*label
= (PageLabelLeaf
*)tree
.getLeaf(index
);
108 GString
*s
= new GString
;
112 char *q
= buf
+ sizeof(buf
);
113 int n
= index
- label
->getKey() + label
->getStart();
123 if (label
->getPrefix())
124 s
->append(label
->getPrefix());
126 switch (label
->getStyle()) {
127 case PageLabelLeaf::StUpperCaseRoman
:
130 case PageLabelLeaf::StLowerCaseRoman
:
131 if (n
> 0 && n
< 4000) {
132 q
= addRomanDigit(q
, n
, 'i' + offset
, 'v' + offset
, 'x' + offset
);
134 q
= addRomanDigit(q
, n
, 'x' + offset
, 'l' + offset
, 'c' + offset
);
136 q
= addRomanDigit(q
, n
, 'c' + offset
, 'd' + offset
, 'm' + offset
);
138 q
= addRomanDigit(q
, n
, 'm' + offset
, '?', '?');
142 case PageLabelLeaf::StDecimal
:
144 *--q
= '0' + (n
% 10);
150 case PageLabelLeaf::StUpperCaseAlpha
:
153 case PageLabelLeaf::StLowerCaseAlpha
:
155 *--q
= 'a' + (n
% 26) + offset
;
169 int PageLabels::getPageIndex(const char *label
) {
171 for (leaf
= parser
.getFirst(); leaf
!= NULL
; leaf
= leaf
->getNext()) {
172 GString
*p
= leaf
->getPrefix();
173 const char *l
= label
;
176 if (!p
->cmpN((char*)l
, p
->getLength()))
181 switch (leaf
->getStyle()) {
182 case PageLabelLeaf::StNoNum
:
183 n
= leaf
->getStart();
185 case PageLabelLeaf::StDecimal
:
186 while(*l
>= '0' && *l
<= '9') {
192 case PageLabelLeaf::StUpperCaseRoman
:
193 while (*l
&& n
>= 0) {
199 } else if (*l
== 'X') {
212 } else if (*l
== 'C') {
225 } else if (*l
== 'M') {
243 case PageLabelLeaf::StLowerCaseRoman
:
244 while (*l
&& n
>= 0) {
250 } else if (*l
== 'x') {
263 } else if (*l
== 'c') {
276 } else if (*l
== 'm') {
294 case PageLabelLeaf::StUpperCaseAlpha
:
295 while(*l
>= 'A' && *l
<= 'Z') {
301 case PageLabelLeaf::StLowerCaseAlpha
:
302 while(*l
>= 'a' && *l
<= 'z') {
310 return n
- leaf
->getStart() + leaf
->getKey();