Example #1
0
 void JFont::writechar(String s,ImageType *j,int x,int y,float scale,ColourType c) {
   // Doesn't work under RH6 int i=fcs.find(&fcalled,s);
   int i=fcs.findlike(&JFontfsamename,FontChar(s));
 if (i>0) {
     FontChar *fc=fcs.p2num(i);
     fc->writetojbmp(j,x,y,scale,c);
   }
 }
Example #2
0
 void writechar(String s,RGBmp *j,int x,int y,float scale,myRGB c) {
   // Doesn't work under RH6 int i=fcs.find(&fcalled,s);
   int i=fcs.findlike(&JFontfsamename,FontChar(s));
 if (i>0) {
     FontChar *fc=fcs.p2num(i);
     fc->writetojbmp(j,x,y,scale,c);
   }
 }
Example #3
0
void main(int argc,String *argv) {
  ArgParser a=ArgParser(argc,argv);
  String fname=a.argafter("-i","Font file (.jf)");
  float fw=a.floatafter("-fw","Font width",0.1);
  // We parse from
  List<String> lines=parsefileintolines(fname);
  // into
  List<FontChar> fcs=List<FontChar>();
  for(int i=1;i<=lines.len;i++) {
    String current=lines.num(i);
//    printf("Parsing line %s\n",current);
    StringParser s=StringParser(current);
    String character=s.getbefore(":");
//    printf("Reading character %s ...",character);
    FontChar fc=FontChar(character);
    while (s.someleft()) {
      char whatisit=s.getchar();
      printf("It is a %c\n",whatisit);
      switch (whatisit) {

        case 'L':
          printf("Found a line\n");
          float xa=tofloat(s.getbefore(","));
          float ya=tofloat(s.getbefore("_"));
          bool keepgoing=true;
          while (keepgoing) {
            float xb=tofloat(s.getbefore(","));
            float yb=s.getfloat();
            fc.bs.add(FLine(xa,ya,xb,yb,fw));
            char c=s.getchar();
            if (c==';')
              keepgoing=false;
            else
              if (c!='_')
                printf("Expected _");
          }
          break;

/*        case 'C':
          String type=s.getanyof("TBLRNESW");
          float x=tofloat(s.getbefore(","));
          float y=tofloat(s.getbefore(","));
          float r=tofloat(s.getbefore(";"));
          FArc fa=FArc(x,y,r);
          if (Seq(type,"T") {
            fa.aa=0;
            fa.ab=2*pi;
          }
          if (Seq(type,"T") {
           fa.aa=-pi/2.0;
           fa.ab=pi/2.0;
          }
          if (Seq(type,"B") {
            fa.aa=pi/2.0;
            fa.ab=2*pi-pi/2.0;
          }
          if (Seq(type,"L") {
            fa.aa=-pi;
            fa.ab=0;
          }
          if (Seq(type,"R") {
            fa.aa=0;
           fa.ab=pi;
          }
          if (Seq(type,"NW") {
            fa.aa=-pi/2.0;
            fa.ab=0;
          }
          if (Seq(type,"NE") {
            fa.aa=0;
            fa.ab=pi/2.0;
          }
          if (Seq(type,"SE") {
            fa.aa=pi/2.0;
            fa.ab=pi;
          }
          if (Seq(type,"SW") {
            fa.aa=-pi;
            fa.ab=-pi/2.0;
          }
          fc.bs.add(fa);
          break;

        case '+':
          String search=s.getbefore(";");
          int find=0;
          for (int j=1;j<i && find==0;j++) {
            if (Seq(search,fcs.p2num(j)->name))
              find=j;
          }
          if (find==0)
            printf("You haven't defined character %s before %s",find,character);
          fc.bs.add(fcs.p2num(j)->bs);
          break;

        default:
          printf("What kind of FontBit is a %s?",toString(whatisit));
          break;
*/
      }
    };
    fcs.add(fc);
    printf(" has %i bits\n",fc.bs.len);
  }
}
Example #4
0
List<FontChar> parsefontchars(String fname,float fwgiven) {
  // We parse from
  List<String> lines=readlinesfromfile(fname);
  // into
  List<FontChar> fcs=List<FontChar>();
  float fw=tofloat(lines.num(1));
  if (fwgiven>0)
    fw=fwgiven;
  for(int i=2;i<=lines.len;i++) {
    String current=lines.num(i);
    StringParser s=StringParser(current);
    if (s.someleft() && !Seq("//",Sleft(current,2))) {
    String character=s.getbefore(":");
    FontChar fc=FontChar(character);
    while (s.someleft()) {
      char whatisit=s.getachar();
      if (whatisit=='L') {
        String type=s.getanyof("HVRL");
        float xa=tofloat(s.getbefore(","));
        float ya=tofloat(s.getbefore("_"));
        bool keepgoing=true;
        while (keepgoing) {
          float xb=tofloat(s.getbefore(","));
          float yb=s.getfloat();
//          printf("new line %f %f %f %f\n",xa,ya,xb,yb);
          fc.bs.add(new FLine(xa,-ya,xb,-yb,fw,type));
          xa=xb; ya=yb;
          // printf("one line added\n");
          // printf("From %s we pick off ",s.current);
          char c=s.getachar();
          // printf("%c, to get %s\n",c,s.current);
          if (c==';')
            keepgoing=false;
          else
          if (c!='_')
            s.error(Sformat("Expected _, got %c",c));
        };
      }
      if (whatisit=='C') {
        String type=s.getanyof("TBLRNESWXOr");
        bool anti=Sdoremove(type,"X");
        bool rounded=Sdoremove(type,"r");
        float x=tofloat(s.getbefore(","));
        float y=tofloat(s.getbefore(","));
//        String next=( Seq(type,"O") ? "," : ";" );
        String next;
        if (Seq(type,"O"))
          next=",";
        else
          next=";";
        float r=tofloat(s.getbefore(next));
//        printf("Arc rad %f ",r);
        FArc *fa=new FArc(x,y,r,fw,rounded);
        if (Slen(type)==0) {
          fa->aa=0;
          fa->ab=2*pi;
        }
        if (Seq(type,"O")) {
          fa->aa=tofloat(s.getbefore(","))*2*pi/8.0;
          fa->ab=tofloat(s.getbefore(";"))*2*pi/8.0;
        }
        if (Seq(type,"T")) {
          fa->aa=-pi/2.0;
          fa->ab=pi/2.0;
        }
        if (Seq(type,"B")) {
          fa->aa=pi/2.0;
          fa->ab=2*pi-pi/2.0;
        }
        if (Seq(type,"L")) {
          fa->aa=-pi;
          fa->ab=0;
        }
        if (Seq(type,"R")) {
          fa->aa=0;
          fa->ab=pi;
        }
        if (Seq(type,"NW")) {
          fa->aa=-pi/2.0;
          fa->ab=0;
        }
        if (Seq(type,"NE")) {
          fa->aa=0;
          fa->ab=pi/2.0;
        }
        if (Seq(type,"SE")) {
          fa->aa=pi/2.0;
          fa->ab=pi;
        }
        if (Seq(type,"SW")) {
          fa->aa=-pi;
          fa->ab=-pi/2.0;
        }
        if (anti)
          swap(&fa->aa,&fa->ab);
        /*if (Seq(type,"XSE")) {
          fa->aa=-pi;
          fa->ab=pi/2.0;
        }
        if (Seq(type,"XNW")) {
          fa->aa=0;
          fa->ab=2*pi-pi/2.0;
        }*/
        fc.bs.add(fa);
      }
      if (whatisit=='+') {
        String search=s.getbefore(";");
        int find=0;
        for (int j=1;j<=fcs.len && find==0;j++) {
          if (Seq(search,fcs.p2num(j)->name))
            find=j;
        }
        if (find==0)
          error("You haven't defined character %s before %s",search,character);
        fc.bs.add(fcs.p2num(find)->bs);
        // default:
        // printf("What kind of FontBit is a %s?",toString(whatisit));
      }
    };
    fcs.add(fc);
//    printf("%s (%i) ... ",fc.name,fc.bs.len);
    }
  }
  printf("Parsed %s\n",fname);
  lines.freedom();
  return fcs;
}
Example #5
0
 FontChar clone() const {
     auto ptr = std::make_unique<uint8_t[]>(this->datasize());
     memcpy(ptr.get(), this->data.get(), this->datasize());
     return FontChar(std::move(ptr), this->offset, this->baseline, this->width, this->height, this->incby);
 }
Example #6
0
    // Constructor
    // Params :
    //    - file_path : path to the font definition file (*.fv1)
    //==============================================================================
    explicit Font(const char * file_path) {
    //==============================================================================
        int fd;
        int b;
         // we start at space, no glyph for chars below 32
        int file_size;

        TODO("Temporary disabling font to avoid useless messages in watchdog");
//        LOG(LOG_INFO, "Reading font file %s", file_path);
        // RAZ of font chars table

        // Does font definition file exist and is it accessible ?
        if (access(file_path, F_OK)) {
            LOG(LOG_ERR,
                "create: error font file [%s] does not exist\n",
                file_path);
            goto ErrorReadingFontFile;
        }

        // Retrieves system stats about the file
        struct stat st;
        if (stat(file_path, &st)) {
            LOG(LOG_ERR, "create: can't stat file [%s]\n", file_path);
            goto ErrorReadingFontFile;
        }
        // Is file empty ?
        if (st.st_size < 1) {
            LOG(LOG_ERR, "create: empty font file [%s]\n", file_path);
            goto ErrorReadingFontFile;
        }

        // Allocate a buffer to read the whole file into
        file_size = st.st_size;

        if (-1 == (fd = open(file_path, O_RDONLY))){
            LOG(LOG_ERR, "create: can't open font file [%s] for reading\n", file_path);
            goto ErrorReadingFontFile;
        }

        {
            std::size_t size_to_read = file_size;
            std::size_t const stream_buf_sz = 8192;
            char stream_buf[stream_buf_sz];

            // Read header
            // -----------
            while ((b = read(fd, stream_buf, stream_buf_sz)) < 0) {
                if (b >= 0){
                    break;
                }
                if ((errno == EAGAIN)||(errno == EINTR)){
                    continue;
                }
                LOG(LOG_ERR,"create: error reading font file [%s] error: %s\n", file_path, strerror(errno));
                goto ErrorReadingFontFile;
            }
            InStream stream(stream_buf, b);
            size_to_read -= b;
            if (size_to_read == 0){
                close(fd);
                fd = -1;
            }

            // Extract font info from the buffer
            //----------------------------------
            stream.in_skip_bytes(4);                       // >>> 4 bytes for FNT1 (dropped)
            stream.in_copy_bytes(this->name, 32);          // >>> 32 bytes for Font Name
            this->size = stream.in_uint16_le();            // >>> 2 bytes for Font Size
            TODO("temporary disabled to avoid warning in watchdog, see other TODO above to reenable later");
//            LOG(LOG_INFO, "font name <%s> size <%u>", this->name, this->size);
            this->style = stream.in_uint16_le();           // >>> 2 bytes for Font Style
            stream.in_skip_bytes(8);                       // >>> 8 bytes for PAD (dropped)

            // Extract each character glyph
            for (int index = 32; index < NUM_GLYPHS ; index++) {
                unsigned remaining = stream.in_remain();
                if (remaining < 1024){
                    if (size_to_read > 0){
                        TODO("Create a pack_left function in stream to do this");
                        //-----------------------------------------------------
                        memmove(stream_buf, stream.get_current(), remaining);
                        //-----------------------------------------------------
                        while ((b = read(fd, stream_buf + remaining, std::min(size_to_read, stream_buf_sz - remaining))) < 0){
                            if (b >= 0){
                                break;
                            }
                            if ((errno == EAGAIN)||(errno == EINTR)){
                                continue;
                            }
                            LOG(LOG_ERR,"create: error reading font file [%s] error: %s\n", file_path, strerror(errno));
                            goto ErrorReadingFontFile;
                        }
                        stream = InStream(stream_buf, remaining + b);
                        size_to_read -= b;
                        if (size_to_read == 0){
                            close(fd);
                            fd = -1;
                        }
                    }
                    // no more remaining glyphs in file
                    if (!stream.in_check_rem(1)){
                        LOG(LOG_INFO, "Font file %s defines glyphs up to %d", file_path, index);
                        break;
                    }
                    if (!stream.in_check_rem(16)){
                        LOG(LOG_WARNING, "Font file %s defines glyphs up to %d, file looks broken", file_path, index);
                        break;
                    }
                }

//                LOG(LOG_INFO, "Reading definition for glyph %u", index);
                int width = stream.in_sint16_le(); // >>> 2 bytes for glyph width
                int height = stream.in_sint16_le(); // >>> 2 bytes for glyph height

    TODO(" baseline is always -height (seen from the code of fontdump) looks strange. It means that baseline is probably not used in current code.");

                int baseline = stream.in_sint16_le(); // >>> 2 bytes for glyph baseline
                int offset = stream.in_sint16_le(); // >>> 2 bytes for glyph offset
                int incby = stream.in_sint16_le(); // >>> 2 bytes for glyph incby
                stream.in_skip_bytes(6); // >>> 6 bytes for PAD (dropped)
                this->font_items[index] = FontChar(offset, baseline, width, height, incby);

                // Check if glyph data size make sense
                unsigned datasize = this->font_items[index].datasize();
                if (datasize > 512) { // shouldn't happen, implies broken font file
                    LOG(LOG_WARNING,
                        "Error loading font %s. Wrong size for glyph %d"
                        "width %d height %d \n", file_path, index,
                        this->font_items[index].width,
                        this->font_items[index].height);
                    // one glyph is broken but we continue with other glyphs
                    continue;
                }

                // Read the data only if there is enough space left in buffer
                if (!stream.in_check_rem(datasize)) {
                    LOG(LOG_ERR
                       , "Error loading font %s: not enough data for definition of glyph %d (expected %u, got %zu)\n"
                        , file_path, index, datasize, stream.in_remain()
                       );
                    goto ErrorReadingFontFile;
                }

                // >>> <datasize> bytes for glyph data (bitmap)
                stream.in_copy_bytes(this->font_items[index].data.get(), datasize);
            }
        }
        return;
ErrorReadingFontFile:
        LOG(LOG_ERR, "Error reading font definition file %s, exiting proxy",  file_path);
        exit(-1);
    }