mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
321 lines
No EOL
6.9 KiB
C++
321 lines
No EOL
6.9 KiB
C++
#if defined(flagWINGL) || defined(flagLINUXGL)
|
|
|
|
#include <CtrlCore/CtrlCore.h>
|
|
|
|
NAMESPACE_UPP
|
|
|
|
void OpenGLFont::LoadBrc(const byte* xml, const byte** imagesData, const int* imagesSize, int imagesCount)
|
|
{
|
|
Parse((const char*) xml, false);
|
|
for(int i = 0; i < imagesCount; i++)
|
|
{
|
|
MemStream ms((void*) imagesData[i], imagesSize[i]);
|
|
Image img = StreamRaster::LoadAny(ms);
|
|
images.Add(img);
|
|
if(preload)
|
|
resources.Add(img, true);
|
|
}
|
|
}
|
|
|
|
void OpenGLFont::Load(const String& fileName, bool preload)
|
|
{
|
|
String filePath = GetDataFile(fileName);
|
|
String xml = LoadFile(filePath);
|
|
Parse(xml, true);
|
|
}
|
|
|
|
void OpenGLFont::Parse(const char* xml, bool parsePages)
|
|
{
|
|
chars.SetCount(512);
|
|
|
|
XmlParser p(xml);
|
|
|
|
while(!p.IsTag())
|
|
p.Skip();
|
|
|
|
p.PassTag("font");
|
|
|
|
while(!p.End())
|
|
{
|
|
if(p.TagE("common"))
|
|
{
|
|
scaleW = (float) p.Double("scaleW");
|
|
scaleH = (float) p.Double("scaleH");
|
|
lineHeight = (float) p.Double("lineHeight");
|
|
base = (float) p.Double("base");
|
|
}
|
|
else if(p.Tag("pages"))
|
|
{
|
|
while(!p.End())
|
|
{
|
|
if(p.TagE("page"))
|
|
{
|
|
if(parsePages)
|
|
{
|
|
String fileName = p["file"];
|
|
Image img = StreamRaster::LoadFileAny(GetDataFile(fileName));
|
|
images.Add(img);
|
|
if(preload)
|
|
resources.Add(img, true);
|
|
}
|
|
pages.Add(StrInt(p["id"]));
|
|
}
|
|
else
|
|
p.Skip();
|
|
}
|
|
|
|
}
|
|
else if(p.Tag("chars"))
|
|
{
|
|
while(!p.End())
|
|
{
|
|
if(p.TagE("char"))
|
|
{
|
|
int id = p.Int("id");
|
|
CharInfo& ci = chars[id];
|
|
|
|
ci.id = id;
|
|
ci.x = (float) p.Double("x");
|
|
ci.y = (float) p.Double("y");
|
|
ci.width = (float) p.Double("width");
|
|
ci.height = (float) p.Double("height");
|
|
ci.xoffset = (float) p.Double("xoffset");
|
|
ci.yoffset = (float) p.Double("yoffset");
|
|
ci.xadvance = (float) p.Double("xadvance");
|
|
ci.page = p.Int("page");
|
|
}
|
|
else
|
|
p.Skip();
|
|
}
|
|
}
|
|
else if(p.Tag("kernings"))
|
|
{
|
|
while(!p.End())
|
|
{
|
|
if(p.TagE("kerning"))
|
|
{
|
|
int first = p.Int("first");
|
|
int second = p.Int("second");
|
|
float amount = (float) p.Double("amount");
|
|
|
|
VectorMap<int, float>& vm = kerns.GetAdd(first);
|
|
vm.Add(second, amount);
|
|
}
|
|
else
|
|
p.Skip();
|
|
}
|
|
}
|
|
else
|
|
p.Skip();
|
|
}
|
|
}
|
|
|
|
void OpenGLFont::UpdateTextures()
|
|
{
|
|
if(texturesUpdated)
|
|
return;
|
|
|
|
for(int i = 0; i < images.GetCount(); i++)
|
|
{
|
|
const TextureResource& t = resources.Bind(images[i], Resources::LINEAR_FILTERING);
|
|
pages[i] = t.serialId;
|
|
}
|
|
|
|
texturesUpdated = true;
|
|
}
|
|
|
|
float ConvStrength(float min, float max, float p)
|
|
{
|
|
return min + (max - min) * p / 100.f;
|
|
}
|
|
|
|
void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Color ink, int outlineStrength, Color outlineColor, int glowStrength, Color glowColor, int n, const int *dx)
|
|
{
|
|
if(!text)
|
|
return;
|
|
|
|
const wchar* s = text;
|
|
OpenGLFont& fi = resources.GetFont(font);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
#if CLIP_MODE == 3
|
|
float cl = (float) clip.left;
|
|
float ct = (float) clip.top;
|
|
float cr = (float) clip.right;
|
|
float cb = (float) clip.bottom;
|
|
#endif
|
|
fi.UpdateTextures();
|
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
alphaMagProg.Start();
|
|
|
|
const float ic = 1.f / 255.f;
|
|
|
|
float outlineCenter = ConvStrength(0.1f, 0.45f, (float) 100 - min(outlineStrength, 100));
|
|
float glowCenter = ConvStrength(0.55f, 0.95f, (float) 100 - min(glowStrength, 100));
|
|
|
|
#ifdef COLOR_ALPHA
|
|
float ac = alpha / 255.f;
|
|
int inkA = ink.GetA();
|
|
int outlineA = outlineColor.GetA();
|
|
int glowA = glowColor.GetA();
|
|
#else
|
|
float ac = alpha;
|
|
int inkA = 1;
|
|
int outlineA = 1;
|
|
int glowA = 1;
|
|
#endif
|
|
|
|
alphaMagProg.SetUniform("GlyphColor", ink.GetR() * ic, ink.GetG() * ic, ink.GetB() * ic, inkA * ic * ac);
|
|
alphaMagProg.SetUniform("OutlineColor", outlineColor.GetR() * ic, outlineColor.GetG() * ic, outlineColor.GetB() * ic, outlineA * ic * ac);
|
|
alphaMagProg.SetUniform("GlowColor", glowColor.GetR() * ic, glowColor.GetG() * ic, glowColor.GetB() * ic, glowA * ic * ac);
|
|
alphaMagProg.SetUniform("Outline", outlineStrength > 0); //0.1 - 0.45
|
|
alphaMagProg.SetUniform("Glow", glowStrength > 0); //0.55 - 0.095
|
|
alphaMagProg.SetUniform("Shadow", false);
|
|
alphaMagProg.SetUniform("OutlineCenter", outlineCenter);
|
|
alphaMagProg.SetUniform("GlowCenter", glowCenter);
|
|
|
|
float xp = (float) x;
|
|
float yp = (float) y;
|
|
|
|
int page = -1;
|
|
|
|
float sw = (float) fi.scaleW;
|
|
float sh = (float) fi.scaleH;
|
|
|
|
float tw = 1.f / sw;
|
|
float th = 1.f / sh;
|
|
|
|
while(*s && n > 0)
|
|
{
|
|
int cn = *s;
|
|
|
|
if(cn >= 0 && cn < fi.chars.GetCount())
|
|
{
|
|
const OpenGLFont::CharInfo& ci = fi.chars[cn];
|
|
|
|
cn <<= 3;
|
|
|
|
if(ci.page != page)
|
|
{
|
|
resources.Bind(fi.pages[ci.page], Resources::LINEAR_FILTERING);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
alphaMagProg.SetUniform("Texture", 0);
|
|
page = ci.page;
|
|
}
|
|
|
|
float sx = (float) ci.xoffset * fi.scale + xp + drawing_offset.x;
|
|
float sy = (float) ci.yoffset * fi.scale + yp + drawing_offset.y;
|
|
float dx = sx + ci.width * fi.scale;
|
|
float dy = sy + ci.height * fi.scale;
|
|
|
|
#if CLIP_MODE == 3
|
|
if(sx <= clip.right && sy <= clip.bottom && dx >= clip.left && dy >= clip.top)
|
|
#endif
|
|
{
|
|
float tl = (float) ci.x;
|
|
float tt = (float) ci.y;
|
|
float tr = (float) ci.x + ci.width;
|
|
float tb = (float) ci.y + ci.height;
|
|
|
|
#if CLIP_MODE == 3
|
|
if(sx < cl)
|
|
{
|
|
tl += (cl - sx);
|
|
sx = cl;
|
|
}
|
|
|
|
if(sy < ct)
|
|
{
|
|
tt += (ct - sy);
|
|
sy = ct;
|
|
}
|
|
|
|
if(dx > cr)
|
|
{
|
|
tr -= dx - cr;
|
|
dx = cr;
|
|
}
|
|
|
|
if(dy > cb)
|
|
{
|
|
tb -= dy - cb;
|
|
dy = cb;
|
|
}
|
|
#endif
|
|
|
|
tl = (tl + TEXEL_OFFSET) * tw;
|
|
tr = (tr - TEXEL_OFFSET) * tw;
|
|
tt = (tt + TEXEL_OFFSET) * th;
|
|
tb = (tb - TEXEL_OFFSET) * th;
|
|
/*
|
|
float vtx[] = {
|
|
sx, dy,
|
|
sx, sy,
|
|
dx, dy,
|
|
dx, sy
|
|
};*/
|
|
float vtx[12];
|
|
SetVtx(vtx, sx, sy, dx, dy);
|
|
|
|
float crd[] = {
|
|
tl, tb,
|
|
tl, tt,
|
|
tr, tb,
|
|
tr, tt
|
|
};
|
|
|
|
glTexCoordPointer(2, GL_FLOAT, 0, crd);
|
|
glVertexPointer(projection_mode ? 3: 2, GL_FLOAT, 0, vtx);
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
|
|
xp += int(ci.xadvance * fi.scale + 0.5f);
|
|
|
|
int k = fi.kerns.Find(*s);
|
|
if(k >= 0)
|
|
xp += int(fi.kerns[k].Get(*(s + 1), 0) * fi.scale);
|
|
}
|
|
|
|
++s;
|
|
--n;
|
|
}
|
|
|
|
alphaMagProg.Stop();
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
|
|
{
|
|
GuiLock __;
|
|
Text(x, y, angle, text, font, ink, 0, White, 0, White, n, dx);
|
|
}
|
|
|
|
Size GetTextSize(const wchar *text, const OpenGLFont& fi, int n)
|
|
{
|
|
if(n < 0)
|
|
n = wstrlen(text);
|
|
Size sz;
|
|
sz.cx = 0;
|
|
const wchar *wtext = (const wchar *)text;
|
|
while(n > 0) {
|
|
int cn = *wtext++;
|
|
if(cn >= 0 && cn < fi.chars.GetCount())
|
|
{
|
|
const OpenGLFont::CharInfo& ci = fi.chars[cn];
|
|
sz.cx += int(ci.xadvance * fi.scale + 0.5f);
|
|
int k = fi.kerns.Find(cn);
|
|
if(k >= 0)
|
|
sz.cx += int(fi.kerns[k].Get(*wtext, 0) * fi.scale);
|
|
}
|
|
n--;
|
|
}
|
|
sz.cy = int(fi.lineHeight * fi.scale + 0.5f);
|
|
return sz;
|
|
}
|
|
|
|
END_UPP_NAMESPACE
|
|
|
|
#endif |