#include "stdafx.h" #ifdef _COUNTRY_ME_ #include #include "KPangoCairo.h" #include #include "SGameOperationManager.h" PangoFontMap* KTextLayout::s_pFontMap = NULL; PangoContext* KTextLayout::s_pPangoContext = NULL; bool g_bSaveToPng = false; bool KTextLayout::InitLayoutEngine() { s_pFontMap = pango_cairo_font_map_get_default(); s_pPangoContext = pango_font_map_create_context( s_pFontMap ); return s_pFontMap && s_pPangoContext; } void KTextLayout::DestroyLayoutEngine() { g_object_unref( s_pPangoContext ); s_pFontMap = NULL; } KTextLayout::KTextLayout( int nWidth, int nHeight, int nSpacing, DWORD dwAlign ) : m_context( NULL ), m_cr( NULL ), m_surface( NULL ), m_layout( NULL ), m_nWidth( nWidth ), m_nHeight( nHeight ), m_nSpacing( nSpacing ), m_dwAlign( dwAlign ) { m_context = (PangoContext*)g_object_ref( s_pPangoContext ); // m_context = pango_font_map_create_context( pango_cairo_font_map_get_default() ); cairo_font_options_t* option; option = cairo_font_options_create(); cairo_font_options_set_antialias ( option, CAIRO_ANTIALIAS_GRAY ); pango_cairo_context_set_font_options( m_context, option ); cairo_font_options_destroy(option); m_layout = pango_layout_new( m_context ); if ( nWidth >= 0 ) pango_layout_set_width( m_layout, nWidth * PANGO_SCALE ); else pango_layout_set_width( m_layout, -1 ); if ( nHeight >= 0 ) pango_layout_set_height( m_layout, nHeight * PANGO_SCALE ); else pango_layout_set_height( m_layout, nHeight ); pango_layout_set_justify( m_layout, false); pango_layout_set_indent( m_layout, 0 ); pango_layout_set_spacing( m_layout, nSpacing * PANGO_SCALE ); pango_layout_set_wrap( m_layout, PANGO_WRAP_WORD_CHAR ); m_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, m_nWidth, m_nHeight ); m_cr = cairo_create( m_surface ); pango_cairo_update_context( m_cr, m_context ); pango_layout_context_changed( m_layout ); } KTextLayout::~KTextLayout() { if ( m_layout ) g_object_unref( m_layout ); if ( m_context ) g_object_unref( m_context ); if ( m_cr ) cairo_destroy( m_cr ); if ( m_surface ) cairo_surface_destroy( m_surface ); } void KTextLayout::_Render( LPCSTR szText, double r, double g, double b, double a, double dX, double dY ) { cairo_set_source_rgba( m_cr, r, g, b, a ); cairo_move_to( m_cr, dX, dY); pango_layout_set_text( m_layout, szText, -1 ); pango_cairo_show_layout( m_cr, m_layout ); if ( g_bSaveToPng ) { static int nFileNo = 0; std::string strFileName; XStringUtil::Format( strFileName, "PNG-%06d.png", nFileNo++ ); cairo_surface_write_to_png( m_surface, strFileName.c_str() ); } } void KTextLayout::Render( KTextParagraph* pParagraph ) { Layout( pParagraph ); PangoAttrList* pAttrList; pAttrList = pParagraph->GetPangoAttrListWithoutColor(); pango_layout_set_attributes( m_layout, pAttrList ); pango_attr_list_unref( pAttrList ); if ( pParagraph->GetAttr()->bShadow ) { double dOffset = (pParagraph->GetAttr()->nFontSize / 10. ); _Render( pParagraph->GetString().c_str(), 0, 0, 0, 0.8, dOffset, dOffset ); } pAttrList = pParagraph->GetPangoAttrList(); pango_layout_set_attributes( m_layout, pAttrList ); pango_attr_list_unref( pAttrList ); _Render( pParagraph->GetString().c_str(), ((pParagraph->GetAttr()->dwColor & 0xff0000) >> 16) / 255.0, ((pParagraph->GetAttr()->dwColor & 0x00ff00) >> 8) / 255.0, ((pParagraph->GetAttr()->dwColor & 0x0000ff) >> 0) / 255.0, 1.0 ); } KSize KTextLayout::GetLayoutSize( KTextParagraph* pParagraph ) { if ( pParagraph->m_bEmoticon ) return KSize( 0, 0 ); Layout( pParagraph ); PangoAttrList* pAttrList = pParagraph->GetPangoAttrListWithoutColor(); pango_layout_set_attributes( m_layout, pAttrList ); pango_attr_list_unref( pAttrList ); pango_layout_set_text( m_layout, pParagraph->GetString().c_str(), -1 ); int nWidth, nHeight; pango_layout_get_pixel_size( m_layout, &nWidth, &nHeight ); return KSize( nWidth, nHeight ); } void KTextLayout::SplitLine( std::vector< std::string > & vecLineList, const std::string& _strOriginal, const char* szFontName, int nFontSize, bool bBold ) { PangoFontDescription *desc; std::string strOriginal = multibyte_to_utf8( _strOriginal ); std::string strFont; XStringUtil::Format( strFont, "%s %d", szFontName, nFontSize ); desc = pango_font_description_from_string( strFont.c_str() ); if ( bBold ) pango_font_description_set_weight( desc, PANGO_WEIGHT_BOLD ); pango_layout_set_font_description( m_layout, desc ); pango_font_description_free( desc ); pango_layout_set_text( m_layout, strOriginal.c_str(), -1 ); int nLines = pango_layout_get_line_count( m_layout ); PangoLayoutLine* pLine; std::string strLine; for ( int i = 0; i < nLines; ++i ) { pLine = pango_layout_get_line_readonly( m_layout, i ); strLine = strOriginal.substr( pLine->start_index, pLine->length ); vecLineList.push_back( utf8_to_multibyte( strLine ) ); } } void KTextLayout::Layout( KTextParagraph* pParagraph ) { PangoFontDescription *desc; std::string strFont; XStringUtil::Format( strFont, "%s %d", pParagraph->GetAttr()->strFontName.c_str(), pParagraph->GetAttr()->nFontSize ); desc = pango_font_description_from_string( strFont.c_str() ); if ( pParagraph->GetAttr()->bBold ) pango_font_description_set_weight( desc, PANGO_WEIGHT_BOLD ); pango_layout_set_font_description( m_layout, desc ); pango_font_description_free( desc ); if ( (m_dwAlign & KTextParagraph::KTALIGN_HCENTER) == KTextParagraph::KTALIGN_HCENTER ) pango_layout_set_alignment( m_layout, PANGO_ALIGN_CENTER ); else if ( (m_dwAlign & KTextParagraph::KTALIGN_LEFT) == KTextParagraph::KTALIGN_LEFT ) pango_layout_set_alignment( m_layout, PANGO_ALIGN_LEFT ); else if ( (m_dwAlign & KTextParagraph::KTALIGN_RIGHT) == KTextParagraph::KTALIGN_RIGHT ) pango_layout_set_alignment( m_layout, PANGO_ALIGN_RIGHT ); } #endif