From 00aa16f116339812bc391fb2cebfc0553e78a6b6 Mon Sep 17 00:00:00 2001 From: Cyril Deguet Date: Sat, 27 Mar 2004 00:21:13 +0000 Subject: [PATCH] * all: beginning of bitmap font support. At the moment only the digits font for xmms/winamp2 skins is supported (the bitmap must have the following layout: [0123456789 -] with letters of size 9x13). Non-digit characters are just skipped, with a hardcoded advance of 6 (it allows correct display of time in xmms skins; the ':' are skipped) Small example at http://people.via.ecp.fr/~asmax/chaos.vlt (uncomplete skin) * vars/time.cpp: notify the observers also when the input is stopped * controls/ctrl_text.cpp: do not reset the FSM state and timer when the text is displayed (was causing bugs in time display) --- modules/gui/skins2/controls/ctrl_text.cpp | 6 +-- modules/gui/skins2/parser/builder.cpp | 19 +++++++++ modules/gui/skins2/parser/builder.hpp | 1 + modules/gui/skins2/parser/builder_data.def | 1 + modules/gui/skins2/parser/builder_data.hpp | 13 ++++++ modules/gui/skins2/parser/skin_parser.cpp | 7 ++++ modules/gui/skins2/src/bitmap_font.cpp | 46 +++++++++++++++++++++- modules/gui/skins2/src/bitmap_font.hpp | 2 + modules/gui/skins2/src/generic_bitmap.cpp | 29 ++++++++------ modules/gui/skins2/src/generic_bitmap.hpp | 16 +++++--- modules/gui/skins2/vars/time.cpp | 7 +--- share/skins2/default/skin.dtd | 2 +- 12 files changed, 118 insertions(+), 31 deletions(-) diff --git a/modules/gui/skins2/controls/ctrl_text.cpp b/modules/gui/skins2/controls/ctrl_text.cpp index 687c9013fb..6026431579 100755 --- a/modules/gui/skins2/controls/ctrl_text.cpp +++ b/modules/gui/skins2/controls/ctrl_text.cpp @@ -184,8 +184,6 @@ void CtrlText::onUpdate( Subject &rVariable ) void CtrlText::displayText( const UString &rText ) { - m_pTimer->stop(); - // Create the images ('normal' and 'double') from the text // 'Normal' image if( m_pImg ) @@ -208,8 +206,6 @@ void CtrlText::displayText( const UString &rText ) // Update the current image used, as if the control size had changed onChangePosition(); - // XXX: will this always work? - m_fsm.setState( "outStill" ); notifyLayout(); } @@ -256,7 +252,7 @@ void CtrlText::transManualMoving( SkinObject *pCtrl ) // Start the automatic movement, but only if the text is wider than the // control - if( pThis->m_pImg && + if( pThis->m_pImg && pThis->m_pImg->getWidth() >= pThis->getPosition()->getWidth() ) { // The current image may have been set incorrectly in displayText(), so diff --git a/modules/gui/skins2/parser/builder.cpp b/modules/gui/skins2/parser/builder.cpp index 2e721a138f..219a15e1f7 100755 --- a/modules/gui/skins2/parser/builder.cpp +++ b/modules/gui/skins2/parser/builder.cpp @@ -31,6 +31,7 @@ #include "../src/generic_bitmap.hpp" #include "../src/top_window.hpp" #include "../src/anchor.hpp" +#include "../src/bitmap_font.hpp" #include "../src/ft2_font.hpp" #include "../src/theme.hpp" #include "../controls/ctrl_button.hpp" @@ -81,6 +82,7 @@ Theme *Builder::build() // Create everything from the data in the XML ADD_OBJECTS( Theme ); ADD_OBJECTS( Bitmap ); + ADD_OBJECTS( BitmapFont ); ADD_OBJECTS( Font ); ADD_OBJECTS( Window ); ADD_OBJECTS( Layout ); @@ -137,6 +139,23 @@ void Builder::addBitmap( const BuilderData::Bitmap &rData ) } +void Builder::addBitmapFont( const BuilderData::BitmapFont &rData ) +{ + GenericBitmap *pBmp = new PngBitmap( getIntf(), rData.m_file, 0 ); + m_pTheme->m_bitmaps[rData.m_id] = GenericBitmapPtr( pBmp ); + + GenericFont *pFont = new BitmapFont( getIntf(), *pBmp ); + if( pFont->init() ) + { + m_pTheme->m_fonts[rData.m_id] = GenericFontPtr( pFont ); + } + else + { + delete pFont; + } +} + + void Builder::addFont( const BuilderData::Font &rData ) { GenericFont *pFont = new FT2Font( getIntf(), rData.m_fontFile, diff --git a/modules/gui/skins2/parser/builder.hpp b/modules/gui/skins2/parser/builder.hpp index 6194a34740..e5c6b4c599 100644 --- a/modules/gui/skins2/parser/builder.hpp +++ b/modules/gui/skins2/parser/builder.hpp @@ -65,6 +65,7 @@ class Builder: public SkinObject void addTheme( const BuilderData::Theme &rData ); void addBitmap( const BuilderData::Bitmap &rData ); + void addBitmapFont( const BuilderData::BitmapFont &rData ); void addFont( const BuilderData::Font &rData ); void addWindow( const BuilderData::Window &rData ); void addLayout( const BuilderData::Layout &rData ); diff --git a/modules/gui/skins2/parser/builder_data.def b/modules/gui/skins2/parser/builder_data.def index b327082a87..b60a224ef6 100644 --- a/modules/gui/skins2/parser/builder_data.def +++ b/modules/gui/skins2/parser/builder_data.def @@ -1,5 +1,6 @@ Theme tooltipfont:string magnet:int alpha:uint32_t moveAlpha:uint32_t fadeTime:uint32_t Bitmap id:string fileName:string alphaColor:uint32_t +BitmapFont id:string file:string type:string Font id:string fontFile:string size:int Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool Layout id:string width:int height:int minWidth:int maxWidth:int minHeight:int maxHeight:int windowId:string diff --git a/modules/gui/skins2/parser/builder_data.hpp b/modules/gui/skins2/parser/builder_data.hpp index ce3f65c04a..e0ad5c002b 100644 --- a/modules/gui/skins2/parser/builder_data.hpp +++ b/modules/gui/skins2/parser/builder_data.hpp @@ -67,6 +67,19 @@ m_id( id ), m_fileName( fileName ), m_alphaColor( alphaColor ) {} /// List list m_listBitmap; + /// Type definition + struct BitmapFont + { + BitmapFont( const string & id, const string & file, const string & type ): +m_id( id ), m_file( file ), m_type( type ) {} + + const string m_id; + const string m_file; + const string m_type; + }; + /// List + list m_listBitmapFont; + /// Type definition struct Font { diff --git a/modules/gui/skins2/parser/skin_parser.cpp b/modules/gui/skins2/parser/skin_parser.cpp index 3ad7171e47..d10a926a92 100644 --- a/modules/gui/skins2/parser/skin_parser.cpp +++ b/modules/gui/skins2/parser/skin_parser.cpp @@ -51,6 +51,13 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) m_data.m_listBitmap.push_back( bitmap ); } + else if( rName == "BitmapFont" ) + { + const BuilderData::BitmapFont font( attr["id"] , attr["file"], + attr["type"] ); + m_data.m_listBitmapFont.push_back( font ); + } + else if( rName == "Button" ) { const BuilderData::Button button( uniqueId( attr["id"] ), atoi( attr["x"] ) + diff --git a/modules/gui/skins2/src/bitmap_font.cpp b/modules/gui/skins2/src/bitmap_font.cpp index 566c7c4598..56efd30047 100644 --- a/modules/gui/skins2/src/bitmap_font.cpp +++ b/modules/gui/skins2/src/bitmap_font.cpp @@ -23,17 +23,61 @@ #include "bitmap_font.hpp" #include "generic_bitmap.hpp" +#include "../utils/ustring.hpp" BitmapFont::BitmapFont( intf_thread_t *pIntf, const GenericBitmap &rBitmap ): GenericFont( pIntf ), m_rBitmap( rBitmap ) { + m_width = 9; + m_height = 13; } GenericBitmap *BitmapFont::drawString( const UString &rString, uint32_t color, int maxWidth ) const { - return NULL; + uint32_t *pString = (uint32_t*)rString.u_str(); + // Compute the text width + int width = 0; + for( uint32_t *ptr = pString; *ptr; ptr++ ) + { + uint32_t c = *ptr; + if( (c >= '0' && c <= '9') || c == '-' ) + { + width += m_width + 3; + } + else + { + width += 6; + } + } + // Create a bitmap + BitmapImpl *pBmp = new BitmapImpl( getIntf(), width, m_height ); + int xDest = 0; + while( *pString ) + { + uint32_t c = *(pString++); + int xSrc = -1; + if( c >= '0' && c <= '9' ) + { + xSrc = (c - '0') * m_width; + } + else if( c == '-' ) + { + xSrc = 11 * m_width; + } + if( xSrc != -1 ) + { + pBmp->drawBitmap( m_rBitmap, xSrc, 0, xDest, 0, m_width, + m_height ); + xDest += m_width + 3; + } + else + { + xDest += 6; + } + } + return pBmp; } diff --git a/modules/gui/skins2/src/bitmap_font.hpp b/modules/gui/skins2/src/bitmap_font.hpp index 436abd0875..ca983f33f8 100644 --- a/modules/gui/skins2/src/bitmap_font.hpp +++ b/modules/gui/skins2/src/bitmap_font.hpp @@ -49,6 +49,8 @@ class BitmapFont: public GenericFont private: /// Bitmap const GenericBitmap &m_rBitmap; + /// Glyph size + int m_width, m_height; }; #endif diff --git a/modules/gui/skins2/src/generic_bitmap.cpp b/modules/gui/skins2/src/generic_bitmap.cpp index b9a088745f..1971e24977 100644 --- a/modules/gui/skins2/src/generic_bitmap.cpp +++ b/modules/gui/skins2/src/generic_bitmap.cpp @@ -24,27 +24,32 @@ #include "generic_bitmap.hpp" -SubBitmap::SubBitmap( intf_thread_t *pIntf, const GenericBitmap &rSource, - int left, int top, int width, int height ): +BitmapImpl::BitmapImpl( intf_thread_t *pIntf, int width, int height ): GenericBitmap( pIntf ), m_width( width ), m_height( height ), m_pData( NULL ) { m_pData = new uint8_t[width * height * 4]; + memset( m_pData, 0, width * height * 4 ); +} + + +BitmapImpl::~BitmapImpl() +{ + delete[] m_pData; +} + - uint32_t *pSrc = (uint32_t*)rSource.getData(); - uint32_t *pDest = (uint32_t*)m_pData; +void BitmapImpl::drawBitmap( const GenericBitmap &rSource, int xSrc, int ySrc, + int xDest, int yDest, int width, int height ) +{ int srcWidth = rSource.getWidth(); - for( int y = top; y < top + height; y++ ) + uint32_t *pSrc = (uint32_t*)rSource.getData() + ySrc * srcWidth + xSrc; + uint32_t *pDest = (uint32_t*)m_pData + yDest * m_width + xDest ; + for( int y = 0; y < height; y++ ) { memcpy( pDest, pSrc, 4 * width ); pSrc += srcWidth; - pDest += width; + pDest += m_width; } } - -SubBitmap::~SubBitmap() -{ - delete[] m_pData; -} - diff --git a/modules/gui/skins2/src/generic_bitmap.hpp b/modules/gui/skins2/src/generic_bitmap.hpp index f59a4e1518..83442e03c7 100644 --- a/modules/gui/skins2/src/generic_bitmap.hpp +++ b/modules/gui/skins2/src/generic_bitmap.hpp @@ -29,7 +29,7 @@ #include "../utils/pointer.hpp" -/// Base class for bitmaps +/// Generic interface for bitmaps class GenericBitmap: public SkinObject { public: @@ -50,13 +50,13 @@ class GenericBitmap: public SkinObject }; -/// Bitmap created from a region of another bitmap -class SubBitmap: public GenericBitmap +/// Basic bitmap implementation +class BitmapImpl: public GenericBitmap { public: - SubBitmap( intf_thread_t *pIntf, const GenericBitmap &rSource, - int left, int top, int width, int height ); - ~SubBitmap(); + /// Create an empty bitmap of the given size + BitmapImpl( intf_thread_t *pIntf, int width, int height ); + ~BitmapImpl(); /// Get the width of the bitmap virtual int getWidth() const { return m_width; } @@ -68,6 +68,10 @@ class SubBitmap: public GenericBitmap /// Each pixel is stored in 4 bytes in the order B,G,R,A virtual uint8_t *getData() const { return m_pData; } + // Copy a region of another bitmap on this bitmap + void drawBitmap( const GenericBitmap &rSource, int xSrc, int ySrc, + int xDest, int yDest, int width, int height ); + private: /// Size of the bitmap. int m_width, m_height; diff --git a/modules/gui/skins2/vars/time.cpp b/modules/gui/skins2/vars/time.cpp index 2cf98aa451..d1fd00767a 100755 --- a/modules/gui/skins2/vars/time.cpp +++ b/modules/gui/skins2/vars/time.cpp @@ -30,15 +30,10 @@ void Time::set( float percentage, bool updateVLC ) { - if( getIntf()->p_sys->p_input == NULL ) - { - return; - } - VarPercent::set( percentage ); // Avoid looping forever... - if( updateVLC ) + if( updateVLC && getIntf()->p_sys->p_input ) { vlc_value_t pos; pos.f_float = percentage; diff --git a/share/skins2/default/skin.dtd b/share/skins2/default/skin.dtd index faf91f1b8c..cfaaa365f5 100644 --- a/share/skins2/default/skin.dtd +++ b/share/skins2/default/skin.dtd @@ -2,7 +2,7 @@ --> - +