size_t Font::getStringWidth(const std::string &s) const { float total = 0; std::string::const_iterator i = s.begin(); uint32_t prev = 0; while (i != s.end()) { uint32_t c = get_unicode_char(i); if (unicode2glyph.find(c) != unicode2glyph.end()) { total += unicode2glyph.find(c)->second->advance; //if (kerning.find(std::make_pair(prev, c)) != kerning.end()) { // total += kerning[make_pair(prev, c)]; //} prev = c; } //i++; } return static_cast<size_t>(total); }
int process_file(FILE *f,long stop) { int bufptr; int tabmode=0; long offset=0; int hyperlink_mode = 0; unsigned short c; /* Now we are starting to read with get_unicode_char */ while (!catdoc_eof(f) && offset<stop) { bufptr = -1; do { int unichar = get_unicode_char(f,&offset,stop); if (unichar < 0) continue; c = unichar; /* Following symbols below 32 are allowed inside paragraph: 0x0002 - footnote mark 0x0007 - table separator (converted to tabmode) 0x0009 - Horizontal tab ( printed as is) 0x000B - hard return 0x000C - page break 0x000D - return - marks an end of paragraph 0x001E - IS2 for some reason means short defis in Word. 0x001F - soft hyphen in Word 0x0013 - start embedded hyperlink 0x0014 - separate hyperlink URL from text 0x0015 - end embedded hyperlink */ if (tabmode) { tabmode=0; if (c==0x007) { buffer[++bufptr]=0x1E; continue; } else { buffer[++bufptr]=0x1C; } } if (c<32) { switch (c) { case 0x007: tabmode = 1; break; case 0x000D: case 0x000B: buffer[++bufptr]=0x000A; break; case 0x000C: buffer[++bufptr]=c; break; case 0x001E: buffer[++bufptr]='-'; break; case 0x0002: break; case 0x001F: buffer[++bufptr]=0xAD;/* translate to Unicode soft hyphen */ break; case 0x0009: buffer[++bufptr]=c; break; case 0x0013: hyperlink_mode=1; buffer[++bufptr]=' '; break; case 0x0014: hyperlink_mode = 0; /*fall through */ case 0x0015: /* just treat hyperlink separators as * space */ buffer[++bufptr]=' '; break; case 0x0001: if (hyperlink_mode) break; /* else fall through */ default: bufptr=-1; /* Any other control char - discard para*/ } } else if (c != 0xfeff) { /* skip ZERO-WIDTH-UNBREAKABLE-SPACE. Output anything * else*/ buffer[++bufptr]=c; } } while (bufptr >=0 && bufptr<PARAGRAPH_BUFFER-2 && !catdoc_eof(f) && buffer[bufptr]!=0x000a); if (bufptr>0) { buffer[++bufptr]=0; output_paragraph(buffer); } } return 0; }
void Font::printString(const std::string &s, float x, float y, float scale, Align align) { if (s.empty()) { return; } std::istringstream manystr; manystr.str(s); glPushMatrix(); glTranslatef(x, y, 0); glScalef(scale, scale, 1); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); std::string onestr; float cur_y = 0; while (getline(manystr, onestr)) { float cur_x = 0; switch (align) { case ALIGN_CENTER: cur_x -= getStringWidth(onestr) / 2; break; case ALIGN_RIGHT: cur_x -= getStringWidth(onestr); break; default: break; } // Print one string std::string::const_iterator i = onestr.begin(); uint32_t prev = 0; while (i != onestr.end()) { uint32_t c = get_unicode_char(i); if (unicode2glyph.find(c) != unicode2glyph.end()) { Glyph *g = unicode2glyph.find(c)->second; // shortcut //if (kerning.find(std::make_pair(prev, c)) != kerning.end()) { // cur_x += kerning[std::make_pair(prev, c)]; //} float left = cur_x + g->bearingX; float right = left + g->width; float top = cur_y + g->bearingY; float bottom = top - g->height; glTexCoord2f(g->tex_left, g->tex_top); glVertex2f(left, top); glTexCoord2f(g->tex_right, g->tex_top); glVertex2f(right, top); glTexCoord2f(g->tex_right, g->tex_bottom); glVertex2f(right, bottom); glTexCoord2f(g->tex_left, g->tex_bottom); glVertex2f(left, bottom); cur_x += g->advance; prev = c; } //i++; } // Advance down cur_y -= getLineHeight(); } glEnd(); glDisable(GL_BLEND); glPopMatrix(); }
void copy_out (FILE *f,char *header) { char *buf=(char *)buffer; int count,i; long offset; if (get_unicode_char == get_word8_char) { /* non-word file and -u specified. Trying to guess which kind of * unicode is used */ if ((unsigned char)header[0]==0xFE && (unsigned char)header[1]==0xFF) { get_unicode_char = get_utf16msb; fputs(convert_char(header[2]<<8|header[3]),output_file); fputs(convert_char(header[4]<<8|header[5]),output_file); fputs(convert_char(header[6]<<8|header[7]),output_file); } else if ((unsigned char)header[0]!=0xFF || (unsigned char)header[1]!=0xFE) { int c,j,d; /* if it is not utf16, assume it is UTF8. We are told -u, * aren't we */ get_unicode_char = get_utf8; i=0; while (i<8) { c=(unsigned char)header[i++]; if (c >=0x80) { if ( c<0xE0) { c=(c & 0x1F); count =1; } else { c=(c & 0xF); count = 2; } for (j=0;j<count;j++) { if (i<7) { d=(unsigned char) header[i++]; } else { d=fgetc(f); } c=c<<6 | (d & 0x3F); } } fputs (convert_char(c),output_file); } } else { get_unicode_char = get_utf16lsb; fputs(convert_char(header[3]<<8|header[2]),output_file); fputs(convert_char(header[5]<<8|header[4]),output_file); fputs(convert_char(header[7]<<8|header[6]),output_file); } while (!catdoc_eof(f)) { i=get_unicode_char(f,&offset,0x7FFFFFFF); if (i!=EOF) fputs(convert_char(i),output_file); } } else { for (i=0;i<8;i++) { fputs(convert_char(to_unicode(source_charset,(unsigned char)header[i])),output_file); } /* Assuming 8-bit input text */ while ((count = catdoc_read(buf,1,PARAGRAPH_BUFFER,f))) { for (i=0;i<count;i++) { fputs(convert_char(to_unicode(source_charset, (unsigned char)buf[i])),output_file); } } } }