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); } }
// Looks up the msgID in the file of messages and returns a pointer to // the beginning of the translated message, if found; and an empty string // otherwise. void DjVuMessageLite::LookUpID( const GUTF8String &xmsgID, GUTF8String &message_text, GUTF8String &message_number ) const { if(!Map.isempty()) { GUTF8String msgID = xmsgID; #if HAS_CTRL_C_IN_ERR_MSG int start = 0; while (msgID[start] == '\003') start ++; if (start > 0) msgID = msgID.substr(start, msgID.length() - start); #endif GPosition pos=Map.contains(msgID); if(pos) { const GP<lt_XMLTags> tag=Map[pos]; GPosition valuepos=tag->get_args().contains(valuestring); if(valuepos) { message_text=tag->get_args()[valuepos]; }else { const GUTF8String raw(tag->get_raw()); const int start_line=raw.search((unsigned long)'\n',0); const int start_text=raw.nextNonSpace(0); const int end_text=raw.firstEndSpace(0); if(start_line<0 || start_text<0 || start_text < start_line) { message_text=raw.substr(0,end_text).fromEscaped(); }else { message_text=raw.substr(start_line+1,end_text-start_line-1).fromEscaped(); } } GPosition numberpos=tag->get_args().contains(numberstring); if(numberpos) { message_number=tag->get_args()[numberpos]; } } } }
// used to build the zone tree // true is returned if the GRect is known for this object, // and false, if the rectangle's size is just the parent size. static bool make_child_layer( DjVuTXT::Zone &parent, const lt_XMLTags &tag, ByteStream &bs, const int height, const double ws, const double hs) { bool retval=true; // the plugin thinks there are only Pages, Lines and Words // so we don't make Paragraphs, Regions and Columns zones // if we did the plugin is not able to search the text but // DjVuToText writes out all the text anyway DjVuTXT::Zone *self_ptr; char sepchar; const GUTF8String name(tag.get_name()); if(name == charactertag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::CHARACTER; sepchar=0; }else if(name == wordtag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::WORD; sepchar=' '; }else if(name == linetag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::LINE; sepchar=DjVuTXT::end_of_line; }else if(name == paragraphtag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::PARAGRAPH; sepchar=DjVuTXT::end_of_paragraph; }else if(name == regiontag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::REGION; sepchar=DjVuTXT::end_of_region; }else if(name == pagecolumntag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::COLUMN; sepchar=DjVuTXT::end_of_column; }else { self_ptr = &parent; self_ptr->ztype = DjVuTXT::PAGE; sepchar=0; } DjVuTXT::Zone &self = *self_ptr; self.text_start = bs.tell(); int &xmin=self.rect.xmin, &ymin=self.rect.ymin, &xmax=self.rect.xmax, &ymax=self.rect.ymax; GRect default_rect; default_rect.xmin=max(parent.rect.xmax,parent.rect.xmin); default_rect.xmax=min(parent.rect.xmax,parent.rect.xmin); default_rect.ymin=max(parent.rect.ymax,parent.rect.ymin); default_rect.ymax=min(parent.rect.ymax,parent.rect.ymin); // Now if there are coordinates, use those. GPosition pos(tag.get_args().contains("coords")); if(pos) { GList<int> rectArgs; intList(tag.get_args()[pos], rectArgs); if((pos=rectArgs)) { xmin=(int)(ws*(double)rectArgs[pos]); if(++pos) { ymin=(height-1)-(int)(hs*(double)rectArgs[pos]); if(++pos) { xmax=(int)(ws*(double)rectArgs[pos]); if(++pos) { ymax=(height-1)-(int)(hs*(double)rectArgs[pos]); if(xmin>xmax) // Make sure xmin is really minimum { const int t=xmin; xmin=xmax; xmax=t; } if(ymin>ymax) // Make sure ymin is really minimum { const int t=ymin; ymin=ymax; ymax=t; } } } } } } if(self.ztype == DjVuTXT::CHARACTER) { if(! pos) { self.rect=default_rect; retval=false; } const GUTF8String raw(tag.get_raw().fromEscaped()); const int i=raw.nextNonSpace(0); bs.writestring(raw.substr(i,raw.firstEndSpace(i)-i)); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; }else if(pos) { pos=tag.get_content(); if(pos) { for(pos=tag.get_content(); pos; ++pos) { const GP<lt_XMLTags> t(tag.get_content()[pos].tag); make_child_layer(self, *t, bs, height,ws,hs); } if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; }else { const GUTF8String raw(tag.get_raw().fromEscaped()); const int i=raw.nextNonSpace(0); bs.writestring(raw.substr(i,raw.firstEndSpace(i)-i)); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; } }else { self.rect=default_rect; if((pos=tag.get_content())) { do { const GP<lt_XMLTags> t(tag.get_content()[pos].tag); const GRect save_rect(self.rect); self.rect=default_rect; if ((retval = make_child_layer(self, *t, bs, height, ws, hs))) { xmin=min(save_rect.xmin,xmin); xmax=max(save_rect.xmax,xmax); ymin=min(save_rect.ymin,ymin); ymax=max(save_rect.ymax,ymax); }else { // If the child doesn't have coordinates, we need to use a box // at least as big as the parent's coordinates. xmin=min(save_rect.xmin,default_rect.xmax); xmax=max(save_rect.xmax,default_rect.xmin); ymin=min(save_rect.ymin,default_rect.ymax); ymax=max(save_rect.ymax,default_rect.ymin); for(; pos; ++pos) { const GP<lt_XMLTags> t(tag.get_content()[pos].tag); make_child_layer(self, *t, bs, height,ws,hs); } break; } } while(++pos); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; }else { const GUTF8String raw(tag.get_raw().fromEscaped()); const int i=raw.nextNonSpace(0); bs.writestring(raw.substr(i,raw.firstEndSpace(i)-i)); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; } } parent.rect.xmin=min(xmin,parent.rect.xmin); parent.rect.ymin=min(ymin,parent.rect.ymin); parent.rect.xmax=max(xmax,parent.rect.xmax); parent.rect.ymax=max(ymax,parent.rect.ymax); if(xmin>xmax) { const int t=xmin; xmin=xmax; xmax=t; } if(ymin>ymax) { const int t=ymin; ymin=ymax; ymax=t; } // DjVuPrintMessage("(%d,%d)(%d,%d)<<<\\%o>>>\n", // xmin,ymin,xmax,ymax, sepchar); return retval; }