Merged in nimetu/ryzomcore (pull request #126)
add bold, italic, underline, strikethrough font styles --HG-- branch : develop
This commit is contained in:
commit
f36e06dfb9
18 changed files with 464 additions and 21 deletions
|
@ -54,11 +54,13 @@ public:
|
||||||
/** generate and return a bitmap
|
/** generate and return a bitmap
|
||||||
* \param c the unicode char
|
* \param c the unicode char
|
||||||
* \param size size of the generated font in ??? format
|
* \param size size of the generated font in ??? format
|
||||||
|
* \param embolden set embolden style (bold)
|
||||||
|
* \param oblique set oblique style (slanted, italic)
|
||||||
* \param width width of the generated bitmap, this value is set by this function
|
* \param width width of the generated bitmap, this value is set by this function
|
||||||
* \param height height of the generated bitmap, this value is set by this function
|
* \param height height of the generated bitmap, this value is set by this function
|
||||||
* \param pitch pitch of the generated bitmap (+ or - the number of bytes per row), this value is set by this function
|
* \param pitch pitch of the generated bitmap (+ or - the number of bytes per row), this value is set by this function
|
||||||
*/
|
*/
|
||||||
uint8 *getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex);
|
uint8 *getBitmap (ucchar c, uint32 size, bool embolden, bool oblique, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex);
|
||||||
|
|
||||||
/** returns the width and height of a character using a specific size and
|
/** returns the width and height of a character using a specific size and
|
||||||
*
|
*
|
||||||
|
|
|
@ -102,6 +102,8 @@ public:
|
||||||
* \param fontGen font generator
|
* \param fontGen font generator
|
||||||
* \param color primitive blocks color
|
* \param color primitive blocks color
|
||||||
* \param fontSize font size
|
* \param fontSize font size
|
||||||
|
* \param embolden font style bold
|
||||||
|
* \param oblique font style slanted (italic)
|
||||||
* \param desc display descriptor (screen size, font ratio)
|
* \param desc display descriptor (screen size, font ratio)
|
||||||
* \param output computed string
|
* \param output computed string
|
||||||
* \param keep800x600Ratio true if you want that CFontManager look at Driver window size, and resize fontSize so it keeps same size...
|
* \param keep800x600Ratio true if you want that CFontManager look at Driver window size, and resize fontSize so it keeps same size...
|
||||||
|
@ -110,6 +112,8 @@ public:
|
||||||
CFontGenerator *fontGen,
|
CFontGenerator *fontGen,
|
||||||
const NLMISC::CRGBA &color,
|
const NLMISC::CRGBA &color,
|
||||||
uint32 fontSize,
|
uint32 fontSize,
|
||||||
|
bool embolden,
|
||||||
|
bool oblique,
|
||||||
IDriver *driver,
|
IDriver *driver,
|
||||||
CComputedString& output,
|
CComputedString& output,
|
||||||
bool keep800x600Ratio= true);
|
bool keep800x600Ratio= true);
|
||||||
|
@ -121,6 +125,8 @@ public:
|
||||||
CFontGenerator *fontGen,
|
CFontGenerator *fontGen,
|
||||||
const NLMISC::CRGBA &color,
|
const NLMISC::CRGBA &color,
|
||||||
uint32 fontSize,
|
uint32 fontSize,
|
||||||
|
bool embolden,
|
||||||
|
bool oblique,
|
||||||
IDriver *driver,
|
IDriver *driver,
|
||||||
CComputedString &output,
|
CComputedString &output,
|
||||||
bool keep800x600Ratio= true);
|
bool keep800x600Ratio= true);
|
||||||
|
@ -132,6 +138,8 @@ public:
|
||||||
CFontGenerator *fontGen,
|
CFontGenerator *fontGen,
|
||||||
const NLMISC::CRGBA &color,
|
const NLMISC::CRGBA &color,
|
||||||
uint32 fontSize,
|
uint32 fontSize,
|
||||||
|
bool embolden,
|
||||||
|
bool oblique,
|
||||||
IDriver *driver,
|
IDriver *driver,
|
||||||
CComputedString &output,
|
CComputedString &output,
|
||||||
bool keep800x600Ratio= true);
|
bool keep800x600Ratio= true);
|
||||||
|
|
|
@ -74,6 +74,10 @@ public:
|
||||||
|
|
||||||
void setFontSize (uint32 fontSize) { _FontSize = fontSize; }
|
void setFontSize (uint32 fontSize) { _FontSize = fontSize; }
|
||||||
|
|
||||||
|
void setEmbolden (bool b) { _Embolden = b; }
|
||||||
|
|
||||||
|
void setOblique (bool b) { _Oblique = b; }
|
||||||
|
|
||||||
void setHotSpot (CComputedString::THotSpot hotSpot) { _HotSpot = hotSpot; }
|
void setHotSpot (CComputedString::THotSpot hotSpot) { _HotSpot = hotSpot; }
|
||||||
|
|
||||||
void setScaleX (float scaleX) { _ScaleX = scaleX; }
|
void setScaleX (float scaleX) { _ScaleX = scaleX; }
|
||||||
|
@ -101,6 +105,10 @@ public:
|
||||||
|
|
||||||
uint32 getFontSize () const { return _FontSize; }
|
uint32 getFontSize () const { return _FontSize; }
|
||||||
|
|
||||||
|
bool getEmbolden () const { return _Embolden; }
|
||||||
|
|
||||||
|
bool getOblique () const { return _Oblique; }
|
||||||
|
|
||||||
CComputedString::THotSpot getHotSpot() const { return _HotSpot; }
|
CComputedString::THotSpot getHotSpot() const { return _HotSpot; }
|
||||||
|
|
||||||
float getScaleX() const { return _ScaleX; }
|
float getScaleX() const { return _ScaleX; }
|
||||||
|
@ -240,7 +248,7 @@ public:
|
||||||
nlassert(_FontGen);
|
nlassert(_FontGen);
|
||||||
|
|
||||||
// compute the string just one time
|
// compute the string just one time
|
||||||
_FontManager->computeString (ucstr, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio);
|
_FontManager->computeString (ucstr, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, _TempString, _Keep800x600Ratio);
|
||||||
|
|
||||||
// draw shaded
|
// draw shaded
|
||||||
if (_Shaded)
|
if (_Shaded)
|
||||||
|
@ -279,7 +287,7 @@ public:
|
||||||
// compute the string just one time
|
// compute the string just one time
|
||||||
char *str;
|
char *str;
|
||||||
NLMISC_CONVERT_VARGS (str, format, NLMISC::MaxCStringSize);
|
NLMISC_CONVERT_VARGS (str, format, NLMISC::MaxCStringSize);
|
||||||
_FontManager->computeString (str, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio);
|
_FontManager->computeString (str, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, _TempString, _Keep800x600Ratio);
|
||||||
|
|
||||||
// draw shaded
|
// draw shaded
|
||||||
if (_Shaded)
|
if (_Shaded)
|
||||||
|
@ -334,7 +342,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void computeString (const std::string& s, CComputedString& output)
|
void computeString (const std::string& s, CComputedString& output)
|
||||||
{
|
{
|
||||||
_FontManager->computeString (s, _FontGen, _Color, _FontSize, _Driver, output, _Keep800x600Ratio);
|
_FontManager->computeString (s, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, output, _Keep800x600Ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -345,12 +353,12 @@ public:
|
||||||
*/
|
*/
|
||||||
void computeString (const ucstring& s, CComputedString& output)
|
void computeString (const ucstring& s, CComputedString& output)
|
||||||
{
|
{
|
||||||
_FontManager->computeString (s, _FontGen, _Color, _FontSize, _Driver, output, _Keep800x600Ratio);
|
_FontManager->computeString (s, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, output, _Keep800x600Ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeStringInfo (const ucstring& s, CComputedString& output)
|
void computeStringInfo (const ucstring& s, CComputedString& output)
|
||||||
{
|
{
|
||||||
_FontManager->computeStringInfo (s, _FontGen, _Color, _FontSize, _Driver, output, _Keep800x600Ratio);
|
_FontManager->computeStringInfo (s, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, output, _Keep800x600Ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Debug : write to the disk the texture cache
|
/// Debug : write to the disk the texture cache
|
||||||
|
@ -381,6 +389,10 @@ private:
|
||||||
/// Font size;
|
/// Font size;
|
||||||
uint32 _FontSize;
|
uint32 _FontSize;
|
||||||
|
|
||||||
|
bool _Embolden;
|
||||||
|
|
||||||
|
bool _Oblique;
|
||||||
|
|
||||||
/// Current text color
|
/// Current text color
|
||||||
NLMISC::CRGBA _Color;
|
NLMISC::CRGBA _Color;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,10 @@ public:
|
||||||
void setColor(NLMISC::CRGBA color);
|
void setColor(NLMISC::CRGBA color);
|
||||||
void setFontSize(uint32 fontSize);
|
void setFontSize(uint32 fontSize);
|
||||||
uint32 getFontSize() const;
|
uint32 getFontSize() const;
|
||||||
|
void setEmbolden(bool b);
|
||||||
|
bool getEmbolden() const;
|
||||||
|
void setOblique(bool b);
|
||||||
|
bool getOblique() const;
|
||||||
void setHotSpot(THotSpot hotSpot);
|
void setHotSpot(THotSpot hotSpot);
|
||||||
THotSpot getHotSpot() const;
|
THotSpot getHotSpot() const;
|
||||||
void setScaleX(float scaleX);
|
void setScaleX(float scaleX);
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
ucchar Char;
|
ucchar Char;
|
||||||
CFontGenerator *FontGenerator;
|
CFontGenerator *FontGenerator;
|
||||||
sint Size;
|
sint Size;
|
||||||
|
bool Embolden;
|
||||||
|
bool Oblique;
|
||||||
|
|
||||||
|
|
||||||
// The less recently used infos
|
// The less recently used infos
|
||||||
|
@ -66,6 +68,8 @@ public:
|
||||||
ucchar Char;
|
ucchar Char;
|
||||||
CFontGenerator *FontGenerator;
|
CFontGenerator *FontGenerator;
|
||||||
sint Size;
|
sint Size;
|
||||||
|
bool Embolden;
|
||||||
|
bool Oblique;
|
||||||
|
|
||||||
uint32 getVal();
|
uint32 getVal();
|
||||||
//bool operator < (const SLetterKey&k) const;
|
//bool operator < (const SLetterKey&k) const;
|
||||||
|
|
|
@ -137,6 +137,24 @@ public:
|
||||||
* \return the font size
|
* \return the font size
|
||||||
*/
|
*/
|
||||||
virtual uint32 getFontSize () const = 0;
|
virtual uint32 getFontSize () const = 0;
|
||||||
|
/**
|
||||||
|
* set embolden (bold) state
|
||||||
|
* \param embolden the embbolden state
|
||||||
|
*/
|
||||||
|
virtual void setEmbolden (bool b) = 0;
|
||||||
|
/**
|
||||||
|
* \return the embolden state
|
||||||
|
*/
|
||||||
|
virtual bool getEmbolden () const = 0;
|
||||||
|
/**
|
||||||
|
* set oblique (italic) state
|
||||||
|
* \param oblique the oblique state
|
||||||
|
*/
|
||||||
|
virtual void setOblique (bool b) = 0;
|
||||||
|
/**
|
||||||
|
* \return the oblique state
|
||||||
|
*/
|
||||||
|
virtual bool getOblique () const = 0;
|
||||||
/**
|
/**
|
||||||
* set the hot spot
|
* set the hot spot
|
||||||
* \param fonSize the font size
|
* \param fonSize the font size
|
||||||
|
|
|
@ -425,6 +425,38 @@ namespace NLGUI
|
||||||
return _FontSize.back();
|
return _FontSize.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint> _FontWeight;
|
||||||
|
inline uint getFontWeight() const
|
||||||
|
{
|
||||||
|
if (_FontWeight.empty())
|
||||||
|
return 400;
|
||||||
|
return _FontWeight.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bool> _FontOblique;
|
||||||
|
inline uint getFontOblique() const
|
||||||
|
{
|
||||||
|
if (_FontOblique.empty())
|
||||||
|
return false;
|
||||||
|
return _FontOblique.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bool> _FontUnderlined;
|
||||||
|
inline uint getFontUnderlined() const
|
||||||
|
{
|
||||||
|
if (_FontUnderlined.empty())
|
||||||
|
return false;
|
||||||
|
return _FontUnderlined.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bool> _FontStrikeThrough;
|
||||||
|
inline uint getFontStrikeThrough() const
|
||||||
|
{
|
||||||
|
if (_FontStrikeThrough.empty())
|
||||||
|
return false;
|
||||||
|
return _FontStrikeThrough.back();
|
||||||
|
}
|
||||||
|
|
||||||
// Current link
|
// Current link
|
||||||
std::vector<std::string> _Link;
|
std::vector<std::string> _Link;
|
||||||
inline const char *getLink() const
|
inline const char *getLink() const
|
||||||
|
@ -544,6 +576,26 @@ namespace NLGUI
|
||||||
};
|
};
|
||||||
std::vector<CCellParams> _CellParams;
|
std::vector<CCellParams> _CellParams;
|
||||||
|
|
||||||
|
class CStyleParams
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CStyleParams () : TextColor(255,255,255,255)
|
||||||
|
{
|
||||||
|
FontSize=10;
|
||||||
|
FontWeight=400;
|
||||||
|
FontOblique=false;
|
||||||
|
Underlined=false;
|
||||||
|
StrikeThrough=false;
|
||||||
|
}
|
||||||
|
uint FontSize;
|
||||||
|
uint FontWeight;
|
||||||
|
bool FontOblique;
|
||||||
|
NLMISC::CRGBA TextColor;
|
||||||
|
bool Underlined;
|
||||||
|
bool StrikeThrough;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Indentation
|
// Indentation
|
||||||
uint _Indent;
|
uint _Indent;
|
||||||
|
|
||||||
|
@ -613,8 +665,10 @@ namespace NLGUI
|
||||||
typedef std::map<uint32, NLMISC::CRefPtr<CGroupHTML> > TGroupHtmlByUIDMap;
|
typedef std::map<uint32, NLMISC::CRefPtr<CGroupHTML> > TGroupHtmlByUIDMap;
|
||||||
static TGroupHtmlByUIDMap _GroupHtmlByUID;
|
static TGroupHtmlByUIDMap _GroupHtmlByUID;
|
||||||
|
|
||||||
private:
|
// read style attribute
|
||||||
|
void getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit = true);
|
||||||
|
|
||||||
|
private:
|
||||||
// decode all HTML entities
|
// decode all HTML entities
|
||||||
static ucstring decodeHTMLEntities(const ucstring &str);
|
static ucstring decodeHTMLEntities(const ucstring &str);
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,13 @@ namespace NLGUI
|
||||||
HTML_ATTR(DIV,STYLE),
|
HTML_ATTR(DIV,STYLE),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HTML_ATTR(SPAN,CLASS) = 0,
|
||||||
|
HTML_ATTR(SPAN,ID),
|
||||||
|
HTML_ATTR(SPAN,STYLE),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#undef HTML_ATTR
|
#undef HTML_ATTR
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,8 @@ namespace NLGUI
|
||||||
|
|
||||||
void setText (const ucstring &text);
|
void setText (const ucstring &text);
|
||||||
void setFontSize (sint nFontSize);
|
void setFontSize (sint nFontSize);
|
||||||
|
void setEmbolden (bool nEmbolden);
|
||||||
|
void setOblique (bool nOblique);
|
||||||
void setColor (const NLMISC::CRGBA &color);
|
void setColor (const NLMISC::CRGBA &color);
|
||||||
void setShadow (bool bShadow);
|
void setShadow (bool bShadow);
|
||||||
void setShadowOutline (bool bShadowOutline);
|
void setShadowOutline (bool bShadowOutline);
|
||||||
|
@ -101,6 +103,8 @@ namespace NLGUI
|
||||||
|
|
||||||
ucstring getText() const { return _Text; }
|
ucstring getText() const { return _Text; }
|
||||||
sint getFontSize() const;
|
sint getFontSize() const;
|
||||||
|
bool getEmbolden() { return _Embolden; }
|
||||||
|
bool getOblique() { return _Oblique; }
|
||||||
NLMISC::CRGBA getColor() { return _Color; }
|
NLMISC::CRGBA getColor() { return _Color; }
|
||||||
bool getShadow() { return _Shadow; }
|
bool getShadow() { return _Shadow; }
|
||||||
bool getShadowOutline() { return _ShadowOutline; }
|
bool getShadowOutline() { return _ShadowOutline; }
|
||||||
|
@ -125,6 +129,8 @@ namespace NLGUI
|
||||||
uint getLastLineW () const;
|
uint getLastLineW () const;
|
||||||
void setUnderlined (bool underlined) { _Underlined = underlined; }
|
void setUnderlined (bool underlined) { _Underlined = underlined; }
|
||||||
bool getUnderlined () const { return _Underlined; }
|
bool getUnderlined () const { return _Underlined; }
|
||||||
|
void setStrikeThrough (bool linethrough) { _StrikeThrough = linethrough; }
|
||||||
|
bool getStrikeThrough () const { return _StrikeThrough; }
|
||||||
// true if the viewText is a single line clamped.
|
// true if the viewText is a single line clamped.
|
||||||
bool isSingleLineTextClamped() const {return _SingleLineTextClamped;}
|
bool isSingleLineTextClamped() const {return _SingleLineTextClamped;}
|
||||||
|
|
||||||
|
@ -220,6 +226,8 @@ namespace NLGUI
|
||||||
NL3D::UTextContext::CStringInfo _Info;
|
NL3D::UTextContext::CStringInfo _Info;
|
||||||
/// the font size
|
/// the font size
|
||||||
sint _FontSize;
|
sint _FontSize;
|
||||||
|
bool _Embolden;
|
||||||
|
bool _Oblique;
|
||||||
// width of the font in pixel. Just a Hint for tabing format (computed with '_')
|
// width of the font in pixel. Just a Hint for tabing format (computed with '_')
|
||||||
uint _FontWidth;
|
uint _FontWidth;
|
||||||
// height of the font in pixel.
|
// height of the font in pixel.
|
||||||
|
@ -374,6 +382,7 @@ namespace NLGUI
|
||||||
bool _TextSelection : 1;
|
bool _TextSelection : 1;
|
||||||
bool _InvalidTextContext : 1;
|
bool _InvalidTextContext : 1;
|
||||||
bool _Underlined : 1;
|
bool _Underlined : 1;
|
||||||
|
bool _StrikeThrough : 1;
|
||||||
bool _ContinuousUpdate : 1;
|
bool _ContinuousUpdate : 1;
|
||||||
bool _Setuped : 1;
|
bool _Setuped : 1;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ using namespace std;
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_SYNTHESIS_H
|
||||||
|
|
||||||
// for freetype 2.0
|
// for freetype 2.0
|
||||||
#ifdef FTERRORS_H
|
#ifdef FTERRORS_H
|
||||||
|
@ -171,7 +172,7 @@ void CFontGenerator::getSizes (ucchar c, uint32 size, uint32 &width, uint32 &hei
|
||||||
height = _Face->glyph->metrics.height >> 6;
|
height = _Face->glyph->metrics.height >> 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex)
|
uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, bool embolden, bool oblique, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex)
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
|
@ -209,6 +210,16 @@ uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (embolden)
|
||||||
|
{
|
||||||
|
FT_GlyphSlot_Embolden(_Face->glyph);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oblique)
|
||||||
|
{
|
||||||
|
FT_GlyphSlot_Oblique(_Face->glyph);
|
||||||
|
}
|
||||||
|
|
||||||
// convert to an anti-aliased bitmap
|
// convert to an anti-aliased bitmap
|
||||||
error = FT_Render_Glyph (_Face->glyph, ft_render_mode_normal);
|
error = FT_Render_Glyph (_Face->glyph, ft_render_mode_normal);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -389,7 +400,7 @@ void CFontGenerator::getSizes (ucchar c, uint32 size, uint32 &width, uint32 &hei
|
||||||
HFONT hFont = NULL;
|
HFONT hFont = NULL;
|
||||||
uint32 CurrentFontSize = 0;
|
uint32 CurrentFontSize = 0;
|
||||||
|
|
||||||
uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex)
|
uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, bool embolden, bool oblique, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex)
|
||||||
{
|
{
|
||||||
/* FT_Error error;
|
/* FT_Error error;
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ void CFontManager::computeString (const std::string &s,
|
||||||
CFontGenerator *fontGen,
|
CFontGenerator *fontGen,
|
||||||
const NLMISC::CRGBA &color,
|
const NLMISC::CRGBA &color,
|
||||||
uint32 fontSize,
|
uint32 fontSize,
|
||||||
|
bool embolden,
|
||||||
|
bool oblique,
|
||||||
IDriver *driver,
|
IDriver *driver,
|
||||||
CComputedString &output,
|
CComputedString &output,
|
||||||
bool keep800x600Ratio)
|
bool keep800x600Ratio)
|
||||||
|
@ -71,7 +73,7 @@ void CFontManager::computeString (const std::string &s,
|
||||||
// static to avoid reallocation
|
// static to avoid reallocation
|
||||||
static ucstring ucs;
|
static ucstring ucs;
|
||||||
ucs= s;
|
ucs= s;
|
||||||
computeString(ucs, fontGen, color, fontSize, driver, output, keep800x600Ratio);
|
computeString(ucs, fontGen, color, fontSize, embolden, oblique, driver, output, keep800x600Ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,6 +82,8 @@ void CFontManager::computeString (const ucstring &s,
|
||||||
CFontGenerator *fontGen,
|
CFontGenerator *fontGen,
|
||||||
const NLMISC::CRGBA &color,
|
const NLMISC::CRGBA &color,
|
||||||
uint32 fontSize,
|
uint32 fontSize,
|
||||||
|
bool embolden,
|
||||||
|
bool oblique,
|
||||||
IDriver *driver,
|
IDriver *driver,
|
||||||
CComputedString &output,
|
CComputedString &output,
|
||||||
bool keep800x600Ratio)
|
bool keep800x600Ratio)
|
||||||
|
@ -147,6 +151,8 @@ void CFontManager::computeString (const ucstring &s,
|
||||||
k.Char = s[i];
|
k.Char = s[i];
|
||||||
k.FontGenerator = fontGen;
|
k.FontGenerator = fontGen;
|
||||||
k.Size = fontSize;
|
k.Size = fontSize;
|
||||||
|
k.Embolden = embolden;
|
||||||
|
k.Oblique = oblique;
|
||||||
CTextureFont::SLetterInfo *pLI = pTexFont->getLetterInfo (k);
|
CTextureFont::SLetterInfo *pLI = pTexFont->getLetterInfo (k);
|
||||||
if(pLI != NULL)
|
if(pLI != NULL)
|
||||||
{
|
{
|
||||||
|
@ -227,6 +233,8 @@ void CFontManager::computeStringInfo ( const ucstring &s,
|
||||||
CFontGenerator *fontGen,
|
CFontGenerator *fontGen,
|
||||||
const NLMISC::CRGBA &color,
|
const NLMISC::CRGBA &color,
|
||||||
uint32 fontSize,
|
uint32 fontSize,
|
||||||
|
bool embolden,
|
||||||
|
bool oblique,
|
||||||
IDriver *driver,
|
IDriver *driver,
|
||||||
CComputedString &output,
|
CComputedString &output,
|
||||||
bool keep800x600Ratio )
|
bool keep800x600Ratio )
|
||||||
|
@ -259,6 +267,8 @@ void CFontManager::computeStringInfo ( const ucstring &s,
|
||||||
k.Char = s[i];
|
k.Char = s[i];
|
||||||
k.FontGenerator = fontGen;
|
k.FontGenerator = fontGen;
|
||||||
k.Size = fontSize;
|
k.Size = fontSize;
|
||||||
|
k.Embolden = embolden;
|
||||||
|
k.Oblique = oblique;
|
||||||
pLI = pTexFont->getLetterInfo (k);
|
pLI = pTexFont->getLetterInfo (k);
|
||||||
if(pLI != NULL)
|
if(pLI != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -277,6 +277,8 @@ void CPSUtil::print(IDriver *driver, const std::string &text, CFontGenerator &fg
|
||||||
&fg,
|
&fg,
|
||||||
col,
|
col,
|
||||||
16,
|
16,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
driver,
|
driver,
|
||||||
cptedString);
|
cptedString);
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ CTextContext::CTextContext()
|
||||||
_FontGen = NULL;
|
_FontGen = NULL;
|
||||||
|
|
||||||
_FontSize = 12;
|
_FontSize = 12;
|
||||||
|
_Embolden = false;
|
||||||
|
_Oblique = false;
|
||||||
|
|
||||||
_Color = NLMISC::CRGBA(0,0,0);
|
_Color = NLMISC::CRGBA(0,0,0);
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ uint32 CTextContext::textPush (const char *format, ...)
|
||||||
// compute the string.
|
// compute the string.
|
||||||
uint32 index = _CacheFreePlaces[_CacheNbFreePlaces-1];
|
uint32 index = _CacheFreePlaces[_CacheNbFreePlaces-1];
|
||||||
CComputedString &strToFill = _CacheStrings[index];
|
CComputedString &strToFill = _CacheStrings[index];
|
||||||
_FontManager->computeString (str, _FontGen, _Color, _FontSize, _Driver, strToFill, _Keep800x600Ratio);
|
_FontManager->computeString (str, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, strToFill, _Keep800x600Ratio);
|
||||||
|
|
||||||
_CacheNbFreePlaces--;
|
_CacheNbFreePlaces--;
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ uint32 CTextContext::textPush (const ucstring &str)
|
||||||
nlassert (index < _CacheStrings.size());
|
nlassert (index < _CacheStrings.size());
|
||||||
CComputedString &strToFill = _CacheStrings[index];
|
CComputedString &strToFill = _CacheStrings[index];
|
||||||
_FontManager->computeString (str, _FontGen, _Color
|
_FontManager->computeString (str, _FontGen, _Color
|
||||||
, _FontSize, _Driver, strToFill, _Keep800x600Ratio);
|
, _FontSize, _Embolden, _Oblique, _Driver, strToFill, _Keep800x600Ratio);
|
||||||
|
|
||||||
_CacheNbFreePlaces--;
|
_CacheNbFreePlaces--;
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,30 @@ uint32 CTextContextUser::getFontSize() const
|
||||||
|
|
||||||
return _TextContext.getFontSize();
|
return _TextContext.getFontSize();
|
||||||
}
|
}
|
||||||
|
void CTextContextUser::setEmbolden(bool b)
|
||||||
|
{
|
||||||
|
H_AUTO2;
|
||||||
|
|
||||||
|
_TextContext.setEmbolden(b);
|
||||||
|
}
|
||||||
|
bool CTextContextUser::getEmbolden() const
|
||||||
|
{
|
||||||
|
H_AUTO2;
|
||||||
|
|
||||||
|
return _TextContext.getEmbolden();
|
||||||
|
}
|
||||||
|
void CTextContextUser::setOblique(bool b)
|
||||||
|
{
|
||||||
|
H_AUTO2;
|
||||||
|
|
||||||
|
_TextContext.setOblique(b);
|
||||||
|
}
|
||||||
|
bool CTextContextUser::getOblique() const
|
||||||
|
{
|
||||||
|
H_AUTO2;
|
||||||
|
|
||||||
|
return _TextContext.getOblique();
|
||||||
|
}
|
||||||
void CTextContextUser::setHotSpot(THotSpot hotSpot)
|
void CTextContextUser::setHotSpot(THotSpot hotSpot)
|
||||||
{
|
{
|
||||||
H_AUTO2;
|
H_AUTO2;
|
||||||
|
|
|
@ -47,11 +47,14 @@ const int NbLine[TEXTUREFONT_NBCATEGORY] = { 4, 6, 4, 1 }; // Based on textsize
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
inline uint32 CTextureFont::SLetterKey::getVal()
|
inline uint32 CTextureFont::SLetterKey::getVal()
|
||||||
{
|
{
|
||||||
|
// this limits Size to 6bits
|
||||||
|
// Large sizes already render wrong when many
|
||||||
|
// different glyphs are used due to limited texture atlas
|
||||||
|
uint8 eb = ((uint)Embolden) + ((uint)Oblique << 1);
|
||||||
if (FontGenerator == NULL)
|
if (FontGenerator == NULL)
|
||||||
return Char + ((Size&255)<<16);
|
return Char + ((Size&255)<<16) + (eb << 22);
|
||||||
else
|
else
|
||||||
return Char + ((Size&255)<<16) + ((FontGenerator->getUID()&0xFF)<<24);
|
return Char + ((Size&255)<<16) + (eb << 22) + ((FontGenerator->getUID()&0xFF)<<24);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -86,6 +89,8 @@ CTextureFont::CTextureFont()
|
||||||
rLetter.Char = 0xffff;
|
rLetter.Char = 0xffff;
|
||||||
rLetter.FontGenerator = NULL;
|
rLetter.FontGenerator = NULL;
|
||||||
rLetter.Size= 0;
|
rLetter.Size= 0;
|
||||||
|
rLetter.Embolden = false;
|
||||||
|
rLetter.Oblique = false;
|
||||||
|
|
||||||
// The less recently used infos
|
// The less recently used infos
|
||||||
if (j < Letters[i].size()-1)
|
if (j < Letters[i].size()-1)
|
||||||
|
@ -164,7 +169,7 @@ void CTextureFont::rebuildLetter (sint cat, sint x, sint y)
|
||||||
sint posy = catTopY + y * Categories[cat];
|
sint posy = catTopY + y * Categories[cat];
|
||||||
|
|
||||||
uint32 pitch = 0;
|
uint32 pitch = 0;
|
||||||
uint8 *bitmap = rLetter.FontGenerator->getBitmap ( rLetter.Char, rLetter.Size,
|
uint8 *bitmap = rLetter.FontGenerator->getBitmap ( rLetter.Char, rLetter.Size, rLetter.Embolden, rLetter.Oblique,
|
||||||
rLetter.CharWidth, rLetter.CharHeight,
|
rLetter.CharWidth, rLetter.CharHeight,
|
||||||
pitch, rLetter.Left, rLetter.Top,
|
pitch, rLetter.Left, rLetter.Top,
|
||||||
rLetter.AdvX, rLetter.GlyphIndex );
|
rLetter.AdvX, rLetter.GlyphIndex );
|
||||||
|
@ -303,7 +308,7 @@ CTextureFont::SLetterInfo* CTextureFont::getLetterInfo (SLetterKey& k)
|
||||||
// \todo mat : Temp !!! Try to use freetype cache
|
// \todo mat : Temp !!! Try to use freetype cache
|
||||||
uint32 nPitch, nGlyphIndex;
|
uint32 nPitch, nGlyphIndex;
|
||||||
sint32 nLeft, nTop, nAdvX;
|
sint32 nLeft, nTop, nAdvX;
|
||||||
k.FontGenerator->getBitmap (k.Char, k.Size, width, height, nPitch, nLeft, nTop,
|
k.FontGenerator->getBitmap (k.Char, k.Size, k.Embolden, k.Oblique, width, height, nPitch, nLeft, nTop,
|
||||||
nAdvX, nGlyphIndex );
|
nAdvX, nGlyphIndex );
|
||||||
|
|
||||||
// Add 1 pixel space for black border to get correct category
|
// Add 1 pixel space for black border to get correct category
|
||||||
|
@ -323,6 +328,8 @@ CTextureFont::SLetterInfo* CTextureFont::getLetterInfo (SLetterKey& k)
|
||||||
k2.Char = Back[cat]->Char;
|
k2.Char = Back[cat]->Char;
|
||||||
k2.FontGenerator = Back[cat]->FontGenerator;
|
k2.FontGenerator = Back[cat]->FontGenerator;
|
||||||
k2.Size = Back[cat]->Size;
|
k2.Size = Back[cat]->Size;
|
||||||
|
k2.Embolden = Back[cat]->Embolden;
|
||||||
|
k2.Oblique = Back[cat]->Oblique;
|
||||||
|
|
||||||
itAccel = Accel.find (k2.getVal());
|
itAccel = Accel.find (k2.getVal());
|
||||||
if (itAccel != Accel.end())
|
if (itAccel != Accel.end())
|
||||||
|
@ -336,6 +343,8 @@ CTextureFont::SLetterInfo* CTextureFont::getLetterInfo (SLetterKey& k)
|
||||||
Back[cat]->Char = k.Char;
|
Back[cat]->Char = k.Char;
|
||||||
Back[cat]->FontGenerator = k.FontGenerator;
|
Back[cat]->FontGenerator = k.FontGenerator;
|
||||||
Back[cat]->Size = k.Size;
|
Back[cat]->Size = k.Size;
|
||||||
|
Back[cat]->Embolden = k.Embolden;
|
||||||
|
Back[cat]->Oblique = k.Oblique;
|
||||||
Back[cat]->CharWidth = width;
|
Back[cat]->CharWidth = width;
|
||||||
Back[cat]->CharHeight = height;
|
Back[cat]->CharHeight = height;
|
||||||
Back[cat]->Top = nTop;
|
Back[cat]->Top = nTop;
|
||||||
|
|
|
@ -485,7 +485,7 @@ namespace NLGUI
|
||||||
string fullstyle = style[1];
|
string fullstyle = style[1];
|
||||||
for (uint j=2; j < style.size(); j++)
|
for (uint j=2; j < style.size(); j++)
|
||||||
fullstyle += ":"+style[j];
|
fullstyle += ":"+style[j];
|
||||||
styles[trim(style[0])] = fullstyle;
|
styles[trim(style[0])] = trim(fullstyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,7 +894,20 @@ namespace NLGUI
|
||||||
switch(element_number)
|
switch(element_number)
|
||||||
{
|
{
|
||||||
case HTML_A:
|
case HTML_A:
|
||||||
_TextColor.push_back(LinkColor);
|
{
|
||||||
|
CStyleParams style;
|
||||||
|
style.FontSize = getFontSize();
|
||||||
|
style.TextColor = LinkColor;
|
||||||
|
style.Underlined = true;
|
||||||
|
style.StrikeThrough = getFontStrikeThrough();
|
||||||
|
|
||||||
|
if (present[HTML_A_STYLE] && value[HTML_A_STYLE])
|
||||||
|
getStyleParams(value[HTML_A_STYLE], style);
|
||||||
|
|
||||||
|
_FontSize.push_back(style.FontSize);
|
||||||
|
_TextColor.push_back(style.TextColor);
|
||||||
|
_FontUnderlined.push_back(style.Underlined);
|
||||||
|
_FontStrikeThrough.push_back(style.StrikeThrough);
|
||||||
_GlobalColor.push_back(LinkColorGlobalColor);
|
_GlobalColor.push_back(LinkColorGlobalColor);
|
||||||
_A.push_back(true);
|
_A.push_back(true);
|
||||||
|
|
||||||
|
@ -903,6 +916,7 @@ namespace NLGUI
|
||||||
if (present[MY_HTML_A_CLASS] && value[MY_HTML_A_CLASS])
|
if (present[MY_HTML_A_CLASS] && value[MY_HTML_A_CLASS])
|
||||||
_LinkClass.push_back(value[MY_HTML_A_CLASS]);
|
_LinkClass.push_back(value[MY_HTML_A_CLASS]);
|
||||||
|
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTML_DIV:
|
case HTML_DIV:
|
||||||
|
@ -1634,6 +1648,28 @@ namespace NLGUI
|
||||||
_Object = true;
|
_Object = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case HTML_SPAN:
|
||||||
|
{
|
||||||
|
CStyleParams style;
|
||||||
|
style.TextColor = getTextColor();
|
||||||
|
style.FontSize = getFontSize();
|
||||||
|
style.FontWeight = getFontWeight();
|
||||||
|
style.FontOblique = getFontOblique();
|
||||||
|
style.Underlined = getFontUnderlined();
|
||||||
|
style.StrikeThrough = getFontStrikeThrough();
|
||||||
|
|
||||||
|
if (present[MY_HTML_SPAN_STYLE] && value[MY_HTML_SPAN_STYLE])
|
||||||
|
getStyleParams(value[MY_HTML_SPAN_STYLE], style);
|
||||||
|
|
||||||
|
_TextColor.push_back(style.TextColor);
|
||||||
|
_FontSize.push_back(style.FontSize);
|
||||||
|
_FontWeight.push_back(style.FontWeight);
|
||||||
|
_FontOblique.push_back(style.FontOblique);
|
||||||
|
_FontUnderlined.push_back(style.Underlined);
|
||||||
|
_FontStrikeThrough.push_back(style.StrikeThrough);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case HTML_STYLE:
|
case HTML_STYLE:
|
||||||
_IgnoreText = true;
|
_IgnoreText = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1655,7 +1691,10 @@ namespace NLGUI
|
||||||
popIfNotEmpty (_FontSize);
|
popIfNotEmpty (_FontSize);
|
||||||
break;
|
break;
|
||||||
case HTML_A:
|
case HTML_A:
|
||||||
|
popIfNotEmpty (_FontSize);
|
||||||
popIfNotEmpty (_TextColor);
|
popIfNotEmpty (_TextColor);
|
||||||
|
popIfNotEmpty (_FontUnderlined);
|
||||||
|
popIfNotEmpty (_FontStrikeThrough);
|
||||||
popIfNotEmpty (_GlobalColor);
|
popIfNotEmpty (_GlobalColor);
|
||||||
popIfNotEmpty (_A);
|
popIfNotEmpty (_A);
|
||||||
popIfNotEmpty (_Link);
|
popIfNotEmpty (_Link);
|
||||||
|
@ -1763,6 +1802,14 @@ namespace NLGUI
|
||||||
popIfNotEmpty (_UL);
|
popIfNotEmpty (_UL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HTML_SPAN:
|
||||||
|
popIfNotEmpty (_FontSize);
|
||||||
|
popIfNotEmpty (_FontWeight);
|
||||||
|
popIfNotEmpty (_FontOblique);
|
||||||
|
popIfNotEmpty (_TextColor);
|
||||||
|
popIfNotEmpty (_FontUnderlined);
|
||||||
|
popIfNotEmpty (_FontStrikeThrough);
|
||||||
|
break;
|
||||||
case HTML_STYLE:
|
case HTML_STYLE:
|
||||||
_IgnoreText = false;
|
_IgnoreText = false;
|
||||||
break;
|
break;
|
||||||
|
@ -3077,6 +3124,7 @@ namespace NLGUI
|
||||||
|
|
||||||
// Text added ?
|
// Text added ?
|
||||||
bool added = false;
|
bool added = false;
|
||||||
|
bool embolden = getFontWeight() >= 700;
|
||||||
|
|
||||||
// Number of child in this paragraph
|
// Number of child in this paragraph
|
||||||
if (_CurrentViewLink)
|
if (_CurrentViewLink)
|
||||||
|
@ -3086,6 +3134,10 @@ namespace NLGUI
|
||||||
if (!skipLine &&
|
if (!skipLine &&
|
||||||
(getTextColor() == _CurrentViewLink->getColor()) &&
|
(getTextColor() == _CurrentViewLink->getColor()) &&
|
||||||
(getFontSize() == (uint)_CurrentViewLink->getFontSize()) &&
|
(getFontSize() == (uint)_CurrentViewLink->getFontSize()) &&
|
||||||
|
(getFontUnderlined() == _CurrentViewLink->getUnderlined()) &&
|
||||||
|
(getFontStrikeThrough() == _CurrentViewLink->getStrikeThrough()) &&
|
||||||
|
(embolden == _CurrentViewLink->getEmbolden()) &&
|
||||||
|
(getFontOblique() == _CurrentViewLink->getOblique()) &&
|
||||||
(getLink() == _CurrentViewLink->Link) &&
|
(getLink() == _CurrentViewLink->Link) &&
|
||||||
(getGlobalColor() == _CurrentViewLink->getModulateGlobalColor()))
|
(getGlobalColor() == _CurrentViewLink->getModulateGlobalColor()))
|
||||||
{
|
{
|
||||||
|
@ -3141,12 +3193,15 @@ namespace NLGUI
|
||||||
if (!newLink->Link.empty())
|
if (!newLink->Link.empty())
|
||||||
{
|
{
|
||||||
newLink->setHTMLView (this);
|
newLink->setHTMLView (this);
|
||||||
newLink->setUnderlined (true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newLink->setText(tmpStr);
|
newLink->setText(tmpStr);
|
||||||
newLink->setColor(getTextColor());
|
newLink->setColor(getTextColor());
|
||||||
newLink->setFontSize(getFontSize());
|
newLink->setFontSize(getFontSize());
|
||||||
|
newLink->setEmbolden(embolden);
|
||||||
|
newLink->setOblique(getFontOblique());
|
||||||
|
newLink->setUnderlined(getFontUnderlined());
|
||||||
|
newLink->setStrikeThrough(getFontStrikeThrough());
|
||||||
newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor));
|
newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor));
|
||||||
newLink->setMultiLine(true);
|
newLink->setMultiLine(true);
|
||||||
newLink->setModulateGlobalColor(getGlobalColor());
|
newLink->setModulateGlobalColor(getGlobalColor());
|
||||||
|
@ -3422,6 +3477,10 @@ namespace NLGUI
|
||||||
_TextColor.clear();
|
_TextColor.clear();
|
||||||
_GlobalColor.clear();
|
_GlobalColor.clear();
|
||||||
_FontSize.clear();
|
_FontSize.clear();
|
||||||
|
_FontWeight.clear();
|
||||||
|
_FontOblique.clear();
|
||||||
|
_FontUnderlined.clear();
|
||||||
|
_FontStrikeThrough.clear();
|
||||||
_Indent = 0;
|
_Indent = 0;
|
||||||
_LI = false;
|
_LI = false;
|
||||||
_UL.clear();
|
_UL.clear();
|
||||||
|
@ -4590,5 +4649,84 @@ namespace NLGUI
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// CGroupHTML::CStyleParams style;
|
||||||
|
// style.FontSize; // font-size: 10px;
|
||||||
|
// style.TextColor; // color: #ABCDEF;
|
||||||
|
// style.Underlined; // text-decoration: underline; text-decoration-line: underline;
|
||||||
|
// style.StrikeThrough; // text-decoration: line-through; text-decoration-line: line-through;
|
||||||
|
void CGroupHTML::getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit)
|
||||||
|
{
|
||||||
|
TStyle styles = parseStyle(styleString);
|
||||||
|
TStyle::iterator it;
|
||||||
|
for (it=styles.begin(); it != styles.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first == "font-size")
|
||||||
|
{
|
||||||
|
float tmp;
|
||||||
|
sint size = 0;
|
||||||
|
getPercentage (size, tmp, it->second.c_str());
|
||||||
|
if (size > 0)
|
||||||
|
style.FontSize = size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (it->first == "font-style")
|
||||||
|
{
|
||||||
|
if (it->second == "italic" || it->second == "oblique")
|
||||||
|
style.FontOblique = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (it->first == "font-weight")
|
||||||
|
{
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
|
||||||
|
uint weight = 400;
|
||||||
|
if (it->second == "normal")
|
||||||
|
weight = 400;
|
||||||
|
else
|
||||||
|
if (it->second == "bold")
|
||||||
|
weight = 700;
|
||||||
|
else
|
||||||
|
if (it->second == "lighter")
|
||||||
|
{
|
||||||
|
const uint lighter[] = {100, 100, 100, 100, 100, 400, 400, 700, 700};
|
||||||
|
int index = getFontWeight() / 100 - 1;
|
||||||
|
clamp(index, 1, 9);
|
||||||
|
weight = lighter[index-1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (it->second == "bolder")
|
||||||
|
{
|
||||||
|
const uint bolder[] = {400, 400, 400, 700, 700, 900, 900, 900, 900};
|
||||||
|
uint index = getFontWeight() / 100 + 1;
|
||||||
|
clamp(index, 1, 9);
|
||||||
|
weight = bolder[index-1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (fromString(it->second, weight))
|
||||||
|
{
|
||||||
|
weight = (weight / 100);
|
||||||
|
clamp(weight, 1, 9);
|
||||||
|
weight *= 100;
|
||||||
|
}
|
||||||
|
style.FontWeight = weight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (it->first == "color")
|
||||||
|
scanHTMLColor(it->second.c_str(), style.TextColor);
|
||||||
|
else
|
||||||
|
if (it->first == "text-decoration" || it->first == "text-decoration-line")
|
||||||
|
{
|
||||||
|
std::string prop(strlwr(it->second));
|
||||||
|
style.Underlined = (prop.find("underline") != std::string::npos);
|
||||||
|
style.StrikeThrough = (prop.find("line-through") != std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inherit)
|
||||||
|
{
|
||||||
|
style.Underlined = getFontUnderlined() || style.Underlined;
|
||||||
|
style.StrikeThrough = getFontStrikeThrough() || style.StrikeThrough;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,14 @@ namespace NLGUI
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HTAttr span_attr[] =
|
||||||
|
{
|
||||||
|
HTML_ATTR(SPAN,CLASS),
|
||||||
|
HTML_ATTR(SPAN,ID),
|
||||||
|
HTML_ATTR(SPAN,STYLE),
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
void _VerifyLibWWW(const char *function, bool ok, const char *file, int line)
|
void _VerifyLibWWW(const char *function, bool ok, const char *file, int line)
|
||||||
|
@ -699,6 +707,8 @@ namespace NLGUI
|
||||||
HTML_DTD->tags[HTML_I].number_of_attributes = 0;
|
HTML_DTD->tags[HTML_I].number_of_attributes = 0;
|
||||||
HTML_DTD->tags[HTML_DIV].attributes = div_attr;
|
HTML_DTD->tags[HTML_DIV].attributes = div_attr;
|
||||||
HTML_DTD->tags[HTML_DIV].number_of_attributes = sizeof(div_attr) / sizeof(HTAttr) - 1;
|
HTML_DTD->tags[HTML_DIV].number_of_attributes = sizeof(div_attr) / sizeof(HTAttr) - 1;
|
||||||
|
HTML_DTD->tags[HTML_SPAN].attributes = span_attr;
|
||||||
|
HTML_DTD->tags[HTML_SPAN].number_of_attributes = sizeof(span_attr) / sizeof(HTAttr) - 1;
|
||||||
|
|
||||||
// Set a request timeout
|
// Set a request timeout
|
||||||
// HTHost_setEventTimeout (30000);
|
// HTHost_setEventTimeout (30000);
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace NLGUI
|
||||||
{
|
{
|
||||||
_CaseMode = CaseNormal;
|
_CaseMode = CaseNormal;
|
||||||
_Underlined = false;
|
_Underlined = false;
|
||||||
|
_StrikeThrough = false;
|
||||||
_ContinuousUpdate = false;
|
_ContinuousUpdate = false;
|
||||||
_Active = true;
|
_Active = true;
|
||||||
_X = 0;
|
_X = 0;
|
||||||
|
@ -58,6 +59,8 @@ namespace NLGUI
|
||||||
|
|
||||||
_FontSize = 12 +
|
_FontSize = 12 +
|
||||||
CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32();
|
CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32();
|
||||||
|
_Embolden = false;
|
||||||
|
_Oblique = false;
|
||||||
_Color = CRGBA(255,255,255,255);
|
_Color = CRGBA(255,255,255,255);
|
||||||
_Shadow = false;
|
_Shadow = false;
|
||||||
_ShadowOutline = false;
|
_ShadowOutline = false;
|
||||||
|
@ -157,6 +160,10 @@ namespace NLGUI
|
||||||
_PosRef = vt._PosRef;
|
_PosRef = vt._PosRef;
|
||||||
|
|
||||||
_FontSize = vt._FontSize;
|
_FontSize = vt._FontSize;
|
||||||
|
_Embolden = vt._Embolden;
|
||||||
|
_Oblique = vt._Oblique;
|
||||||
|
_Underlined = vt._Underlined;
|
||||||
|
_StrikeThrough = vt._StrikeThrough;
|
||||||
_Color = vt._Color;
|
_Color = vt._Color;
|
||||||
_Shadow = vt._Shadow;
|
_Shadow = vt._Shadow;
|
||||||
_ShadowOutline = vt._ShadowOutline;
|
_ShadowOutline = vt._ShadowOutline;
|
||||||
|
@ -221,6 +228,21 @@ namespace NLGUI
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( name == "fontweight" )
|
||||||
|
{
|
||||||
|
if (_Embolden)
|
||||||
|
return "bold";
|
||||||
|
|
||||||
|
return "normal";
|
||||||
|
}
|
||||||
|
if( name == "fontstyle" )
|
||||||
|
{
|
||||||
|
if (_Oblique)
|
||||||
|
return "oblique";
|
||||||
|
|
||||||
|
return "normal";
|
||||||
|
}
|
||||||
|
else
|
||||||
if( name == "shadow" )
|
if( name == "shadow" )
|
||||||
{
|
{
|
||||||
return toString( _Shadow );
|
return toString( _Shadow );
|
||||||
|
@ -286,6 +308,11 @@ namespace NLGUI
|
||||||
return toString( _Underlined );
|
return toString( _Underlined );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( name == "strikthrough" )
|
||||||
|
{
|
||||||
|
return toString( _StrikeThrough );
|
||||||
|
}
|
||||||
|
else
|
||||||
if( name == "case_mode" )
|
if( name == "case_mode" )
|
||||||
{
|
{
|
||||||
return toString( uint32( _CaseMode ) );
|
return toString( uint32( _CaseMode ) );
|
||||||
|
@ -358,6 +385,20 @@ namespace NLGUI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( name == "fontweight" )
|
||||||
|
{
|
||||||
|
if (value == "bold")
|
||||||
|
_Embolden = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if( name == "fontstyle" )
|
||||||
|
{
|
||||||
|
if( value == "oblique" )
|
||||||
|
_Oblique = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
if( name == "shadow" )
|
if( name == "shadow" )
|
||||||
{
|
{
|
||||||
bool b;
|
bool b;
|
||||||
|
@ -444,6 +485,14 @@ namespace NLGUI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( name == "strikethrough" )
|
||||||
|
{
|
||||||
|
bool b;
|
||||||
|
if( fromString( value, b ) )
|
||||||
|
_StrikeThrough = b;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
if( name == "case_mode" )
|
if( name == "case_mode" )
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
@ -533,6 +582,16 @@ namespace NLGUI
|
||||||
_FontSize - CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32()
|
_FontSize - CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32()
|
||||||
).c_str() );
|
).c_str() );
|
||||||
|
|
||||||
|
std::string fontweight("normal");
|
||||||
|
if (_Embolden)
|
||||||
|
fontweight = "bold";
|
||||||
|
xmlSetProp( node, BAD_CAST "fontweight", BAD_CAST fontweight.c_str() );
|
||||||
|
|
||||||
|
std::string fontstyle("normal");
|
||||||
|
if (_Oblique)
|
||||||
|
fontstyle = "oblique";
|
||||||
|
xmlSetProp( node, BAD_CAST "fontstyle", BAD_CAST fontstyle.c_str() );
|
||||||
|
|
||||||
xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() );
|
xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() );
|
xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "shadow_color", BAD_CAST toString( _ShadowColor ).c_str() );
|
xmlSetProp( node, BAD_CAST "shadow_color", BAD_CAST toString( _ShadowColor ).c_str() );
|
||||||
|
@ -561,6 +620,7 @@ namespace NLGUI
|
||||||
xmlSetProp( node, BAD_CAST "multi_line_maxw_only", BAD_CAST toString( _MultiLineMaxWOnly ).c_str() );
|
xmlSetProp( node, BAD_CAST "multi_line_maxw_only", BAD_CAST toString( _MultiLineMaxWOnly ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "multi_max_line", BAD_CAST toString( _MultiMaxLine ).c_str() );
|
xmlSetProp( node, BAD_CAST "multi_max_line", BAD_CAST toString( _MultiMaxLine ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "underlined", BAD_CAST toString( _Underlined ).c_str() );
|
xmlSetProp( node, BAD_CAST "underlined", BAD_CAST toString( _Underlined ).c_str() );
|
||||||
|
xmlSetProp( node, BAD_CAST "strikethrough", BAD_CAST toString( _StrikeThrough ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "case_mode", BAD_CAST toString( uint32( _CaseMode ) ).c_str() );
|
xmlSetProp( node, BAD_CAST "case_mode", BAD_CAST toString( uint32( _CaseMode ) ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "over_extend_view_text", BAD_CAST toString( _OverExtendViewText ).c_str() );
|
xmlSetProp( node, BAD_CAST "over_extend_view_text", BAD_CAST toString( _OverExtendViewText ).c_str() );
|
||||||
xmlSetProp( node, BAD_CAST "over_extend_parent_rect",
|
xmlSetProp( node, BAD_CAST "over_extend_parent_rect",
|
||||||
|
@ -614,6 +674,22 @@ namespace NLGUI
|
||||||
_FontSize += CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32();
|
_FontSize += CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prop = (char*) xmlGetProp( cur, (xmlChar*)"fontweight" );
|
||||||
|
_Embolden = false;
|
||||||
|
if (prop)
|
||||||
|
{
|
||||||
|
if (nlstricmp("bold", (const char*)prop) == 0) _Embolden = true;
|
||||||
|
else nlwarning("<CViewText::parse> bad fontweight '%s'", (const char *)prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop = (char*) xmlGetProp( cur, (xmlChar*)"fontstyle" );
|
||||||
|
_Oblique = false;
|
||||||
|
if (prop)
|
||||||
|
{
|
||||||
|
if (nlstricmp("oblique", (const char *) prop) == 0) _Oblique = true;
|
||||||
|
else nlwarning("<CViewText::parse> bad fontstyle '%s'", (const char *)prop);
|
||||||
|
}
|
||||||
|
|
||||||
prop = (char*) xmlGetProp( cur, (xmlChar*)"shadow" );
|
prop = (char*) xmlGetProp( cur, (xmlChar*)"shadow" );
|
||||||
_Shadow = false;
|
_Shadow = false;
|
||||||
if (prop)
|
if (prop)
|
||||||
|
@ -668,6 +744,11 @@ namespace NLGUI
|
||||||
if (prop)
|
if (prop)
|
||||||
_Underlined = convertBool(prop);
|
_Underlined = convertBool(prop);
|
||||||
|
|
||||||
|
prop = (char*) xmlGetProp( cur, (xmlChar*)"strikethrough" );
|
||||||
|
_StrikeThrough = false;
|
||||||
|
if (prop)
|
||||||
|
_StrikeThrough = convertBool(prop);
|
||||||
|
|
||||||
prop = (char*) xmlGetProp( cur, (xmlChar*)"case_mode" );
|
prop = (char*) xmlGetProp( cur, (xmlChar*)"case_mode" );
|
||||||
_CaseMode = CaseNormal;
|
_CaseMode = CaseNormal;
|
||||||
if (prop)
|
if (prop)
|
||||||
|
@ -887,6 +968,8 @@ namespace NLGUI
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setShadeColor (shcol);
|
TextContext->setShadeColor (shcol);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
|
|
||||||
float y = (float)(_YReal) * ooh; // y is expressed in scree, coordinates [0..1]
|
float y = (float)(_YReal) * ooh; // y is expressed in scree, coordinates [0..1]
|
||||||
//y += _LinesInfos[_LinesInfos.size()-1].StringLine / h;
|
//y += _LinesInfos[_LinesInfos.size()-1].StringLine / h;
|
||||||
|
@ -953,7 +1036,7 @@ namespace NLGUI
|
||||||
// skip spaces before current word
|
// skip spaces before current word
|
||||||
float firstSpace = currWord.NumSpaces * currLine.getSpaceWidth();
|
float firstSpace = currWord.NumSpaces * currLine.getSpaceWidth();
|
||||||
sint line_width = 0;
|
sint line_width = 0;
|
||||||
if (_Underlined)
|
if (_Underlined || _StrikeThrough)
|
||||||
{
|
{
|
||||||
line_width = (sint)floorf(currLine.getWidthWithoutSpaces() + currLine.getSpaceWidth());
|
line_width = (sint)floorf(currLine.getWidthWithoutSpaces() + currLine.getSpaceWidth());
|
||||||
line_width -= (sint)floorf(firstSpace);
|
line_width -= (sint)floorf(firstSpace);
|
||||||
|
@ -971,6 +1054,9 @@ namespace NLGUI
|
||||||
if (_Underlined)
|
if (_Underlined)
|
||||||
rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1, 0, false, rVR.getBlankTextureId(), col);
|
rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||||
|
|
||||||
|
if (_StrikeThrough)
|
||||||
|
rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||||
|
|
||||||
// skip word
|
// skip word
|
||||||
px += currWord.Info.StringWidth;
|
px += currWord.Info.StringWidth;
|
||||||
}
|
}
|
||||||
|
@ -1002,6 +1088,8 @@ namespace NLGUI
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setShadeColor (shcol);
|
TextContext->setShadeColor (shcol);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
|
|
||||||
|
|
||||||
if(_LetterColors!=NULL && !TextContext->isSameLetterColors(_LetterColors, _Index))
|
if(_LetterColors!=NULL && !TextContext->isSameLetterColors(_LetterColors, _Index))
|
||||||
|
@ -1032,6 +1120,9 @@ namespace NLGUI
|
||||||
if (_Underlined)
|
if (_Underlined)
|
||||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2, _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2, _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||||
|
|
||||||
|
if (_StrikeThrough)
|
||||||
|
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+(_FontLegHeight/2), _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||||
|
|
||||||
// reset selection
|
// reset selection
|
||||||
if(_TextSelection)
|
if(_TextSelection)
|
||||||
TextContext->resetStringSelection(_Index);
|
TextContext->resetStringSelection(_Index);
|
||||||
|
@ -1154,6 +1245,22 @@ namespace NLGUI
|
||||||
return _FontSize - CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32();
|
return _FontSize - CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CViewText::setEmbolden (bool embolden)
|
||||||
|
{
|
||||||
|
_Embolden = embolden;
|
||||||
|
computeFontSize ();
|
||||||
|
invalidateContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CViewText::setOblique (bool oblique)
|
||||||
|
{
|
||||||
|
_Oblique = oblique;
|
||||||
|
computeFontSize ();
|
||||||
|
invalidateContent();
|
||||||
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
void CViewText::setColor(const NLMISC::CRGBA & color)
|
void CViewText::setColor(const NLMISC::CRGBA & color)
|
||||||
{
|
{
|
||||||
|
@ -1679,6 +1786,8 @@ namespace NLGUI
|
||||||
TextContext->setShaded (_Shadow);
|
TextContext->setShaded (_Shadow);
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
|
|
||||||
// default state
|
// default state
|
||||||
_SingleLineTextClamped= false;
|
_SingleLineTextClamped= false;
|
||||||
|
@ -2000,6 +2109,8 @@ namespace NLGUI
|
||||||
TextContext->setShaded (_Shadow);
|
TextContext->setShaded (_Shadow);
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
// CViewRenderer &rVR = *CViewRenderer::getInstance();
|
// CViewRenderer &rVR = *CViewRenderer::getInstance();
|
||||||
height = getFontHeight();
|
height = getFontHeight();
|
||||||
//
|
//
|
||||||
|
@ -2132,6 +2243,8 @@ namespace NLGUI
|
||||||
TextContext->setShaded (_Shadow);
|
TextContext->setShaded (_Shadow);
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
// find the line where the character is
|
// find the line where the character is
|
||||||
// CViewRenderer &rVR = *CViewRenderer::getInstance();
|
// CViewRenderer &rVR = *CViewRenderer::getInstance();
|
||||||
uint charPos = 0;
|
uint charPos = 0;
|
||||||
|
@ -2407,6 +2520,8 @@ namespace NLGUI
|
||||||
TextContext->setShaded (_Shadow);
|
TextContext->setShaded (_Shadow);
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
|
|
||||||
TCharPos linePos = 0;
|
TCharPos linePos = 0;
|
||||||
while (linePos < _Text.length())
|
while (linePos < _Text.length())
|
||||||
|
@ -2492,6 +2607,8 @@ namespace NLGUI
|
||||||
TextContext->setShaded (_Shadow);
|
TextContext->setShaded (_Shadow);
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
|
|
||||||
// Current position in text
|
// Current position in text
|
||||||
TCharPos currPos = 0;
|
TCharPos currPos = 0;
|
||||||
|
@ -2544,6 +2661,8 @@ namespace NLGUI
|
||||||
TextContext->setShaded (_Shadow);
|
TextContext->setShaded (_Shadow);
|
||||||
TextContext->setShadeOutline (_ShadowOutline);
|
TextContext->setShadeOutline (_ShadowOutline);
|
||||||
TextContext->setFontSize (_FontSize);
|
TextContext->setFontSize (_FontSize);
|
||||||
|
TextContext->setEmbolden (_Embolden);
|
||||||
|
TextContext->setOblique (_Oblique);
|
||||||
|
|
||||||
// Letter size
|
// Letter size
|
||||||
UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext
|
UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext
|
||||||
|
|
Loading…
Reference in a new issue