mirror of
https://github.com/edubart/otclient.git
synced 2025-10-20 06:23:26 +02:00
a bunch of stuff
This commit is contained in:
@@ -75,14 +75,21 @@ void BorderedImage::setTexCoords(const Rect& left,
|
||||
m_bottomRightCornerTexCoords = bottomRight;
|
||||
m_centerTexCoords = center;
|
||||
|
||||
m_cornersSize = Size(left.width() + right.width(),
|
||||
m_bordersSize = Size(left.width() + right.width(),
|
||||
top.height() + bottom.height());
|
||||
|
||||
m_defaultSize = Size(std::max(std::max(topLeft.width(), bottomLeft.width()), left.width()) +
|
||||
std::max(std::max(topRight.width(), bottomRight.width()), right.width()) +
|
||||
center.width(),
|
||||
std::max(std::max(topLeft.height(), topRight.height()), top.height()) +
|
||||
std::max(std::max(bottomLeft.height(), bottomRight.height()), bottom.height()) +
|
||||
center.height());
|
||||
}
|
||||
|
||||
void BorderedImage::draw(const Rect& screenCoords)
|
||||
{
|
||||
Rect rectCoords;
|
||||
Size centerSize = screenCoords.size() - m_cornersSize;
|
||||
Size centerSize = screenCoords.size() - m_bordersSize;
|
||||
|
||||
// first the center
|
||||
if(centerSize.area() > 0) {
|
||||
@@ -144,3 +151,4 @@ void BorderedImage::draw(const Rect& screenCoords)
|
||||
m_bottomRightCornerTexCoords.size());
|
||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
|
||||
}
|
||||
|
||||
|
@@ -66,6 +66,8 @@ public:
|
||||
|
||||
void draw(const Rect& screenCoords);
|
||||
|
||||
Size getDefaultSize() const { return m_defaultSize; }
|
||||
|
||||
private:
|
||||
Rect m_leftBorderTexCoords;
|
||||
Rect m_rightBorderTexCoords;
|
||||
@@ -79,7 +81,8 @@ private:
|
||||
|
||||
Rect m_centerTexCoords;
|
||||
|
||||
Size m_cornersSize;
|
||||
Size m_bordersSize;
|
||||
Size m_defaultSize;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<BorderedImage> BorderedImagePtr;
|
||||
|
@@ -34,9 +34,9 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
||||
uchar *texturePixels = m_texture->getPixels();
|
||||
|
||||
// small AI to auto calculate pixels widths
|
||||
for(int glyph = 32; glyph< 256; ++glyph) {
|
||||
Rect glyphCoords(((glyph - 32) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
for(int glyph = m_firstGlyph; glyph< 256; ++glyph) {
|
||||
Rect glyphCoords(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
glyphSize.width(),
|
||||
m_glyphHeight);
|
||||
int width = glyphSize.width();
|
||||
@@ -85,13 +85,11 @@ bool Font::load(const std::string& file)
|
||||
// required values
|
||||
doc["glyph height"] >> m_glyphHeight;
|
||||
doc["image glyph size"] >> glyphSize;
|
||||
doc["image"] >> textureName;
|
||||
|
||||
// optional values
|
||||
if(doc.FindValue("glyph spacing"))
|
||||
doc["glyph spacing"] >> m_glyphSpacing;
|
||||
if(doc.FindValue("top margin"))
|
||||
doc["top margin"] >> m_topMargin;
|
||||
textureName = yamlRead<std::string>(doc, "image");
|
||||
m_glyphHeight = yamlRead<int>(doc, "glyph height");
|
||||
m_firstGlyph = yamlRead<int>(doc, "first glyph", 32);
|
||||
m_topMargin = yamlRead<int>(doc, "top margin", 0);
|
||||
m_glyphSpacing = yamlRead(doc, "glyph spacing", Size(0,0));
|
||||
|
||||
// load texture
|
||||
m_texture = g_textures.get("fonts/" + textureName);
|
||||
@@ -104,21 +102,15 @@ bool Font::load(const std::string& file)
|
||||
calculateGlyphsWidthsAutomatically(glyphSize);
|
||||
|
||||
// read custom widths
|
||||
if(doc.FindValue("glyph widths")) {
|
||||
const YAML::Node& widthsNode = doc["glyph widths"];
|
||||
for(auto it = widthsNode.begin(); it != widthsNode.end(); ++it) {
|
||||
int glyph, glyphWidth;
|
||||
it.first() >> glyph;
|
||||
it.second() >> glyphWidth;
|
||||
m_glyphsSize[glyph].setWidth(glyphWidth);
|
||||
}
|
||||
}
|
||||
std::map<int, int> glyphWidths = yamlReadMap<int, int>(doc, "glyph widths");
|
||||
foreach(const auto& pair, glyphWidths)
|
||||
m_glyphsSize[pair.first].setWidth(pair.second);
|
||||
|
||||
// calculate glyphs texture coords
|
||||
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
|
||||
for(int glyph = 32; glyph< 256; ++glyph) {
|
||||
m_glyphsTextureCoords[glyph].setRect(((glyph - 32) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
for(int glyph = m_firstGlyph; glyph< 256; ++glyph) {
|
||||
m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
m_glyphsSize[glyph].width(),
|
||||
m_glyphHeight);
|
||||
}
|
||||
@@ -136,13 +128,13 @@ void Font::renderText(const std::string& text,
|
||||
{
|
||||
Size boxSize = g_graphics.getScreenSize() - startPos.toSize();
|
||||
Rect screenCoords(startPos, boxSize);
|
||||
renderText(text, screenCoords, ALIGN_TOP_LEFT, color);
|
||||
renderText(text, screenCoords, AlignTopLeft, color);
|
||||
}
|
||||
|
||||
|
||||
void Font::renderText(const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align,
|
||||
AlignmentFlag align,
|
||||
const Color& color)
|
||||
{
|
||||
// prevent glitches from invalid rects
|
||||
@@ -167,19 +159,19 @@ void Font::renderText(const std::string& text,
|
||||
Rect glyphTextureCoords = m_glyphsTextureCoords[glyph];
|
||||
|
||||
// first translate to align position
|
||||
if(align & ALIGN_BOTTOM) {
|
||||
if(align & AlignBottom) {
|
||||
glyphScreenCoords.translate(0, screenCoords.height() - textBoxSize.height());
|
||||
} else if(align & ALIGN_VERTICAL_CENTER) {
|
||||
} else if(align & AlignVerticalCenter) {
|
||||
glyphScreenCoords.translate(0, (screenCoords.height() - textBoxSize.height()) / 2);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignTop
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
if(align & ALIGN_RIGHT) {
|
||||
if(align & AlignRight) {
|
||||
glyphScreenCoords.translate(screenCoords.width() - textBoxSize.width(), 0);
|
||||
} else if(align & ALIGN_HORIZONTAL_CENTER) {
|
||||
} else if(align & AlignHorizontalCenter) {
|
||||
glyphScreenCoords.translate((screenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignLeft
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@@ -205,7 +197,7 @@ void Font::renderText(const std::string& text,
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize) const
|
||||
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text, AlignmentFlag align, Size *textBoxSize) const
|
||||
{
|
||||
// for performance reasons we use statics vectors that are allocated on demand
|
||||
static std::vector<Point> glyphsPositions(1);
|
||||
@@ -229,7 +221,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
||||
glyphsPositions.resize(textLength);
|
||||
|
||||
// calculate lines width
|
||||
if((align & ALIGN_RIGHT || align & ALIGN_HORIZONTAL_CENTER) || textBoxSize) {
|
||||
if((align & AlignRight || align & AlignHorizontalCenter) || textBoxSize) {
|
||||
lineWidths[0] = 0;
|
||||
for(i = 0; i< textLength; ++i) {
|
||||
glyph = (uchar)text[i];
|
||||
@@ -259,11 +251,11 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
||||
}
|
||||
|
||||
// calculate start x pos
|
||||
if(align & ALIGN_RIGHT) {
|
||||
if(align & AlignRight) {
|
||||
virtualPos.x = (maxLineWidth - lineWidths[lines]);
|
||||
} else if(align & ALIGN_HORIZONTAL_CENTER) {
|
||||
} else if(align & AlignHorizontalCenter) {
|
||||
virtualPos.x = (maxLineWidth - lineWidths[lines]) / 2;
|
||||
} else { // ALIGN_LEFT
|
||||
} else { // AlignLeft
|
||||
virtualPos.x = 0;
|
||||
}
|
||||
}
|
||||
@@ -288,7 +280,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
||||
Size Font::calculateTextRectSize(const std::string& text)
|
||||
{
|
||||
Size size;
|
||||
calculateGlyphsPositions(text, ALIGN_TOP_LEFT, &size);
|
||||
calculateGlyphsPositions(text, AlignTopLeft, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@@ -28,27 +28,11 @@
|
||||
#include <prerequisites.h>
|
||||
#include <graphics/texture.h>
|
||||
|
||||
enum EAlign {
|
||||
ALIGN_TOP = 1 << 0,
|
||||
ALIGN_BOTTOM = 1 << 1,
|
||||
ALIGN_LEFT = 1 << 2,
|
||||
ALIGN_RIGHT = 1 << 3,
|
||||
ALIGN_HORIZONTAL_CENTER = 1 << 4,
|
||||
ALIGN_VERTICAL_CENTER = 1 << 5,
|
||||
ALIGN_CENTER = ALIGN_HORIZONTAL_CENTER | ALIGN_VERTICAL_CENTER,
|
||||
ALIGN_TOP_RIGHT = ALIGN_TOP | ALIGN_RIGHT,
|
||||
ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT,
|
||||
ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT,
|
||||
ALIGN_BOTTOM_LEFT = ALIGN_BOTTOM | ALIGN_LEFT
|
||||
};
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
Font(const std::string& name) :
|
||||
m_name(name),
|
||||
m_glyphHeight(10),
|
||||
m_topMargin(0) { }
|
||||
m_name(name) { }
|
||||
|
||||
/// Load font from file
|
||||
bool load(const std::string &file);
|
||||
@@ -61,28 +45,29 @@ public:
|
||||
/// Advanced text render
|
||||
void renderText(const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align = ALIGN_TOP_LEFT,
|
||||
AlignmentFlag align = AlignTopLeft,
|
||||
const Color& color = Color::white);
|
||||
|
||||
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
||||
const std::vector<Point>& calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL) const;
|
||||
const std::vector<Point>& calculateGlyphsPositions(const std::string& text, AlignmentFlag align = AlignTopLeft, Size *textBoxSize = NULL) const;
|
||||
|
||||
/// Simulate render and calculate text size
|
||||
Size calculateTextRectSize(const std::string& text);
|
||||
|
||||
const std::string& getName() const { return m_name; }
|
||||
std::string getName() const { return m_name; }
|
||||
int getGlyphHeight() const { return m_glyphHeight; }
|
||||
const Rect *getGlyphsTextureCoords() const { return m_glyphsTextureCoords; }
|
||||
const Size *getGlyphsSize() const { return m_glyphsSize; }
|
||||
const TexturePtr& getTexture() const { return m_texture; }
|
||||
int getTopMargin() const { return m_topMargin; }
|
||||
const Size& getGlyphSpacing() const { return m_glyphSpacing; }
|
||||
Size getGlyphSpacing() const { return m_glyphSpacing; }
|
||||
|
||||
private:
|
||||
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
|
||||
|
||||
std::string m_name;
|
||||
int m_glyphHeight;
|
||||
int m_firstGlyph;
|
||||
int m_topMargin;
|
||||
Size m_glyphSpacing;
|
||||
TexturePtr m_texture;
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
Fonts g_fonts;
|
||||
|
||||
void Fonts::init(const std::string& defaultFontName)
|
||||
void Fonts::init()
|
||||
{
|
||||
// load all fonts
|
||||
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
|
||||
@@ -37,27 +37,21 @@ void Fonts::init(const std::string& defaultFontName)
|
||||
std::string name = file;
|
||||
boost::erase_first(name, ".yml");
|
||||
FontPtr font(new Font(name));
|
||||
if(font->load("fonts/" + file)) {
|
||||
if(font->load("fonts/" + file))
|
||||
m_fonts.push_back(font);
|
||||
|
||||
if(name == defaultFontName)
|
||||
m_defaultFont = font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_defaultFont)
|
||||
flogFatal("FATAL ERROR: Could not load the default font \"%s\"\n", defaultFontName.c_str());
|
||||
}
|
||||
|
||||
Font* Fonts::get(const std::string& fontName)
|
||||
FontPtr Fonts::get(const std::string& fontName)
|
||||
{
|
||||
// find font by name
|
||||
for(auto it = m_fonts.begin(); it != m_fonts.end(); ++it) {
|
||||
if((*it)->getName() == fontName)
|
||||
return (*it).get();
|
||||
foreach(const FontPtr& font, m_fonts) {
|
||||
if(font->getName() == fontName)
|
||||
return font;
|
||||
}
|
||||
|
||||
flogError("ERROR: Font \"%s\" not found, returing the default one", fontName.c_str());
|
||||
return m_defaultFont.get();
|
||||
flogFatal("ERROR: Font \"%s\" not found", fontName.c_str());
|
||||
return FontPtr();
|
||||
}
|
||||
|
||||
|
@@ -34,20 +34,16 @@ public:
|
||||
Fonts() { }
|
||||
|
||||
/// Initialize all fonts
|
||||
void init(const std::string& defaultFontName);
|
||||
void init();
|
||||
|
||||
/// Terminate all fonts
|
||||
void terminate() { }
|
||||
|
||||
/// Get a font by name
|
||||
Font *get(const std::string& fontName);
|
||||
|
||||
/// Get the default font
|
||||
Font *getDefaultFont() { return m_defaultFont.get(); };
|
||||
FontPtr get(const std::string& fontName);
|
||||
|
||||
private:
|
||||
std::vector<FontPtr> m_fonts;
|
||||
FontPtr m_defaultFont;
|
||||
};
|
||||
|
||||
extern Fonts g_fonts;
|
||||
|
@@ -40,6 +40,7 @@ void Graphics::init()
|
||||
glEnable(GL_TEXTURE_2D); // enable textures by default
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
@@ -266,7 +267,7 @@ void Graphics::bindColor(const Color& color)
|
||||
void Graphics::bindTexture(const TexturePtr& texture, const Color& color)
|
||||
{
|
||||
// switch drawing to textured quads
|
||||
if(m_drawMode != DRAW_TEXTURE_QUADS || m_bindedTexture != texture) {
|
||||
if(m_drawMode != DRAW_TEXTURE_QUADS || m_bindedTexture != texture || m_bindedColor != color) {
|
||||
if(m_drawMode != DRAW_NONE)
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
class Graphics
|
||||
{
|
||||
enum EDrawMode {
|
||||
enum DrawMode {
|
||||
DRAW_NONE = 0,
|
||||
DRAW_QUADS = 1,
|
||||
DRAW_TEXTURE = 2,
|
||||
@@ -80,8 +80,7 @@ private:
|
||||
TexturePtr m_bindedTexture;
|
||||
Color m_bindedColor;
|
||||
Size m_screenSize;
|
||||
EDrawMode m_drawMode;
|
||||
EDrawMode m_lastDrawMode;
|
||||
DrawMode m_drawMode;
|
||||
};
|
||||
|
||||
extern Graphics g_graphics;
|
||||
|
@@ -28,8 +28,7 @@
|
||||
#include <graphics/graphics.h>
|
||||
|
||||
TextArea::TextArea() :
|
||||
m_font(0),
|
||||
m_align(ALIGN_TOP_LEFT),
|
||||
m_align(AlignLeftCenter),
|
||||
m_color(Color::white),
|
||||
m_cursorPos(-1),
|
||||
m_startRenderPos(0),
|
||||
@@ -37,10 +36,10 @@ TextArea::TextArea() :
|
||||
{
|
||||
}
|
||||
|
||||
TextArea::TextArea(Font* font,
|
||||
TextArea::TextArea(FontPtr font,
|
||||
const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align,
|
||||
AlignmentFlag align,
|
||||
const Color& color) :
|
||||
m_font(font),
|
||||
m_text(text),
|
||||
@@ -165,19 +164,19 @@ void TextArea::recalculate()
|
||||
Rect glyphTextureCoords = glyphsTextureCoords[glyph];
|
||||
|
||||
// first translate to align position
|
||||
if(m_align & ALIGN_BOTTOM) {
|
||||
if(m_align & AlignBottom) {
|
||||
glyphScreenCoords.translate(0, m_screenCoords.height() - textBoxSize.height());
|
||||
} else if(m_align & ALIGN_VERTICAL_CENTER) {
|
||||
} else if(m_align & AlignVerticalCenter) {
|
||||
glyphScreenCoords.translate(0, (m_screenCoords.height() - textBoxSize.height()) / 2);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignTop
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
if(m_align & ALIGN_RIGHT) {
|
||||
if(m_align & AlignRight) {
|
||||
glyphScreenCoords.translate(m_screenCoords.width() - textBoxSize.width(), 0);
|
||||
} else if(m_align & ALIGN_HORIZONTAL_CENTER) {
|
||||
} else if(m_align & AlignHorizontalCenter) {
|
||||
glyphScreenCoords.translate((m_screenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignLeft
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@@ -221,7 +220,7 @@ void TextArea::recalculate()
|
||||
}
|
||||
}
|
||||
|
||||
void TextArea::setFont(Font* font)
|
||||
void TextArea::setFont(FontPtr font)
|
||||
{
|
||||
if(m_font != font) {
|
||||
m_font = font;
|
||||
@@ -249,7 +248,7 @@ void TextArea::setScreenCoords(const Rect& screenCoords)
|
||||
}
|
||||
}
|
||||
|
||||
void TextArea::setAlign(int align)
|
||||
void TextArea::setAlign(AlignmentFlag align)
|
||||
{
|
||||
if(m_align != align) {
|
||||
m_align = align;
|
||||
|
@@ -32,18 +32,18 @@ class TextArea
|
||||
{
|
||||
public:
|
||||
TextArea();
|
||||
TextArea(Font *font,
|
||||
TextArea(FontPtr font,
|
||||
const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align = ALIGN_TOP_LEFT,
|
||||
AlignmentFlag align = AlignTopLeft,
|
||||
const Color& color = Color::white);
|
||||
|
||||
void draw();
|
||||
|
||||
void setFont(Font *font);
|
||||
void setFont(FontPtr font);
|
||||
void setText(const std::string& text);
|
||||
void setScreenCoords(const Rect& screenCoords);
|
||||
void setAlign(int align);
|
||||
void setAlign(AlignmentFlag align);
|
||||
void setColor(const Color& color) { m_color = color; }
|
||||
void setCursorPos(int pos);
|
||||
void enableCursor(bool enable = true);
|
||||
@@ -55,17 +55,17 @@ public:
|
||||
|
||||
std::string getText() const { return m_text; }
|
||||
|
||||
Font *getFont() const { return m_font; }
|
||||
FontPtr getFont() const { return m_font; }
|
||||
int getTextPos(Point pos);
|
||||
|
||||
private:
|
||||
void recalculate();
|
||||
|
||||
Font *m_font;
|
||||
FontPtr m_font;
|
||||
std::string m_text;
|
||||
Rect m_screenCoords;
|
||||
Rect m_drawArea;
|
||||
int m_align;
|
||||
AlignmentFlag m_align;
|
||||
Color m_color;
|
||||
int m_cursorPos;
|
||||
Point m_startInternalPos;
|
||||
|
Reference in New Issue
Block a user