コード例 #1
0
ファイル: XMLParser.cpp プロジェクト: smyts/tengwa-djvu
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);
}
コード例 #2
0
static GUTF8String
getbodies(
  GList<GURL> &paths,
  const GUTF8String &MessageFileName,
  GPList<lt_XMLTags> &body, 
  GMap<GUTF8String, void *> & map )
{
  GUTF8String errors;
  bool isdone=false;
  GPosition firstpathpos=paths;
  for(GPosition pathpos=firstpathpos;!isdone && pathpos;++pathpos)
  {
    const GURL::UTF8 url(MessageFileName,paths[pathpos]);
    if(url.is_file())
    {
      map[MessageFileName]=0;
      GP<lt_XMLTags> gtags;
      {
        GP<ByteStream> bs=ByteStream::create(url,"rb");
        G_TRY
        {
          gtags=lt_XMLTags::create(bs);
        }
        G_CATCH(ex)
        {
          GUTF8String mesg(failed_to_parse_XML+("\t"+url.get_string()));
          if(errors.length())
          {
            errors+="\n"+mesg;
          }else
          {
            errors=mesg;
          }
          errors+="\n"+GUTF8String(ex.get_cause());
        }
        G_ENDCATCH;
      }
      if(gtags)
      {
        lt_XMLTags &tags=*gtags;
        GPList<lt_XMLTags> Bodies=tags.get_Tags(bodystring);
        if(! Bodies.isempty())
        {
          isdone=true;
          for(GPosition pos=Bodies;pos;++pos)
          {
            body.append(Bodies[pos]);
          }
        }
        GPList<lt_XMLTags> Head=tags.get_Tags(headstring);
        if(! Head.isempty())
        {
          isdone=true;
          GMap<GUTF8String, GP<lt_XMLTags> > includes;
          lt_XMLTags::get_Maps(includestring,namestring,Head,includes);
          for(GPosition pos=includes;pos;++pos)
          {
            const GUTF8String file=includes.key(pos);
            if(! map.contains(file))
            {
              GList<GURL> xpaths;
              xpaths.append(url.base());
              const GUTF8String err2(getbodies(xpaths,file,body,map));
              if(err2.length())
              {
                if(errors.length())
                {
                  errors+="\n"+err2;
                }else
                {
                  errors=err2;
                }
              }
            }
          }
        }
      }
    }
  }
コード例 #3
0
GList<GURL>
DjVuMessage::GetProfilePaths(void)
{
  static bool first=true;
  static GList<GURL> realpaths;
  if(first)
  {
    first=false;
    GMap<GUTF8String,void *> pathsmap;
    GList<GURL> paths;
    GURL path;
    const GUTF8String envp(GOS::getenv(DjVuEnv));
    if(envp.length())
      appendPath(GURL::Filename::UTF8(envp),pathsmap,paths);
#if defined(WIN32) || defined(UNIX)
    GURL mpath(GetModulePath());
    if(!mpath.is_empty() && mpath.is_dir())
    {
#if defined(UNIX) && !defined(AUTOCONF) && !defined(NDEBUG)
      appendPath(GURL::UTF8(DebugModuleDjVuDir,mpath),pathsmap,paths);
#endif
      appendPath(mpath,pathsmap,paths);
      appendPath(GURL::UTF8(ModuleDjVuDir,mpath),pathsmap,paths);
      appendPath(GURL::UTF8(ProfilesDjVuDir,mpath),pathsmap,paths);
      mpath=mpath.base();
      appendPath(GURL::UTF8(ModuleDjVuDir,mpath),pathsmap,paths);
      appendPath(GURL::UTF8(ProfilesDjVuDir,mpath),pathsmap,paths);
      mpath=mpath.base();
      appendPath(GURL::UTF8(ModuleDjVuDir,mpath),pathsmap,paths);
      appendPath(GURL::UTF8(ProfilesDjVuDir,mpath),pathsmap,paths);
      mpath=mpath.base();
      appendPath(GURL::UTF8(ModuleDjVuDir,mpath),pathsmap,paths);
      appendPath(GURL::UTF8(ProfilesDjVuDir,mpath),pathsmap,paths);
    }
#endif
#if defined(AUTOCONF)
    GURL dpath = GURL::Filename::UTF8(DjVuDataDir);
    appendPath(dpath,pathsmap,paths);
#endif
#ifdef WIN32
    appendPath(RegOpenReadConfig(HKEY_CURRENT_USER),pathsmap,paths);
    appendPath(RegOpenReadConfig(HKEY_LOCAL_MACHINE),pathsmap,paths);
#else
    GUTF8String home=GOS::getenv("HOME");
# if HAVE_GETPWUID
    if (! home.length()) {
      struct passwd *pw=0;
      if ((pw = getpwuid(getuid())))
        home=GNativeString(pw->pw_dir);
    }
# endif
    if (home.length()) {
      GURL hpath = GURL::UTF8(LocalDjVuDir,GURL::Filename::UTF8(home));
      appendPath(hpath,pathsmap,paths);
    }
#endif
#ifdef LT_DEFAULT_PREFIX
    appendPath(GURL::Filename::UTF8(DjVuPrefixDir),pathsmap,paths);
#endif
    appendPath(GURL::Filename::UTF8(RootDjVuDir),pathsmap,paths);
    pathsmap.empty();

    GPosition pos;
    GList< GMap<GUTF8String,GP<lt_XMLTags> > > localemaps;
    for(pos=paths;pos;++pos)
    {
      path=GURL::UTF8(LanguageFile,paths[pos]);
      if(path.is_file())
      {
        const GP<lt_XMLTags> xml(lt_XMLTags::create(ByteStream::create(path,"rb")));
        const GPList<lt_XMLTags> Body(xml->get_Tags(bodystring));
        GPosition pos=Body;
        if(!pos || (pos != Body.lastpos()))
        {
          G_THROW( ERR_MSG("XMLAnno.extra_body") );
        }
        const GP<lt_XMLTags> GBody(Body[pos]);
        if(!GBody)
        {
          G_THROW( ERR_MSG("XMLAnno.no_body") );
        }
        GMap<GUTF8String,GP<lt_XMLTags> > localemap;
        lt_XMLTags::get_Maps(languagestring,localestring,Body,localemap);
        localemaps.append(localemap);
      }
    } 
    GList<GURL> localepaths;

    // Need to do it the right way!
    GUTF8String defaultlocale = getenv("LANGUAGE");
    if (! defaultlocale) 
      {
        const GUTF8String oldlocale(setlocale(LC_MESSAGES,0));
        defaultlocale = setlocale(LC_MESSAGES,"");
        setlocale(LC_MESSAGES,(const char *)oldlocale);
      }
    // Unfathomable search.
    for(int loop=0; loop<2; loop++)
    {
      static const char sepchars[]=" _.@";
      const char *p=sepchars+sizeof(sepchars)-1;
      do
      {
        int sepcharpos=p[0]?defaultlocale.search(p[0]):defaultlocale.length();
        if(sepcharpos > 0)
        {
          const GUTF8String sublocale(defaultlocale,sepcharpos);
          const GUTF8String downcasesublocale("downcase^"+sublocale.downcase());
          for(pos=localemaps;pos;++pos) 
          {
            const GMap<GUTF8String,GP<lt_XMLTags> > &localemap=localemaps[pos];
            GPosition pos=localemap.contains(sublocale);
            if(!pos)
              pos=localemap.contains(downcasesublocale);
            if(pos)
            {
              const GMap<GUTF8String,GUTF8String>&args
                = localemap[pos]->get_args();
              pos = args.contains(srcstring);
              if (pos)
              {
                const GUTF8String src(args[pos]);
                for(pos=paths;pos;++pos)
                {
                  path=GURL::UTF8(src,paths[pos]);
                  if(path.is_dir())
                    localepaths.append(path);
                }
              }
              // We don't need to check anymore language files.
              p=sepchars;
              break;
            }
          }
          if(!pos)
            {
            for(pos=paths;pos;++pos)
              {
              path=GURL::UTF8(sublocale,paths[pos]);
              if(path.is_dir())
                localepaths.append(path);
            }
          }
        }
      } while(p-- != sepchars);
      if((GPosition) localepaths)
        break;
      defaultlocale="C";
    }
    for(pos=localepaths;pos;++pos)
      appendPath(localepaths[pos],pathsmap,realpaths);
    for(pos=paths;pos;++pos)
      appendPath(paths[pos],pathsmap,realpaths);
  }
  return realpaths;
}
コード例 #4
0
ファイル: XMLTags.cpp プロジェクト: AllenChow/vudroid
static inline bool
isspaces(const GUTF8String &raw)
{
  return (raw.nextNonSpace() == (int)raw.length());
}
コード例 #5
0
void
GIFFManager::add_chunk(GUTF8String parent_name, const GP<GIFFChunk> & chunk,
		       int pos)
      // parent_name is the fully qualified name of the PARENT
      //             IT MAY BE EMPTY
      // All the required chunks will be created
      // pos=-1 means to append the chunk
{
  DEBUG_MSG("GIFFManager::add_chunk(): Adding chunk to name='" << parent_name << "'\n");
  DEBUG_MAKE_INDENT(3);
   
  if (!top_level->get_name().length())
  {
    if ((!parent_name.length())||(parent_name[0]!='.'))
      G_THROW( ERR_MSG("GIFFManager.no_top_name") );
    if (parent_name.length() < 2)
    {
      // 'chunk' is actually the new top-level chunk
      DEBUG_MSG("since parent_name=='.', making the chunk top-level\n");
      if (!chunk->is_container())
        G_THROW( ERR_MSG("GIFFManager.no_top_cont") );
      top_level=chunk;
      return;
    }

    DEBUG_MSG("Setting the name of the top-level chunk\n");
    const int next_dot=parent_name.search('.',1);
    if(next_dot>=0)
    {
      top_level->set_name(parent_name.substr(1,next_dot-1));
    }else
    {
      top_level->set_name(parent_name.substr(1,(unsigned int)-1));
    }
  }

  DEBUG_MSG("top level chunk name='" << top_level->get_name() << "'\n");
   
  if (parent_name.length() && parent_name[0] == '.')
  {
    int next_dot=parent_name.search('.',1);
    if(next_dot<0)
    {
      next_dot=parent_name.length();
    }
    GUTF8String top_name=parent_name.substr(1,next_dot-1);
    if (!top_level->check_name(top_name))
      G_THROW( ERR_MSG("GIFFManager.wrong_name") "\t"+top_name);
    parent_name=parent_name.substr(next_dot,(unsigned int)-1);
  }

  GP<GIFFChunk> cur_sec=top_level;
  const char * start, * end=(const char *)parent_name-1;
  do
  {
    for(start=++end;*end&&(*end!='.');end++)
      EMPTY_LOOP;
    if (end>start)
    {
      GUTF8String name(start,end-start);
      GUTF8String short_name;
      int number=0;
      const int obracket=name.search('[');
      if (obracket >= 0)
      {
        const int cbracket=name.search(']',obracket+1);
        if (cbracket < 0)
          G_THROW( ERR_MSG("GIFFManager.unmatched") );
//        number=atoi((const char *)name.substr(obracket+1,cbracket-obracket-1));
        number = name.substr(obracket+1,cbracket-obracket-1).toInt();
        short_name=name.substr(0,obracket);
      }else
      {
        short_name=name;
      }

      for(int i=cur_sec->get_chunks_number(short_name);i<number+1;i++)
        cur_sec->add_chunk(GIFFChunk::create(short_name));
      cur_sec=cur_sec->get_chunk(name);
      if (!cur_sec)
        G_THROW( ERR_MSG("GIFFManager.unknown") "\t"+name);
    }
  } while(*end);
  cur_sec->add_chunk(chunk, pos);
}
コード例 #6
0
ファイル: DjVuMessageLite.cpp プロジェクト: 717717/sumatrapdf
// 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));
    }
  }
}