optimized rendering tab labels, more and more (ref.4197)
@@ -633,7 +633,7 @@ | ||
633 | 633 | int label_width_org; // 変更前のタブの文字数 |
634 | 634 | int label_width; // 変更後のタブの文字数 |
635 | 635 | int width_total = 0; |
636 | - int n, tab_width, layout_width; | |
636 | + int tab_width, max_width; | |
637 | 637 | |
638 | 638 | for( int i = 0; i < pages; ++i ){ |
639 | 639 |
@@ -645,7 +645,9 @@ | ||
645 | 645 | |
646 | 646 | bool cut_suffix = false; |
647 | 647 | label_width_org = label_width = ulabel.length(); |
648 | + | |
648 | 649 | tab_width = -1; // タブ幅を未計算状態に初期化 |
650 | + max_width = avg_width_tab * ( i + 1 ) - width_total; // 最大値 ( 収まらないときマイナスになる ) | |
649 | 651 | |
650 | 652 | // 長すぎるタブの文字列は表示しないよう、あらかじめ最大値を256に制限する |
651 | 653 | if( label_width > 256 ){ |
@@ -653,7 +655,7 @@ | ||
653 | 655 | ulabel.resize( label_width ); |
654 | 656 | } |
655 | 657 | |
656 | - // 一端、全てのタブの幅を平均値以下に縮める | |
658 | + // タブの幅を最大値以下に縮める | |
657 | 659 | while( label_width > CONFIG::get_tab_min_str() ){ |
658 | 660 | |
659 | 661 | if( ! cut_suffix && label_width < label_width_org ){ |
@@ -662,56 +664,63 @@ | ||
662 | 664 | } |
663 | 665 | |
664 | 666 | m_layout_tab->set_text( ulabel ); |
665 | - tab_width = m_layout_tab->get_pixel_logical_extents().get_width() + label_margin; | |
667 | + int width = m_layout_tab->get_pixel_logical_extents().get_width() + label_margin; | |
666 | 668 | |
667 | 669 | #ifdef _DEBUG_RESIZE_TAB |
668 | - std::cout << "s " << i << " " << width << " / " << avg_width_tab | |
670 | + std::cout << "s " << i << " " << width << " / " << max_width << " + " << width_total | |
669 | 671 | << " lng = " << label_width << " : " << ulabel << std::endl; |
670 | 672 | #endif |
673 | + if( width < max_width ){ // 最大値以下 | |
674 | + tab_width = width; // タブ幅を保存 | |
675 | + break; | |
676 | + } | |
671 | 677 | |
672 | - if( tab_width < avg_width_tab ) break; // 平均値以下 | |
673 | - | |
674 | - n = 1; | |
675 | - if( label_width > 16 && tab_width > avg_width_tab * 2 ){ | |
676 | - n = label_width / 4; // 2倍以上差がある場合は、1/4文字を消す | |
678 | + // 最大値を越えていたら、概算で収まるように縮める | |
679 | + int n = label_width - (int)( (double)label_width * max_width / width ); | |
680 | + if( n < 1 ) n = 1; | |
681 | + if( label_width - n < CONFIG::get_tab_min_str() ){ | |
682 | + n = label_width - CONFIG::get_tab_min_str(); | |
677 | 683 | } |
678 | 684 | label_width -= n; |
679 | 685 | ulabel.erase( label_width, n ); // 末尾のn文字を消す |
680 | - tab_width = -1; // タブ幅を初期化 | |
681 | 686 | } |
682 | 687 | |
683 | 688 | // 横をはみださないようにタブ幅を延ばしていく |
684 | 689 | for(;;){ |
685 | 690 | |
686 | - if( label_width >= label_width_org ) break; | |
691 | + if( label_width >= label_width_org ) break; // 全て収まった | |
692 | + if( max_width < 0 ) break; // 確実に収まらない | |
687 | 693 | |
688 | 694 | ulabel.insert( label_width, 1, ulabel_org[ label_width ] ); // 末尾の1文字を戻す |
689 | 695 | ++label_width; |
690 | 696 | |
691 | 697 | m_layout_tab->set_text( ulabel ); |
692 | - layout_width = m_layout_tab->get_pixel_logical_extents().get_width() + label_margin; | |
698 | + int width = m_layout_tab->get_pixel_logical_extents().get_width() + label_margin; | |
693 | 699 | |
694 | 700 | #ifdef _DEBUG_RESIZE_TAB |
695 | - std::cout << "w " << i << " " << width << " / " << avg_width_tab | |
696 | - << " total= " << width_total + width << " / " << avg_width_tab * ( i + 1 ) | |
701 | + std::cout << "w " << i << " " << width << " / " << max_width << " + " << width_total | |
697 | 702 | << " lng = " << label_width << " : " << ulabel << std::endl; |
698 | 703 | #endif |
699 | 704 | // 最大値を越えたらひとつ戻してbreak; |
700 | - if( width_total + layout_width > avg_width_tab * ( i + 1 ) ){ | |
705 | + if( width > max_width ){ | |
701 | 706 | --label_width; |
702 | 707 | ulabel.erase( label_width, 1 ); // 末尾の1文字を消す |
703 | 708 | break; |
704 | 709 | } |
705 | - tab_width = layout_width; // 最大値を超えていないタブ幅を保存 | |
710 | + tab_width = width; // 最大値を超えていないタブ幅を保存 | |
706 | 711 | } |
707 | 712 | |
708 | 713 | // タブ幅を確定する |
709 | 714 | if( tab_width < 0 ){ |
710 | 715 | m_layout_tab->set_text( ulabel ); |
711 | - width_total += ( m_layout_tab->get_pixel_logical_extents().get_width() + label_margin ); | |
712 | - } else { | |
713 | - width_total += tab_width; | |
716 | + tab_width = m_layout_tab->get_pixel_logical_extents().get_width() + label_margin; | |
717 | + | |
718 | +#ifdef _DEBUG_RESIZE_TAB | |
719 | + std::cout << "f " << i << " " << tab_width << " / " << max_width << " + " << width_total | |
720 | + << " lng = " << label_width << " : " << ulabel << std::endl; | |
721 | +#endif | |
714 | 722 | } |
723 | + width_total += tab_width; | |
715 | 724 | |
716 | 725 | tab->resize_tab( label_width ); |
717 | 726 | } |
@@ -12,6 +12,9 @@ | ||
12 | 12 | #ifdef _DEBUG_CARETMOVE |
13 | 13 | #include <iostream> |
14 | 14 | #endif |
15 | +#ifdef _DEBUG_RESIZE_TAB | |
16 | +#include <iostream> | |
17 | +#endif | |
15 | 18 | |
16 | 19 | #include <assert.h> |
17 | 20 |