Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment/use percentage in zooming #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sakura/sakura.vcxproj
Original file line number Diff line number Diff line change
@@ -527,6 +527,7 @@
<ClInclude Include="..\sakura_core\util\tchar_printf.h" />
<ClInclude Include="..\sakura_core\util\tchar_template.h" />
<ClInclude Include="..\sakura_core\util\window.h" />
<ClInclude Include="..\sakura_core\util\zoom.h" />
<ClInclude Include="..\sakura_core\version.h" />
<ClInclude Include="..\sakura_core\view\CCaret.h" />
<ClInclude Include="..\sakura_core\view\CEditView.h" />
@@ -921,6 +922,7 @@
<ClCompile Include="..\sakura_core\util\tchar_printf.cpp" />
<ClCompile Include="..\sakura_core\util\tchar_template.cpp" />
<ClCompile Include="..\sakura_core\util\window.cpp" />
<ClCompile Include="..\sakura_core\util\zoom.cpp" />
<ClCompile Include="..\sakura_core\view\CCaret.cpp" />
<ClCompile Include="..\sakura_core\view\CEditView.cpp" />
<ClCompile Include="..\sakura_core\view\CEditView_Cmdgrep.cpp" />
6 changes: 6 additions & 0 deletions sakura/sakura.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1097,6 +1097,9 @@
<ClInclude Include="..\sakura_core\GrepInfo.h">
<Filter>Cpp Source Files</Filter>
</ClInclude>
<ClInclude Include="..\sakura_core\util\zoom.h">
<Filter>Cpp Source Files\util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\resource\auto_scroll_center.cur">
@@ -2279,6 +2282,9 @@
<ClCompile Include="..\sakura_core\GrepInfo.cpp">
<Filter>Cpp Source Files</Filter>
</ClCompile>
<ClCompile Include="..\sakura_core\util\zoom.cpp">
<Filter>Cpp Source Files\util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="..\resource\auto_scroll_center.bmp">
5 changes: 3 additions & 2 deletions sakura_core/String_define.h
Original file line number Diff line number Diff line change
@@ -428,7 +428,8 @@
#define STR_MENU_KEYWORDINFO 34340
#define STR_MENU_OPENKEYWORDDIC 34341
#define STR_STATUS_ROW_COL 34342
#define STR_STATUS_FONTSIZE 35043
#define STR_STATUS_FONTZOOM_0 35043
#define STR_STATUS_FONTZOOM_1 35044
#define STR_INS_MODE_INS 34343
#define STR_INS_MODE_OVR 34344
#define STR_GREP_SEARCH_CONDITION 34345
@@ -1300,4 +1301,4 @@
#define STR_FILEDIALOG_MRU 35040
#define STR_FILEDIALOG_OPENFOLDER 35041

// Now using max number 35043 by STR_STATUS_FONTSIZE
// Now using max number 35044 by STR_STATUS_FONTZOOM_1
61 changes: 38 additions & 23 deletions sakura_core/cmd/CViewCommander_Settings.cpp
Original file line number Diff line number Diff line change
@@ -28,6 +28,9 @@
#include "util/shell.h"
#include "CPropertyManager.h"
#include "util/window.h"
#include "util/zoom.h"
#include "debug//Debug2.h"


/*! ツールバーの表示/非表示

@@ -251,18 +254,28 @@ void CViewCommander::Command_FONT( void )
/*! フォントサイズ設定
@param fontSize フォントサイズ(1/10ポイント単位)
@param shift フォントサイズを拡大or縮小するための変更量(fontSize=0のとき有効)
@param mode フォントサイズ設定対象(0:フォント設定 1:タイプ別設定(なければ0と同じ) 2:一時適用フォント)

@note TrueTypeのみサポート

@date 2013.04.10 novice 新規作成
*/
void CViewCommander::Command_SETFONTSIZE( int fontSize, int shift, int mode )
{
// The point sizes recommended by "The Windows Interface: An Application Design Guide", 1/10ポイント単位
static const INT sizeTable[] = { 8*10, 9*10, 10*10, (INT)(10.5*10), 11*10, 12*10, 14*10, 16*10, 18*10, 20*10, 22*10, 24*10, 26*10, 28*10, 36*10, 48*10, 72*10 };
// フォントサイズのズーム倍率テーブル
constexpr double nZoomFactors[] = {
0.01, 0.011, 0.0125, 0.015, 0.0175, 0.02, 0.0225, 0.025, 0.0275, 0.03, 0.035, 0.04, 0.045, 0.05, 0.06, 0.07, 0.08, 0.09,
0.1, 0.11, 0.125, 0.15, 0.175, 0.2, 0.225, 0.25, 0.275, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9,
1.0, 1.1, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0,
10.0, 11.0, 12.5, 15.0, 17.5, 20.0, 22.5, 25.0, 27.5, 30.0, 35.0, 40.0, 45.0, 50.0, 60.0, 70.0, 80.0, 90
};
// 設定できるフォントサイズの下限/上限/最小単位(いずれも1/10ポイント単位)
constexpr int nPointSizeMin = 10;
constexpr int nPointSizeMax = 720;
constexpr int nPointSizeUnit = 5;
static const ZoomSetting zoomSetting( nZoomFactors, nPointSizeMin, nPointSizeMax, nPointSizeUnit );
const LOGFONT& lf = (mode == 0 ? GetDllShareData().m_Common.m_sView.m_lf
: GetEditWindow()->GetLogfont( mode == 2 ));
INT nPointSize;

// TrueTypeのみ対応
if( OUT_STROKE_PRECIS != lf.lfOutPrecision && OUT_PS_ONLY_PRECIS != lf.lfOutPrecision ) {
@@ -273,32 +286,33 @@ void CViewCommander::Command_SETFONTSIZE( int fontSize, int shift, int mode )
return;
}

const int nCurrentPointSize = (mode == 0) ?
GetDllShareData().m_Common.m_sView.m_nPointSize :
GetEditWindow()->GetFontPointSize( mode == 2 );
const int nOriginalPointSize = GetEditWindow()->GetFontPointSize( false );
double nCurrentZoom = (mode == 2 && GetDocument()->m_blfCurTemp) ? GetDocument()->m_nCurrentZoom : 1.0;
int nPointSize = nCurrentPointSize;

if( 0 != fontSize ){
// フォントサイズを直接選択する場合
nPointSize = t_max(sizeTable[0], t_min(sizeTable[_countof(sizeTable)-1], fontSize));
} else if( 0 != shift ) {
nPointSize = std::clamp( fontSize, nPointSizeMin, nPointSizeMax );
}else if( 0 != shift ){
// 現在のフォントに対して、縮小or拡大したフォント選択する場合
nPointSize = (mode == 0 ? GetDllShareData().m_Common.m_sView.m_nPointSize
: GetEditWindow()->GetFontPointSize( mode == 2 ));

// フォントの拡大or縮小するためのサイズ検索
int i;
for( i = 0; i < _countof(sizeTable); i++) {
if( nPointSize <= sizeTable[i] ){
int index = t_max(0, t_min((int)_countof(sizeTable) - 1, (int)(i + shift)));
int nNewPointSize = sizeTable[index];
// フォントサイズが変わらないので終了
if (nPointSize == nNewPointSize) {
return;
}
nPointSize = nNewPointSize;
break;
}
double nPointSizeF = 0.0;
if( !GetZoomedValue( zoomSetting, nOriginalPointSize, nCurrentZoom, shift, &nPointSizeF, &nCurrentZoom ) ){
return;
}
nPointSize = (int)nPointSizeF;

// フォントサイズが変わらないなら終了
if( nPointSize == nCurrentPointSize ){
return;
}
} else {
}else{
// フォントサイズが変わらないので終了
return;
}

// 新しいフォントサイズ設定
int lfHeight = DpiPointsToPixels(-nPointSize, 10);
int nTypeIndex = -1;
@@ -324,7 +338,8 @@ void CViewCommander::Command_SETFONTSIZE( int fontSize, int shift, int mode )
GetDocument()->m_lfCur = lf;
GetDocument()->m_lfCur.lfHeight = lfHeight;
GetDocument()->m_nPointSizeCur = nPointSize;
GetDocument()->m_nPointSizeOrg = GetEditWindow()->GetFontPointSize(false);
GetDocument()->m_nPointSizeOrg = nOriginalPointSize;
GetDocument()->m_nCurrentZoom = nCurrentZoom;
}

HWND hwndFrame;
1 change: 1 addition & 0 deletions sakura_core/doc/CEditDoc.h
Original file line number Diff line number Diff line change
@@ -160,6 +160,7 @@ class CEditDoc
int m_nPointSizeCur; // 一時設定フォントサイズ
bool m_blfCurTemp; // フォント設定適用中
int m_nPointSizeOrg; // 元のフォントサイズ
double m_nCurrentZoom; // 一時設定フォントのズーム倍率
bool m_bTabSpaceCurTemp; // タブ幅一時設定適用中 // 2013.05.30 Moca

HBITMAP m_hBackImg;
3 changes: 2 additions & 1 deletion sakura_core/sakura_rc.rc
Original file line number Diff line number Diff line change
@@ -3409,7 +3409,8 @@ BEGIN
STR_ERR_DLGEDITVW6 "■"
STR_MENU_KEYWORDINFO "キーワードの説明をクリップボードにコピー"
STR_MENU_OPENKEYWORDDIC "キーワード辞書を開く"
STR_STATUS_FONTSIZE "%4d %%"
STR_STATUS_FONTZOOM_0 "%4.0f %%"
STR_STATUS_FONTZOOM_1 "%4.1f %%"
STR_STATUS_ROW_COL "%5d 行 %4d 桁"
STR_INS_MODE_INS "挿入"
STR_INS_MODE_OVR "上書"
180 changes: 180 additions & 0 deletions sakura_core/util/zoom.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*! @file
@brief ズーム倍率算出
*/
/*
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.

2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.
*/

#include "StdAfx.h"
#include "zoom.h"
#include <algorithm>
#include <cmath>

/*!
@brief 設定値の正当性判定
*/
bool ZoomSetting::IsValid() const
{
return (m_nValueMin <= m_nValueMax)
&& (0.0 <= m_nValueUnit)
&& std::is_sorted( m_vZoomFactors.begin(), m_vZoomFactors.end() );
}

/*!
@brief 値テーブル上における指定値の位置を取得
@param[in] vTable 値テーブル
@param[in] nValue 指定値
@return 位置
@note 「位置」は基本的にはテーブルのインデックスに相当しますが、
テーブル範囲外およびテーブル上の隣り合う二値間については 0.5 で表現します。
@note 例として vTable:{10, 20, 30} の場合の nValue と戻り値との関係を示します。
nValue | 0 | 5 | 10 | 15 | 25 | 30 | 35 | 40 |
-------|------|------|------|------|------|------|------|------|
戻り値 | -0.5 | -0.5 | 0.0 | 0.5 | 1.5 | 2.0 | 2.5 | 2.5 |
*/
static double GetPositionInTable( const std::vector<double>& vTable, double nValue )
{
double nPosition = (double)vTable.size() - 0.5;
for( size_t i = 0; i < vTable.size(); ++i ){
if( nValue <= vTable[i] ){
if( nValue == vTable[i] ){
nPosition = (double)i;
}else{
nPosition = (double)i - 0.5;
}
break;
}
}
return nPosition;
}

/*!
@brief 最小単位で丸めた値を取得
@param[in] nValue 対象値
@param[in] nUnit 最小単位(0.0 の場合は丸めなし)
@return 丸められた値
*/
static double GetQuantizedValue( double nValue, double nUnit )
{
return (0.0 < nUnit) ? std::floor( nValue / nUnit ) * nUnit : nValue;
}

/*!
@brief 基準値に対してズーム倍率を適用した値を取得
@param[in] zoomSetting ズーム設定
@param[in] nBaseValue 基準値
@param[in] nCurrentZoom 現在のズーム倍率
@param[in] nSteps ズーム段階の変更量
@param[in] pnValueOut 変更後のズーム倍率を適用した値
@param[in] pnZoomOut 変更後のズーム倍率
@return 丸められた値
*/
bool GetZoomedValue( const ZoomSetting& zoomSetting, double nBaseValue, double nCurrentZoom, int nSteps, double* pnValueOut, double* pnZoomOut )
{
if( nSteps == 0 ){
return false;
}

const bool bZoomUp = (0 < nSteps);
const int nTableIndexMin = 0;
const int nTableIndexMax = (int)zoomSetting.m_vZoomFactors.size() - 1;

const double nPosition = GetPositionInTable( zoomSetting.m_vZoomFactors, nCurrentZoom );
int nTableIndex = (int)(bZoomUp ? std::floor( nPosition ) : std::ceil( nPosition ));
if( (!bZoomUp && nTableIndex <= nTableIndexMin) || (bZoomUp && nTableIndexMax <= nTableIndex) ){
// 現在の倍率がすでに倍率テーブルの範囲外でかつ
// さらに外側へ移動しようとした場合は今の位置を維持
return false;
}

const double nCurrentValue = GetQuantizedValue( nBaseValue * nCurrentZoom, zoomSetting.m_nValueUnit );
const double nValueMin = std::min( {zoomSetting.m_nValueMin, nBaseValue, nCurrentValue} );
const double nValueMax = std::max( {zoomSetting.m_nValueMax, nBaseValue, nCurrentValue} );
double nNextValue = nCurrentValue;
double nNextZoom = nCurrentZoom;
double nLastValue = nCurrentValue;
double nLastZoom = nCurrentZoom;
bool bFindingOneMoreChange = false;

// 最小単位で丸めた後の値が変更前の値から変わらなければ
// 変わる位置までインデックスを動かしていく
nTableIndex += nSteps;
// 本当は while( true ) で良いが万一の暴走回避のため有限回
for( size_t i = 0; i < zoomSetting.m_vZoomFactors.size(); ++i ){
int clampedIndex = std::clamp( nTableIndex, nTableIndexMin, nTableIndexMax );
nNextZoom = zoomSetting.m_vZoomFactors[clampedIndex];
nNextValue = GetQuantizedValue( nBaseValue * nNextZoom, zoomSetting.m_nValueUnit );

if( bFindingOneMoreChange ){
if( nNextValue != nLastValue || clampedIndex != nTableIndex ){
nNextValue = nLastValue;
nNextZoom = nLastZoom;
break;
}
}else{
// 値の上下限を超過したら上下限に丸めて終わる
// 倍率は丸めた後のサイズで再計算
double clampedValue = std::clamp( nNextValue, nValueMin, nValueMax );
if( nNextValue != clampedValue ){
if( nBaseValue != 0.0 ){
nNextZoom = clampedValue / nBaseValue;
}
nNextValue = clampedValue;
break;
}

// 倍率テーブルの端まで到達していたら終わり
if( clampedIndex != nTableIndex ){
break;
}

bool bSizeChanged = (nNextValue != nCurrentValue);
if( bZoomUp ){
// 拡大側は値が変わったらすぐ終わる
if( bSizeChanged ){
break;
}
}else{
// 縮小側は一度値が変わった後もう一度値が変わる位置までインデックスを進めてから終わる
if( bSizeChanged ){
bFindingOneMoreChange = true;
}
}
}

nLastValue = nNextValue;
nLastZoom = nNextZoom;
nTableIndex += bZoomUp ? 1 : -1;
};

if( nCurrentValue == nNextValue ){
return false;
}

if( pnValueOut != NULL ){
*pnValueOut = nNextValue;
}
if( pnZoomOut != NULL ){
*pnZoomOut = nNextZoom;
}

return true;
}
61 changes: 61 additions & 0 deletions sakura_core/util/zoom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*! @file
@brief ズーム倍率算出
*/
/*
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/

#ifndef SAKURA_ZOOM_0CD4E589_F708_48BF_8601_8BF851827765_H_
#define SAKURA_ZOOM_0CD4E589_F708_48BF_8601_8BF851827765_H_
#pragma once

#include <vector>

/*!
@brief ズーム設定を保持
*/
struct ZoomSetting
{
/*!
@brief コンストラクタ
@param[in] nZoomFactors ズーム倍率の並び(昇順)
@param[in] nValueMin 下限値(上限値以下)
@param[in] nValueMax 上限値(下限値以上)
@param[in] nValueUnit 値の最小単位(0以上)
*/
template<size_t nCount>
ZoomSetting( const double (&nZoomFactors)[nCount], double nValueMin, double nValueMax, double nValueUnit ) :
m_vZoomFactors( std::begin( nZoomFactors ), std::end( nZoomFactors ) ),
m_nValueMin( nValueMin ),
m_nValueMax( nValueMax ),
m_nValueUnit( nValueUnit )
{}

const std::vector<double> m_vZoomFactors;
const double m_nValueMin;
const double m_nValueMax;
const double m_nValueUnit;

bool IsValid() const;
};

bool GetZoomedValue( const ZoomSetting& zoomSetting, double nBaseValue, double nCurrentZoom, int nSteps, double* pnValueOut, double* pnZoomOut );
#endif /* SAKURA_ZOOM_0CD4E589_F708_48BF_8601_8BF851827765_H_ */
9 changes: 6 additions & 3 deletions sakura_core/view/CCaret.cpp
Original file line number Diff line number Diff line change
@@ -836,9 +836,12 @@ void CCaret::ShowCaretPosInfo()
}

WCHAR szFontSize[16];
int currentPointSize = m_pEditDoc->m_pcEditWnd->GetFontPointSize( true );
int originalPointSize = m_pEditDoc->m_pcEditWnd->GetFontPointSize( false );
auto_sprintf( szFontSize, LS( STR_STATUS_FONTSIZE ), 100 * currentPointSize / originalPointSize );
double nZoomPercentage = m_pEditDoc->m_blfCurTemp ? (m_pEditDoc->m_nCurrentZoom * 100.0) : 100.0;
if( nZoomPercentage < 5.0 ){
auto_sprintf( szFontSize, LS( STR_STATUS_FONTZOOM_1 ), nZoomPercentage );
}else{
auto_sprintf( szFontSize, LS( STR_STATUS_FONTZOOM_0 ), nZoomPercentage );
}

auto& statusBar = m_pEditDoc->m_pcEditWnd->m_cStatusBar;

3 changes: 2 additions & 1 deletion sakura_lang_en_US/sakura_lang_rc.rc
Original file line number Diff line number Diff line change
@@ -3460,7 +3460,8 @@ BEGIN
STR_ERR_DLGEDITVW6 "■"
STR_MENU_KEYWORDINFO "Copy Keyword description to clipboard"
STR_MENU_OPENKEYWORDDIC "Open keyword dictionary"
STR_STATUS_FONTSIZE "%4d %%"
STR_STATUS_FONTZOOM_0 "%4.0f %%"
STR_STATUS_FONTZOOM_1 "%4.1f %%"
STR_STATUS_ROW_COL "%5d Ln %4d Col"
STR_INS_MODE_INS "INS"
STR_INS_MODE_OVR "OVR"
13 changes: 13 additions & 0 deletions tests/unittests/test-winmain.cpp
Original file line number Diff line number Diff line change
@@ -301,6 +301,19 @@ TEST_F( WinMainTest, runEditorProcess )
strStartupMacro += L"ShowFunckey();"; //ShowFunckey 消す
strStartupMacro += L"ShowMiniMap();"; //ShowMiniMap 消す
strStartupMacro += L"ShowTab();"; //ShowTab 消す
// フォントサイズ設定のテスト
strStartupMacro += L"SetFontSize( 10, 0, 0 );"; // 直接指定 - 対象:共通設定
strStartupMacro += L"SetFontSize( 10, 0, 1 );"; // 直接指定 - 対象:タイプ別設定
strStartupMacro += L"SetFontSize( 10, 0, 2 );"; // 直接指定 - 対象:一時適用
strStartupMacro += L"SetFontSize( 10, 0, 3 );"; // 直接指定 - 対象が不正
strStartupMacro += L"SetFontSize( 0, 0, 0 );"; // 直接指定 - フォントサイズ下限未満
strStartupMacro += L"SetFontSize( 9999, 0, 0 );"; // 直接指定 - フォントサイズ上限超過
strStartupMacro += L"SetFontSize( 0, 0, 2 );"; // 相対指定 - サイズ変化なし
strStartupMacro += L"SetFontSize( 0, 1, 2 );"; // 相対指定 - 拡大
strStartupMacro += L"SetFontSize( 0, -1, 2 );"; // 相対指定 - 縮小
strStartupMacro += L"SetFontSize( 0, 9999, 2 );"; // 相対指定 - 限界まで拡大
strStartupMacro += L"SetFontSize( 0, -9999, 2 );"; // 相対指定 - 限界まで縮小
strStartupMacro += L"SetFontSize( 10, 0, 2 );"; // 元に戻す
strStartupMacro += L"ExitAll();"; //NOTE: このコマンドにより、エディタプロセスは起動された直後に終了する。

// コマンドラインを組み立てる
191 changes: 191 additions & 0 deletions tests/unittests/test-zoom.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/*! @file */
/*
Copyright (C) 2018-2020 Sakura Editor Organization
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <gtest/gtest.h>
#include "util/zoom.h"

/*!
* @brief ZoomSetting構造体のテスト
*/
TEST( zoom, ZoomSetting )
{
// 不正な引数 - テーブルが昇順になっていない
EXPECT_EQ( false, ZoomSetting( {0.0, 2.0, 1.0}, 0.0, 0.0, 1.0 ).IsValid() );

// 不正な引数 - 最大最小があべこべ
EXPECT_EQ( false, ZoomSetting( {1.0}, 1.0, 0.0, 1.0 ).IsValid() );

// 不正な引数 - 解像度が負数
EXPECT_EQ( false, ZoomSetting( {1.0}, 0.0, 0.0, -1.0 ).IsValid() );

// 正しい引数 - テーブルに同一値が含まれる
EXPECT_EQ( true, ZoomSetting( {0.0, 1.0, 1.0, 2.0}, 0.0, 0.0, 1.0 ).IsValid() );

// 正しい引数 - 解像度が0
EXPECT_EQ( true, ZoomSetting( {0.0}, 0.0, 0.0, 0.0 ).IsValid() );
}

/*!
* @brief GetZoomedValue関数のテスト - 引数チェック
*/
TEST( zoom, GetZoomedValue_CheckArguments )
{
// ズーム設定が不正
EXPECT_EQ( false, GetZoomedValue( ZoomSetting( {1.0}, 1.0, 0.0, 0.0 ), 100.0, 1.0, 1, NULL, NULL ) );

// ズームステップが0
EXPECT_EQ( false, GetZoomedValue( ZoomSetting( {0.5, 1.0, 1.5}, 0.0, 200.0, 0.0 ), 100.0, 1.0, 0, NULL, NULL ) );

// 出力引数はNULLを許容
EXPECT_EQ( true, GetZoomedValue( ZoomSetting( {0.5, 1.0, 1.5}, 0.0, 200.0, 0.0 ), 100.0, 1.0, 1, NULL, NULL ) );
}

/*!
* @brief GetZoomedValue関数のテスト - 基本的な拡大/縮小
*/
TEST( zoom, GetZoomedValue_ZoomUpDown )
{
const ZoomSetting setting_50_150_10( {0.1, 0.9, 0.95, 1.0, 1.05, 1.1, 2.0}, 50.0, 150.0, 10.0 );
const ZoomSetting setting_5_300_10( {0.1, 0.9, 0.95, 1.0, 1.05, 1.1, 2.0}, 5.0, 300.0, 10.0 );
const ZoomSetting setting_5_300_0( {0.1, 0.9, 0.95, 1.0, 1.05, 1.1, 2.0}, 5.0, 300.0, 0.0 );
double nValue = 0.0;
double nZoom = 0.0;

// 拡大 - 変化が最小単位以上となるまで拡大(2ステップ分)
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 1.0, 1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 110.0, nValue );
EXPECT_DOUBLE_EQ( 1.1, nZoom );

// 拡大 - 指定通り
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 1.0, 2, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 110.0, nValue );
EXPECT_DOUBLE_EQ( 1.1, nZoom );

// 拡大 - 最大値による丸め込み
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 1.0, 3, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 150.0, nValue );
EXPECT_DOUBLE_EQ( 1.5, nZoom );

// 拡大 - ズームテーブル末尾の倍率を適用
EXPECT_EQ( true, GetZoomedValue( setting_5_300_10, 100.0, 1.0, 4, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 200.0, nValue );
EXPECT_DOUBLE_EQ( 2.0, nZoom );

// 縮小 - 変化が最小単位以上となるまで縮小(2ステップ分)
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 1.0, -1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 90.0, nValue );
EXPECT_DOUBLE_EQ( 0.9, nZoom );

// 縮小 - 指定通り
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 1.0, -2, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 90.0, nValue );
EXPECT_DOUBLE_EQ( 0.9, nZoom );

// 縮小 - 最小値による丸め込み
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 1.0, -3, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 50.0, nValue );
EXPECT_DOUBLE_EQ( 0.5, nZoom );

// 縮小 - ズームテーブル先頭の倍率を適用
EXPECT_EQ( true, GetZoomedValue( setting_5_300_10, 100.0, 1.0, -4, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 10.0, nValue );
EXPECT_DOUBLE_EQ( 0.1, nZoom );

// 拡大 - 最小単位なし
EXPECT_EQ( true, GetZoomedValue( setting_5_300_0, 1.1, 1.0, 1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( nValue, 1.155 );
EXPECT_DOUBLE_EQ( nZoom, 1.05 );
}

/*!
* @brief GetZoomedValue関数のテスト - 基準値が上限/下限の範囲外
*/
TEST( zoom, GetZoomedValue_OutOfRange )
{
const ZoomSetting setting_50_150_10( {0.1, 0.9, 0.95, 1.0, 1.05, 1.1, 2.0}, 50.0, 150.0, 10.0 );
double nValue = 0.0;
double nZoom = 0.0;

// 上限値を超える値から拡大 -> ズーム不可
EXPECT_EQ( false, GetZoomedValue( setting_50_150_10, 200.0, 1.0, 1, &nValue, &nZoom ) );

// 上限値を超える値から縮小 -> 上限値を上回る状態で縮小
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 200.0, 1.0, -1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 190.0, nValue );
EXPECT_DOUBLE_EQ( 0.95, nZoom );

// 下限値を超える値から縮小 -> ズーム不可
EXPECT_EQ( false, GetZoomedValue( setting_50_150_10, 10.0, 1.0, -1, &nValue, &nZoom ) );

// 下限値を超える値から拡大 -> 下限値を下回る状態で拡大(変化が最小単位以上となるまで拡大(3ステップ分))
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 10.0, 1.0, 1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 20.0, nValue );
EXPECT_DOUBLE_EQ( 2.0, nZoom );
}

/*!
* @brief GetZoomedValue関数のテスト - 開始ズーム値がズームテーブルの範囲外
*/
TEST( zoom, GetZoomedValue_OutOfZoomTable )
{
const ZoomSetting setting_50_150_10( {0.1, 0.9, 0.95, 1.0, 1.05, 1.1, 2.0}, 50.0, 150.0, 10.0 );
double nValue = 0.0;
double nZoom = 0.0;

// ズームテーブル上限を上回る倍率から拡大 -> ズーム不可
EXPECT_EQ( false, GetZoomedValue( setting_50_150_10, 100.0, 2.5, 1, &nValue, &nZoom ) );

// ズームテーブル上限を上回る倍率から縮小 -> ズームテーブル末尾の倍率を適用
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 2.5, -1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 200.0, nValue );
EXPECT_DOUBLE_EQ( 2.0, nZoom );

// ズームテーブル下限を下回る倍率から縮小 -> ズーム不可
EXPECT_EQ( false, GetZoomedValue( setting_50_150_10, 100.0, 0.08, -1, &nValue, &nZoom ) );

// ズームテーブル下限を下回る倍率から拡大 -> ズームテーブル先頭の倍率を適用
EXPECT_EQ( true, GetZoomedValue( setting_50_150_10, 100.0, 0.08, 1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 10.0, nValue );
EXPECT_DOUBLE_EQ( 0.1, nZoom );
}

/*!
* @brief GetZoomedValue関数のテスト - 縮小時の固有動作を狙ったテスト
*/
TEST( zoom, GetZoomedValue_FindingOneMoreChange )
{
const ZoomSetting setting_0_100_10( {0.97, 0.98, 0.99, 1.0}, 0.0, 100.0, 10.0 );
double nValue = 0.0;
double nZoom = 0.0;
// 探している最中にテーブル先頭まで到達
EXPECT_EQ( true, GetZoomedValue( setting_0_100_10, 100.0, 1.0, -1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 90.0, nValue );
EXPECT_DOUBLE_EQ( 0.97, nZoom );

const ZoomSetting setting_95_100_10( {0.97, 0.98, 0.99, 1.0}, 95.0, 100.0, 10.0 );
// 下限値に当たる
EXPECT_EQ( true, GetZoomedValue( setting_95_100_10, 100.0, 1.0, -1, &nValue, &nZoom ) );
EXPECT_DOUBLE_EQ( 95.0, nValue );
EXPECT_DOUBLE_EQ( 0.95, nZoom );
}
1 change: 1 addition & 0 deletions tests/unittests/tests1.vcxproj
Original file line number Diff line number Diff line change
@@ -127,6 +127,7 @@
<ClCompile Include="test-ssearchoption.cpp" />
<ClCompile Include="test-StdControl.cpp" />
<ClCompile Include="test-string_ex.cpp" />
<ClCompile Include="test-zoom.cpp" />
<ClCompile Include="test-winmain.cpp" />
</ItemGroup>
<ItemGroup>
3 changes: 3 additions & 0 deletions tests/unittests/tests1.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -91,6 +91,9 @@
<ClCompile Include="test-cwordparse.cpp">
<Filter>Test Files</Filter>
</ClCompile>
<ClCompile Include="test-zoom.cpp">
<Filter>Test Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="StartEditorProcessForTest.h">