void EM_reset(string fname) { anyErrors=FALSE; fileName=fname; lineNum=1; linePos=intList(0,NULL); yyin = fopen(fname,"r"); if (!yyin) {EM_error(0,"cannot open"); exit(1);} }
void EM_restart(string fname) { ifError = 0; fileName = fname; lineNum = 1; linePos=intList(0, NULL); yyin = fopen(fname,"r"); if(!yyin) EM_error(0, "cannot open"); exit(1); }
t_CKBOOL EM_reset( c_str fname, FILE * fd ) { anyErrors = FALSE; fileName = fname ? fname : (c_str)""; lineNum = 1; EM_lineNum = 1; linePos = intList( 0, NULL ); // if( yyin ) fclose( yyin ); if( fd ) yyin = fd; else yyin = fopen( fname, "r" ); if (!yyin) EM_error2( 0, "no such file or directory" ); else fseek( yyin, 0, SEEK_SET ); EM_lineNum = 0; return (yyin != 0); }
void EM_newline(void) { lineNum++; linePos = intList(EM_token, linePos); }
// 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; }
void lt_XMLParser::Impl::ChangeAnno( const int width, const int height, DjVuFile &dfile, const lt_XMLTags &map ) { dfile.resume_decode(true); const GP<DjVuInfo> info(dfile.info); const GP<DjVuAnno> ganno(DjVuAnno::create()); DjVuAnno &anno=*ganno; GPosition map_pos; map_pos=map.contains(areatag); if(dfile.contains_anno()) { GP<ByteStream> annobs=dfile.get_merged_anno(); if(annobs) { anno.decode(annobs); if(anno.ant && info) { anno.ant->map_areas.empty(); } } // dfile.remove_anno(); } if(info && map_pos) { const int h=info->height; const int w=info->width; double ws=1.0; double hs=1.0; if(width && width != w) { ws=((double)w)/((double)width); } if(height && height != h) { hs=((double)h)/((double)height); } if(!anno.ant) { anno.ant=DjVuANT::create(); } GPList<GMapArea> &map_areas=anno.ant->map_areas; map_areas.empty(); GPList<lt_XMLTags> gareas=map[map_pos]; for(GPosition pos=gareas;pos;++pos) { if(gareas[pos]) { lt_XMLTags &areas=*(gareas[pos]); GMap<GUTF8String,GUTF8String> args(areas.get_args()); GList<int> coords; // ****************************************************** // Parse the coords attribute: first read the raw data into // a list, then scale the x, y data into another list. For // circles, you also get a radius element with (looks like an x // with no matching y). // ****************************************************** { GPosition coords_pos=args.contains("coords"); if(coords_pos) { GList<int> raw_coords; intList(args[coords_pos],raw_coords); for(GPosition raw_pos=raw_coords;raw_pos;++raw_pos) { const int r=raw_coords[raw_pos]; const int x=(int)(ws*(double)r+0.5); coords.append(x); int y=h-1; if(! ++raw_pos) { y-=(int)(hs*(double)r+0.5); }else { y-=(int)(hs*(double)raw_coords[raw_pos]+0.5); } coords.append(y); // DjVuPrintMessage("Coords (%d,%d)\n",x,y); } } } GUTF8String shape; { GPosition shape_pos=args.contains("shape"); if(shape_pos) { shape=args[shape_pos]; } } GP<GMapArea> a; if(shape == "default") { GRect rect(0,0,w,h); a=GMapRect::create(rect); }else if(!shape.length() || shape == "rect") { int xx[4]; int i=0; for(GPosition rect_pos=coords;(rect_pos)&&(i<4);++rect_pos,++i) { xx[i]=coords[rect_pos]; } if(i!=4) { G_THROW( ERR_MSG("XMLAnno.bad_rect") ); } int xmin,xmax; if(xx[0]>xx[2]) { xmax=xx[0]; xmin=xx[2]; }else { xmin=xx[0]; xmax=xx[2]; } int ymin,ymax; if(xx[1]>xx[3]) { ymax=xx[1]; ymin=xx[3]; }else { ymin=xx[1]; ymax=xx[3]; } GRect rect(xmin,ymin,xmax-xmin,ymax-ymin); a=GMapRect::create(rect); }else if(shape == "circle") { int xx[4]; int i=0; GPosition rect_pos=coords.lastpos(); if(rect_pos) { coords.append(coords[rect_pos]); for(rect_pos=coords;(rect_pos)&&(i<4);++rect_pos) { xx[i++]=coords[rect_pos]; } } if(i!=4) { G_THROW( ERR_MSG("XMLAnno.bad_circle") ); } int x=xx[0],y=xx[1],rx=xx[2],ry=(h-xx[3])-1; GRect rect(x-rx,y-ry,2*rx,2*ry); a=GMapOval::create(rect); }else if(shape == "oval") { int xx[4]; int i=0; for(GPosition rect_pos=coords;(rect_pos)&&(i<4);++rect_pos,++i) { xx[i]=coords[rect_pos]; } if(i!=4) { G_THROW( ERR_MSG("XMLAnno.bad_oval") ); } int xmin,xmax; if(xx[0]>xx[2]) { xmax=xx[0]; xmin=xx[2]; }else { xmin=xx[0]; xmax=xx[2]; } int ymin,ymax; if(xx[1]>xx[3]) { ymax=xx[1]; ymin=xx[3]; }else { ymin=xx[1]; ymax=xx[3]; } GRect rect(xmin,ymin,xmax-xmin,ymax-ymin); a=GMapOval::create(rect); }else if(shape == "poly") { GP<GMapPoly> p=GMapPoly::create(); for(GPosition poly_pos=coords;poly_pos;++poly_pos) { int x=coords[poly_pos]; if(! ++poly_pos) break; int y=coords[poly_pos]; p->add_vertex(x,y); } p->close_poly(); a=p; }else { G_THROW( ( ERR_MSG("XMLAnno.unknown_shape") "\t")+shape ); } if(a) { GPosition pos; if((pos=args.contains("href"))) { a->url=args[pos]; } if((pos=args.contains("target"))) { a->target=args[pos]; } if((pos=args.contains("alt"))) { a->comment=args[pos]; } if((pos=args.contains("bordertype"))) { GUTF8String b=args[pos]; static const GMap<GUTF8String,GMapArea::BorderType> typeMap=BorderTypeMap(); if((pos=typeMap.contains(b))) { a->border_type=typeMap[pos]; }else { G_THROW( (ERR_MSG("XMLAnno.unknown_border") "\t")+b ); } } a->border_always_visible=!!args.contains("visible"); if((pos=args.contains("bordercolor"))) { a->border_color=convertToColor(args[pos]); } if((pos=args.contains("highlight"))) { a->hilite_color=convertToColor(args[pos]); } if((pos=args.contains("border"))) { a->border_width=args[pos].toInt(); //atoi(args[pos]); } map_areas.append(a); } } } } dfile.set_modified(true); dfile.anno=ByteStream::create(); anno.encode(dfile.anno); }