Ticket #6004: osd.xml.rtl.v3.patch
File osd.xml.rtl.v3.patch, 22.6 KB (added by , 15 years ago) |
---|
-
mythtv/libs/libmythtv/libmythtv.pro
==== osd.xml.rtl.patch by Tony Arie Kolev 17-Dec-2008 ==== OSD text of RTL languages fix for text falling out of pop-up box background ==== found after RTL text was correctly Justified to Right side (patch ticket #6004) ==== ==== to apply store it in top directory of MythTV sources and do: ==== patch -p0 < osd.xml.rtl.patch ====
243 243 244 244 # On screen display (video output overlay) 245 245 using_fribidi:DEFINES += USING_FRIBIDI 246 HEADERS += osd.h osdtypes.h 246 HEADERS += osd.h osdtypes.h rtl.h 247 247 HEADERS += osdsurface.h osdlistbtntype.h 248 248 HEADERS += osdimagecache.h osdtypeteletext.h 249 249 HEADERS += udpnotify.h 250 SOURCES += osd.cpp osdtypes.cpp 250 SOURCES += osd.cpp osdtypes.cpp rtl.cpp 251 251 SOURCES += osdsurface.cpp osdlistbtntype.cpp 252 252 SOURCES += osdimagecache.cpp osdtypeteletext.cpp 253 253 SOURCES += udpnotify.cpp -
mythtv/libs/libmythtv/osdtypes.h
12 12 #include <qcolor.h> 13 13 #include "cc708window.h" 14 14 #include "osdimagecache.h" 15 #include "rtl.h" 15 16 16 17 using namespace std; 17 18 … … 238 239 void SetButton(bool is_button) { m_button = is_button; } 239 240 void SetEntryNum(int entrynum) { m_entrynum = entrynum; } 240 241 241 QString ConvertFromRtoL(const QString &text) const;242 243 static QString BasicConvertFromRtoL(const QString &text);244 242 245 243 protected: 246 244 ~OSDTypeText(); … … 292 290 mutable uint m_draw_info_len; 293 291 mutable vector<DrawInfo> m_draw_info; 294 292 295 mutable QMutex fribidi_lock; 296 mutable QTextCodec *codeci; 293 RTL *rtl; 297 294 }; 298 295 299 296 class OSDTypeImage : public OSDType -
mythtv/libs/libmythtv/osdtypes.cpp
17 17 #include "mythcontext.h" 18 18 #include "mythdialogs.h" 19 19 20 #ifdef USING_FRIBIDI21 #include "fribidi/fribidi.h"22 #include <qtextcodec.h>23 #endif // USING_FRIBIDI24 20 25 21 /// Shared OSD image cache 26 22 OSDImageCache OSDTypeImage::c_cache; … … 707 703 m_linespacing(1.5f), 708 704 709 705 m_draw_info_str(""), 710 m_draw_info_len(0), 711 712 codeci(NULL) 706 m_draw_info_len(0) 713 707 { 708 rtl=new RTL(); 714 709 } 715 710 716 711 OSDTypeText::OSDTypeText(const OSDTypeText &other) : … … 745 740 m_linespacing(1.5f), 746 741 747 742 m_draw_info_str(""), 748 m_draw_info_len(0) ,743 m_draw_info_len(0) 749 744 750 codeci(NULL)751 745 { 752 746 QMutexLocker locker(&other.m_lock); 753 747 … … 779 773 m_scrollinit = other.m_scrollinit; 780 774 781 775 m_linespacing = other.m_linespacing; 776 rtl=new RTL(); 782 777 } 783 778 784 779 OSDTypeText::~OSDTypeText() 785 780 { 781 if (rtl) 782 delete rtl; 786 783 } 787 784 788 785 void OSDTypeText::SetAltFont(TTFFont *font) … … 791 786 m_altfont = font; 792 787 } 793 788 794 QString OSDTypeText::BasicConvertFromRtoL(const QString &text)795 {796 QStringList rtl_string_composer;797 bool handle_rtl = false;798 QChar prev_char;799 800 // Handling Right-to-Left languages.801 // Left-to-Right languages are not affected.802 for (int i = (int)text.length() - 1; i >= 0; i--)803 {804 QChar::Direction text_dir = text[i].direction();805 if (text_dir != QChar::DirR &&806 text_dir != QChar::DirRLE &&807 text_dir != QChar::DirRLO)808 {809 if (handle_rtl || rtl_string_composer.empty())810 rtl_string_composer.append(QString());811 812 if (text[i].isSpace() && !prev_char.isNull()813 && prev_char.isDigit() && handle_rtl)814 rtl_string_composer.back().append(text[i]);815 else816 rtl_string_composer.back().prepend(text[i]);817 818 prev_char = text[i];819 820 handle_rtl = false;821 }822 else823 {824 if (!handle_rtl)825 {826 rtl_string_composer.append(QString());827 handle_rtl = true;828 prev_char = QChar();829 }830 rtl_string_composer.back().append(text[i]);831 }832 }833 834 QString output = rtl_string_composer.join("");835 836 return QDeepCopy<QString>(output);837 }838 839 QString OSDTypeText::ConvertFromRtoL(const QString &text) const840 {841 QString output = BasicConvertFromRtoL(text);842 843 #ifdef USING_FRIBIDI844 QMutexLocker locker(&fribidi_lock);845 if (!codeci)846 codeci = QTextCodec::codecForName("utf8");847 848 if (!codeci)849 return output;850 851 QCString temp = codeci->fromUnicode(output);852 853 FriBidiCharType base;854 size_t len;855 856 bool fribidi_flip_commas = true;857 base = (fribidi_flip_commas) ? FRIBIDI_TYPE_ON : FRIBIDI_TYPE_L;858 859 const char *ip = temp;860 FriBidiChar logical[strlen(ip) + 1], visual[strlen(ip) + 1];861 862 int char_set_num = fribidi_parse_charset("UTF-8");863 864 len = fribidi_charset_to_unicode(865 (FriBidiCharSet) char_set_num, ip, strlen(ip), logical);866 867 bool log2vis = fribidi_log2vis(868 logical, len, &base, visual, NULL, NULL, NULL); // output869 870 if (log2vis)871 len = fribidi_remove_bidi_marks(visual, len, NULL, NULL, NULL);872 873 output = "";874 for (size_t i = 0; i < len ; i++)875 output += QChar(visual[i]);876 #endif // USING_FRIBIDI877 878 return output;879 }880 789 881 790 void OSDTypeText::SetText(const QString &text) 882 791 { 883 792 QMutexLocker locker(&m_lock); 884 m_message = ConvertFromRtoL(text);793 m_message = text; 885 794 m_cursorpos = m_message.length(); 886 795 m_scrollinit = false; 887 796 } … … 895 804 void OSDTypeText::SetDefaultText(const QString &text) 896 805 { 897 806 QMutexLocker locker(&m_lock); 898 m_message = ConvertFromRtoL(text);807 m_message = text; 899 808 m_default_msg = QDeepCopy<QString>(m_message); 900 809 m_scrollinit = false; 901 810 } … … 1219 1128 { 1220 1129 QMutexLocker locker(&m_lock); 1221 1130 1131 bool isRTL=false; 1132 QString msg = rtl->ConvertFromRtoL(text,&isRTL); 1133 if (isRTL) m_right=true; 1134 1222 1135 if (m_centered || m_right) 1223 1136 { 1224 1137 int textlength = 0; … … 1244 1157 if ((m_usingalt || m_selected) && m_altfont) 1245 1158 font = m_altfont; 1246 1159 1247 font->DrawString(surface, rect.left(), rect.top(), text,1160 font->DrawString(surface, rect.left(), rect.top(), msg, 1248 1161 rect.right(), rect.bottom(), alphamod, doubl); 1249 1162 1250 1163 // draw cursor -
mythtv/libs/libmythtv/osdlistbtntype.h
37 37 #include "osdtypes.h" 38 38 #include "ttfont.h" 39 39 #include "generictree.h" 40 #include "rtl.h" 40 41 41 42 class OSDListBtnType; 42 43 class OSDListBtnTypeItem; … … 313 314 QRect m_arrowRect; 314 315 QRect m_pixmapRect; 315 316 QRect m_textRect; 317 RTL *rtl; 316 318 }; 317 319 318 320 -
mythtv/libs/libmythtv/osdlistbtntype.cpp
767 767 tw -= (m_showArrow) ? m_arrowRect.width() + margin : 0; 768 768 tw -= (m_pixmap) ? m_pixmapRect.width() + margin : 0; 769 769 m_textRect = QRect(tx, 0, tw, height); 770 rtl=new RTL(); 770 771 771 772 m_parent->InsertItem(this); 772 773 } … … 774 774 OSDListBtnTypeItem::~OSDListBtnTypeItem() 775 775 { 776 776 if (m_parent) 777 777 m_parent->RemoveItem(this); 778 if (rtl) 779 delete rtl; 778 780 } 779 781 780 782 void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font, 781 783 int fade, int maxfade, int x, int y) … … 828 829 QRect tr(m_textRect); 829 830 tr.moveBy(x, y); 830 831 tr.moveBy(0, font->Size() / 4); 831 font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom()); 832 bool isRTL=false; 833 QString m_message = rtl->ConvertFromRtoL(m_text,&isRTL); 834 if (isRTL) 835 { 836 int textlength = 0; 837 font->CalcWidth(m_text, &textlength); 838 int xoffset = tr.width() - textlength; 839 if (xoffset > 0) 840 tr.moveBy(xoffset, 0); 841 } 842 font->DrawString(surface, tr.x(), tr.y(), m_message, tr.right(), tr.bottom()); 832 843 } -
mythtv/libs/libmythtv/rtl.h
1 #ifndef RTL_H_ 2 #define RTL_H_ 3 class RTL { 4 private: 5 mutable QMutex fribidi_lock; 6 mutable QTextCodec *codeci; 7 public: 8 RTL(); 9 ~RTL(); 10 QString ConvertFromRtoL(const QString &text,bool *isRTL) const; 11 static QString BasicConvertFromRtoL(const QString &text,bool *isRTL); 12 }; 13 #endif -
mythtv/libs/libmythtv/rtl.cpp
1 /* 2 * Right To Left Languages manipulation for OSD 3 * Tony Arie Kolev 14-Dec-2008 4 * RTL conversion taken from previously implemented patches: 5 * release 0.21-192.89 6 * #4885: patch: multi line BiDi support in OSD 7 * (some corrections made to fix double conversion when fribidi-devel is installed) 8 * and a new RTL class introduced to integrate unsuccessful attempts 9 * to make RTL conversion in osdtypes.cpp and later in ttfont.cpp 10 * now it may be used everywhere when needed 11 * 12 */ 13 #include <qimage.h> 14 #include <qmap.h> 15 #include <qregexp.h> 16 #include <qdeepcopy.h> 17 18 #include <iostream> 19 #include <algorithm> 20 using namespace std; 21 22 #include "yuv2rgb.h" 23 #include "osdtypes.h" 24 #include "ttfont.h" 25 #include "osdsurface.h" 26 #include "osdlistbtntype.h" 27 #include "osdtypeteletext.h" 28 29 #include "mythcontext.h" 30 #include "mythdialogs.h" 31 32 #ifdef USING_FRIBIDI 33 #include "fribidi/fribidi.h" 34 #include <qtextcodec.h> 35 #endif // USING_FRIBIDI 36 37 #include "rtl.h" 38 39 RTL::RTL() : codeci(NULL) 40 { 41 } 42 RTL::~RTL() { 43 } 44 45 QString RTL::BasicConvertFromRtoL(const QString &text,bool *isRTL) 46 { 47 QStringList rtl_string_composer; 48 bool handle_rtl = false; 49 QChar prev_char; 50 51 // Handling Right-to-Left languages. 52 // Left-to-Right languages are not affected. 53 for (int i = (int)text.length() - 1; i >= 0; i--) 54 { 55 QChar::Direction text_dir = text[i].direction(); 56 if (text_dir != QChar::DirR && 57 text_dir != QChar::DirRLE && 58 text_dir != QChar::DirRLO) 59 { 60 if (handle_rtl || rtl_string_composer.empty()) 61 rtl_string_composer.append(QString()); 62 63 if (text[i].isSpace() && !prev_char.isNull() 64 && prev_char.isDigit() && handle_rtl) 65 rtl_string_composer.back().append(text[i]); 66 else 67 rtl_string_composer.back().prepend(text[i]); 68 69 prev_char = text[i]; 70 71 handle_rtl = false; 72 } 73 else 74 { 75 if (!handle_rtl) 76 { 77 rtl_string_composer.append(QString()); 78 handle_rtl = true; 79 prev_char = QChar(); 80 } 81 rtl_string_composer.back().append(text[i]); 82 *isRTL=true; 83 } 84 } 85 86 QString output = rtl_string_composer.join(""); 87 88 return QDeepCopy<QString>(output); 89 } 90 91 QString RTL::ConvertFromRtoL(const QString &text,bool *isRTL) const 92 { 93 *isRTL=false; 94 #ifndef USING_FRIBIDI 95 QString output = BasicConvertFromRtoL(text,isRTL); 96 #endif 97 #ifdef USING_FRIBIDI 98 QString output = text; 99 QMutexLocker locker(&fribidi_lock); 100 if (!codeci) 101 codeci = QTextCodec::codecForName("utf8"); 102 103 if (!codeci) 104 return output; 105 106 QCString temp = codeci->fromUnicode(output); 107 108 FriBidiCharType base; 109 size_t len; 110 111 112 bool fribidi_flip_commas = true; 113 base = (fribidi_flip_commas) ? FRIBIDI_TYPE_ON : FRIBIDI_TYPE_L; 114 115 const char *ip = temp; 116 FriBidiChar logical[strlen(ip) + 1], visual[strlen(ip) + 1]; 117 118 int char_set_num = fribidi_parse_charset("UTF-8"); 119 120 len = fribidi_charset_to_unicode( 121 (FriBidiCharSet) char_set_num, ip, strlen(ip), logical); 122 123 FriBidiLevel embedding_level_list[len]; 124 FriBidiStrIndex position_L_to_V_list[len]; 125 FriBidiStrIndex position_V_to_L_list[len]; 126 127 bool log2vis = fribidi_log2vis( 128 logical, len, &base, visual, position_L_to_V_list, position_V_to_L_list, embedding_level_list); // output 129 130 if (log2vis) { 131 len = fribidi_remove_bidi_marks(visual, len, NULL, NULL, NULL); 132 for (int i=0;i<(int)len;i++) { 133 if (embedding_level_list[i]%2==1) { 134 *isRTL=true; 135 break; 136 } 137 } 138 } 139 output = ""; 140 for (size_t i = 0; i < len ; i++) 141 output += QChar(visual[i]); 142 #endif // USING_FRIBIDI 143 144 return output; 145 } 146 -
myththemes/Gray-OSD/osd.xml
425 425 <multiline>yes</multiline> 426 426 </textarea> 427 427 <textarea name="option1"> 428 <area>100,255, 455,30</area>428 <area>100,255,395,30</area> 429 429 <font>infofont</font> 430 430 <altfont>infofontgray</altfont> 431 431 </textarea> 432 432 <textarea name="option2"> 433 <area>100,285, 455,30</area>433 <area>100,285,395,30</area> 434 434 <font>infofont</font> 435 435 <altfont>infofontgray</altfont> 436 436 </textarea> 437 437 <textarea name="option3"> 438 <area>100,315, 455,30</area>438 <area>100,315,395,30</area> 439 439 <font>infofont</font> 440 440 <altfont>infofontgray</altfont> 441 441 </textarea> 442 442 <textarea name="option4"> 443 <area>100,345, 455,30</area>443 <area>100,345,395,30</area> 444 444 <font>infofont</font> 445 445 <altfont>infofontgray</altfont> 446 446 </textarea> 447 447 <textarea name="option5"> 448 <area>100,375, 455,30</area>448 <area>100,375,395,30</area> 449 449 <font>infofont</font> 450 450 <altfont>infofontgray</altfont> 451 451 </textarea> -
myththemes/isthmus/osd.xml
315 315 316 316 <container name="settings"> 317 317 <textarea name="settings"> 318 <area>50,50, 350,32</area>318 <area>50,50,250,32</area> 319 319 <font>settings</font> 320 320 </textarea> 321 321 </container> … … 339 339 <multiline>yes</multiline> 340 340 </textarea> 341 341 <textarea name="option1"> 342 <area>100,255, 455,30</area>342 <area>100,255,395,30</area> 343 343 <font>infofont</font> 344 344 <altfont>infofontgray</altfont> 345 345 </textarea> 346 346 <textarea name="option2"> 347 <area>100,285, 455,30</area>347 <area>100,285,395,30</area> 348 348 <font>infofont</font> 349 349 <altfont>infofontgray</altfont> 350 350 </textarea> 351 351 <textarea name="option3"> 352 <area>100,315, 455,30</area>352 <area>100,315,395,30</area> 353 353 <font>infofont</font> 354 354 <altfont>infofontgray</altfont> 355 355 </textarea> 356 356 <textarea name="option4"> 357 <area>100,345, 455,30</area>357 <area>100,345,395,30</area> 358 358 <font>infofont</font> 359 359 <altfont>infofontgray</altfont> 360 360 </textarea> 361 361 <textarea name="option5"> 362 <area>100,375, 455,30</area>362 <area>100,375,395,30</area> 363 363 <font>infofont</font> 364 364 <altfont>infofontgray</altfont> 365 365 </textarea> -
myththemes/Iulius-OSD/osd.xml
251 251 252 252 <container name="settings"> 253 253 <textarea name="settings"> 254 <area>64,85, 350,32</area>254 <area>64,85,264,32</area> 255 255 <font>settings</font> 256 256 </textarea> 257 257 </container> -
myththemes/Retro-OSD/osd.xml
297 297 <position>30,30</position> 298 298 </image> 299 299 <textarea name="settings"> 300 <area>50,50, 350,32</area>300 <area>50,50,250,32</area> 301 301 <font>settings</font> 302 302 </textarea> 303 303 </container> … … 321 321 <multiline>yes</multiline> 322 322 </textarea> 323 323 <textarea name="option1"> 324 <area>120,239, 455,30</area>324 <area>120,239,395,30</area> 325 325 <font>notify</font> 326 326 <altfont>grayfont</altfont> 327 327 </textarea> 328 328 <textarea name="option2"> 329 <area>120,269, 455,30</area>329 <area>120,269,395,30</area> 330 330 <font>notify</font> 331 331 <altfont>grayfont</altfont> 332 332 </textarea> 333 333 <textarea name="option3"> 334 <area>120,299, 455,30</area>334 <area>120,299,395,30</area> 335 335 <font>notify</font> 336 336 <altfont>grayfont</altfont> 337 337 </textarea> 338 338 <textarea name="option4"> 339 <area>120,329, 455,30</area>339 <area>120,329,395,30</area> 340 340 <font>notify</font> 341 341 <altfont>grayfont</altfont> 342 342 </textarea> 343 343 <textarea name="option5"> 344 <area>120,359, 455,30</area>344 <area>120,359,395,30</area> 345 345 <font>notify</font> 346 346 <altfont>grayfont</altfont> 347 347 </textarea> -
myththemes/Titivillus-OSD/osd.xml
359 359 360 360 <container name="settings"> 361 361 <textarea name="settings"> 362 <area>50,50, 350,32</area>362 <area>50,50,250,32</area> 363 363 <font>settings</font> 364 364 </textarea> 365 365 </container> -
themes/blootube-osd/osd.xml
286 286 <position>30,30</position> 287 287 </image> 288 288 <textarea name="settings"> 289 <area>50,50, 350,32</area>289 <area>50,50,250,32</area> 290 290 <font>settings</font> 291 291 </textarea> 292 292 </container> … … 309 309 <multiline>yes</multiline> 310 310 </textarea> 311 311 <textarea name="option1"> 312 <area>120,269, 455,30</area>312 <area>120,269,395,30</area> 313 313 <font>notify</font> 314 314 <altfont>grayfont</altfont> 315 315 </textarea> 316 316 <textarea name="option2"> 317 <area>120,299, 455,30</area>317 <area>120,299,395,30</area> 318 318 <font>notify</font> 319 319 <altfont>grayfont</altfont> 320 320 </textarea> 321 321 <textarea name="option3"> 322 <area>120,329, 455,30</area>322 <area>120,329,395,30</area> 323 323 <font>notify</font> 324 324 <altfont>grayfont</altfont> 325 325 </textarea> 326 326 <textarea name="option4"> 327 <area>120,359, 455,30</area>327 <area>120,359,395,30</area> 328 328 <font>notify</font> 329 329 <altfont>grayfont</altfont> 330 330 </textarea> -
themes/ProjectGrayhem-OSD/osd.xml
284 284 <position>0,320</position> 285 285 </image> 286 286 <textarea name="settings"> 287 <area>50,335, 350,32</area>287 <area>50,335,250,32</area> 288 288 <font>settings</font> 289 289 </textarea> 290 290 </container> … … 307 307 <multiline>yes</multiline> 308 308 </textarea> 309 309 <textarea name="option1"> 310 <area>120,269, 455,30</area>310 <area>120,269,395,30</area> 311 311 <font>notify</font> 312 312 <altfont>grayfont</altfont> 313 313 </textarea> 314 314 <textarea name="option2"> 315 <area>120,299, 455,30</area>315 <area>120,299,395,30</area> 316 316 <font>notify</font> 317 317 <altfont>grayfont</altfont> 318 318 </textarea> 319 319 <textarea name="option3"> 320 <area>120,329, 455,30</area>320 <area>120,329,395,30</area> 321 321 <font>notify</font> 322 322 <altfont>grayfont</altfont> 323 323 </textarea> 324 324 <textarea name="option4"> 325 <area>120,359, 455,30</area>325 <area>120,359,395,30</area> 326 326 <font>notify</font> 327 327 <altfont>grayfont</altfont> 328 328 </textarea> -
mythtv/themes/defaultosd/osd.xml
239 239 240 240 <container name="settings"> 241 241 <textarea name="settings"> 242 <area>50,50, 350,32</area>242 <area>50,50,250,32</area> 243 243 <font>settings</font> 244 244 </textarea> 245 245 </container> -
mythtv/themes/blueosd/osd.xml
276 276 277 277 <container name="settings"> 278 278 <textarea name="settings"> 279 <area>50,50, 350,32</area>279 <area>50,50,250,32</area> 280 280 <font>settings</font> 281 281 </textarea> 282 282 </container> -
themes/ProjectGrayhem/theme.xml
1 1 <myththeme> 2 2 3 3 <background style="normal"> 4 <buttonarea> 60,95,390,402</buttonarea>4 <buttonarea>20,95,390,402</buttonarea> 5 5 <buttonspread>no</buttonspread> 6 6 <visiblerowlimit>6</visiblerowlimit> 7 7 <columns>1</columns> -
themes/blootube/theme.xml
38 38 <normal>button_off.png</normal> 39 39 <active>button_on.png</active> 40 40 <text> 41 <area>20,13, 0,0</area>41 <area>20,13,20,0</area> 42 42 <color>white</color> 43 43 <fontname>Bitstream Vera Sans</fontname> 44 44 <fontsize>21</fontsize> -
themes/blootubelite-wide/theme.xml
1 1 <myththeme> 2 2 3 3 <background style="normal"> 4 <buttonarea>620, 60,536,620</buttonarea>4 <buttonarea>620,90,536,620</buttonarea> 5 5 <buttonspread>no</buttonspread> 6 6 <visiblerowlimit>8</visiblerowlimit> 7 7 <columns>1</columns> … … 39 39 <normal>button_off.png</normal> 40 40 <active>button_on.png</active> 41 41 <text> 42 <area>20,11, 0,0</area>42 <area>20,11,30,0</area> 43 43 <color>white</color> 44 44 <fontname>Bitstream Vera Sans</fontname> 45 45 <fontsize>21</fontsize> -
themes/blootube-wide/theme.xml
1 1 <myththeme> 2 2 3 3 <background style="normal"> 4 <buttonarea>620, 70,536,650</buttonarea>4 <buttonarea>620,100,536,650</buttonarea> 5 5 <buttonspread>no</buttonspread> 6 6 <visiblerowlimit>8</visiblerowlimit> 7 7 <columns>1</columns> … … 44 44 <normal>button_off.png</normal> 45 45 <active>button_on.png</active> 46 46 <text> 47 <area>20,10, 0,0</area>47 <area>20,10,30,0</area> 48 48 <color>white</color> 49 49 <fontname>Bitstream Vera Sans</fontname> 50 50 <fontsize>21</fontsize> -
themes/neon-wide/theme.xml
39 39 <normal>button_off.png</normal> 40 40 <active>button_on.png</active> 41 41 <text> 42 <area>20,20, 0,0</area>42 <area>20,20,20,0</area> 43 43 <color>white</color> 44 44 <fontname>Vera</fontname> 45 45 <fontsize>21</fontsize>