void renderString(int x, int y, string glstring){ UnicodeChar c; int uc; int span = 0; double wid = pow(2, ceil(log2(32 * stretch))); wchar_t* wstr = nullptr; MBToWC(glstring.c_str(), wstr, glstring.length()+128); glEnable(GL_TEXTURE_2D); for (unsigned int k = 0; k < wstrlen(wstr); k++) { uc = wstr[k]; c = chars[uc]; if (uc == (int)'\n') { UITrans(0, 20); span = 0; continue; } if (!c.aval) { loadchar(uc); c = chars[uc]; } glBindTexture(GL_TEXTURE_2D, c.tex); UITrans(x + 1 + span, y + 1); glColor4f(0.5, 0.5, 0.5, a); glBegin(GL_QUADS); glTexCoord2d(0.0, 0.0); UIVertex(c.xpos / stretch, 15 - c.ypos / stretch); glTexCoord2d(c.width / wid, 0.0); UIVertex(c.xpos / stretch + c.width / stretch, 15- c.ypos / stretch); glTexCoord2d(c.width / wid, c.height / wid); UIVertex(c.xpos / stretch + c.width / stretch, 15 + c.height / stretch - c.ypos / stretch); glTexCoord2d(0.0, c.height / wid); UIVertex(c.xpos / stretch, 15 + c.height / stretch - c.ypos / stretch); glEnd(); UITrans(-1, -1); glColor4f(r, g, b, a); glBegin(GL_QUADS); glTexCoord2d(0.0, 0.0); UIVertex(c.xpos / stretch, 15 - c.ypos / stretch); glTexCoord2d(c.width / wid, 0.0); UIVertex(c.xpos / stretch + c.width / stretch, 15 - c.ypos / stretch); glTexCoord2d(c.width / wid, c.height / wid); UIVertex(c.xpos / stretch + c.width / stretch, 15 + c.height / stretch - c.ypos / stretch); glTexCoord2d(0.0, c.height / wid); UIVertex(c.xpos / stretch, 15 + c.height / stretch - c.ypos / stretch); glEnd(); UITrans(-x - span, -y); span += c.advance / stretch; } glColor4f(1.0, 1.0, 1.0, 1.0); free(wstr); }
int getStrWidth(string s){ UnicodeChar c; int uc, res = 0; wchar_t* wstr = nullptr; MBToWC(s.c_str(), wstr, s.length()+128); for (unsigned int k = 0; k < wstrlen(wstr); k++){ uc = wstr[k]; c = chars[uc]; if (!c.aval) { loadchar(uc); c = chars[uc]; } res += c.advance / stretch; } free(wstr); return res; }
int cachechars(Font *f, char **ss, Rune **rr, ushort *cp, int max, int *wp, char **subfontname) { int i, th, sh, h, ld, w, rw, wid, nc; char *sp; Rune r, *rp, vr; ulong a; Cacheinfo *c, *tc, *ec; if(ss){ sp = *ss; rp = L""; }else{ sp = ""; rp = *rr; } wid = 0; *subfontname = 0; for(i=0; i<max && (*sp || *rp); sp+=w, rp+=rw){ if(ss){ r = *(uchar*)sp; if(r < Runeself) w = 1; else{ w = chartorune(&vr, sp); r = vr; } rw = 0; }else{ r = *rp; w = 0; rw = 1; } sh = (17 * (uint)r) & (f->ncache-NFLOOK-1); c = &f->cache[sh]; ec = c+NFLOOK; h = sh; while(c < ec){ if(c->value==r && c->age) goto Found; c++; h++; } /* * Not found; toss out oldest entry */ a = ~0; th = sh; tc = &f->cache[th]; while(tc < ec){ if(tc->age < a){ a = tc->age; h = th; c = tc; } tc++; th++; } if(a && (f->age-a)<500){ /* kicking out too recent; resize */ nc = 2*(f->ncache-NFLOOK) + NFLOOK; if(nc <= MAXFCACHE){ if(i == 0) fontresize(f, f->width, nc, f->maxdepth); /* else flush first; retry will resize */ break; } } if(c->age == f->age) /* flush pending string output */ break; ld = loadchar(f, r, c, h, i, subfontname); if(ld <= 0){ if(ld == 0) continue; break; } c = &f->cache[h]; /* may have reallocated f->cache */ Found: wid += c->width; c->age = f->age; cp[i] = h; i++; } if(ss) *ss = sp; else *rr = rp; *wp = wid; return i; }