LoginSignup
0
1

More than 5 years have passed since last update.

C++ Builder XE4 > 違い > this->ScaleBy(100 / s_curFactor, 100); と this->ScaleBy(100, s_curFactor * 100); > 前者では計算誤差が生じる

Posted at
動作環境
C++ Builder XE4

関連

上記にて作業中、IDEのバグによる誤差の蓄積に気づいた。

今後、同じ問題に遭遇するかもしれないので、記事として切出す。

症状と実装

  • フォントサイズを変更可能なソフト
  • ScaleBy()を使う
  • フォントサイズ変更を繰返すことで誤差が蓄積される
    • TButtonの横幅が狭くなる
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

enum {
    FONT_SMALL = 0,
    FONT_MEDIUM,
    FONT_LARGE,
    FONT_EXTRA_LARGE,
    FONT_HUGE,
};

static float s_curFactor = 1.0; // 拡大率
static int s_cntChangeSize = 0; // フォントサイズ変更回数

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CMB_fontSizeChange(TObject *Sender)
{
    s_cntChangeSize += 1;
    Label1->Caption = IntToStr(s_cntChangeSize);

//-----------
    int preH = this->Height;
    int preW = this->Width;

    this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す
//  this->ScaleBy(100, s_curFactor * 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す

    switch(CMB_fontSize->ItemIndex){
    case FONT_SMALL:
        s_curFactor = 1.00; // 結果を見て調整する
        break;
    case FONT_MEDIUM:
        s_curFactor = 1.20; // 結果を見て調整する
        break;
    case FONT_LARGE:
        s_curFactor = 1.40; // 結果を見て調整する
        break;
    case FONT_EXTRA_LARGE:
        s_curFactor = 1.60; // 結果を見て調整する
        break;
    case FONT_HUGE:
        s_curFactor = 1.80; // 結果を見て調整する
        break;
    }

    this->ScaleBy(100 * s_curFactor, 100);

    // 元の高さ、幅に戻すことで、パネルのコンポーネントのサイズだけを拡大できる
    // (結果として、TChartは小さくなる)
    this->Height = preH;
    this->Width = preW;
}
//---------------------------------------------------------------------------

再現方法

  • 1. フォントサイズをHugeにする
  • 2. フォントサイズをSmallにする
  • 3. 手順1に戻る (s_cntChangeSizeが16になるまで)

2018-10-22_17h27_23.png

ButtonのBの文字が半分消えてしまう。

対策

対策を行うが、以下を検討した。

  • IDEのバージョンアップ時にも問題がないような対策

バージョン固有の不具合対応は、将来のIDEバージョンアップ時にはまる。
どのバージョンでも問題がない実装が望ましい。

下記の方法で対処できることを見つけた。

//  this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す
    this->ScaleBy(100, s_curFactor * 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す

2018-10-22_17h31_17.png

ButtonのBの文字表示に問題がなくなった。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1