Blame libdjvu/DjVuAnno.cpp

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
# include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma implementation
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#include "DjVuAnno.h"
Packit df99a1
#include "GContainer.h"
Packit df99a1
#include "GException.h"
Packit df99a1
#include "IFFByteStream.h"
Packit df99a1
#include "BSByteStream.h"
Packit df99a1
#include "GMapAreas.h"
Packit df99a1
Packit df99a1
#include "debug.h"
Packit df99a1
Packit df99a1
#include <ctype.h>
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
// GLParser.h and GLParser.cpp used to be separate files capable to decode
Packit df99a1
// that weird ANTa chunk format into C++ structures and lists. But since
Packit df99a1
// its implementation is temporary and is used only in this file (DjVuAnno.cpp)
Packit df99a1
// it appears reasonable to build it in here.
Packit df99a1
Packit df99a1
//***************************************************************************
Packit df99a1
//****************************** GLParser.h *********************************
Packit df99a1
//***************************************************************************
Packit df99a1
Packit df99a1
Packit df99a1
class GLObject : public GPEnabled
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   enum GLObjectType { INVALID=0, NUMBER=1, STRING=2, SYMBOL=3, LIST=4 };
Packit df99a1
   static const char * const GLObjectString[LIST+1];
Packit df99a1
Packit df99a1
   GLObject(int _number=0);
Packit df99a1
   GLObject(GLObjectType type, const char * str);
Packit df99a1
   GLObject(const char * name, const GPList<GLObject> & list);
Packit df99a1
   virtual ~GLObject(void);
Packit df99a1
   
Packit df99a1
   int		get_number(void) const;
Packit df99a1
   GUTF8String	get_string(void) const;
Packit df99a1
   GUTF8String	get_symbol(void) const;
Packit df99a1
   GPList<GLObject>	& get_list(void);
Packit df99a1
   GP<GLObject>	operator[](int n) const;
Packit df99a1
   
Packit df99a1
   GLObjectType	get_type(void) const;
Packit df99a1
   GUTF8String	get_name(void) const;
Packit df99a1
   void		print(ByteStream & str, int compact=1, int indent=0, int * cur_pos=0) const;
Packit df99a1
private:
Packit df99a1
   GLObjectType	type;
Packit df99a1
   GUTF8String	name;
Packit df99a1
   
Packit df99a1
   int		number;
Packit df99a1
   GUTF8String	string;
Packit df99a1
   GUTF8String	symbol;
Packit df99a1
   GPList<GLObject>	list;
Packit df99a1
   void throw_can_not_convert_to(const GLObjectType to) const;
Packit df99a1
};
Packit df99a1
Packit df99a1
const char * const GLObject::GLObjectString[]=
Packit df99a1
  {"invalid", "number", "string", "symbol", "list"};
Packit df99a1
Packit df99a1
inline GLObject::GLObjectType
Packit df99a1
GLObject::get_type(void) const { return type; }
Packit df99a1
Packit df99a1
inline
Packit df99a1
GLObject::~GLObject(void) {}
Packit df99a1
Packit df99a1
class GLToken
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   enum GLTokenType { OPEN_PAR, CLOSE_PAR, OBJECT };
Packit df99a1
   GLTokenType	type;
Packit df99a1
   GP<GLObject>	object;
Packit df99a1
   
Packit df99a1
   GLToken(GLTokenType type, const GP<GLObject> & object);
Packit df99a1
};
Packit df99a1
Packit df99a1
inline
Packit df99a1
GLToken::GLToken(GLTokenType xtype, const GP<GLObject> & xobject) :
Packit df99a1
      type(xtype), object(xobject) {}
Packit df99a1
Packit df99a1
class GLParser
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   void		parse(const char * str);
Packit df99a1
   GPList<GLObject>	& get_list(void);
Packit df99a1
   GP<GLObject>		get_object(const char * name, bool last=true);
Packit df99a1
   void		print(ByteStream & str, int compact=1);
Packit df99a1
Packit df99a1
   GLParser(void);
Packit df99a1
   GLParser(const char * str);
Packit df99a1
   ~GLParser(void);
Packit df99a1
private:
Packit df99a1
   GPList<GLObject>	list;
Packit df99a1
Packit df99a1
   bool   	compat;
Packit df99a1
   void		skip_white_space(const char * & start);
Packit df99a1
   void 	check_compat(const char *str);
Packit df99a1
   GLToken	get_token(const char * & start);
Packit df99a1
   void		parse(const char * cur_name, GPList<GLObject> & list,
Packit df99a1
		      const char * & start);
Packit df99a1
};
Packit df99a1
Packit df99a1
GLParser::GLParser(void) 
Packit df99a1
  : compat(false)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
GLParser::~GLParser(void) 
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
GPList<GLObject> &
Packit df99a1
GLParser::get_list(void) 
Packit df99a1
{ 
Packit df99a1
  return list; 
Packit df99a1
}
Packit df99a1
Packit df99a1
GLParser::GLParser(const char * str) 
Packit df99a1
  : compat(false)
Packit df99a1
{
Packit df99a1
  parse(str); 
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
//***************************************************************************
Packit df99a1
//***************************** GLParser.cpp ********************************
Packit df99a1
//***************************************************************************
Packit df99a1
Packit df99a1
Packit df99a1
GLObject::GLObject(int xnumber) : type(NUMBER), number(xnumber) {}
Packit df99a1
Packit df99a1
GLObject::GLObject(GLObjectType xtype, const char * str) : type(xtype)
Packit df99a1
{
Packit df99a1
   if (type!=STRING && type!=SYMBOL)
Packit df99a1
      G_THROW( ERR_MSG("DjVuAnno.bad_type") );
Packit df99a1
   if (type==STRING) 
Packit df99a1
      string=str;
Packit df99a1
   else symbol=str;
Packit df99a1
}
Packit df99a1
Packit df99a1
GLObject::GLObject(const char * xname, const GPList<GLObject> & xlist) :
Packit df99a1
      type(LIST), name(xname), list(xlist) {}
Packit df99a1
Packit df99a1
Packit df99a1
static GUTF8String make_c_string(GUTF8String string)
Packit df99a1
{
Packit df99a1
  GUTF8String buffer;
Packit df99a1
  const char *data = (const char*)string;
Packit df99a1
  int length = string.length();
Packit df99a1
  buffer = GUTF8String("\"");
Packit df99a1
  while (*data && length>0) 
Packit df99a1
    {
Packit df99a1
      int span = 0;
Packit df99a1
      while (span<length && (unsigned char)(data[span])>=0x20 && 
Packit df99a1
             data[span]!=0x7f && data[span]!='"' && data[span]!='\\' )
Packit df99a1
        span++;
Packit df99a1
      if (span > 0) 
Packit df99a1
        {  
Packit df99a1
          buffer = buffer + GUTF8String(data, span);
Packit df99a1
          data += span;
Packit df99a1
          length -= span;
Packit df99a1
        }  
Packit df99a1
      else 
Packit df99a1
        {
Packit df99a1
          char buf[8];
Packit df99a1
          static const char *tr1 = "\"\\tnrbf";
Packit df99a1
          static const char *tr2 = "\"\\\t\n\r\b\f";
Packit df99a1
          sprintf(buf,"\\%03o", (int)(((unsigned char*)data)[span]));
Packit df99a1
          for (int i=0; tr2[i]; i++)
Packit df99a1
            if (data[span] == tr2[i])
Packit df99a1
              buf[1] = tr1[i];
Packit df99a1
          if (buf[1]<'0' || buf[1]>'3')
Packit df99a1
            buf[2] = 0;
Packit df99a1
          buffer = buffer + GUTF8String(buf);
Packit df99a1
          data += 1;
Packit df99a1
          length -= 1;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  buffer = buffer + GUTF8String("\"");
Packit df99a1
  return buffer;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
GLObject::print(ByteStream & str, int compact, int indent, int * cur_pos) const
Packit df99a1
{
Packit df99a1
  int local_cur_pos = 0;
Packit df99a1
  if (!cur_pos) { cur_pos = &local_cur_pos; }
Packit df99a1
  
Packit df99a1
  GUTF8String buffer;
Packit df99a1
  switch(type)
Packit df99a1
  {
Packit df99a1
  case NUMBER:
Packit df99a1
    buffer.format("%d",number);
Packit df99a1
    break;
Packit df99a1
  case STRING:
Packit df99a1
    buffer = make_c_string(string);
Packit df99a1
    break;
Packit df99a1
  case SYMBOL:
Packit df99a1
    buffer.format("%s",(const char *)symbol);
Packit df99a1
    break;
Packit df99a1
  case LIST:
Packit df99a1
    buffer.format("(%s",(const char *)name);
Packit df99a1
    break;
Packit df99a1
  case INVALID:
Packit df99a1
    break;
Packit df99a1
  }
Packit df99a1
  const char * to_print = (const char*)buffer;
Packit df99a1
  if (!compact && *cur_pos+strlen(to_print)>70)
Packit df99a1
  {
Packit df99a1
    char ch='\n';
Packit df99a1
    str.write(&ch, 1);
Packit df99a1
    ch=' ';
Packit df99a1
    for(int i=0;i
Packit df99a1
    *cur_pos=indent;
Packit df99a1
  }
Packit df99a1
  str.write(to_print, strlen(to_print));
Packit df99a1
  char ch=' ';
Packit df99a1
  str.write(&ch, 1);
Packit df99a1
  *cur_pos+=strlen(to_print)+1;
Packit df99a1
  if (type==LIST)
Packit df99a1
  {
Packit df99a1
    int indent=*cur_pos-strlen(to_print);
Packit df99a1
    for(GPosition pos=list;pos;++pos)
Packit df99a1
      list[pos]->print(str, compact, indent, cur_pos);
Packit df99a1
    str.write(") ", 2);
Packit df99a1
    *cur_pos+=2;
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
//  This function constructs message names for external lookup.
Packit df99a1
//  The message names are constructed to avoid the problems of concatenating
Packit df99a1
//  phrases (which does not translate well into other languages). The
Packit df99a1
//  message names that can be generated are (listed here to appease the
Packit df99a1
//  auditing program which reads comments):
Packit df99a1
//    ERR_MSG("DjVuAnno.invalid2number"), ERR_MSG("DjVuAnno.string2number"),
Packit df99a1
//    ERR_MSG("DjVuAnno.symbol2number"), ERR_MSG("DjVuAnno.list2number")
Packit df99a1
//    ERR_MSG("DjVuAnno.invalid2string"), ERR_MSG("DjVuAnno.number2string"),
Packit df99a1
//    ERR_MSG("DjVuAnno.symbol2string"), ERR_MSG("DjVuAnno.list2string")
Packit df99a1
//    ERR_MSG("DjVuAnno.invalid2symbol"), ERR_MSG("DjVuAnno.number2symbol"),
Packit df99a1
//    ERR_MSG("DjVuAnno.string2symbol"), ERR_MSG("DjVuAnno.list2symbol")
Packit df99a1
//    ERR_MSG("DjVuAnno.invalid2list"), ERR_MSG("DjVuAnno.number2list"),
Packit df99a1
//    ERR_MSG("DjVuAnno.string2list"), ERR_MSG("DjVuAnno.symbol2list")
Packit df99a1
void
Packit df99a1
GLObject::throw_can_not_convert_to(const GLObjectType to) const
Packit df99a1
{
Packit df99a1
  static const GUTF8String two('2');
Packit df99a1
  static const GUTF8String tab('\t');
Packit df99a1
  GUTF8String mesg("DjVuAnno.");
Packit df99a1
  switch(type)
Packit df99a1
  {
Packit df99a1
    case NUMBER:
Packit df99a1
      mesg+=GLObjectString[NUMBER]+two+GLObjectString[to]+tab+GUTF8String(number);
Packit df99a1
      break;
Packit df99a1
    case STRING:
Packit df99a1
      mesg+=GLObjectString[STRING]+two+GLObjectString[to]+tab+string;
Packit df99a1
      break;
Packit df99a1
    case SYMBOL:
Packit df99a1
      mesg+=GLObjectString[SYMBOL]+two+GLObjectString[to]+tab+symbol;
Packit df99a1
      break;
Packit df99a1
    case LIST:
Packit df99a1
      mesg+=GLObjectString[LIST]+two+GLObjectString[to]+tab+name;
Packit df99a1
      break;
Packit df99a1
    default:
Packit df99a1
      mesg+=GLObjectString[INVALID]+two+GLObjectString[to];
Packit df99a1
      break;
Packit df99a1
  }
Packit df99a1
  G_THROW(mesg);
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GLObject::get_string(void) const
Packit df99a1
{
Packit df99a1
   if (type!=STRING)
Packit df99a1
   {
Packit df99a1
      throw_can_not_convert_to(STRING);
Packit df99a1
   }
Packit df99a1
   return string;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GLObject::get_symbol(void) const
Packit df99a1
{
Packit df99a1
   if (type!=SYMBOL)
Packit df99a1
   {
Packit df99a1
      throw_can_not_convert_to(SYMBOL);
Packit df99a1
   }
Packit df99a1
   return symbol;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GLObject::get_number(void) const
Packit df99a1
{
Packit df99a1
   if (type!=NUMBER)
Packit df99a1
   {
Packit df99a1
      throw_can_not_convert_to(NUMBER);
Packit df99a1
   }
Packit df99a1
   return number;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GLObject::get_name(void) const
Packit df99a1
{
Packit df99a1
   if (type!=LIST)
Packit df99a1
   {
Packit df99a1
      throw_can_not_convert_to(LIST);
Packit df99a1
   }
Packit df99a1
   return name;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GLObject>
Packit df99a1
GLObject::operator[](int n) const
Packit df99a1
{
Packit df99a1
   if (type!=LIST)
Packit df99a1
   {
Packit df99a1
      throw_can_not_convert_to(LIST);
Packit df99a1
   }
Packit df99a1
   if (n>=list.size()) G_THROW( ERR_MSG("DjVuAnno.too_few") "\t"+name);
Packit df99a1
   int i;
Packit df99a1
   GPosition pos;
Packit df99a1
   for(i=0, pos=list;i
Packit df99a1
   		continue;
Packit df99a1
   return list[pos];
Packit df99a1
}
Packit df99a1
Packit df99a1
GPList<GLObject> &
Packit df99a1
GLObject::get_list(void)
Packit df99a1
{
Packit df99a1
   if (type!=LIST)
Packit df99a1
   {
Packit df99a1
      throw_can_not_convert_to(LIST);
Packit df99a1
   }
Packit df99a1
   return list;
Packit df99a1
}
Packit df99a1
Packit df99a1
//********************************** GLParser *********************************
Packit df99a1
Packit df99a1
void
Packit df99a1
GLParser::skip_white_space(const char * & start)
Packit df99a1
{
Packit df99a1
   while(*start && isspace(*start)) start++;
Packit df99a1
   if (!*start) 
Packit df99a1
       G_THROW( ByteStream::EndOfFile );
Packit df99a1
}
Packit df99a1
Packit df99a1
GLToken
Packit df99a1
GLParser::get_token(const char * & start)
Packit df99a1
{
Packit df99a1
   skip_white_space(start);
Packit df99a1
   char c = *start;
Packit df99a1
   if (c == '(')
Packit df99a1
     {
Packit df99a1
       start++;
Packit df99a1
       return GLToken(GLToken::OPEN_PAR, 0);
Packit df99a1
     }
Packit df99a1
   else if (c == ')')
Packit df99a1
     {
Packit df99a1
       start++;
Packit df99a1
       return GLToken(GLToken::CLOSE_PAR, 0);
Packit df99a1
     }
Packit df99a1
   else if (c == '"')
Packit df99a1
     {
Packit df99a1
       GUTF8String str;
Packit df99a1
       start++;
Packit df99a1
       while(1)
Packit df99a1
	 {
Packit df99a1
           int span = 0;
Packit df99a1
           while (start[span] && start[span]!='\\' && start[span]!='\"')
Packit df99a1
             span++;
Packit df99a1
           if (span > 0)
Packit df99a1
             {
Packit df99a1
               str = str + GUTF8String(start,span);
Packit df99a1
               start += span;
Packit df99a1
             }
Packit df99a1
           else if (start[0]=='\"')
Packit df99a1
             {
Packit df99a1
               start += 1;
Packit df99a1
               break;
Packit df99a1
             }
Packit df99a1
           else if (start[0]=='\\' && compat)
Packit df99a1
             {
Packit df99a1
               char c = start[1];
Packit df99a1
               if (c == '\"')
Packit df99a1
                 {
Packit df99a1
                   start += 2;
Packit df99a1
                   str += '\"';
Packit df99a1
                 }
Packit df99a1
               else
Packit df99a1
                 {
Packit df99a1
                   start += 1;
Packit df99a1
                   str += '\\';
Packit df99a1
                 }
Packit df99a1
             }
Packit df99a1
           else if (start[0]=='\\' && start[1])
Packit df99a1
             {
Packit df99a1
               char c = *++start;
Packit df99a1
               if (c>='0' && c<='7')
Packit df99a1
                 {
Packit df99a1
                   int x = 0;
Packit df99a1
                   for (int i=0; i<3 && c>='0' && c<='7'; i++) 
Packit df99a1
                     {
Packit df99a1
                       x = x * 8 + c - '0';
Packit df99a1
                       c = *++start;
Packit df99a1
                     }
Packit df99a1
                   str += (char)(x & 0xff);
Packit df99a1
                 }
Packit df99a1
               else
Packit df99a1
                 {
Packit df99a1
                   static const char *tr1 = "tnrbfva";
Packit df99a1
                   static const char *tr2 = "\t\n\r\b\f\013\007";
Packit df99a1
                   for (int i=0; tr1[i]; i++)
Packit df99a1
                     if (c == tr1[i])
Packit df99a1
                       c = tr2[i];
Packit df99a1
                   start += 1;
Packit df99a1
                   str += c;
Packit df99a1
                 }
Packit df99a1
             }
Packit df99a1
           else 
Packit df99a1
             {
Packit df99a1
               G_THROW( ByteStream::EndOfFile );
Packit df99a1
             }
Packit df99a1
         }
Packit df99a1
       return GLToken(GLToken::OBJECT, new GLObject(GLObject::STRING, str));
Packit df99a1
     }
Packit df99a1
   else if (c=='-' || (c>='0' && c<='9'))
Packit df99a1
     {
Packit df99a1
       const char *here = start;
Packit df99a1
       long val = strtol(start, (char**) &start, 10);
Packit df99a1
       if (start > here)
Packit df99a1
         return GLToken(GLToken::OBJECT, new GLObject(val));
Packit df99a1
     }
Packit df99a1
   
Packit df99a1
   GUTF8String str;
Packit df99a1
   while(c != 0 && c != ')' && c != '(' && c != '"' && !isspace(c))
Packit df99a1
     {
Packit df99a1
       str += c;
Packit df99a1
       c = *++start;
Packit df99a1
     }
Packit df99a1
   if (c == 0)
Packit df99a1
     G_THROW(ByteStream::EndOfFile);
Packit df99a1
   else
Packit df99a1
     return GLToken(GLToken::OBJECT, new GLObject(GLObject::SYMBOL, str));
Packit df99a1
} 
Packit df99a1
Packit df99a1
void
Packit df99a1
GLParser::parse(const char * cur_name, GPList<GLObject> & list,
Packit df99a1
		const char * & start)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("GLParse::parse(): Parsing contents of object '" << cur_name << "'\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  
Packit df99a1
  while(1)
Packit df99a1
  {
Packit df99a1
    GLToken token=get_token(start);
Packit df99a1
    if (token.type==GLToken::OPEN_PAR)
Packit df99a1
    {
Packit df99a1
      if (isspace(*start))
Packit df99a1
      {
Packit df99a1
        GUTF8String mesg=GUTF8String( ERR_MSG("DjVuAnno.paren") "\t")+cur_name;
Packit df99a1
        G_THROW(mesg);
Packit df99a1
      }
Packit df99a1
      
Packit df99a1
      GLToken tok=get_token(start);
Packit df99a1
      GP<GLObject> object=tok.object;	// This object should be SYMBOL
Packit df99a1
      // We will convert it to LIST later
Packit df99a1
      if (tok.type!=GLToken::OBJECT || object->get_type()!=GLObject::SYMBOL)
Packit df99a1
      {
Packit df99a1
        if (tok.type==GLToken::OPEN_PAR ||
Packit df99a1
          tok.type==GLToken::CLOSE_PAR)
Packit df99a1
        {
Packit df99a1
          GUTF8String mesg=GUTF8String( ERR_MSG("DjVuAnno.no_paren") "\t")+cur_name;
Packit df99a1
          G_THROW(mesg);
Packit df99a1
        }
Packit df99a1
        if (tok.type==GLToken::OBJECT)
Packit df99a1
        {
Packit df99a1
          GLObject::GLObjectType type=object->get_type();
Packit df99a1
          if (type==GLObject::NUMBER)
Packit df99a1
          {
Packit df99a1
            GUTF8String mesg( ERR_MSG("DjVuAnno.no_number") "\t");
Packit df99a1
            mesg += cur_name;
Packit df99a1
            G_THROW(mesg);
Packit df99a1
          }
Packit df99a1
          else if (type==GLObject::STRING)
Packit df99a1
          {
Packit df99a1
            GUTF8String mesg( ERR_MSG("DjVuAnno.no_string") "\t");
Packit df99a1
            mesg += cur_name;
Packit df99a1
            G_THROW(mesg);
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
      
Packit df99a1
      // OK. Get the object contents
Packit df99a1
      GPList<GLObject> new_list;
Packit df99a1
      G_TRY
Packit df99a1
      {
Packit df99a1
        parse(object->get_symbol(), new_list, start);
Packit df99a1
      } 
Packit df99a1
      G_CATCH(exc)
Packit df99a1
      {
Packit df99a1
        if (exc.cmp_cause(ByteStream::EndOfFile))
Packit df99a1
          G_RETHROW;
Packit df99a1
      } 
Packit df99a1
      G_ENDCATCH;
Packit df99a1
      list.append(new GLObject(object->get_symbol(), new_list));
Packit df99a1
      continue;
Packit df99a1
    }
Packit df99a1
    if (token.type==GLToken::CLOSE_PAR) 
Packit df99a1
      return;
Packit df99a1
    list.append(token.object);
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
GLParser::check_compat(const char *s)
Packit df99a1
{
Packit df99a1
  int state = 0;
Packit df99a1
  while (s && *s && !compat)
Packit df99a1
    {
Packit df99a1
      switch(state)
Packit df99a1
        {
Packit df99a1
        case 0:
Packit df99a1
          if (*s == '\"')
Packit df99a1
            state = '\"';
Packit df99a1
          break;
Packit df99a1
        case '\"':
Packit df99a1
          if (*s == '\"')
Packit df99a1
            state = 0;
Packit df99a1
          else if (*s == '\\')
Packit df99a1
            state = '\\';
Packit df99a1
          else if ((unsigned char)(*s)<0x20 || *s==0x7f)
Packit df99a1
            compat = true;
Packit df99a1
          break;
Packit df99a1
        case '\\':
Packit df99a1
          if (!strchr("01234567tnrbfva\"\\",*s))
Packit df99a1
            compat = true;
Packit df99a1
          state = '\"';
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
      s += 1;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
GLParser::parse(const char * str)
Packit df99a1
{
Packit df99a1
   DEBUG_MSG("GLParser::parse(): parsing string contents\n");
Packit df99a1
   DEBUG_MAKE_INDENT(3);
Packit df99a1
   
Packit df99a1
   G_TRY
Packit df99a1
   {
Packit df99a1
      check_compat(str);
Packit df99a1
      parse("toplevel", list, str);
Packit df99a1
   } G_CATCH(exc)
Packit df99a1
   {
Packit df99a1
      if (exc.cmp_cause(ByteStream::EndOfFile))
Packit df99a1
        G_RETHROW;
Packit df99a1
   } G_ENDCATCH;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
GLParser::print(ByteStream & str, int compact)
Packit df99a1
{
Packit df99a1
   for(GPosition pos=list;pos;++pos)
Packit df99a1
      list[pos]->print(str, compact);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GLObject>
Packit df99a1
GLParser::get_object(const char * name, bool last)
Packit df99a1
{
Packit df99a1
   GP<GLObject> object;
Packit df99a1
   for(GPosition pos=list;pos;++pos)
Packit df99a1
   {
Packit df99a1
      GP<GLObject> obj=list[pos];
Packit df99a1
      if (obj->get_type()==GLObject::LIST &&
Packit df99a1
	  obj->get_name()==name)
Packit df99a1
      {
Packit df99a1
	 object=obj;
Packit df99a1
	 if (!last) break;
Packit df99a1
      }
Packit df99a1
   }
Packit df99a1
   return object;
Packit df99a1
}
Packit df99a1
Packit df99a1
//***************************************************************************
Packit df99a1
//********************************** ANT ************************************
Packit df99a1
//***************************************************************************
Packit df99a1
Packit df99a1
static const char *zoom_strings[]={
Packit df99a1
  "default","page","width","one2one","stretch"};
Packit df99a1
static const int zoom_strings_size=sizeof(zoom_strings)/sizeof(const char *);
Packit df99a1
Packit df99a1
static const char *mode_strings[]={
Packit df99a1
  "default","color","fore","back","bw"};
Packit df99a1
static const int mode_strings_size=sizeof(mode_strings)/sizeof(const char *);
Packit df99a1
Packit df99a1
static const char *align_strings[]={
Packit df99a1
  "default","left","center","right","top","bottom"};
Packit df99a1
static const int align_strings_size=sizeof(align_strings)/sizeof(const char *);
Packit df99a1
Packit df99a1
#define PNOTE_TAG	"pnote"
Packit df99a1
#define BACKGROUND_TAG	"background"
Packit df99a1
#define ZOOM_TAG	"zoom"
Packit df99a1
#define MODE_TAG	"mode"
Packit df99a1
#define ALIGN_TAG	"align"
Packit df99a1
#define HALIGN_TAG	"halign"
Packit df99a1
#define VALIGN_TAG	"valign"
Packit df99a1
#define METADATA_TAG    "metadata"
Packit df99a1
#define XMP_TAG         "xmp"
Packit df99a1
Packit df99a1
static const unsigned long default_bg_color=0xffffffff;
Packit df99a1
Packit df99a1
DjVuANT::DjVuANT(void)
Packit df99a1
{
Packit df99a1
   bg_color=default_bg_color;
Packit df99a1
   zoom=0;
Packit df99a1
   mode=MODE_UNSPEC;
Packit df99a1
   hor_align=ver_align=ALIGN_UNSPEC;
Packit df99a1
}
Packit df99a1
Packit df99a1
DjVuANT::~DjVuANT()
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuANT::get_paramtags(void) const
Packit df99a1
{
Packit df99a1
  GUTF8String retval;
Packit df99a1
  if(zoom > 0)
Packit df99a1
  {
Packit df99a1
    retval+="<PARAM name=\"" ZOOM_TAG "\" value=\""+GUTF8String(zoom)+="\" />\n";
Packit df99a1
  }else if(zoom && ((-zoom)
Packit df99a1
  {
Packit df99a1
    retval+="<PARAM name=\"" ZOOM_TAG "\" value=\""+GUTF8String(zoom_strings[-zoom])+"\" />\n";
Packit df99a1
  }
Packit df99a1
  if((mode>0)&&(mode
Packit df99a1
  {
Packit df99a1
    retval+="<PARAM name=\"" MODE_TAG "\" value=\""+GUTF8String(mode_strings[mode])+"\" />\n";
Packit df99a1
  }
Packit df99a1
  if((hor_align>ALIGN_UNSPEC)&&(hor_align
Packit df99a1
  {
Packit df99a1
    retval+="<PARAM name=\"" HALIGN_TAG "\" value=\""+GUTF8String(align_strings[hor_align])+"\" />\n";
Packit df99a1
  }
Packit df99a1
  if((ver_align>ALIGN_UNSPEC)&&(ver_align
Packit df99a1
  {
Packit df99a1
    retval+="<PARAM name=\"" VALIGN_TAG "\" value=\""+GUTF8String(align_strings[ver_align])+"\" />\n";
Packit df99a1
  }
Packit df99a1
  if((bg_color&0xffffff) == bg_color)
Packit df99a1
  {
Packit df99a1
    retval+="<PARAM name=\"" BACKGROUND_TAG "\" value=\""+GUTF8String().format("#%06lX",bg_color)+"\" />\n";
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuANT::writeParam(ByteStream &str_out) const
Packit df99a1
{
Packit df99a1
  str_out.writestring(get_paramtags());
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuANT::get_xmlmap(const GUTF8String &name,const int height) const
Packit df99a1
{
Packit df99a1
  GUTF8String retval("<MAP name=\""+name.toEscaped()+"\" >\n");
Packit df99a1
  for(GPosition pos(map_areas);pos;++pos)
Packit df99a1
  {
Packit df99a1
    retval+=map_areas[pos]->get_xmltag(height);
Packit df99a1
  }
Packit df99a1
  return retval+"</MAP>\n";
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuANT::writeMap(
Packit df99a1
  ByteStream &str_out,const GUTF8String &name,const int height) const
Packit df99a1
{
Packit df99a1
  str_out.writestring("<MAP name=\""+name.toEscaped()+"\" >\n");
Packit df99a1
  for(GPosition pos(map_areas);pos;++pos)
Packit df99a1
  {
Packit df99a1
    str_out.writestring(GUTF8String(map_areas[pos]->get_xmltag(height)));
Packit df99a1
  }
Packit df99a1
  str_out.writestring(GUTF8String("</MAP>\n"));
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuANT::read_raw(ByteStream & str)
Packit df99a1
{
Packit df99a1
   GUTF8String raw;
Packit df99a1
   char buffer[1024];
Packit df99a1
   int length;
Packit df99a1
   while((length=str.read(buffer, 1024)))
Packit df99a1
      raw+=GUTF8String(buffer, length);
Packit df99a1
   return raw;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuANT::decode(class GLParser & parser)
Packit df99a1
{
Packit df99a1
   bg_color=get_bg_color(parser);
Packit df99a1
   zoom=get_zoom(parser);
Packit df99a1
   mode=get_mode(parser);
Packit df99a1
   hor_align=get_hor_align(parser);
Packit df99a1
   ver_align=get_ver_align(parser);
Packit df99a1
   map_areas=get_map_areas(parser);
Packit df99a1
   metadata=get_metadata(parser); 
Packit df99a1
   xmpmetadata=get_xmpmetadata(parser);
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuANT::decode(ByteStream & str)
Packit df99a1
{
Packit df99a1
   GLParser parser(read_raw(str));
Packit df99a1
   decode(parser);
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuANT::merge(ByteStream & str)
Packit df99a1
{
Packit df99a1
   GLParser parser(encode_raw());
Packit df99a1
   GUTF8String add_raw=read_raw(str);
Packit df99a1
   parser.parse(add_raw);
Packit df99a1
   decode(parser);
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuANT::encode(ByteStream &bs)
Packit df99a1
{
Packit df99a1
  GUTF8String raw=encode_raw();
Packit df99a1
  bs.writall((const char*) raw, raw.length());
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned int 
Packit df99a1
DjVuANT::get_memory_usage() const
Packit df99a1
{
Packit df99a1
  return sizeof(DjVuANT);
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned char
Packit df99a1
DjVuANT::decode_comp(char ch1, char ch2)
Packit df99a1
{
Packit df99a1
   unsigned char dig1=0;
Packit df99a1
   if (ch1)
Packit df99a1
   {
Packit df99a1
      ch1=toupper(ch1);
Packit df99a1
      if (ch1>='0' && ch1<='9') dig1=ch1-'0';
Packit df99a1
      if (ch1>='A' && ch1<='F') dig1=10+ch1-'A';
Packit df99a1
      
Packit df99a1
      unsigned char dig2=0;
Packit df99a1
      if (ch2)
Packit df99a1
      {
Packit df99a1
	 ch2=toupper(ch2);
Packit df99a1
	 if (ch2>='0' && ch2<='9') dig2=ch2-'0';
Packit df99a1
	 if (ch2>='A' && ch2<='F') dig2=10+ch2-'A';
Packit df99a1
	 return (dig1 << 4) | dig2;
Packit df99a1
      }
Packit df99a1
      return dig1;
Packit df99a1
   }
Packit df99a1
   return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned long int
Packit df99a1
DjVuANT::cvt_color(const char * color, unsigned long int def)
Packit df99a1
{
Packit df99a1
   if (color[0]!='#') return def;
Packit df99a1
Packit df99a1
   unsigned long int color_rgb=0;
Packit df99a1
   color++;
Packit df99a1
   const char * start, * end;
Packit df99a1
   
Packit df99a1
      // Do blue
Packit df99a1
   end=color+strlen(color); start=end-2;
Packit df99a1
   if (start
Packit df99a1
   if (end>start)
Packit df99a1
      color_rgb|=decode_comp(start[0], start+1
Packit df99a1
   
Packit df99a1
      // Do green
Packit df99a1
   end=color+strlen(color)-2; start=end-2;
Packit df99a1
   if (start
Packit df99a1
   if (end>start)
Packit df99a1
      color_rgb|=decode_comp(start[0], start+1
Packit df99a1
   
Packit df99a1
      // Do red
Packit df99a1
   end=color+strlen(color)-4; start=end-2;
Packit df99a1
   if (start
Packit df99a1
   if (end>start)
Packit df99a1
      color_rgb|=decode_comp(start[0], start+1
Packit df99a1
Packit df99a1
      // Do the fourth byte
Packit df99a1
   end=color+strlen(color)-6; start=end-2;
Packit df99a1
   if (start
Packit df99a1
   if (end>start)
Packit df99a1
      color_rgb|=decode_comp(start[0], start+1
Packit df99a1
   
Packit df99a1
   return color_rgb;
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned long int
Packit df99a1
DjVuANT::get_bg_color(GLParser & parser)
Packit df99a1
{
Packit df99a1
  unsigned long retval=default_bg_color;
Packit df99a1
  DEBUG_MSG("DjVuANT::get_bg_color(): getting background color ...\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  G_TRY
Packit df99a1
  {
Packit df99a1
    GP<GLObject> obj=parser.get_object(BACKGROUND_TAG);
Packit df99a1
    if (obj && obj->get_list().size()==1)
Packit df99a1
    {
Packit df99a1
      GUTF8String color=(*obj)[0]->get_symbol();
Packit df99a1
      DEBUG_MSG("color='" << color << "'\n");
Packit df99a1
      retval=cvt_color(color, 0xffffff);
Packit df99a1
    }
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if(retval == default_bg_color)
Packit df99a1
    {
Packit df99a1
      DEBUG_MSG("can't find any.\n");
Packit df99a1
    }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  } G_CATCH_ALL {} G_ENDCATCH;
Packit df99a1
#ifndef NDEBUG
Packit df99a1
  if(retval == default_bg_color)
Packit df99a1
  {
Packit df99a1
    DEBUG_MSG("resetting color to 0xffffffff (UNSPEC)\n");
Packit df99a1
  }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
DjVuANT::get_zoom(GLParser & parser)
Packit df99a1
      // Returns:
Packit df99a1
      //   <0 - special zoom (like ZOOM_STRETCH)
Packit df99a1
      //   =0 - not set
Packit df99a1
      //   >0 - numeric zoom (%%)
Packit df99a1
{
Packit df99a1
  int retval=ZOOM_UNSPEC;
Packit df99a1
  DEBUG_MSG("DjVuANT::get_zoom(): getting zoom factor ...\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  G_TRY
Packit df99a1
  {
Packit df99a1
    GP<GLObject> obj=parser.get_object(ZOOM_TAG);
Packit df99a1
    if (obj && obj->get_list().size()==1)
Packit df99a1
    {
Packit df99a1
      const GUTF8String zoom((*obj)[0]->get_symbol());
Packit df99a1
      DEBUG_MSG("zoom='" << zoom << "'\n");
Packit df99a1
     
Packit df99a1
      for(int i=0;(i
Packit df99a1
      {
Packit df99a1
        if(zoom == zoom_strings[i])
Packit df99a1
        {
Packit df99a1
          retval=(-i);
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
      if(retval == ZOOM_UNSPEC)
Packit df99a1
      {
Packit df99a1
        if (zoom[0]!='d')
Packit df99a1
        {
Packit df99a1
          G_THROW( ERR_MSG("DjVuAnno.bad_zoom") );
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          retval=zoom.substr(1, zoom.length()).toInt(); //atoi((const char *) zoom+1);
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if(retval == ZOOM_UNSPEC)
Packit df99a1
    {
Packit df99a1
      DEBUG_MSG("can't find any.\n");
Packit df99a1
    }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  } G_CATCH_ALL {} G_ENDCATCH;
Packit df99a1
#ifndef NDEBUG
Packit df99a1
  if(retval == ZOOM_UNSPEC)
Packit df99a1
  {
Packit df99a1
    DEBUG_MSG("resetting zoom to 0 (UNSPEC)\n");
Packit df99a1
  }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
DjVuANT::get_mode(GLParser & parser)
Packit df99a1
{
Packit df99a1
  int retval=MODE_UNSPEC;
Packit df99a1
  DEBUG_MSG("DjVuAnt::get_mode(): getting default mode ...\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  G_TRY
Packit df99a1
  {
Packit df99a1
    GP<GLObject> obj=parser.get_object(MODE_TAG);
Packit df99a1
    if (obj && obj->get_list().size()==1)
Packit df99a1
    {
Packit df99a1
      const GUTF8String mode((*obj)[0]->get_symbol());
Packit df99a1
      DEBUG_MSG("mode='" << mode << "'\n");
Packit df99a1
      for(int i=0;(i
Packit df99a1
      {
Packit df99a1
        if(mode == mode_strings[i])
Packit df99a1
        {
Packit df99a1
          retval=i;
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if(retval == MODE_UNSPEC)
Packit df99a1
    {
Packit df99a1
      DEBUG_MSG("can't find any.\n");
Packit df99a1
    }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  } G_CATCH_ALL {} G_ENDCATCH;
Packit df99a1
#ifndef NDEBUG
Packit df99a1
  if(retval == MODE_UNSPEC)
Packit df99a1
  {
Packit df99a1
    DEBUG_MSG("resetting mode to MODE_UNSPEC\n");
Packit df99a1
  }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline DjVuANT::alignment
Packit df99a1
legal_halign(const int i)
Packit df99a1
{
Packit df99a1
  DjVuANT::alignment retval;
Packit df99a1
  switch((DjVuANT::alignment)i)
Packit df99a1
  {
Packit df99a1
  case DjVuANT::ALIGN_LEFT:
Packit df99a1
  case DjVuANT::ALIGN_CENTER:
Packit df99a1
  case DjVuANT::ALIGN_RIGHT:
Packit df99a1
    retval=(DjVuANT::alignment)i;
Packit df99a1
    break;
Packit df99a1
  default:
Packit df99a1
    retval=DjVuANT::ALIGN_UNSPEC;
Packit df99a1
    break;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline DjVuANT::alignment
Packit df99a1
legal_valign(const int i)
Packit df99a1
{
Packit df99a1
  DjVuANT::alignment retval;
Packit df99a1
  switch((DjVuANT::alignment)i)
Packit df99a1
  {
Packit df99a1
  case DjVuANT::ALIGN_CENTER:
Packit df99a1
  case DjVuANT::ALIGN_TOP:
Packit df99a1
  case DjVuANT::ALIGN_BOTTOM:
Packit df99a1
    retval=(DjVuANT::alignment)i;
Packit df99a1
    break;
Packit df99a1
  default:
Packit df99a1
    retval=DjVuANT::ALIGN_UNSPEC;
Packit df99a1
    break;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
DjVuANT::alignment
Packit df99a1
DjVuANT::get_hor_align(GLParser & parser)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuAnt::get_hor_align(): getting hor page alignemnt ...\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  alignment retval=ALIGN_UNSPEC;
Packit df99a1
  G_TRY
Packit df99a1
  {
Packit df99a1
    GP<GLObject> obj=parser.get_object(ALIGN_TAG);
Packit df99a1
    if (obj && obj->get_list().size()==2)
Packit df99a1
    {
Packit df99a1
      const GUTF8String align((*obj)[0]->get_symbol());
Packit df99a1
      DEBUG_MSG("hor_align='" << align << "'\n");
Packit df99a1
      
Packit df99a1
      for(int i=(int)ALIGN_UNSPEC;(i
Packit df99a1
      {
Packit df99a1
        const alignment j=legal_halign(i);
Packit df99a1
        if((i == (int)j)&&(align == align_strings[i]))
Packit df99a1
        {
Packit df99a1
          retval=j;
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if(retval == ALIGN_UNSPEC)
Packit df99a1
    {
Packit df99a1
      DEBUG_MSG("can't find any.\n");
Packit df99a1
    }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  } G_CATCH_ALL {} G_ENDCATCH;
Packit df99a1
#ifndef NDEBUG
Packit df99a1
  if(retval == ALIGN_UNSPEC)
Packit df99a1
  {
Packit df99a1
    DEBUG_MSG("resetting alignment to ALIGN_UNSPEC\n");
Packit df99a1
  }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
DjVuANT::alignment
Packit df99a1
DjVuANT::get_ver_align(GLParser & parser)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuAnt::get_ver_align(): getting vert page alignemnt ...\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  alignment retval=ALIGN_UNSPEC;
Packit df99a1
  G_TRY
Packit df99a1
  {
Packit df99a1
    GP<GLObject> obj=parser.get_object(ALIGN_TAG);
Packit df99a1
    if (obj && obj->get_list().size()==2)
Packit df99a1
    {
Packit df99a1
      const GUTF8String align((*obj)[1]->get_symbol());
Packit df99a1
      DEBUG_MSG("ver_align='" << align << "'\n");
Packit df99a1
      for(int i=(int)ALIGN_UNSPEC;(i
Packit df99a1
      {
Packit df99a1
        const alignment j=legal_valign(i);
Packit df99a1
        if((i == (int)j)&&(align == align_strings[i]))
Packit df99a1
        {
Packit df99a1
          retval=j;
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if(retval == ALIGN_UNSPEC)
Packit df99a1
    {
Packit df99a1
      DEBUG_MSG("can't find any.\n");
Packit df99a1
    }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  } G_CATCH_ALL {} G_ENDCATCH;
Packit df99a1
#ifndef NDEBUG
Packit df99a1
  if(retval == ALIGN_UNSPEC)
Packit df99a1
  {
Packit df99a1
    DEBUG_MSG("resetting alignment to ALIGN_UNSPEC\n");
Packit df99a1
  }
Packit df99a1
#endif // NDEBUG
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GMap<GUTF8String, GUTF8String>
Packit df99a1
DjVuANT::get_metadata(GLParser & parser)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuANT::get_metadata(): forming and returning metadata table\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  
Packit df99a1
  GMap<GUTF8String, GUTF8String> mdata;
Packit df99a1
  
Packit df99a1
  GPList<GLObject> list=parser.get_list();
Packit df99a1
  for(GPosition pos=list;pos;++pos)
Packit df99a1
    {
Packit df99a1
      GLObject & obj=*list[pos];
Packit df99a1
      if (obj.get_type()==GLObject::LIST && obj.get_name()==METADATA_TAG)  
Packit df99a1
        { 
Packit df99a1
          G_TRY 
Packit df99a1
            {
Packit df99a1
              for(int obj_num=0;obj_num
Packit df99a1
                {
Packit df99a1
                  GLObject & el=*obj[obj_num];
Packit df99a1
                  const int type = el.get_type();
Packit df99a1
                  if (type == GLObject::LIST)
Packit df99a1
                    { 
Packit df99a1
                      const GUTF8String & name=el.get_name();  
Packit df99a1
                      mdata[name]=(el[0])->get_string();
Packit df99a1
                    }
Packit df99a1
                }
Packit df99a1
            } 
Packit df99a1
          G_CATCH_ALL { } G_ENDCATCH;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return mdata;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuANT::get_xmpmetadata(GLParser & parser)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuANT::get_xmpmetadata(): returning xmp metadata string\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  
Packit df99a1
  GUTF8String xmp;
Packit df99a1
  GPList<GLObject> list=parser.get_list();
Packit df99a1
  for(GPosition pos=list;pos;++pos)
Packit df99a1
    {
Packit df99a1
      GLObject &obj = *list[pos];
Packit df99a1
      if (obj.get_type()==GLObject::LIST && obj.get_name()==XMP_TAG)  
Packit df99a1
        { 
Packit df99a1
          G_TRY 
Packit df99a1
            {
Packit df99a1
              if (obj.get_list().size() >= 1)
Packit df99a1
                {
Packit df99a1
                  GLObject &el = *obj[0];
Packit df99a1
                  xmp = el.get_string();
Packit df99a1
                  break;
Packit df99a1
                }
Packit df99a1
            } 
Packit df99a1
          G_CATCH_ALL { } G_ENDCATCH;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return xmp;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
GPList<GMapArea>
Packit df99a1
DjVuANT::get_map_areas(GLParser & parser)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuANT::get_map_areas(): forming and returning back list of map areas\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  
Packit df99a1
  GPList<GMapArea> map_areas;
Packit df99a1
  
Packit df99a1
  GPList<GLObject> list=parser.get_list();
Packit df99a1
Packit df99a1
  for(GPosition pos=list;pos;++pos)
Packit df99a1
  {
Packit df99a1
    GLObject & obj=*list[pos];
Packit df99a1
    const int type=obj.get_type();
Packit df99a1
    if (type == GLObject::LIST)
Packit df99a1
    {
Packit df99a1
      const GUTF8String name=obj.get_name();
Packit df99a1
      if(name == GMapArea::MAPAREA_TAG)
Packit df99a1
      {
Packit df99a1
        G_TRY {
Packit df99a1
	       // Getting the url
Packit df99a1
          GUTF8String url;
Packit df99a1
          GUTF8String target=GMapArea::TARGET_SELF;
Packit df99a1
          GLObject & url_obj=*(obj[0]);
Packit df99a1
          if (url_obj.get_type()==GLObject::LIST)
Packit df99a1
          {
Packit df99a1
            if (url_obj.get_name()!=GMapArea::URL_TAG)
Packit df99a1
              G_THROW( ERR_MSG("DjVuAnno.bad_url") );
Packit df99a1
            url=(url_obj[0])->get_string();
Packit df99a1
            target=(url_obj[1])->get_string();
Packit df99a1
          } else url=url_obj.get_string();
Packit df99a1
        
Packit df99a1
	       // Getting the comment
Packit df99a1
          GUTF8String comment=(obj[1])->get_string();
Packit df99a1
        
Packit df99a1
          DEBUG_MSG("found maparea '" << comment << "' (" <<
Packit df99a1
            url << ":" << target << ")\n");
Packit df99a1
        
Packit df99a1
          GLObject * shape=obj[2];
Packit df99a1
          GP<GMapArea> map_area;
Packit df99a1
          if (shape->get_type()==GLObject::LIST)
Packit df99a1
          {
Packit df99a1
            if (shape->get_name()==GMapArea::RECT_TAG)
Packit df99a1
            {
Packit df99a1
              DEBUG_MSG("it's a rectangle.\n");
Packit df99a1
              GRect grect((*shape)[0]->get_number(),
Packit df99a1
                          (*shape)[1]->get_number(),
Packit df99a1
                          (*shape)[2]->get_number(),
Packit df99a1
                          (*shape)[3]->get_number());
Packit df99a1
              GP<GMapRect> map_rect=GMapRect::create(grect);
Packit df99a1
              map_area=(GMapRect *)map_rect;
Packit df99a1
            } else if (shape->get_name()==GMapArea::POLY_TAG)
Packit df99a1
            {
Packit df99a1
              DEBUG_MSG("it's a polygon.\n");
Packit df99a1
              int points=shape->get_list().size()/2;
Packit df99a1
              GTArray<int> xx(points-1), yy(points-1);
Packit df99a1
              for(int i=0;i
Packit df99a1
              {
Packit df99a1
                xx[i]=(*shape)[2*i]->get_number();
Packit df99a1
                yy[i]=(*shape)[2*i+1]->get_number();
Packit df99a1
              }
Packit df99a1
              GP<GMapPoly> map_poly=GMapPoly::create(xx,yy,points);
Packit df99a1
              map_area=(GMapPoly *)map_poly;
Packit df99a1
            } else if (shape->get_name()==GMapArea::OVAL_TAG)
Packit df99a1
            {
Packit df99a1
              DEBUG_MSG("it's an ellipse.\n");
Packit df99a1
              GRect grect((*shape)[0]->get_number(),
Packit df99a1
                          (*shape)[1]->get_number(),
Packit df99a1
                          (*shape)[2]->get_number(),
Packit df99a1
                          (*shape)[3]->get_number());
Packit df99a1
              GP<GMapOval> map_oval=GMapOval::create(grect);
Packit df99a1
              map_area=(GMapOval *)map_oval;
Packit df99a1
            }
Packit df99a1
          }
Packit df99a1
        
Packit df99a1
          if (map_area)
Packit df99a1
          {
Packit df99a1
            map_area->url=url;
Packit df99a1
            map_area->target=target;
Packit df99a1
            map_area->comment=comment;
Packit df99a1
            for(int obj_num=3;obj_num
Packit df99a1
            {
Packit df99a1
              GLObject * el=obj[obj_num];
Packit df99a1
              if (el->get_type()==GLObject::LIST)
Packit df99a1
              {
Packit df99a1
                const GUTF8String & name=el->get_name();
Packit df99a1
                if (name==GMapArea::BORDER_AVIS_TAG)
Packit df99a1
                  map_area->border_always_visible=true;
Packit df99a1
                else if (name==GMapArea::HILITE_TAG)
Packit df99a1
                {
Packit df99a1
                  GLObject * obj=el->get_list()[el->get_list().firstpos()];
Packit df99a1
                  if (obj->get_type()==GLObject::SYMBOL)
Packit df99a1
                    map_area->hilite_color=cvt_color(obj->get_symbol(), 0xff);
Packit df99a1
                } else
Packit df99a1
                {
Packit df99a1
                  int border_type=
Packit df99a1
                    name==GMapArea::NO_BORDER_TAG ? GMapArea::NO_BORDER :
Packit df99a1
                    name==GMapArea::XOR_BORDER_TAG ? GMapArea::XOR_BORDER :
Packit df99a1
                    name==GMapArea::SOLID_BORDER_TAG ? GMapArea::SOLID_BORDER :
Packit df99a1
                    name==GMapArea::SHADOW_IN_BORDER_TAG ? GMapArea::SHADOW_IN_BORDER :
Packit df99a1
                    name==GMapArea::SHADOW_OUT_BORDER_TAG ? GMapArea::SHADOW_OUT_BORDER :
Packit df99a1
                    name==GMapArea::SHADOW_EIN_BORDER_TAG ? GMapArea::SHADOW_EIN_BORDER :
Packit df99a1
                    name==GMapArea::SHADOW_EOUT_BORDER_TAG ? GMapArea::SHADOW_EOUT_BORDER : -1;
Packit df99a1
                  if (border_type>=0)
Packit df99a1
                  {
Packit df99a1
                    map_area->border_type=(GMapArea::BorderType) border_type;
Packit df99a1
                    for(GPosition pos=el->get_list();pos;++pos)
Packit df99a1
                    {
Packit df99a1
                      GLObject * obj=el->get_list()[pos];
Packit df99a1
                      if (obj->get_type()==GLObject::SYMBOL)
Packit df99a1
                        map_area->border_color=cvt_color(obj->get_symbol(), 0xff);
Packit df99a1
                      if (obj->get_type()==GLObject::NUMBER)
Packit df99a1
                        map_area->border_width=obj->get_number();
Packit df99a1
                    }
Packit df99a1
                  }
Packit df99a1
                }	    
Packit df99a1
              } // if (el->get_type()==...)
Packit df99a1
            } // for(int obj_num=...)
Packit df99a1
            map_areas.append(map_area);
Packit df99a1
          } // if (map_area) ...
Packit df99a1
        } G_CATCH_ALL {} G_ENDCATCH;
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  } // while(item==...)
Packit df99a1
   
Packit df99a1
  DEBUG_MSG("map area list size = " << list.size() << "\n");
Packit df99a1
  
Packit df99a1
  return map_areas;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuANT::del_all_items(const char * name, GLParser & parser)
Packit df99a1
{
Packit df99a1
   GPList<GLObject> & list=parser.get_list();
Packit df99a1
   GPosition pos=list;
Packit df99a1
   while(pos)
Packit df99a1
   {
Packit df99a1
      GLObject & obj=*list[pos];
Packit df99a1
      if (obj.get_type()==GLObject::LIST &&
Packit df99a1
	  obj.get_name()==name)
Packit df99a1
      {
Packit df99a1
	 GPosition this_pos=pos;
Packit df99a1
	 ++pos;
Packit df99a1
	 list.del(this_pos);
Packit df99a1
      } else ++pos;
Packit df99a1
   }
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuANT::encode_raw(void) const
Packit df99a1
{
Packit df99a1
   GUTF8String buffer;
Packit df99a1
   GLParser parser;
Packit df99a1
Packit df99a1
      //*** Background color
Packit df99a1
   del_all_items(BACKGROUND_TAG, parser);
Packit df99a1
   if (bg_color!=default_bg_color)
Packit df99a1
   {
Packit df99a1
      buffer.format("(" BACKGROUND_TAG " #%02X%02X%02X)",
Packit df99a1
	      (unsigned int)((bg_color & 0xff0000) >> 16),
Packit df99a1
	      (unsigned int)((bg_color & 0xff00) >> 8),
Packit df99a1
	      (unsigned int)(bg_color & 0xff));
Packit df99a1
      parser.parse(buffer);
Packit df99a1
   }
Packit df99a1
Packit df99a1
      //*** Zoom
Packit df99a1
   del_all_items(ZOOM_TAG, parser);
Packit df99a1
   if (zoom>0 || (zoom>=ZOOM_STRETCH && zoom<=ZOOM_PAGE))
Packit df99a1
   {
Packit df99a1
      buffer="(" ZOOM_TAG " ";
Packit df99a1
      if (zoom < 0)
Packit df99a1
        buffer += zoom_strings[-zoom];
Packit df99a1
      else
Packit df99a1
        buffer += "d"+GUTF8String(zoom);
Packit df99a1
      buffer+=")";
Packit df99a1
      parser.parse(buffer);
Packit df99a1
   }
Packit df99a1
Packit df99a1
      //*** Mode
Packit df99a1
   del_all_items(MODE_TAG, parser);
Packit df99a1
   if (mode!=MODE_UNSPEC)
Packit df99a1
   {
Packit df99a1
      const int i=mode-1;
Packit df99a1
      if((i>=0)&& (i
Packit df99a1
      { 
Packit df99a1
        buffer="(" MODE_TAG " " + GUTF8String(mode_strings[mode]) + ")";
Packit df99a1
      }
Packit df99a1
      parser.parse(buffer);
Packit df99a1
   }
Packit df99a1
Packit df99a1
      //*** Alignment
Packit df99a1
   del_all_items(ALIGN_TAG, parser);
Packit df99a1
   if (hor_align!=ALIGN_UNSPEC || ver_align!=ALIGN_UNSPEC)
Packit df99a1
   {
Packit df99a1
      buffer= GUTF8String("(" ALIGN_TAG " ")
Packit df99a1
        +align_strings[((hor_align
Packit df99a1
                        (hor_align>=align_strings_size))?ALIGN_UNSPEC:hor_align]
Packit df99a1
        +" "+align_strings[((ver_align
Packit df99a1
                            (ver_align>=align_strings_size))?ALIGN_UNSPEC:ver_align]+")";
Packit df99a1
      parser.parse(buffer);
Packit df99a1
   }
Packit df99a1
      //*** Metadata
Packit df99a1
   del_all_items(METADATA_TAG, parser);
Packit df99a1
   if (!metadata.isempty())
Packit df99a1
     {
Packit df99a1
       GUTF8String mdatabuffer("(");
Packit df99a1
       mdatabuffer +=  METADATA_TAG ;
Packit df99a1
       for (GPosition pos=metadata; pos; ++pos)
Packit df99a1
         mdatabuffer +=" (" + metadata.key(pos) + " " + make_c_string(metadata[pos]) + ")";
Packit df99a1
       mdatabuffer += " )";
Packit df99a1
       parser.parse(mdatabuffer);
Packit df99a1
     }
Packit df99a1
      //*** XMP Metadata
Packit df99a1
   del_all_items(XMP_TAG, parser);
Packit df99a1
   if (!!xmpmetadata)
Packit df99a1
     {
Packit df99a1
       GUTF8String mdatabuffer("(");
Packit df99a1
       mdatabuffer +=  XMP_TAG;
Packit df99a1
       mdatabuffer += " " + make_c_string(xmpmetadata) + ")";
Packit df99a1
       parser.parse(mdatabuffer);
Packit df99a1
     }
Packit df99a1
     //*** Mapareas
Packit df99a1
   del_all_items(GMapArea::MAPAREA_TAG, parser);
Packit df99a1
   for(GPosition pos=map_areas;pos;++pos)
Packit df99a1
     {
Packit df99a1
       GUTF8String mapareabuffer = map_areas[pos]->print();
Packit df99a1
       parser.parse(mapareabuffer);
Packit df99a1
     }
Packit df99a1
   GP<ByteStream> gstr=ByteStream::create();
Packit df99a1
   ByteStream &str=*gstr;
Packit df99a1
   parser.print(str, 1);
Packit df99a1
   GUTF8String ans;
Packit df99a1
   int size = str.size();
Packit df99a1
   str.seek(0);
Packit df99a1
   str.read(ans.getbuf(size), size);
Packit df99a1
   return ans;
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
DjVuANT::is_empty(void) const
Packit df99a1
{
Packit df99a1
   GUTF8String raw=encode_raw();
Packit df99a1
   for(int i=raw.length()-1;i>=0;i--)
Packit df99a1
      if (isspace(raw[i])) raw.setat(i, 0);
Packit df99a1
      else break;
Packit df99a1
   return raw.length()==0;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<DjVuANT>
Packit df99a1
DjVuANT::copy(void) const
Packit df99a1
{
Packit df99a1
   GP<DjVuANT> ant=new DjVuANT(*this);
Packit df99a1
      // Now process the list of hyperlinks.
Packit df99a1
   ant->map_areas.empty();
Packit df99a1
   for(GPosition pos=map_areas;pos;++pos)
Packit df99a1
      ant->map_areas.append(map_areas[pos]->get_copy());
Packit df99a1
   return ant;
Packit df99a1
}
Packit df99a1
Packit df99a1
//***************************************************************************
Packit df99a1
//******************************** DjVuAnno *********************************
Packit df99a1
//***************************************************************************
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuAnno::get_xmlmap(const GUTF8String &name,const int height) const
Packit df99a1
{
Packit df99a1
  return ant
Packit df99a1
    ?(ant->get_xmlmap(name,height))
Packit df99a1
    :("<MAP name=\""+name.toEscaped()+"\"/>\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuAnno::writeMap(ByteStream &str_out,const GUTF8String &name,const int height) const
Packit df99a1
{
Packit df99a1
  if(ant)
Packit df99a1
  {
Packit df99a1
    ant->writeMap(str_out,name,height);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    str_out.writestring(get_xmlmap(name,height));
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
DjVuAnno::get_paramtags(void) const
Packit df99a1
{
Packit df99a1
  return ant
Packit df99a1
    ?(ant->get_paramtags())
Packit df99a1
    :GUTF8String();
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuAnno::writeParam(ByteStream &str_out) const
Packit df99a1
{
Packit df99a1
  str_out.writestring(get_paramtags());
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuAnno::decode(const GP<ByteStream> &gbs)
Packit df99a1
{
Packit df99a1
  GUTF8String chkid;
Packit df99a1
  GP<IFFByteStream> giff=IFFByteStream::create(gbs);
Packit df99a1
  IFFByteStream &iff=*giff;
Packit df99a1
  while( iff.get_chunk(chkid) )
Packit df99a1
  {
Packit df99a1
    if (chkid == "ANTa")
Packit df99a1
    {
Packit df99a1
      if (ant) {
Packit df99a1
        ant->merge(*iff.get_bytestream());
Packit df99a1
      } else {
Packit df99a1
        ant=DjVuANT::create();
Packit df99a1
        ant->decode(*iff.get_bytestream());
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
    else if (chkid == "ANTz")
Packit df99a1
    {
Packit df99a1
      GP<ByteStream> gbsiff=BSByteStream::create(giff->get_bytestream());
Packit df99a1
      if (ant) {
Packit df99a1
        ant->merge(*gbsiff);
Packit df99a1
      } else {
Packit df99a1
        ant=DjVuANT::create();
Packit df99a1
        ant->decode(*gbsiff);
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
    // Add decoding of other chunks here
Packit df99a1
    iff.close_chunk();
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuAnno::encode(const GP<ByteStream> &gbs)
Packit df99a1
{
Packit df99a1
  GP<IFFByteStream> giff=IFFByteStream::create(gbs);
Packit df99a1
  IFFByteStream &iff=*giff;
Packit df99a1
  if (ant)
Packit df99a1
    {
Packit df99a1
#if 0
Packit df99a1
      iff.put_chunk("ANTa");
Packit df99a1
      ant->encode(iff);
Packit df99a1
      iff.close_chunk();
Packit df99a1
#else
Packit df99a1
      iff.put_chunk("ANTz");
Packit df99a1
      {
Packit df99a1
//	 GP<ByteStream> bsbinput = giff.get_bytestream();
Packit df99a1
	 GP<ByteStream> bsb = BSByteStream::create(giff->get_bytestream(), 50);
Packit df99a1
	 ant->encode(*bsb);
Packit df99a1
      }
Packit df99a1
      iff.close_chunk();
Packit df99a1
#endif
Packit df99a1
    }
Packit df99a1
  // Add encoding of other chunks here
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
GP<DjVuAnno>
Packit df99a1
DjVuAnno::copy(void) const
Packit df99a1
{
Packit df99a1
   GP<DjVuAnno> anno= new DjVuAnno;
Packit df99a1
      // Copy any primitives (if any)
Packit df99a1
   *anno=*this;
Packit df99a1
      // Copy each substructure
Packit df99a1
   if (ant) anno->ant = ant->copy();
Packit df99a1
   return anno;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuAnno::merge(const GP<DjVuAnno> & anno)
Packit df99a1
{
Packit df99a1
   if (anno)
Packit df99a1
   {
Packit df99a1
      GP<ByteStream> gstr=ByteStream::create();
Packit df99a1
      encode(gstr);
Packit df99a1
      anno->encode(gstr);
Packit df99a1
      gstr->seek(0);
Packit df99a1
      decode(gstr);
Packit df99a1
   }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif