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); } }
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(); } }
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)); } } }
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); } } } }