示例#1
0
static void
writeText( ByteStream & str_out,
            const GUTF8String &textUTF8,
            const DjVuTXT::Zone &zone,
            const int WindowHeight )
{
//  DEBUG_MSG( "--zonetype=" << zone.ztype << "\n" );

  const GUTF8String xindent(indent( 2 * zone.ztype + 2 ));
  GPosition pos=zone.children;
  // Build attribute string
  if( ! pos )
  {
    GUTF8String coords;
    coords.format("coords=\"%d,%d,%d,%d\"",
      zone.rect.xmin, WindowHeight - 1 - zone.rect.ymin,
      zone.rect.xmax, WindowHeight - 1 - zone.rect.ymax);
    const int start=zone.text_start;
    const int end=textUTF8.firstEndSpace(start,zone.text_length);
    str_out.writestring(start_tag(zone.ztype,coords));
    str_out.writestring(textUTF8.substr(start,end-start).toEscaped());
    str_out.writestring(end_tag(zone.ztype));
  } else
  {
    writeText(str_out,textUTF8,zone.ztype,zone.children,WindowHeight);
  }
}
示例#2
0
static void
display_chunks(ByteStream & out_str, IFFByteStream &iff,
	       const GUTF8String &head, DjVmInfo djvminfo)
{
  size_t size;
  GUTF8String id, fullid;
  GUTF8String head2 = head + "  ";
  GPMap<int,DjVmDir::File> djvmmap;
  int rawoffset;
  GMap<GUTF8String, int> counters;
  
  while ((size = iff.get_chunk(id, &rawoffset)))
  {
    if (!counters.contains(id)) counters[id]=0;
    else counters[id]++;
    
    GUTF8String msg;
    msg.format("%s%s [%d] ", (const char *)head, (const char *)id, size);
    out_str.format( "%s", (const char *)msg);
    // Display DJVM is when adequate
    if (djvminfo.dir)
    {
      GP<DjVmDir::File> rec = djvminfo.map[rawoffset];
      if (rec)
        {
          GUTF8String id = rec->get_load_name();
          GUTF8String title = rec->get_title();
          out_str.format( "{%s}", (const char*) id);
          if (rec->is_include())
            out_str.format(" [I]");
          if (rec->is_thumbnails())
            out_str.format(" [T]");
          if (rec->is_shared_anno())
            out_str.format(" [S]");
          if (rec->is_page())
            out_str.format(" [P%d]", rec->get_page_num()+1);
          if (id != title)
            out_str.format(" (%s)", (const char*)title);
        }
    }
    // Test chunk type
    iff.full_id(fullid);
    for (int i=0; disproutines[i].id; i++)
      if (fullid == disproutines[i].id || id == disproutines[i].id)
      {
        int n = msg.length();
        while (n++ < 14+(int) head.length()) putchar(out_str, ' ');
        if (!iff.composite()) out_str.format( "    ");
        (*disproutines[i].subr)(out_str, iff, head2,
                                size, djvminfo, counters[id]);
        break;
      }
      // Default display of composite chunk
      out_str.format( "\n");
      if (iff.composite())
        display_chunks(out_str, iff, head2, djvminfo);
      // Terminate
      iff.close_chunk();
  }
}
示例#3
0
GURL
DjVuErrorList::set_stream(GP<ByteStream> xibs)
{
  GUTF8String name;
  static unsigned long serial=0;
  pool=DataPool::create(xibs);
  name.format("data://%08lx/%08lx.djvu",
    ++serial,(unsigned long)(size_t)((const ByteStream *)xibs));
  pool_url=GURL::UTF8(name);
  return pool_url;
}
void
GLObject::print(ByteStream & str, int compact, int indent, int * cur_pos) const
{
  int local_cur_pos = 0;
  if (!cur_pos) { cur_pos = &local_cur_pos; }
  
  GUTF8String buffer;
  const char * to_print=0;
  switch(type)
  {
  case NUMBER:
    to_print=buffer.format("%d",number);
    break;
  case STRING:
    {
       int length = string.length();
       const char *data = (const char*)string;
       buffer = GUTF8String("\"");
       while (*data && length>0) 
         {
           int span = 0;
           while (span<length && (unsigned char)(data[span])>=0x20 && 
                  data[span]!=0x7f && data[span]!='"' && data[span]!='\\' )
             span++;
           if (span > 0) 
             {  
               buffer = buffer + GUTF8String(data, span);
               data += span;
               length -= span;
             }  
           else 
             {
               char buf[8];
               static const char *tr1 = "\"\\tnrbf";
               static const char *tr2 = "\"\\\t\n\r\b\f";
               sprintf(buf,"\\%03o", (int)(((unsigned char*)data)[span]));
               for (int i=0; tr2[i]; i++)
                 if (data[span] == tr2[i])
                   buf[1] = tr1[i];
               if (buf[1]<'0' || buf[1]>'3')
                 buf[2] = 0;
               buffer = buffer + GUTF8String(buf);
               data += 1;
               length -= 1;
             }
         }
       buffer = buffer + GUTF8String("\"");
       to_print = buffer;
    }
    break;
  case SYMBOL:
    to_print=buffer.format("%s",(const char *)symbol);
    break;
  case LIST:
    to_print=buffer.format("(%s",(const char *)name);
    break;
  case INVALID:
    break;
  }
  if (!compact && *cur_pos+strlen(to_print)>70)
  {
    char ch='\n';
    str.write(&ch, 1);
    ch=' ';
    for(int i=0;i<indent;i++) str.write(&ch, 1);
    *cur_pos=indent;
  }
  str.write(to_print, strlen(to_print));
  char ch=' ';
  str.write(&ch, 1);
  *cur_pos+=strlen(to_print)+1;
  if (type==LIST)
  {
    int indent=*cur_pos-strlen(to_print);
    for(GPosition pos=list;pos;++pos)
      list[pos]->print(str, compact, indent, cur_pos);
    str.write(") ", 2);
    *cur_pos+=2;
  }
}
void
QDBase::exportToPNM(void)
{
   DEBUG_MSG("QDViewer::exportToPNM(): exporting the image into a PPM file\n");
   DEBUG_MAKE_INDENT(3);

      // Guess on the format
   bool bw=getMode()==IDC_DISPLAY_BLACKWHITE;

   QString format_str=bw ? "PBM" : "PPM";
   GUTF8String ext=bw ? ".pbm" : ".ppm";
   
   bool raw=0;
   {
     QString mesg = 
       tr("This will export the DjVu image in either 'Raw %1'\n"
          "or 'ASCII %2' format. Which one do you prefer?\n")
       .arg(format_str)
       .arg(format_str);
       
       switch(QMessageBox::information(this, 
                                       tr("Exporting DjVu image..."), mesg,
                                       tr("&Raw"), tr("&Ascii"), tr("&Cancel"), 
                                       0, 2))
       {
         case 0: raw=1; break;
         case 1: raw=0; break;
         default: return;
       }
   }
   
   static const char *filters[] = { 0, 0, 0 };
   QString filter1 = tr("All files (*)");
   filters[0]= ((bw) ? "*.pbm" : "*.ppm");
   filters[1] = filter1;
 
   GURL file_url=dimg->get_djvu_file()->get_url();
   QString save_dir=QeFileDialog::lastSaveDir;
   if (!QFileInfo(save_dir).isDir())
      if (file_url.is_local_file_url())
	 while(true)
	 {
	    QString dir = QFileInfo(QStringFromGString(
                            file_url.UTF8Filename())).dirPath();
	    if (dir)
              {
                save_dir=dir;
	       break;
	    }
	    file_url=GURL::UTF8(file_url.name(),file_url.base().base());
	 }
   if (!QFileInfo(save_dir).isDir()) save_dir=QDir::currentDirPath();

   GUTF8String fname=GURL::expand_name(file_url.fname(), 
                                       GStringFromQString(save_dir));
   QFileInfo fi=QFileInfo(QStringFromGString(fname));
   fname=GStringFromQString(fi.dirPath())+"/"+GOS::basename(fname, ".djvu")+ext;
   
   QeFileDialog fd(save_dir, filters[0], this, "djvu_fd", TRUE);
   fd.setFilters((const char **) filters);
   fd.setCaption(tr("Select export file name..."));
   fd.setSelection(QStringFromGString(fname));
      
   if (fd.exec()==QDialog::Accepted)
   {
      int width=dimg->get_width();
      int height=dimg->get_height();
	 
      QProgressDialog progress(tr("Please stand by..."),
			       tr("&Abort"), height, this, "progress", TRUE);
      progress.setMinimumWidth(progress.sizeHint().width()*3/2);
      progress.setCaption(tr("DjVu: Exporting image..."));
      progress.setMinimumDuration(0);
      progress.setProgress(0);

      static char char_to_str[256][5];
      for(int i=0;i<256;i++) sprintf(char_to_str[i], "%d ", i);
      static short char_to_str_len[256];
      for(int i=0;i<256;i++) char_to_str_len[i]=strlen(char_to_str[i]);
      
      GRect doc_grect(0, 0, width, height);
      GUTF8String selected=GStringFromQString(fd.selectedFile());
      GP<ByteStream> gstr=ByteStream::create(GURL::Filename::UTF8(selected), "wb");
      ByteStream &str=*gstr;
      static const char *generated="#Image generated by DjVu";
      if (bw)
      {
	 GUTF8String head;
	 if (raw) head.format("P4\n%d %d\n", width, height);
	 else head.format("P1\n%s (xdpi=%u,ypdi=%u)\n%d %d\n",
			  generated, dimg->get_dpi(), dimg->get_dpi(),
			  width, height);
	 str.writall((void*)(const char *)head, head.length());
      } else
      {
	 GUTF8String head;
	 if (raw) head.format("P6\n%d %d\n255\n", width, height);
	 else head.format("P3\n%s (xdpi=%u,ydpi=%u)\n%d %d\n255\n",
			  generated, dimg->get_dpi(), dimg->get_dpi(),
			  width, height);
	 str.writall((void*)(const char *)head, head.length());
      }

      const int MAXPIXELS=100000;
      int band_height=MAXPIXELS/width;
      if (band_height>height*7/8) band_height=height;

      for(int band_y=height-band_height;band_height;band_y-=band_height)
      {
	 GRect grect(0, band_y, width, band_height);

	 if (bw)
	 {
	    GP<GBitmap> bmp=dimg->get_bitmap(grect, doc_grect);
	    if (!bmp) 
              G_THROW(ERR_MSG("QDBase.bitmap_not_found"));
	    for(int n=bmp->rows()-1;n>=0;n--)
	    {
	       const unsigned char * row=(*bmp)[n];
	       if (raw)
	       {
		  TArray<char> buffer(bmp->columns()/8+1);
		  char * ptr=buffer;
		  unsigned char acc=0;
		  unsigned char mask=0;
		  for(u_int c=0;c<bmp->columns();c++)
		  {
		     if (mask==0) mask=0x80;
		     if (row[c]) acc|=mask;
		     mask>>=1;
		     if (mask==0)
		     {
			*ptr++=acc;
			acc=mask=0;
		     }
		  }
		  if (mask!=0) *ptr++=acc;
		  str.writall((const char*)buffer, ptr-buffer);
	       }
	       else
	       {
		  TArray<char> buffer(256);
		  char * ptr=buffer;
		  for(u_int c=0;c<bmp->columns();)
		  {
		     unsigned char bit=(row[c] ? '1' : '0');
		     *ptr++=bit;
		     c++;
		     if (c==bmp->columns() || (c & 0xff)==0)
		     {
			*ptr++='\n';
			str.writall((const char*)buffer, ptr-buffer);
			ptr=buffer;
		     }
		  }
	       } // raw or not raw
	    } // for(row=...)
	 } else	// not bw
	 {
// Insert a string into the message text. Will insert into any field
// description.  Except for an ArgId of zero (message number), if the ArgId
// is not found, the routine adds a line with the parameter so information
// will not be lost.
void
DjVuMessageLite::InsertArg( GUTF8String &message,
  const int ArgId, const GUTF8String &arg ) const
{
    // argument target string
  const GUTF8String target= "%"+GUTF8String(ArgId)+"!";
    // location of target string
  int format_start = message.search( (const char *)target );
  if( format_start >= 0 )
  {
    do
    {
      const int n=format_start+target.length()+1;
      const int format_end=message.search((unsigned long)'!',n);
      if(format_end > format_start)
      { 
        const int len=1+format_end-n;
        if(len && isascii(message[n-1]))
        {
          GUTF8String narg;
          GUTF8String format="%"+message.substr(n-1,len);
          switch(format[len])
          {
            case 'd':
            case 'i':
              narg.format((const char *)format,arg.toInt());
              break;
            case 'u':
            case 'o':
            case 'x':
            case 'X':
              narg.format((const char *)format,(unsigned int)arg.toInt());
              break;
            case 'f':
            case 'g':
            case 'e':
              {
                int endpos;
                narg.format((const char *)format, arg.toDouble(0,endpos));
                if( endpos < 0 )
                  narg = arg;
              }
              break;
            default:
              narg.format((const char *)format,(const char *)arg);
              break;
          }
          message = message.substr( 0, format_start )+narg
            +message.substr( format_end+1, -1 );
        }else
        {
          message = message.substr( 0, format_start )+arg
            +message.substr( format_end+1, -1 );
        }
      }
      format_start=message.search((const char*)target, format_start+arg.length());
    } while(format_start >= 0);
  }
  else
  {
    //  Not found, fake it
    if( ArgId != 0 )
    {
      message += "\n"+LookUpSingle(uparameter+("\t"+arg));
    }
  }
}
示例#7
0
void
lt_XMLTags::init(XMLByteStream &xmlbs)
{
  if(!get_count())
  {
    G_THROW( ERR_MSG("XMLTags.no_GP") );
  }
  GPList<lt_XMLTags> level;
  GUTF8String tag,raw(xmlbs.gets(0,'<',false));
  int linesread=xmlbs.get_lines_read();
  if(!isspaces(raw))
  {
    G_THROW( (ERR_MSG("XMLTags.raw_string") "\t")+raw);
  }
  GUTF8String encoding;
  for(int len;(len=(tag=xmlbs.gets(0,'>',true)).length());)
  {
    if(tag[len-1] != '>')
    {
      G_THROW((ERR_MSG("XMLTags.bad_tag") "\t")+tag);
    }
    switch(tag[1])
    {
      case '?':
      {
        while(len < 4 || tag.substr(len-2,len) != "?>")
        {
          GUTF8String cont(xmlbs.gets(0,'>',true));
          if(!cont.length())
          { 
            G_THROW( (ERR_MSG("XMLTags.bad_PI") "\t")+tag);
          }
          len=((tag+=cont).length());
        }
        char const *n;
        GUTF8String xtag = tag.substr(2,-1);
        GUTF8String xname = tagtoname(xtag,n);
        if(xname.downcase() == "xml")
        {
          ParseValues(n,args);
          for(GPosition pos=args;pos;++pos)
          {
            if(args.key(pos) == "encoding")
            {
              const GUTF8String e=args[pos].upcase();
              if(e != encoding)
              {
                xmlbs.set_encoding((encoding=e));
              }
            }
          }
        }
        break;
      }
      case '!':
      {
        if(tag[2] == '-' && tag[3] == '-')
        {
          while((len < 7) ||
            (tag.substr(len-3,-1) != "-->"))
          {
            GUTF8String cont(xmlbs.gets(0,'>',true));
            if(!cont.length())
            { 
              GUTF8String mesg;
              mesg.format( ERR_MSG("XMLTags.bad_comment") "\t%s",(const char *)tag);
              G_THROW(mesg);
            }
            len=((tag+=cont).length());
          }
        }
        break;
      }
      case '/':
      {
        GUTF8String xname=tagtoname(tag.substr(2,-1));
        GPosition last=level.lastpos();
        if(last)
        {
          if(level[last]->name != xname)
          {
            G_THROW( (ERR_MSG("XMLTags.unmatched_end") "\t")
              +level[last]->name+("\t"+GUTF8String(level[last]->get_Line()))
              +("\t"+xname)+("\t"+GUTF8String(linesread+1)));
          }
          level.del(last);
        }else
        {
          G_THROW( ERR_MSG("XMLTags.bad_form") );
        }
        break;
      }
      default:
      {
        GPosition last=level.lastpos();
        GP<lt_XMLTags> t;
        if(last)
        {
          t=new lt_XMLTags(tag.substr(1,len-1));
          level[last]->addtag(t);
          if(tag[len-2] != '/')
          {
            level.append(t);
          }
        }else if(tag[len-2] != '/')
        {
          char const *n;
          GUTF8String xtag = tag.substr(1,-1); 
          name=tagtoname(xtag, n);
          ParseValues(n,args);
          t=this;
          level.append(t);
        }else
        {
          G_THROW( ERR_MSG("XMLTags.no_body") );
        }
        t->set_Line(linesread+1);
        break;
      }
    }
    if((raw=xmlbs.gets(0,'<',false))[0])
    { 
      linesread=xmlbs.get_lines_read();
      GPosition last=level.lastpos();
      if(last)
      {
        level[last]->addraw(raw);
      }else if(!isspaces(raw))
      {
        G_THROW(( ERR_MSG("XMLTags.raw_string") "\t")+raw);
      }
    }
  }
}