Element Interpret_( Environment& , std::vector<Element> const& elements , Element const&) { Element out; if (1 != elements.size()) { out = Error("size requires a single argument of either string/superstring/container type."); } else { out = Number(SizeOf_(elements[0])); } return out; }
float CGameFont::SizeOf_( LPCSTR s ) { if ( ! ( s && s[ 0 ] ) ) return 0; if ( IsMultibyte() ) { wide_char wsStr[ MAX_MB_CHARS ]; mbhMulti2Wide( wsStr , NULL , MAX_MB_CHARS , s ); return SizeOf_( wsStr ); } int len = xr_strlen(s); float X = 0; if (len) for (int j=0; j<len; j++) X += GetCharTC( ( u16 ) ( u8 ) s[ j ] ).z; return (X*vInterval.x); }
void CGameFont::OnRender() { VERIFY (g_bRendering); if (pShader) RCache.set_Shader (pShader); if (!(uFlags&fsValid)){ CTexture* T = RCache.get_ActiveTexture(0); vTS.set ((int)T->get_Width(),(int)T->get_Height()); /* vHalfPixel.set (0.5f/float(vTS.x),0.5f/float(vTS.y)); for (int i=0; i<256; i++){ Fvector& tc = TCMap[i]; tc.x /= float(vTS.x); tc.y /= float(vTS.y); tc.z /= float(vTS.x); } fTCHeight = fHeight/float(vTS.y); uFlags |= fsValid; */ fTCHeight = fHeight/float(vTS.y); uFlags |= fsValid; } for (u32 i=0; i<strings.size(); ){ // calculate first-fit int count = 1; int length = xr_strlen(strings[i].string); while ((i+count)<strings.size()) { int L = xr_strlen(strings[i+count].string); if ((L+length)<MAX_CHARS){ count ++; length += L; } else break; } // lock AGP memory u32 vOffset; FVF::TL* v = (FVF::TL*)RCache.Vertex.Lock (length*4,pGeom.stride(),vOffset); FVF::TL* start = v; // fill vertices u32 last = i+count; for (; i<last; i++) { String &PS = strings[i]; int len = xr_strlen(PS.string); if (len) { float X = float(iFloor(PS.x)); float Y = float(iFloor(PS.y)); float S = PS.height*g_current_font_scale.y; float Y2 = Y+S; switch(PS.align) { case alCenter: X -= ( iFloor(SizeOf_(PS.string,PS.height)*.5f) ) * g_current_font_scale.x; break; case alRight: X -= iFloor(SizeOf_(PS.string,PS.height)); break; } u32 clr,clr2; clr2 = clr = PS.c; if (uFlags&fsGradient){ u32 _R = color_get_R (clr)/2; u32 _G = color_get_G (clr)/2; u32 _B = color_get_B (clr)/2; u32 _A = color_get_A (clr); clr2 = color_rgba (_R,_G,_B,_A); } float tu,tv; for (int j=0; j<len; j++) { int c = GetCharRM (PS.string[j]); Fvector l = GetCharTC (PS.string[j]); float scw = l.z * g_current_font_scale.x; //. float scw = vTS.x * l.z * g_current_font_scale.x; float fTCWidth = l.z/vTS.x; if ((c>=0)&&!fis_zero(l.z)) { tu = l.x/vTS.x;//+vHalfPixel.x; tv = l.y/vTS.y;//+vHalfPixel.y; v->set (X-0.5f, Y2-0.5f, clr2,tu, tv+fTCHeight); v++; v->set (X-0.5f, Y-0.5f, clr, tu, tv); v++; v->set (X+scw-0.5f, Y2-0.5f, clr2,tu+fTCWidth, tv+fTCHeight); v++; v->set (X+scw-0.5f, Y-0.5f, clr, tu+fTCWidth, tv); v++; } X+=scw*vInterval.x; } } } // Unlock and draw u32 vCount = (u32)(v-start); RCache.Vertex.Unlock (vCount,pGeom.stride()); if (vCount){ RCache.set_Geometry (pGeom); RCache.Render (D3DPT_TRIANGLELIST,vOffset,0,vCount,0,vCount/2); } } strings.clear_not_free (); }