TWAIN跨平台基础代码
This commit is contained in:
parent
63acafc433
commit
9af89edc32
|
@ -76,6 +76,7 @@
|
|||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -83,6 +84,7 @@
|
|||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
|
@ -90,6 +92,7 @@
|
|||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\code_device\hgdriver\3rdparty\nick;$(SolutionDir)..\..\sdk\include\opencv\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\cyusb\inc\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\libtiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\log4cplus\include\;$(SolutionDir)..\..\code_device\sdk\;$(SolutionDir)..\..\code_device\hgdriver\ImageProcess\;$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\code_device\hgdriver\hgdev\;$(SolutionDir)..\..\code_device\hgdriver\wrapper\;$(ProjectDir);$(SolutionDir)..\..\code_device\hgdriver\3rdparty\tiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\openssl\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -97,6 +100,7 @@
|
|||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\code_device\hgdriver\3rdparty\nick;$(SolutionDir)..\..\sdk\include\opencv\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\cyusb\inc\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\libtiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\log4cplus\include\;$(SolutionDir)..\..\code_device\sdk\;$(SolutionDir)..\..\code_device\hgdriver\ImageProcess\;$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\code_device\hgdriver\hgdev\;$(SolutionDir)..\..\code_device\hgdriver\wrapper\;$(ProjectDir);$(SolutionDir)..\..\code_device\hgdriver\3rdparty\tiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\openssl\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -118,8 +122,10 @@
|
|||
</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
copy /y "$(TargetPath)" "C:\Windows\twain_32\HuaGoTwain"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -147,8 +153,9 @@
|
|||
</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -169,8 +176,10 @@
|
|||
<ModuleDefinitionFile>$(ProjectDir)device.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
copy /y "$(TargetPath)" "C:\Program Files\HuaGoScan"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -196,8 +205,9 @@
|
|||
<ModuleDefinitionFile>$(ProjectDir)device.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -48,9 +48,6 @@ void usb_callback::notify(libusb_context* ctx, usb_device* dev, int ev)
|
|||
}
|
||||
std::string u2utf8(const wchar_t* u)
|
||||
{
|
||||
#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG) || defined(OEM_ZHONGJING)
|
||||
return hg_log::u2utf8(u);
|
||||
#else
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
|
||||
char *ansi = new char[len + 4];
|
||||
|
||||
|
@ -61,7 +58,6 @@ std::string u2utf8(const wchar_t* u)
|
|||
delete[] ansi;
|
||||
|
||||
return utf8;
|
||||
#endif
|
||||
}
|
||||
std::wstring ansi2unicode(const char* ansi, UINT cp = CP_ACP)
|
||||
{
|
||||
|
|
|
@ -10,3 +10,5 @@ EXPORTS
|
|||
to_default_language
|
||||
from_default_language
|
||||
lang_refresh_language
|
||||
language_option_descriptor
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
|
@ -42,7 +42,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
|
@ -74,27 +74,31 @@
|
|||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include;$(IncludePath)</IncludePath>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include;$(IncludePath)</IncludePath>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include;$(IncludePath)</IncludePath>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include;$(IncludePath)</IncludePath>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;VENDOR=huagao</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
|
@ -106,8 +110,11 @@
|
|||
<ModuleDefinitionFile>lang.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
copy /y "$(TargetPath)" "C:\Windows\twain_32\HuaGoTwain"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -116,7 +123,7 @@
|
|||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;OEM=huagao</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
|
@ -131,15 +138,17 @@
|
|||
<ModuleDefinitionFile>lang.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;OEM=huagao</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
|
@ -151,8 +160,11 @@
|
|||
<ModuleDefinitionFile>lang.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
copy /y "$(TargetPath)" "C:\Program Files\HuaGoScan"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -161,7 +173,7 @@
|
|||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;OEM=huagao</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
|
@ -176,8 +188,10 @@
|
|||
<ModuleDefinitionFile>lang.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
|
814
sane/DlgArea.cpp
814
sane/DlgArea.cpp
|
@ -1,814 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgArea.h"
|
||||
#include "resource.h"
|
||||
#include "scanned_img.h" // for local_trans
|
||||
#include "mem_dc.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
#define MM_PER_INCH 25.4f
|
||||
|
||||
int dlg_area::area_min_pixel = 50;
|
||||
|
||||
dlg_area::dlg_area(HWND parent) : dlg_base(parent, IDD_AREA)
|
||||
, unit_(PAPER_UNIT_MM), paper_w_(210), paper_h_(297), dpi_(200)
|
||||
, x_(0), y_(0), w_(paper_w_), h_(paper_h_)
|
||||
, paper_(L"A4")
|
||||
, paper_w_0_(paper_w_), paper_h_0_(paper_h_), cursor_(NULL), drag_(DRAG_POS_NONE)
|
||||
, in_set_func_(false)
|
||||
{
|
||||
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM_AREA));
|
||||
|
||||
create();
|
||||
|
||||
SetWindowTextW(hwnd(), title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_MM) + L" (mm)";
|
||||
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]);
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_INCH) + L" (inch)";
|
||||
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]);
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_PIXEL) + L" (px)";
|
||||
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]);
|
||||
SendMessage(get_item(IDC_UNIT), CB_SETCURSEL, 0, 0);
|
||||
|
||||
|
||||
if (!dlg_base::is_language_pack_default_code_page())
|
||||
{
|
||||
int width_diff = 0, w = 0;
|
||||
RECT r = { 0 }, rp = { 0 };
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OPT_PAPER) + L":";
|
||||
set_item_text(IDC_STATIC_PAPER, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT) + L":";
|
||||
set_item_text(IDC_STATIC_UNIT, title.c_str());
|
||||
title = L"DPI (" + local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_PIXEL) + L"/" + local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_INCH) + L"):";
|
||||
set_item_text(IDC_STATIC_DPI, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_AREA_SET) + L":";
|
||||
set_item_text(IDC_STATIC_AREA, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_LEFT) + L":";
|
||||
set_item_text(IDC_STATIC_LEFT, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_TOP) + L":";
|
||||
set_item_text(IDC_STATIC_TOP, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_WIDTH) + L":";
|
||||
set_item_text(IDC_STATIC_W, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_HEIGHT) + L":";
|
||||
set_item_text(IDC_STATIC_H, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE_AREA);
|
||||
set_item_text(IDC_BUTTON_RESET, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
|
||||
set_item_text(IDCANCEL, title.c_str());
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
|
||||
set_item_text(IDOK, title.c_str());
|
||||
|
||||
layout();
|
||||
}
|
||||
}
|
||||
dlg_area::~dlg_area()
|
||||
{
|
||||
}
|
||||
|
||||
float dlg_area::mm_2_pixel(float mm, float dpi)
|
||||
{
|
||||
return inches_2_pixel(mm_2_inches(mm), dpi);
|
||||
}
|
||||
float dlg_area::mm_2_inches(float mm)
|
||||
{
|
||||
return mm / MM_PER_INCH;
|
||||
}
|
||||
float dlg_area::inches_2_pixel(float inch, float dpi)
|
||||
{
|
||||
return inch * dpi;
|
||||
}
|
||||
float dlg_area::inches_2_mm(float inch)
|
||||
{
|
||||
return inch * MM_PER_INCH;
|
||||
}
|
||||
float dlg_area::pixel_2_mm(float px, float dpi)
|
||||
{
|
||||
return inches_2_mm(pixel_2_inches(px, dpi));
|
||||
}
|
||||
float dlg_area::pixel_2_inches(float px, float dpi)
|
||||
{
|
||||
return px / dpi;
|
||||
}
|
||||
|
||||
BOOL dlg_area::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
UpdateWindow(hwnd());
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps = { 0 };
|
||||
HDC hdc = BeginPaint(hwnd(), &ps);
|
||||
{
|
||||
compatible_dc dc(hdc);
|
||||
on_paint(dc.get_dc());
|
||||
}
|
||||
EndPaint(hwnd(), &ps);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
on_mouse_move(wp, LOWORD(lp), HIWORD(lp));
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
on_lbutton_down(LOWORD(lp), HIWORD(lp));
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
on_lbutton_up(LOWORD(lp), HIWORD(lp));
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void dlg_area::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
if (id == IDC_UNIT)
|
||||
{
|
||||
if (code == CBN_SELCHANGE)
|
||||
{
|
||||
on_unit_changed((HWND)ctrl);
|
||||
}
|
||||
}
|
||||
else if (id == IDCANCEL)
|
||||
{
|
||||
quit_modal(id);
|
||||
}
|
||||
else if (id == IDOK)
|
||||
{
|
||||
quit_modal(id);
|
||||
}
|
||||
else if (id == IDC_BUTTON_RESET)
|
||||
{
|
||||
clear_area();
|
||||
}
|
||||
else if (id == IDC_EDIT_x ||
|
||||
id == IDC_EDIT_y ||
|
||||
id == IDC_EDIT_W ||
|
||||
id == IDC_EDIT_H)
|
||||
{
|
||||
if (code == EN_CHANGE && !in_set_func_)
|
||||
{
|
||||
wchar_t val[80] = { 0 };
|
||||
float num = .0f;
|
||||
|
||||
GetWindowTextW((HWND)ctrl, val, _countof(val) - 1);
|
||||
num = (float)_wtof(val);
|
||||
if (id == IDC_EDIT_x)
|
||||
{
|
||||
if (num < .0f)
|
||||
num = .0f;
|
||||
if (num > paper_w_ - dlg_area::area_min_pixel)
|
||||
num = paper_w_ - dlg_area::area_min_pixel;
|
||||
x_ = num;
|
||||
user_sel_.left = whole_.left + (LONG)(x_ / ratio_);
|
||||
if (x_ + w_ > paper_w_)
|
||||
w_ = paper_w_ - x_;
|
||||
user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_);
|
||||
refresh_paper_info();
|
||||
InvalidateRect(hwnd(), &whole_, FALSE);
|
||||
}
|
||||
else if (id == IDC_EDIT_y)
|
||||
{
|
||||
if (num < .0f)
|
||||
num = .0f;
|
||||
if (num > paper_h_ - dlg_area::area_min_pixel)
|
||||
num = paper_h_ - dlg_area::area_min_pixel;
|
||||
y_ = num;
|
||||
user_sel_.top = whole_.top + (LONG)(y_ / ratio_);
|
||||
if (y_ + h_ > paper_h_)
|
||||
h_ = paper_h_ - y_;
|
||||
user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_);
|
||||
refresh_paper_info();
|
||||
InvalidateRect(hwnd(), &whole_, FALSE);
|
||||
}
|
||||
else if (id == IDC_EDIT_W)
|
||||
{
|
||||
if (num < dlg_area::area_min_pixel)
|
||||
num = (float)dlg_area::area_min_pixel;
|
||||
if (num > paper_w_)
|
||||
num = paper_w_;
|
||||
w_ = num;
|
||||
user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_);
|
||||
if (user_sel_.right > whole_.right)
|
||||
{
|
||||
OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0);
|
||||
if (user_sel_.left < whole_.left)
|
||||
{
|
||||
user_sel_.left = whole_.left;
|
||||
x_ = 0;
|
||||
}
|
||||
}
|
||||
refresh_paper_info();
|
||||
InvalidateRect(hwnd(), &whole_, FALSE);
|
||||
}
|
||||
else if (id == IDC_EDIT_H)
|
||||
{
|
||||
if (num < dlg_area::area_min_pixel)
|
||||
num = (float)dlg_area::area_min_pixel;
|
||||
if (num > paper_h_)
|
||||
num = paper_h_;
|
||||
h_ = num;
|
||||
user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_);
|
||||
if (user_sel_.bottom > whole_.bottom)
|
||||
{
|
||||
OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom);
|
||||
if (user_sel_.top < whole_.top)
|
||||
{
|
||||
user_sel_.top = whole_.top;
|
||||
y_ = 0;
|
||||
}
|
||||
}
|
||||
refresh_paper_info();
|
||||
InvalidateRect(hwnd(), &whole_, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void dlg_area::layout(void)
|
||||
{
|
||||
RECT r = { 0 };
|
||||
int w_dif = get_width_diff_as_text_length(IDC_STATIC_LEFT),
|
||||
top1 = get_width_diff_as_text_length(IDC_STATIC_PAPER),
|
||||
top21 = get_width_diff_as_text_length(IDC_STATIC_UNIT),
|
||||
top22 = get_width_diff_as_text_length(IDC_STATIC_DPI);
|
||||
|
||||
#define CHECK_CTRL_W(id) \
|
||||
if(w_dif < get_width_diff_as_text_length(id)) \
|
||||
w_dif = get_width_diff_as_text_length(id);
|
||||
|
||||
CHECK_CTRL_W(IDC_STATIC_TOP);
|
||||
CHECK_CTRL_W(IDC_STATIC_W);
|
||||
CHECK_CTRL_W(IDC_STATIC_H);
|
||||
CHECK_CTRL_W(IDC_BUTTON_RESET);
|
||||
if (w_dif < top21 + top22)
|
||||
w_dif = top21 + top22;
|
||||
|
||||
// layout ...
|
||||
if (w_dif > 0)
|
||||
{
|
||||
GetWindowRect(hwnd(), &r);
|
||||
r.right += w_dif;
|
||||
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
||||
|
||||
expand_item(IDC_STATIC_PAPER, top1, 0);
|
||||
offset_item(IDC_EDIT_PAPER, top1, 0);
|
||||
expand_item(IDC_EDIT_PAPER, w_dif - top1, 0);
|
||||
|
||||
expand_item(IDC_STATIC_UNIT, top21, 0);
|
||||
offset_item(IDC_UNIT, top21, 0);
|
||||
|
||||
offset_item(IDC_STATIC_DPI, w_dif - top22, 0);
|
||||
expand_item(IDC_STATIC_DPI, top22, 0);
|
||||
offset_item(IDC_EDIT_DPI, top21 + top22, 0);
|
||||
|
||||
expand_item(IDC_STATIC_AREA, w_dif, 0);
|
||||
|
||||
expand_item(IDC_STATIC_LEFT, w_dif, 0);
|
||||
offset_item(IDC_EDIT_x, w_dif, 0);
|
||||
|
||||
expand_item(IDC_STATIC_TOP, w_dif, 0);
|
||||
offset_item(IDC_EDIT_y, w_dif, 0);
|
||||
|
||||
expand_item(IDC_STATIC_W, w_dif, 0);
|
||||
offset_item(IDC_EDIT_W, w_dif, 0);
|
||||
|
||||
expand_item(IDC_STATIC_H, w_dif, 0);
|
||||
offset_item(IDC_EDIT_H, w_dif, 0);
|
||||
|
||||
top1 = get_width_diff_as_text_length(IDC_BUTTON_RESET);
|
||||
expand_item(IDC_BUTTON_RESET, top1, 0);
|
||||
offset_item(IDC_BUTTON_RESET, (w_dif - top1) / 2, 0);
|
||||
|
||||
offset_item(IDOK, w_dif, 0);
|
||||
offset_item(IDCANCEL, w_dif, 0);
|
||||
}
|
||||
}
|
||||
|
||||
float dlg_area::as_mm(float v)
|
||||
{
|
||||
if (unit_ == PAPER_UNIT_INCH)
|
||||
return dlg_area::inches_2_mm(v);
|
||||
else if (unit_ == PAPER_UNIT_PIXEL)
|
||||
return dlg_area::pixel_2_mm(v, dpi_);
|
||||
else
|
||||
return v;
|
||||
}
|
||||
float dlg_area::from_mm(float v)
|
||||
{
|
||||
if (unit_ == PAPER_UNIT_INCH)
|
||||
return dlg_area::mm_2_inches(v);
|
||||
else if (unit_ == PAPER_UNIT_PIXEL)
|
||||
return dlg_area::mm_2_pixel(v, dpi_);
|
||||
else
|
||||
return v;
|
||||
}
|
||||
float dlg_area::as_inches(float v)
|
||||
{
|
||||
if (unit_ == PAPER_UNIT_MM)
|
||||
return dlg_area::mm_2_inches(v);
|
||||
else if (unit_ == PAPER_UNIT_PIXEL)
|
||||
return dlg_area::pixel_2_inches(v, dpi_);
|
||||
else
|
||||
return v;
|
||||
}
|
||||
float dlg_area::as_pixels(float v)
|
||||
{
|
||||
if (unit_ == PAPER_UNIT_MM)
|
||||
return dlg_area::mm_2_pixel(v, dpi_);
|
||||
else if (unit_ == PAPER_UNIT_INCH)
|
||||
return dlg_area::inches_2_pixel(v, dpi_);
|
||||
else
|
||||
return v;
|
||||
}
|
||||
std::wstring dlg_area::format_number(float v)
|
||||
{
|
||||
wchar_t str[40] = { 0 };
|
||||
|
||||
if (unit_ == PAPER_UNIT_PIXEL)
|
||||
swprintf_s(str, _countof(str) - 1, L"%d", (int)(v + .5f));
|
||||
else
|
||||
swprintf_s(str, _countof(str) - 1, L"%.2f", v);
|
||||
|
||||
return str;
|
||||
}
|
||||
void dlg_area::refresh_paper_info(void)
|
||||
{
|
||||
SetWindowTextW(get_item(IDC_EDIT_PAPER), (paper_ + L"(" + format_number(paper_w_) + local_trans::lang_trans_between_hz936(CONST_STRING_MULTIPLE) + format_number(paper_h_) + L")").c_str());
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_DPI, UINT(dpi_), FALSE);
|
||||
|
||||
in_set_func_ = true;
|
||||
SetWindowTextW(get_item(IDC_EDIT_x), format_number(x_).c_str());
|
||||
SetWindowTextW(get_item(IDC_EDIT_y), format_number(y_).c_str());
|
||||
SetWindowTextW(get_item(IDC_EDIT_W), format_number(w_).c_str());
|
||||
SetWindowTextW(get_item(IDC_EDIT_H), format_number(h_).c_str());
|
||||
in_set_func_ = false;
|
||||
|
||||
InvalidateRect(hwnd(), &whole_, FALSE);
|
||||
}
|
||||
void dlg_area::to_unit(paper_unit unit)
|
||||
{
|
||||
float(dlg_area:: * conv)(float) = NULL;
|
||||
|
||||
if (unit == PAPER_UNIT_INCH)
|
||||
{
|
||||
conv = &dlg_area::as_inches;
|
||||
paper_w_ = dlg_area::mm_2_inches(paper_w_0_);
|
||||
paper_h_ = dlg_area::mm_2_inches(paper_h_0_);
|
||||
}
|
||||
else if (unit == PAPER_UNIT_PIXEL)
|
||||
{
|
||||
conv = &dlg_area::as_pixels;
|
||||
paper_w_ = dlg_area::mm_2_pixel(paper_w_0_, dpi_);
|
||||
paper_h_ = dlg_area::mm_2_pixel(paper_h_0_, dpi_);
|
||||
}
|
||||
else // if (unit == PAPER_UNIT_MM)
|
||||
{
|
||||
conv = &dlg_area::as_mm;
|
||||
paper_w_ = paper_w_0_;
|
||||
paper_h_ = paper_h_0_;
|
||||
}
|
||||
|
||||
#define CONV_UNIT(v) \
|
||||
v = (this->*conv)(v);
|
||||
|
||||
CONV_UNIT(x_);
|
||||
CONV_UNIT(y_);
|
||||
CONV_UNIT(w_);
|
||||
CONV_UNIT(h_);
|
||||
unit_ = unit;
|
||||
refresh_paper_info();
|
||||
}
|
||||
void dlg_area::clear_area(void)
|
||||
{
|
||||
x_ = y_ = 0;
|
||||
w_ = paper_w_;
|
||||
h_ = paper_h_;
|
||||
user_sel_ = whole_;
|
||||
|
||||
refresh_paper_info();
|
||||
}
|
||||
void dlg_area::drag_blocks(std::vector<DRAGRECT>& blocks)
|
||||
{
|
||||
int l = 5;
|
||||
DRAGRECT r;
|
||||
|
||||
r.left = user_sel_.left;
|
||||
r.top = user_sel_.top;
|
||||
r.right = r.left + l;
|
||||
r.bottom = r.top + l;
|
||||
r.pos = DRAG_POS_LT;
|
||||
|
||||
blocks.clear();
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, (user_sel_.right - user_sel_.left) / 2 - l / 2, 0); r.pos = DRAG_POS_MT;
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, (user_sel_.right - r.right), 0); r.pos = DRAG_POS_RT;
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, 0, (user_sel_.bottom - user_sel_.top) / 2 - l / 2); r.pos = DRAG_POS_RM;
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, 0, (user_sel_.bottom - r.bottom)); r.pos = DRAG_POS_RB;
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, -((user_sel_.right - user_sel_.left) / 2 - l / 2), 0); r.pos = DRAG_POS_MB;
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, user_sel_.left - r.left, 0); r.pos = DRAG_POS_LB;
|
||||
blocks.push_back(r);
|
||||
OffsetRect(&r, 0, -((user_sel_.bottom - user_sel_.top) / 2 - l / 2)); r.pos = DRAG_POS_LM;
|
||||
blocks.push_back(r);
|
||||
}
|
||||
float dlg_area::pos_2_area(int val, bool x)
|
||||
{
|
||||
float r = x ? (float)(val - whole_.left) : (float)(val - whole_.top);
|
||||
|
||||
r *= ratio_;
|
||||
if (unit_ == PAPER_UNIT_INCH)
|
||||
r = dlg_area::mm_2_inches(r);
|
||||
else if (unit_ == PAPER_UNIT_PIXEL)
|
||||
r = dlg_area::mm_2_pixel(r, dpi_);
|
||||
|
||||
return r;
|
||||
}
|
||||
void dlg_area::valid_x(int& x, bool left)
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
if (x < whole_.left)
|
||||
x = whole_.left;
|
||||
if (x > user_sel_.right - dlg_area::area_min_pixel)
|
||||
x = user_sel_.right - dlg_area::area_min_pixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > whole_.right)
|
||||
x = whole_.right;
|
||||
if (x < user_sel_.left + dlg_area::area_min_pixel)
|
||||
x = user_sel_.left + dlg_area::area_min_pixel;
|
||||
}
|
||||
}
|
||||
void dlg_area::valid_y(int& y, bool top)
|
||||
{
|
||||
if (top)
|
||||
{
|
||||
if (y < whole_.top)
|
||||
y = whole_.top;
|
||||
if (y > user_sel_.bottom - dlg_area::area_min_pixel)
|
||||
y = user_sel_.bottom - dlg_area::area_min_pixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y > whole_.bottom)
|
||||
y = whole_.bottom;
|
||||
if (y < user_sel_.top + dlg_area::area_min_pixel)
|
||||
y = user_sel_.top + dlg_area::area_min_pixel;
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_area::on_unit_changed(HWND wnd)
|
||||
{
|
||||
wchar_t text[80] = { 0 };
|
||||
|
||||
GetWindowTextW(wnd, text, _countof(text) - 1);
|
||||
if (wcsstr(text, L"mm"))
|
||||
{
|
||||
if (unit_ != PAPER_UNIT_MM)
|
||||
{
|
||||
to_unit(PAPER_UNIT_MM);
|
||||
}
|
||||
}
|
||||
else if (wcsstr(text, L"inch"))
|
||||
{
|
||||
if (unit_ != PAPER_UNIT_INCH)
|
||||
{
|
||||
to_unit(PAPER_UNIT_INCH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unit_ != PAPER_UNIT_PIXEL)
|
||||
{
|
||||
to_unit(PAPER_UNIT_PIXEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
void dlg_area::on_paint(HDC hdc)
|
||||
{
|
||||
HBRUSH brsh_all = CreateSolidBrush(RGB(192, 192, 192)),
|
||||
brsh_drag = CreateSolidBrush(RGB(255, 0, 0)),
|
||||
brsh_sel = CreateSolidBrush(RGB(255, 255, 255));
|
||||
HPEN pen_border = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)),
|
||||
pen_ruler = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)),
|
||||
pen_old = (HPEN)SelectObject(hdc, pen_border);
|
||||
int step = 3, minor = 3, major = 5, count = 1, len = 0;
|
||||
|
||||
FillRect(hdc, &whole_, brsh_all);
|
||||
FillRect(hdc, &user_sel_, brsh_sel);
|
||||
Rectangle(hdc, user_sel_.left, user_sel_.top, user_sel_.right, user_sel_.bottom);
|
||||
SelectObject(hdc, pen_ruler);
|
||||
for (int i = whole_.left + step; i < whole_.right; i += step)
|
||||
{
|
||||
++count;
|
||||
len = (count % 5) == 0 ? major : minor;
|
||||
MoveToEx(hdc, i, whole_.top, NULL);
|
||||
LineTo(hdc, i, whole_.top + len);
|
||||
MoveToEx(hdc, i, whole_.bottom, NULL);
|
||||
LineTo(hdc, i, whole_.bottom - len);
|
||||
}
|
||||
count = 1;
|
||||
for (int i = whole_.top + step; i < whole_.bottom; i += step)
|
||||
{
|
||||
++count;
|
||||
len = (count % 5) == 0 ? major : minor;
|
||||
MoveToEx(hdc, whole_.left, i, NULL);
|
||||
LineTo(hdc, whole_.left + len, i);
|
||||
MoveToEx(hdc, whole_.right, i, NULL);
|
||||
LineTo(hdc, whole_.right - len, i);
|
||||
}
|
||||
|
||||
std::vector<DRAGRECT> r;
|
||||
drag_blocks(r);
|
||||
for(size_t i = 0; i < r.size(); ++i)
|
||||
FillRect(hdc, &r[i], brsh_drag);
|
||||
|
||||
SelectObject(hdc, pen_old);
|
||||
DeleteObject(pen_border);
|
||||
DeleteObject(pen_ruler);
|
||||
DeleteObject(brsh_all);
|
||||
DeleteObject(brsh_sel);
|
||||
DeleteObject(brsh_drag);
|
||||
}
|
||||
void dlg_area::on_mouse_move(DWORD key, int x, int y)
|
||||
{
|
||||
if (key == MK_LBUTTON)
|
||||
{
|
||||
if (drag_ == DRAG_POS_NONE)
|
||||
return;
|
||||
|
||||
float dif = .0f;
|
||||
|
||||
SetCursor(LoadCursorW(NULL, cursor_));
|
||||
if (drag_ == DRAG_POS_LT)
|
||||
{
|
||||
valid_x(x, true);
|
||||
valid_y(y, true);
|
||||
user_sel_.left = x;
|
||||
user_sel_.top = y;
|
||||
dif = x_;
|
||||
x_ = pos_2_area(x, true);
|
||||
w_ -= x_ - dif;
|
||||
dif = y_;
|
||||
y_ = pos_2_area(y, false);
|
||||
h_ -= y_ - dif;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_MT)
|
||||
{
|
||||
valid_y(y, true);
|
||||
user_sel_.top = y;
|
||||
dif = y_;
|
||||
y_ = pos_2_area(y, false);
|
||||
h_ -= y_ - dif;
|
||||
}
|
||||
else if(drag_ == DRAG_POS_RT)
|
||||
{
|
||||
valid_x(x, false);
|
||||
valid_y(y, true);
|
||||
user_sel_.right = x;
|
||||
user_sel_.top = y;
|
||||
w_ = pos_2_area(x, true) - x_;
|
||||
if (x_ + w_ > paper_w_)
|
||||
w_ = paper_w_ - x_;
|
||||
dif = y_;
|
||||
y_ = pos_2_area(y, false);
|
||||
h_ -= y_ - dif;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_LM)
|
||||
{
|
||||
valid_x(x, true);
|
||||
user_sel_.left = x;
|
||||
dif = x_;
|
||||
x_ = pos_2_area(x, true);
|
||||
w_ -= x_ - dif;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_RM)
|
||||
{
|
||||
valid_x(x, false);
|
||||
user_sel_.right = x;
|
||||
w_ = pos_2_area(x, true) - x_;
|
||||
if (x_ + w_ > paper_w_)
|
||||
w_ = paper_w_ - x_;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_LB)
|
||||
{
|
||||
valid_x(x, true);
|
||||
valid_y(y, false);
|
||||
user_sel_.left = x;
|
||||
user_sel_.bottom = y;
|
||||
dif = x_;
|
||||
x_ = pos_2_area(x, true);
|
||||
w_ -= x_ - dif;
|
||||
h_ = pos_2_area(y, false) - y_;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_MB)
|
||||
{
|
||||
valid_y(y, false);
|
||||
user_sel_.bottom = y;
|
||||
h_ = pos_2_area(y, false) - y_;
|
||||
if (y_ + h_ > paper_h_)
|
||||
h_ = paper_h_ - y_;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_RB)
|
||||
{
|
||||
valid_x(x, false);
|
||||
valid_y(y, false);
|
||||
user_sel_.right = x;
|
||||
user_sel_.bottom = y;
|
||||
w_ = pos_2_area(x, true) - x_;
|
||||
if (x_ + w_ > paper_w_)
|
||||
w_ = paper_w_ - x_;
|
||||
h_ = pos_2_area(y, false) - y_;
|
||||
if (y_ + h_ > paper_h_)
|
||||
h_ = paper_h_ - y_;
|
||||
}
|
||||
else if (drag_ == DRAG_POS_MOVE)
|
||||
{
|
||||
x += move_.x;
|
||||
y += move_.y;
|
||||
OffsetRect(&user_sel_, x - user_sel_.left, y - user_sel_.top);
|
||||
if (user_sel_.left < whole_.left)
|
||||
OffsetRect(&user_sel_, whole_.left - user_sel_.left, 0);
|
||||
if (user_sel_.right > whole_.right)
|
||||
OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0);
|
||||
if (user_sel_.top < whole_.top)
|
||||
OffsetRect(&user_sel_, 0, whole_.top - user_sel_.top);
|
||||
if (user_sel_.bottom > whole_.bottom)
|
||||
OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom);
|
||||
x_ = pos_2_area(user_sel_.left, true);
|
||||
if (x_ + w_ > paper_w_)
|
||||
x_ = paper_w_ - w_;
|
||||
y_ = pos_2_area(user_sel_.top, false);
|
||||
if (y_ + h_ > paper_h_)
|
||||
y_ = paper_h_ - h_;
|
||||
}
|
||||
|
||||
refresh_paper_info();
|
||||
InvalidateRect(hwnd(), &whole_, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
POINT pt = { x, y };
|
||||
std::vector<DRAGRECT> r;
|
||||
bool handled = false;
|
||||
|
||||
drag_blocks(r);
|
||||
for (size_t i = 0; i < r.size(); ++i)
|
||||
{
|
||||
if (PtInRect(&r[i], pt))
|
||||
{
|
||||
handled = true;
|
||||
if (r[i].pos == DRAG_POS_LT || r[i].pos == DRAG_POS_RB)
|
||||
cursor_ = IDC_SIZENWSE;
|
||||
else if(r[i].pos == DRAG_POS_RT || r[i].pos == DRAG_POS_LB)
|
||||
cursor_ = IDC_SIZENESW;
|
||||
else if(r[i].pos == DRAG_POS_MT || r[i].pos == DRAG_POS_MB)
|
||||
cursor_ = IDC_SIZENS;
|
||||
else
|
||||
cursor_ = IDC_SIZEWE;
|
||||
|
||||
drag_ = r[i].pos;
|
||||
SetCursor(LoadCursor(NULL, cursor_));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
if (PtInRect(&user_sel_, pt))
|
||||
{
|
||||
drag_ = DRAG_POS_MOVE;
|
||||
cursor_ = IDC_SIZEALL;
|
||||
SetCursor(LoadCursor(NULL, cursor_));
|
||||
}
|
||||
else
|
||||
{
|
||||
drag_ = DRAG_POS_NONE;
|
||||
cursor_ = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
void dlg_area::on_lbutton_down(int x, int y)
|
||||
{
|
||||
move_.x = user_sel_.left - x;
|
||||
move_.y = user_sel_.top - y;
|
||||
if (cursor_)
|
||||
SetCursor(LoadCursorW(NULL, cursor_));
|
||||
SetCapture(hwnd());
|
||||
}
|
||||
void dlg_area::on_lbutton_up(int x, int y)
|
||||
{
|
||||
drag_ = DRAG_POS_NONE;
|
||||
cursor_ = NULL;
|
||||
ReleaseCapture();
|
||||
}
|
||||
|
||||
|
||||
void dlg_area::set_paper(const wchar_t* name, float width_mm, float height_mm, float dpi)
|
||||
{
|
||||
wchar_t paper[40] = { 0 };
|
||||
|
||||
dpi_ = dpi;
|
||||
paper_ = name;
|
||||
|
||||
paper_w_0_ = width_mm;
|
||||
paper_h_0_ = height_mm;
|
||||
|
||||
if (unit_ == PAPER_UNIT_INCH)
|
||||
{
|
||||
paper_w_ = dlg_area::mm_2_inches(width_mm);
|
||||
paper_h_ = dlg_area::mm_2_inches(height_mm);
|
||||
}
|
||||
else if (unit_ == PAPER_UNIT_PIXEL)
|
||||
{
|
||||
paper_w_ = dlg_area::mm_2_pixel(width_mm, dpi_);
|
||||
paper_h_ = dlg_area::mm_2_pixel(height_mm, dpi_);
|
||||
}
|
||||
else
|
||||
{
|
||||
paper_w_ = width_mm;
|
||||
paper_h_ = height_mm;
|
||||
}
|
||||
|
||||
RECT r = { 0 };
|
||||
float xr = 1.0f,
|
||||
yr = 1.0f;
|
||||
|
||||
GetWindowRect(get_item(IDC_STATIC_PAINT), &r);
|
||||
screen_2_client(&r);
|
||||
xr = paper_w_0_ / (r.right - r.left);
|
||||
yr = paper_h_0_ / (r.bottom - r.top);
|
||||
ratio_ = xr >= yr ? xr : yr;
|
||||
|
||||
xr = paper_w_0_ / ratio_;
|
||||
xr = (r.right - r.left - xr) / 2;
|
||||
yr = paper_h_0_ / ratio_;
|
||||
yr = (r.bottom - r.top - yr) / 2;
|
||||
whole_.left = r.left + (LONG)xr; whole_.right = r.right - (LONG)xr;
|
||||
whole_.top = r.top + (LONG)yr; whole_.bottom = r.bottom - (LONG)yr;
|
||||
|
||||
clear_area();
|
||||
}
|
||||
void dlg_area::set_area(float x, float y, float w, float h)
|
||||
{
|
||||
x_ = from_mm(x);
|
||||
y_ = from_mm(y);
|
||||
w_ = from_mm(w);
|
||||
h_ = from_mm(h);
|
||||
|
||||
if (x_ > paper_w_)
|
||||
{
|
||||
if (w_ < paper_w_)
|
||||
x_ = paper_w_ - w_;
|
||||
else
|
||||
x_ = 0;
|
||||
}
|
||||
if (w_ + x_ > paper_w_)
|
||||
w_ = paper_w_ - x_;
|
||||
if (y_ > paper_h_)
|
||||
{
|
||||
if (h_ < paper_h_)
|
||||
y_ = paper_h_ - h_;
|
||||
else
|
||||
y_ = 0;
|
||||
}
|
||||
if (h_ + y_ > paper_h_)
|
||||
h_ = paper_h_ - y_;
|
||||
user_sel_.left = whole_.left + (LONG)(x_ / ratio_);
|
||||
user_sel_.top = whole_.top + (LONG)(y_ / ratio_);
|
||||
user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_);
|
||||
user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_);
|
||||
|
||||
refresh_paper_info();
|
||||
}
|
||||
float dlg_area::x_in_mm(void)
|
||||
{
|
||||
return as_mm(x_);
|
||||
}
|
||||
float dlg_area::y_in_mm(void)
|
||||
{
|
||||
return as_mm(y_);
|
||||
}
|
||||
float dlg_area::w_in_mm(void)
|
||||
{
|
||||
return as_mm(w_);
|
||||
}
|
||||
float dlg_area::h_in_mm(void)
|
||||
{
|
||||
return as_mm(h_);
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
class dlg_area: public dlg_base
|
||||
{
|
||||
enum paper_unit
|
||||
{
|
||||
PAPER_UNIT_MM = 0,
|
||||
PAPER_UNIT_INCH,
|
||||
PAPER_UNIT_PIXEL,
|
||||
};
|
||||
enum drag_pos
|
||||
{
|
||||
DRAG_POS_NONE = 0,
|
||||
DRAG_POS_LT,
|
||||
DRAG_POS_MT,
|
||||
DRAG_POS_RT,
|
||||
DRAG_POS_LM,
|
||||
DRAG_POS_RM,
|
||||
DRAG_POS_LB,
|
||||
DRAG_POS_MB,
|
||||
DRAG_POS_RB,
|
||||
DRAG_POS_MOVE,
|
||||
};
|
||||
typedef struct _drag_block : RECT
|
||||
{
|
||||
drag_pos pos;
|
||||
}DRAGRECT;
|
||||
std::wstring paper_;
|
||||
paper_unit unit_;
|
||||
float paper_w_0_;
|
||||
float paper_h_0_;
|
||||
float paper_w_;
|
||||
float paper_h_;
|
||||
float dpi_;
|
||||
float x_;
|
||||
float y_;
|
||||
float w_;
|
||||
float h_;
|
||||
|
||||
RECT whole_;
|
||||
RECT user_sel_;
|
||||
float ratio_; // mm / pixel
|
||||
drag_pos drag_;
|
||||
POINT move_;
|
||||
bool in_set_func_;
|
||||
const wchar_t* cursor_;
|
||||
|
||||
static int area_min_pixel;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void layout(void);
|
||||
|
||||
float as_mm(float v);
|
||||
float from_mm(float v);
|
||||
float as_inches(float v);
|
||||
float as_pixels(float v);
|
||||
std::wstring format_number(float v);
|
||||
void refresh_paper_info(void);
|
||||
void to_unit(paper_unit unit);
|
||||
void clear_area(void);
|
||||
void drag_blocks(std::vector<DRAGRECT>& blocks);
|
||||
float pos_2_area(int val, bool x);
|
||||
void valid_x(int& x, bool left);
|
||||
void valid_y(int& y, bool top);
|
||||
|
||||
void on_unit_changed(HWND wnd);
|
||||
void on_paint(HDC hdc);
|
||||
void on_mouse_move(DWORD key, int x, int y);
|
||||
void on_lbutton_down(int x, int y);
|
||||
void on_lbutton_up(int x, int y);
|
||||
|
||||
public:
|
||||
dlg_area(HWND parent);
|
||||
~dlg_area();
|
||||
|
||||
static float mm_2_pixel(float mm, float dpi);
|
||||
static float mm_2_inches(float mm);
|
||||
static float inches_2_pixel(float inch, float dpi);
|
||||
static float inches_2_mm(float inch);
|
||||
static float pixel_2_mm(float px, float dpi);
|
||||
static float pixel_2_inches(float px, float dpi);
|
||||
|
||||
public:
|
||||
void set_paper(const wchar_t* name, float width_mm, float height_mm, float dpi);
|
||||
void set_area(float x, float y, float w, float h);
|
||||
float x_in_mm(void);
|
||||
float y_in_mm(void);
|
||||
float w_in_mm(void);
|
||||
float h_in_mm(void);
|
||||
};
|
|
@ -1,216 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgCfgMgr.h"
|
||||
#include "resource.h"
|
||||
#include "scanned_img.h" // for local_trans
|
||||
#include "mem_dc.h"
|
||||
#include "gb_json.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
dlg_cfg_mgr::dlg_cfg_mgr(gb::scanner_cfg* cfg, HWND parent) : cfg_(cfg), dlg_base(parent, IDD_CFG_MGR), schm_changed_(false)
|
||||
{
|
||||
create();
|
||||
|
||||
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CFG_MANAGER));
|
||||
int dif = 0;
|
||||
|
||||
SetWindowTextW(hwnd(), title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_CFG_SCHEME);
|
||||
set_item_text(IDC_STATIC_PAPER, title.c_str());
|
||||
set_item_fit_to_text(IDC_STATIC_PAPER);
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_DEL_SELECTED);
|
||||
set_item_text(IDC_BUTTON_DEL_SEL, title.c_str());
|
||||
dif = set_item_fit_to_text(IDC_BUTTON_DEL_SEL);
|
||||
if (dif)
|
||||
offset_item(IDC_BUTTON_DEL_SEL, -dif, 0);
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_DEL_ALL);
|
||||
set_item_text(IDC_BUTTON_DEL_ALL, title.c_str());
|
||||
set_item_fit_to_text(IDC_BUTTON_DEL_ALL);
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_CFG_CONTENT);
|
||||
set_item_text(IDC_STATIC_SKETCH, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
|
||||
set_item_text(IDOK, title.c_str());
|
||||
}
|
||||
dlg_cfg_mgr::~dlg_cfg_mgr()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOOL dlg_cfg_mgr::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
on_init_dlg();
|
||||
UpdateWindow(hwnd());
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
handle_notify(wp, (LPNMHDR)lp);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps = { 0 };
|
||||
HDC hdc = BeginPaint(hwnd(), &ps);
|
||||
{
|
||||
compatible_dc dc(hdc);
|
||||
on_paint(dc.get_dc());
|
||||
}
|
||||
EndPaint(hwnd(), &ps);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void dlg_cfg_mgr::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
wchar_t cls[128] = { 0 };
|
||||
|
||||
GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1);
|
||||
if (IS_BUTTON(cls))
|
||||
{
|
||||
if (code == BN_CLICKED)
|
||||
{
|
||||
if (id == IDOK || id == IDCANCEL)
|
||||
quit_modal(id);
|
||||
else if (id == IDC_BUTTON_DEL_SEL)
|
||||
on_del_selected();
|
||||
else if (id == IDC_BUTTON_DEL_ALL)
|
||||
on_del_all();
|
||||
}
|
||||
}
|
||||
else if (IS_EDIT(cls))
|
||||
{
|
||||
//if (code == EN_SETFOCUS)
|
||||
// label_edit_ = (HWND)ctrl;
|
||||
}
|
||||
}
|
||||
void dlg_cfg_mgr::handle_notify(UINT id, LPNMHDR pnhdr)
|
||||
{
|
||||
if (id == IDC_LIST1)
|
||||
{
|
||||
if (pnhdr->code == LVN_BEGINLABELEDITW)
|
||||
{
|
||||
LPNMLVDISPINFOW pdisp = (LPNMLVDISPINFOW)pnhdr;
|
||||
|
||||
label_ = pdisp->item.pszText ? pdisp->item.pszText : L"";
|
||||
}
|
||||
else if (pnhdr->code == LVN_ENDLABELEDITW)
|
||||
{
|
||||
LPNMLVDISPINFOW pdisp = (LPNMLVDISPINFOW)pnhdr;
|
||||
|
||||
if (pdisp->item.pszText && label_ != pdisp->item.pszText)
|
||||
{
|
||||
ListView_SetItemText(get_item(IDC_LIST1), pdisp->item.iItem, pdisp->item.iSubItem, pdisp->item.pszText);
|
||||
|
||||
if (cfg_)
|
||||
{
|
||||
if (!cfg_->rename_scheme(local_trans::u2a(label_.c_str(), CP_UTF8).c_str(), local_trans::u2a(pdisp->item.pszText, CP_UTF8).c_str()))
|
||||
{
|
||||
std::wstring input(pdisp->item.pszText);
|
||||
|
||||
input += L" " + local_trans::lang_trans_between_hz936(CONST_STRING_ALREADY_EXISTS);
|
||||
::MessageBoxW(hwnd(), input.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_RE_INPUT).c_str(), MB_OK | MB_ICONINFORMATION);
|
||||
dlg_base::list_set_item_text(get_item(IDC_LIST1), pdisp->item.iItem, 0, label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pnhdr->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
LPNMLISTVIEW pv = (LPNMLISTVIEW)pnhdr;
|
||||
if ((pv->uNewState & LVIS_SELECTED) && (pv->uOldState & LVIS_SELECTED) == 0)
|
||||
on_sel_changed(pv->iItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
void dlg_cfg_mgr::layout(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void dlg_cfg_mgr::on_init_dlg(void)
|
||||
{
|
||||
HWND lstwnd = get_item(IDC_LIST1);
|
||||
std::vector<std::string> schemes;
|
||||
|
||||
cfg_->get_all_schemes(schemes);
|
||||
dlg_base::list_insert_column(lstwnd, local_trans::lang_trans_between_hz936(CONST_STRING_CFG_NAME).c_str(), 270);
|
||||
for (size_t i = 1; i < schemes.size(); ++i) // 0 is default scheme
|
||||
{
|
||||
dlg_base::list_insert_item(lstwnd, local_trans::a2u(schemes[i].c_str(), CP_UTF8).c_str());
|
||||
}
|
||||
}
|
||||
void dlg_cfg_mgr::on_paint(HDC hdc)
|
||||
{
|
||||
}
|
||||
void dlg_cfg_mgr::on_sel_changed(int sel)
|
||||
{
|
||||
std::wstring name(dlg_base::list_get_text(get_item(IDC_LIST1), sel));
|
||||
gb::sane_config_schm* schm = cfg_->get_scheme(local_trans::u2a(name.c_str(), CP_UTF8).c_str());
|
||||
|
||||
name = L"";
|
||||
if (schm)
|
||||
{
|
||||
std::string key(""), val("");
|
||||
int cnt = 1;
|
||||
|
||||
if (schm->first_config(key, val))
|
||||
{
|
||||
do
|
||||
{
|
||||
std::string v(gb::sane_config_schm::sane_option_value_2_string(&val[0], val.length(), (SANE_Value_Type)cfg_->option_value_type(key.c_str())));
|
||||
|
||||
name += std::to_wstring(cnt++) + L" - " + local_trans::a2u(cfg_->option_title(key.c_str()).c_str(), CP_UTF8) + L"\r\n ";
|
||||
if (cfg_->option_value_type(key.c_str()) == SANE_TYPE_STRING)
|
||||
v = local_trans::u2a(local_trans::lang_trans_between_hz936(local_trans::a2u(v.c_str(), CP_UTF8).c_str()).c_str(), CP_UTF8);
|
||||
name += local_trans::a2u(v.c_str(), CP_UTF8) + L"\r\n\r\n";
|
||||
} while (schm->next_config(key, val));
|
||||
}
|
||||
schm->release();
|
||||
}
|
||||
dlg_base::set_item_text(IDC_EDIT1, name.c_str());
|
||||
}
|
||||
void dlg_cfg_mgr::on_del_selected(void)
|
||||
{
|
||||
std::vector<int> sels;
|
||||
HWND lwnd = get_item(IDC_LIST1);
|
||||
bool changed = false;
|
||||
|
||||
dlg_base::list_get_selected_items(lwnd, sels);
|
||||
for(int i = sels.size() - 1; i >= 0; i--)
|
||||
{
|
||||
std::string name(local_trans::u2a(dlg_base::list_get_text(lwnd, sels[i]).c_str(), CP_UTF8));
|
||||
if (cfg_->remove_scheme(name.c_str()))
|
||||
{
|
||||
changed = true;
|
||||
ListView_DeleteItem(lwnd, sels[i]);
|
||||
schm_changed_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
void dlg_cfg_mgr::on_del_all(void)
|
||||
{
|
||||
cfg_->remove_all_schemes();
|
||||
ListView_DeleteAllItems(get_item(IDC_LIST1)); // clear list
|
||||
schm_changed_ = true;
|
||||
dlg_base::set_item_text(IDC_EDIT1, L"");
|
||||
}
|
||||
bool dlg_cfg_mgr::is_scheme_changed(void)
|
||||
{
|
||||
return schm_changed_;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
namespace gb
|
||||
{
|
||||
class scanner_cfg;
|
||||
}
|
||||
|
||||
class dlg_cfg_mgr: public dlg_base
|
||||
{
|
||||
gb::scanner_cfg* cfg_;
|
||||
std::wstring label_;
|
||||
bool schm_changed_; // to notify parent refreshing UI and settings
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void handle_notify(UINT id, LPNMHDR pnhdr);
|
||||
void layout(void);
|
||||
|
||||
void on_init_dlg(void);
|
||||
void on_paint(HDC hdc);
|
||||
void on_sel_changed(int sel);
|
||||
void on_del_selected(void);
|
||||
void on_del_all(void);
|
||||
|
||||
public:
|
||||
dlg_cfg_mgr(gb::scanner_cfg* cfg, HWND parent);
|
||||
~dlg_cfg_mgr();
|
||||
|
||||
public:
|
||||
bool is_scheme_changed(void);
|
||||
};
|
|
@ -1,825 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgGamma.h"
|
||||
#include "resource.h"
|
||||
#include "mem_dc.h"
|
||||
|
||||
#include "scanned_img.h"
|
||||
|
||||
#define MAX_KEY_POINTS 4 // not include (0, 0) and (255, 255)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// calculator
|
||||
#include <math.h>
|
||||
namespace calc
|
||||
{
|
||||
void solve_matrix(double** a, int n, std::vector<double>& coef)
|
||||
{
|
||||
int m = 0;
|
||||
int i, j;
|
||||
|
||||
coef.clear();
|
||||
for (j = 0; j < n; j++) {
|
||||
double max = 0;
|
||||
double imax = 0;
|
||||
for (i = j; i < n; i++) {
|
||||
if (imax < fabs(a[i][j])) {
|
||||
imax = fabs(a[i][j]);
|
||||
max = a[i][j];//得到各行中所在列最大元素
|
||||
m = i;
|
||||
}
|
||||
}
|
||||
if (fabs(a[j][j]) != max) {
|
||||
double b = 0;
|
||||
for (int k = j; k < n + 1; k++) {
|
||||
b = a[j][k];
|
||||
a[j][k] = a[m][k];
|
||||
a[m][k] = b;
|
||||
}
|
||||
}
|
||||
for (int r = j; r < n + 1; r++) {
|
||||
a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素,目的是让首元素为1
|
||||
}
|
||||
for (i = j + 1; i < n; i++) {
|
||||
double c = a[i][j];
|
||||
if (c == 0) continue;
|
||||
for (int s = j; s < n + 1; s++) {
|
||||
//double tempdata = a[i][s];
|
||||
a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减,使下一行或者上一行的首元素为0
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = n - 2; i >= 0; i--) {
|
||||
for (j = i + 1; j < n; j++) {
|
||||
a[i][n] = a[i][n] - a[j][n] * a[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < n; k++) {
|
||||
coef.push_back(a[k][n]);
|
||||
}
|
||||
}
|
||||
int power(int m, int exp)
|
||||
{
|
||||
int val = 1;
|
||||
for (int i = 0; i < exp; ++i)
|
||||
val *= m;
|
||||
|
||||
return val;
|
||||
}
|
||||
std::vector<double> coefs_from_points(const std::vector<POINT>& pt)
|
||||
{
|
||||
std::vector<double> coef;
|
||||
double** a = new double* [pt.size()];
|
||||
|
||||
for (int i = 0; i < (int)pt.size(); ++i)
|
||||
a[i] = new double[pt.size() + 1];
|
||||
|
||||
for (int i = 0; i < (int)pt.size(); ++i)
|
||||
{
|
||||
for (int j = 0; j < (int)pt.size(); ++j)
|
||||
a[i][j] = power(pt[i].x, pt.size() - j - 1);
|
||||
a[i][pt.size()] = pt[i].y;
|
||||
}
|
||||
solve_matrix(a, pt.size(), coef);
|
||||
for (int i = 0; i < (int)pt.size(); ++i)
|
||||
delete[] a[i];
|
||||
delete[] a;
|
||||
|
||||
return coef;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// dlg_gamma
|
||||
dlg_gamma::dlg_gamma(HWND parent, bool color) : dlg_base(parent, IDD_GAMMA), is_color_(color), bkgnd_(NULL)
|
||||
, show_all_(false)
|
||||
{
|
||||
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM_TONE));
|
||||
|
||||
create();
|
||||
SetWindowTextW(hwnd(), title.c_str());
|
||||
|
||||
if (!dlg_base::is_language_pack_default_code_page())
|
||||
{
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_TONE_SCHEME);
|
||||
set_item_text(IDC_STATIC_SCHEME, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_COLOR_CHANNEL);
|
||||
set_item_text(IDC_STATIC_COLOR, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_INITIALIZE);
|
||||
set_item_text(IDC_BUTTON_RESET, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_INPUT);
|
||||
set_item_text(IDC_STATIC_INPUT, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OUTPUT);
|
||||
set_item_text(IDC_STATIC_OUTPUT, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
|
||||
set_item_text(IDCANCEL, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
|
||||
set_item_text(IDOK, title.c_str());
|
||||
|
||||
layout();
|
||||
}
|
||||
}
|
||||
dlg_gamma::~dlg_gamma()
|
||||
{
|
||||
DeleteObject(bkgnd_);
|
||||
}
|
||||
|
||||
|
||||
BOOL dlg_gamma::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
on_init_dlg();
|
||||
UpdateWindow(hwnd());
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps = { 0 };
|
||||
HDC hdc = BeginPaint(hwnd(), &ps);
|
||||
{
|
||||
compatible_dc dc(hdc);
|
||||
on_paint(dc.get_dc());
|
||||
}
|
||||
EndPaint(hwnd(), &ps);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
on_mouse_move(wp, LOWORD(lp), HIWORD(lp));
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
on_lbutton_down(LOWORD(lp), HIWORD(lp));
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
on_lbutton_up(LOWORD(lp), HIWORD(lp));
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void dlg_gamma::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
if (code == BN_CLICKED)
|
||||
{
|
||||
if (id == IDC_BUTTON_RESET)
|
||||
{
|
||||
init_curve(cur_, cur_->clr);
|
||||
InvalidateRect(hwnd(), NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
quit_modal(id);
|
||||
}
|
||||
}
|
||||
else if (code == EN_CHANGE)
|
||||
{
|
||||
if (id == IDC_EDIT_INPUT)
|
||||
{
|
||||
wchar_t val[40] = { 0 };
|
||||
int y = 0;
|
||||
|
||||
GetDlgItemTextW(hwnd(), id, val, _countof(val) - 1);
|
||||
y = _wtoi(val);
|
||||
if (y < cur_->points[0].x)
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, cur_->points[0].x, FALSE);
|
||||
if (y > cur_->points[1].x)
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, cur_->points[1].x, FALSE);
|
||||
else
|
||||
{
|
||||
y = calc_value(y);
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, y, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (code == CBN_SELCHANGE)
|
||||
{
|
||||
on_combo_sel_changed(id, SendMessage((HWND)ctrl, CB_GETCURSEL, 0, 0));
|
||||
}
|
||||
}
|
||||
void dlg_gamma::layout(void)
|
||||
{
|
||||
int r1 = get_width_diff_as_text_length(IDC_STATIC_SCHEME),
|
||||
r21 = get_width_diff_as_text_length(IDC_STATIC_COLOR),
|
||||
r22 = get_width_diff_as_text_length(IDC_BUTTON_RESET),
|
||||
r31 = get_width_diff_as_text_length(IDC_STATIC_INPUT),
|
||||
r32 = get_width_diff_as_text_length(IDC_STATIC_OUTPUT),
|
||||
r33 = get_width_diff_as_text_length(IDCANCEL),
|
||||
r34 = get_width_diff_as_text_length(IDOK),
|
||||
diff = 0;
|
||||
|
||||
if (diff < r1)
|
||||
diff = r1;
|
||||
if (diff < r21 + r22)
|
||||
diff = r21 + r22;
|
||||
if (diff < r31 + r32 + r33 + r34)
|
||||
diff = r31 + r32 + r33 + r34;
|
||||
|
||||
if (diff > 0)
|
||||
{
|
||||
RECT r = { 0 };
|
||||
|
||||
GetWindowRect(hwnd(), &r);
|
||||
r.right += diff;
|
||||
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
||||
|
||||
expand_item(IDC_STATIC_SCHEME, r1, 0);
|
||||
offset_item(IDC_SCHEME, r1, 0);
|
||||
expand_item(IDC_SCHEME, diff - r1, 0);
|
||||
|
||||
expand_item(IDC_STATIC_COLOR, r21, 0);
|
||||
offset_item(IDC_CHANNEL, r21, 0);
|
||||
|
||||
expand_item(IDC_BUTTON_RESET, r22, 0);
|
||||
offset_item(IDC_BUTTON_RESET, diff - r22, 0);
|
||||
|
||||
expand_item(IDC_STATIC_INPUT, r31, 0);
|
||||
offset_item(IDC_EDIT_INPUT, r31, 0);
|
||||
|
||||
offset_item(IDC_STATIC_OUTPUT, r31, 0);
|
||||
expand_item(IDC_STATIC_OUTPUT, r32, 0);
|
||||
offset_item(IDC_EDIT_OUTPUT, r31 + r32, 0);
|
||||
|
||||
offset_item(IDCANCEL, diff - r33, 0);
|
||||
expand_item(IDCANCEL, r33, 0);
|
||||
|
||||
offset_item(IDOK, diff - r34, 0);
|
||||
expand_item(IDOK, r34, 0);
|
||||
|
||||
expand_item(IDC_STATIC_PAINT, diff, 0);
|
||||
}
|
||||
}
|
||||
void dlg_gamma::create_background(void)
|
||||
{
|
||||
COLORREF bclr = RGB(128, 128, 128);
|
||||
HDC hdc = GetWindowDC(hwnd()),
|
||||
cdc = CreateCompatibleDC(hdc);
|
||||
HBRUSH bkg = CreateSolidBrush(bclr);
|
||||
HPEN grid = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)),
|
||||
old = (HPEN)SelectObject(cdc, grid);
|
||||
HBITMAP ob = NULL;
|
||||
int w = paint_area_.right - paint_area_.left + 2,
|
||||
h = paint_area_.bottom - paint_area_.top + 2;
|
||||
RECT r = { 1, 1, w - 1, h - 1};
|
||||
|
||||
if (bkgnd_)
|
||||
DeleteObject(bkgnd_);
|
||||
|
||||
// create bitmap and select into DC
|
||||
bkgnd_ = CreateCompatibleBitmap(hdc, w, h);
|
||||
ob = (HBITMAP)SelectObject(cdc, bkgnd_);
|
||||
SetBkColor(cdc, bclr);
|
||||
|
||||
// background and grid
|
||||
FillRect(cdc, &r, bkg);
|
||||
MoveToEx(cdc, r.left, r.top, NULL);
|
||||
LineTo(cdc, r.right, r.top);
|
||||
LineTo(cdc, r.right, r.bottom);
|
||||
LineTo(cdc, r.left, r.bottom);
|
||||
LineTo(cdc, r.left, r.top);
|
||||
SelectObject(cdc, old);
|
||||
DeleteObject(grid);
|
||||
grid = CreatePen(PS_DASH, 1, RGB(0, 0, 0));
|
||||
SelectObject(cdc, grid);
|
||||
for (int i = 1; i < 6; ++i)
|
||||
{
|
||||
MoveToEx(cdc, r.left + i * 50, r.bottom, NULL);
|
||||
LineTo(cdc, r.left + i * 50, r.top);
|
||||
|
||||
MoveToEx(cdc, r.left, r.bottom - i * 50, NULL);
|
||||
LineTo(cdc, r.right, r.bottom - i * 50);
|
||||
}
|
||||
|
||||
// default curve
|
||||
MoveToEx(cdc, r.left, r.bottom, NULL);
|
||||
LineTo(cdc, r.right, r.top);
|
||||
|
||||
// free resource
|
||||
SelectObject(cdc, old);
|
||||
SelectObject(cdc, ob);
|
||||
DeleteDC(cdc);
|
||||
ReleaseDC(hwnd(), hdc);
|
||||
|
||||
DeleteObject(bkg);
|
||||
DeleteObject(grid);
|
||||
}
|
||||
void dlg_gamma::init_curve(GAMMACURVE* curv, COLORREF clr)
|
||||
{
|
||||
curv->points.clear();
|
||||
curv->points.push_back({ 0, 0 });
|
||||
curv->points.push_back({ 255, 255 });
|
||||
curv->coefs = calc::coefs_from_points(curv->points);
|
||||
curv->drag = -1;
|
||||
curv->left = 0;
|
||||
curv->right = 1;
|
||||
curv->clr = clr;
|
||||
}
|
||||
int dlg_gamma::add_drag_point(int x, int y)
|
||||
{
|
||||
int ind = -1;
|
||||
|
||||
if (cur_->points.size() < MAX_KEY_POINTS + 2)
|
||||
{
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
if (x < cur_->points[i].x)
|
||||
{
|
||||
cur_->points.insert(cur_->points.begin() + i, { x, calc_value(x) });
|
||||
ind = i;
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
break;
|
||||
}
|
||||
else if (x == cur_->points[i].x)
|
||||
{
|
||||
ind = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ind == -1)
|
||||
{
|
||||
ind = cur_->points.size();
|
||||
cur_->points.push_back({ x, calc_value(x) });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
}
|
||||
cur_->left = ind - 1;
|
||||
cur_->right = ind + 1;
|
||||
if (cur_->left == 1)
|
||||
cur_->left = 0;
|
||||
if (cur_->right >= (int)cur_->points.size())
|
||||
cur_->right = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
if (x == cur_->points[i].x)
|
||||
{
|
||||
ind = i;
|
||||
cur_->left = ind - 1;
|
||||
cur_->right = ind + 1;
|
||||
if (cur_->left == 1)
|
||||
cur_->left = 0;
|
||||
if (cur_->right >= (int)cur_->points.size())
|
||||
cur_->right = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur_->drag = ind;
|
||||
|
||||
return ind;
|
||||
}
|
||||
BYTE dlg_gamma::calc_value(BYTE x)
|
||||
{
|
||||
double y = .0f;
|
||||
for(int j = 0; j < (int)cur_->points.size(); ++j)
|
||||
y += cur_->coefs[j] * calc::power(x, cur_->points.size() - j - 1);
|
||||
|
||||
if (y > 255.0f)
|
||||
y = 255.0f;
|
||||
if (y < .0f)
|
||||
y = .0f;
|
||||
|
||||
bool upper = cur_->points[1].y > cur_->points[0].y;
|
||||
if (y < cur_->points[!upper].y)
|
||||
y = cur_->points[!upper].y;
|
||||
if (y > cur_->points[upper].y)
|
||||
y = cur_->points[upper].y;
|
||||
|
||||
return (BYTE)(y + .5f);
|
||||
}
|
||||
bool dlg_gamma::is_adjacent(POINT p1, POINT p2)
|
||||
{
|
||||
bool neighbour = abs(p1.x - p2.x) <= 3 && abs(p1.y - p2.y) <= 3;
|
||||
|
||||
return neighbour;
|
||||
}
|
||||
bool dlg_gamma::hit_test(int* x, int* y)
|
||||
{
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
POINT pt = { *x, *y };
|
||||
if (is_adjacent(pt, cur_->points[i]))
|
||||
{
|
||||
*x = cur_->points[i].x;
|
||||
*y = cur_->points[i].y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int val = calc_value(*x), tolerant = 3;
|
||||
bool hit = false;
|
||||
|
||||
if (abs(val - *y) < tolerant)
|
||||
{
|
||||
*y = val;
|
||||
hit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int l = *x - tolerant,
|
||||
u = *x + tolerant;
|
||||
if (l < 0)
|
||||
l = 0;
|
||||
if (u > 255)
|
||||
u = 255;
|
||||
for (; l <= u; ++l)
|
||||
{
|
||||
val = calc_value(l);
|
||||
if (abs(val - *y) < tolerant)
|
||||
{
|
||||
hit = true;
|
||||
*x = l;
|
||||
*y = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
void dlg_gamma::draw_ellipse(HDC hdc, POINT center, int xl, int yl)
|
||||
{
|
||||
center.x += paint_area_.left;
|
||||
center.y = paint_area_.bottom - center.y;
|
||||
|
||||
HRGN rgn = CreateEllipticRgn(center.x - xl, center.y - yl, center.x + xl, center.y + yl);
|
||||
HBRUSH brsh = CreateSolidBrush(RGB(255, 0, 255));
|
||||
FillRgn(hdc, rgn, brsh);
|
||||
DeleteObject(brsh);
|
||||
DeleteObject(rgn);
|
||||
}
|
||||
void dlg_gamma::draw_current_curve(HDC hdc)
|
||||
{
|
||||
MoveToEx(hdc, paint_area_.left + cur_->points[0].x, paint_area_.bottom - cur_->points[0].y, NULL);
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
int y = calc_value(i);
|
||||
LineTo(hdc, paint_area_.left + i, paint_area_.bottom - y);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_gamma::on_init_dlg(void)
|
||||
{
|
||||
HWND combo = get_item(IDC_SCHEME);
|
||||
|
||||
GetWindowRect(get_item(IDC_STATIC_PAINT), &paint_area_);
|
||||
screen_2_client(&paint_area_);
|
||||
paint_area_.right = paint_area_.left + 255;
|
||||
paint_area_.bottom = paint_area_.top + 255;
|
||||
create_background();
|
||||
|
||||
init_curve(&rgb_gray_);
|
||||
init_curve(&red_, RGB(255, 0, 0));
|
||||
init_curve(&green_, RGB(0, 255, 0));
|
||||
init_curve(&blue_, RGB(0, 0, 255));
|
||||
|
||||
std::wstring lang(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM));
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_NEG_PHOTO) + L" (RGB)";
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_COLOR_NEG_PHOTO) + L" (RGB)";
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_DARKER) + L" (RGB)";
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_BRIGHTER) + L" (RGB)";
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
SendMessage(combo, CB_SETCURSEL, 0, 0);
|
||||
|
||||
combo = get_item(IDC_CHANNEL);
|
||||
if (is_color_)
|
||||
{
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)L"RGB");
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_RED);
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_GREEN);
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_BLUE);
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
lang = local_trans::lang_trans_between_hz936(CONST_STRING_GRAY);
|
||||
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
|
||||
}
|
||||
SendMessage(combo, CB_SETCURSEL, 0, 0);
|
||||
cur_ = &rgb_gray_;
|
||||
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, 0, FALSE);
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, 0, FALSE);
|
||||
}
|
||||
void dlg_gamma::on_paint(HDC hdc)
|
||||
{
|
||||
HPEN pen = CreatePen(PS_SOLID, 1, cur_->clr),
|
||||
drag = CreatePen(PS_SOLID, 1, RGB(255, 0, 255)),
|
||||
old = (HPEN)SelectObject(hdc, pen);
|
||||
HDC cdc = CreateCompatibleDC(hdc);
|
||||
HBITMAP ob = (HBITMAP)SelectObject(cdc, bkgnd_);
|
||||
|
||||
BitBlt(hdc, paint_area_.left - 1, paint_area_.top - 1, paint_area_.right - paint_area_.left + 2, paint_area_.bottom - paint_area_.top + 2,
|
||||
cdc, 0, 0, SRCCOPY);
|
||||
SelectObject(cdc, ob);
|
||||
DeleteDC(cdc);
|
||||
|
||||
if (show_all_)
|
||||
{
|
||||
GAMMACURVE* prev = cur_;
|
||||
HPEN now = NULL;
|
||||
|
||||
cur_ = &red_;
|
||||
now = CreatePen(PS_SOLID, 1, cur_->clr);
|
||||
SelectObject(hdc, now);
|
||||
draw_current_curve(hdc);
|
||||
|
||||
cur_ = &green_;
|
||||
SelectObject(hdc, old);
|
||||
DeleteObject(now);
|
||||
now = CreatePen(PS_SOLID, 1, cur_->clr);
|
||||
SelectObject(hdc, now);
|
||||
draw_current_curve(hdc);
|
||||
|
||||
cur_ = &blue_;
|
||||
SelectObject(hdc, old);
|
||||
DeleteObject(now);
|
||||
now = CreatePen(PS_SOLID, 1, cur_->clr);
|
||||
SelectObject(hdc, now);
|
||||
draw_current_curve(hdc);
|
||||
|
||||
SelectObject(hdc, pen);
|
||||
DeleteObject(now);
|
||||
cur_ = prev;
|
||||
}
|
||||
else
|
||||
draw_current_curve(hdc);
|
||||
SelectObject(hdc, drag);
|
||||
|
||||
for (int i = 0; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
draw_ellipse(hdc, cur_->points[i], 3, 3);
|
||||
}
|
||||
SelectObject(hdc, old);
|
||||
|
||||
DeleteObject(pen);
|
||||
}
|
||||
void dlg_gamma::on_mouse_move(DWORD key, int x, int y)
|
||||
{
|
||||
POINT pt = { x, y };
|
||||
|
||||
if (PtInRect(&paint_area_, pt))
|
||||
{
|
||||
x -= paint_area_.left;
|
||||
y = paint_area_.bottom - y;
|
||||
if (key == MK_LBUTTON && cur_->drag != -1)
|
||||
{
|
||||
if (x <= cur_->points[cur_->left].x)
|
||||
x = cur_->points[cur_->left].x + 1;
|
||||
else if (x >= cur_->points[cur_->right].x)
|
||||
x = cur_->points[cur_->right].x - 1;
|
||||
cur_->points[cur_->drag].x = x;
|
||||
cur_->points[cur_->drag].y = y;
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
InvalidateRect(hwnd(), NULL, FALSE);
|
||||
}
|
||||
else if (key == MK_CONTROL)
|
||||
{
|
||||
y = calc_value(x);
|
||||
pt.y = paint_area_.bottom - y;
|
||||
ClientToScreen(hwnd(), &pt);
|
||||
SetCursorPos(pt.x, pt.y);
|
||||
}
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, x, FALSE);
|
||||
SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, y, FALSE);
|
||||
}
|
||||
}
|
||||
void dlg_gamma::on_lbutton_down(int x, int y)
|
||||
{
|
||||
x -= paint_area_.left;
|
||||
y = paint_area_.bottom - y;
|
||||
if (hit_test(&x, &y))
|
||||
{
|
||||
if(add_drag_point(x, y) != -1)
|
||||
SetCapture(hwnd());
|
||||
}
|
||||
}
|
||||
void dlg_gamma::on_lbutton_up(int x, int y)
|
||||
{
|
||||
cur_->drag = -1;
|
||||
cur_->left = 0;
|
||||
cur_->right = 1;
|
||||
ReleaseCapture();
|
||||
}
|
||||
void dlg_gamma::on_combo_sel_changed(int id, int sel)
|
||||
{
|
||||
show_all_ = false;
|
||||
if (id == IDC_SCHEME)
|
||||
{
|
||||
if (sel == 1)
|
||||
{
|
||||
cur_ = &rgb_gray_;
|
||||
init_curve(cur_);
|
||||
cur_->points.clear();
|
||||
cur_->points.push_back({ 0, 255 });
|
||||
cur_->points.push_back({ 255, 0 });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
}
|
||||
else if (sel == 2)
|
||||
{
|
||||
show_all_ = true;
|
||||
cur_ = &red_;
|
||||
init_curve(cur_, cur_->clr);
|
||||
cur_->points.clear();
|
||||
cur_->points.push_back({ 33, 255 });
|
||||
cur_->points.push_back({ 185, 0 });
|
||||
cur_->points.push_back({ 119, 127 });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
|
||||
cur_ = &green_;
|
||||
init_curve(cur_, cur_->clr);
|
||||
cur_->points.clear();
|
||||
cur_->points.push_back({ 28, 255 });
|
||||
cur_->points.push_back({ 132, 0 });
|
||||
cur_->points.push_back({ 77, 127 });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
|
||||
cur_ = &blue_;
|
||||
init_curve(cur_, cur_->clr);
|
||||
cur_->points.clear();
|
||||
cur_->points.push_back({ 25, 255 });
|
||||
cur_->points.push_back({ 108, 0 });
|
||||
cur_->points.push_back({ 60, 127 });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
|
||||
cur_ = &red_;
|
||||
}
|
||||
else if (sel == 3)
|
||||
{
|
||||
cur_ = &rgb_gray_;
|
||||
init_curve(cur_);
|
||||
cur_->points.push_back({ 130, 101 });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
}
|
||||
else if (sel == 4)
|
||||
{
|
||||
cur_ = &rgb_gray_;
|
||||
init_curve(cur_);
|
||||
cur_->points.push_back({ 103, 125 });
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
}
|
||||
InvalidateRect(hwnd(), NULL, FALSE);
|
||||
}
|
||||
else if (id == IDC_CHANNEL)
|
||||
{
|
||||
GAMMACURVE* prev = cur_, * all[] = { &rgb_gray_, &red_, &green_, &blue_ };
|
||||
|
||||
cur_ = all[sel];
|
||||
if (prev != cur_)
|
||||
{
|
||||
if (cur_->points.size() == 2)
|
||||
{
|
||||
COLORREF clr = cur_->clr;
|
||||
|
||||
*cur_ = *prev;
|
||||
cur_->clr = clr;
|
||||
}
|
||||
InvalidateRect(hwnd(), NULL, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_gamma::get_gamma(SANE_Gamma* gamma)
|
||||
{
|
||||
gamma->apply_to_back = SANE_FALSE;
|
||||
//if (cur_ == &rgb_gray_)
|
||||
{
|
||||
cur_ = &rgb_gray_;
|
||||
gamma->pt_count = (SANE_Byte)(cur_->points.size() - 2);
|
||||
// gamma->pt_count_r = gamma->pt_count_g = gamma->pt_count_b = 0;
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
gamma->keypoint[i - 2].x = (SANE_Byte)cur_->points[i].x;
|
||||
gamma->keypoint[i - 2].y = (SANE_Byte)cur_->points[i].y;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
gamma->table[i] = calc_value(i);
|
||||
}
|
||||
//else
|
||||
{
|
||||
// gamma->pt_count = 0;
|
||||
|
||||
cur_ = &red_;
|
||||
gamma->pt_count_r = (SANE_Byte)(cur_->points.size() - 2);
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
gamma->keypoint_r[i - 2].x = (SANE_Byte)cur_->points[i].x;
|
||||
gamma->keypoint_r[i - 2].y = (SANE_Byte)cur_->points[i].y;
|
||||
}
|
||||
for (int i = 0; i < 256; ++i)
|
||||
gamma->table[i] = calc_value(i);
|
||||
|
||||
cur_ = &green_;
|
||||
gamma->pt_count_g = (SANE_Byte)(cur_->points.size() - 2);
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
gamma->keypoint_g[i - 2].x = (SANE_Byte)cur_->points[i].x;
|
||||
gamma->keypoint_g[i - 2].y = (SANE_Byte)cur_->points[i].y;
|
||||
}
|
||||
for (int i = 0; i < 256; ++i)
|
||||
gamma->table[256 + i] = calc_value(i);
|
||||
|
||||
cur_ = &blue_;
|
||||
gamma->pt_count_b = (SANE_Byte)(cur_->points.size() - 2);
|
||||
for (int i = 2; i < (int)cur_->points.size(); ++i)
|
||||
{
|
||||
gamma->keypoint_b[i - 2].x = (SANE_Byte)cur_->points[i].x;
|
||||
gamma->keypoint_b[i - 2].y = (SANE_Byte)cur_->points[i].y;
|
||||
}
|
||||
for (int i = 0; i < 256; ++i)
|
||||
gamma->table[512 + i] = calc_value(i);
|
||||
}
|
||||
}
|
||||
void dlg_gamma::set_gamma(const SANE_Gamma* gamma, bool gray)
|
||||
{
|
||||
int sel = 0;
|
||||
std::wstring text(L"");
|
||||
|
||||
SendMessage(get_item(IDC_CHANNEL), CB_RESETCONTENT, 0, 0);
|
||||
is_color_ = !gray;
|
||||
cur_ = &rgb_gray_;
|
||||
init_curve(cur_);
|
||||
for (int i = 0; i < gamma->pt_count; ++i)
|
||||
{
|
||||
POINT pt = { gamma->keypoint[i].x, gamma->keypoint[i].y };
|
||||
cur_->points.push_back(pt);
|
||||
}
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
if (is_color_)
|
||||
{
|
||||
SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)L"RGB");
|
||||
}
|
||||
else
|
||||
{
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_GRAY);
|
||||
SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
|
||||
}
|
||||
|
||||
if(!gray)
|
||||
{
|
||||
is_color_ = true;
|
||||
cur_ = &red_;
|
||||
init_curve(cur_);
|
||||
for (int i = 0; i < gamma->pt_count_r; ++i)
|
||||
{
|
||||
POINT pt = { gamma->keypoint_r[i].x, gamma->keypoint_r[i].y };
|
||||
cur_->points.push_back(pt);
|
||||
}
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
|
||||
cur_ = &green_;
|
||||
init_curve(cur_);
|
||||
for (int i = 0; i < gamma->pt_count_g; ++i)
|
||||
{
|
||||
POINT pt = { gamma->keypoint_g[i].x, gamma->keypoint_g[i].y };
|
||||
cur_->points.push_back(pt);
|
||||
}
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
|
||||
cur_ = &blue_;
|
||||
init_curve(cur_);
|
||||
for (int i = 0; i < gamma->pt_count_b; ++i)
|
||||
{
|
||||
POINT pt = { gamma->keypoint_b[i].x, gamma->keypoint_b[i].y };
|
||||
cur_->points.push_back(pt);
|
||||
}
|
||||
cur_->coefs = calc::coefs_from_points(cur_->points);
|
||||
|
||||
// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)L"RGB");
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_RED);
|
||||
SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_GREEN);
|
||||
SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_BLUE);
|
||||
SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
|
||||
}
|
||||
cur_ = &rgb_gray_;
|
||||
sel = 0;
|
||||
SendMessage(get_item(IDC_CHANNEL), CB_SETCURSEL, sel, 0);
|
||||
SendMessage(get_item(IDC_SCHEME), CB_SETCURSEL, 0, 0);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
class dlg_gamma: public dlg_base
|
||||
{
|
||||
bool is_color_;
|
||||
bool show_all_;
|
||||
RECT paint_area_;
|
||||
HBITMAP bkgnd_;
|
||||
|
||||
typedef struct _gamma_curve
|
||||
{
|
||||
std::vector<POINT> points;
|
||||
std::vector<double> coefs;
|
||||
int drag;
|
||||
int left;
|
||||
int right;
|
||||
COLORREF clr;
|
||||
}GAMMACURVE;
|
||||
GAMMACURVE rgb_gray_;
|
||||
GAMMACURVE red_;
|
||||
GAMMACURVE green_;
|
||||
GAMMACURVE blue_;
|
||||
GAMMACURVE* cur_;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void layout(void);
|
||||
void create_background(void);
|
||||
void init_curve(GAMMACURVE* curv, COLORREF clr = RGB(255, 255, 255));
|
||||
int add_drag_point(int x, int y);
|
||||
BYTE calc_value(BYTE x);
|
||||
bool is_adjacent(POINT p1, POINT p2);
|
||||
bool hit_test(int* x, int* y);
|
||||
void draw_ellipse(HDC hdc, POINT center, int xl, int yl);
|
||||
void draw_current_curve(HDC hdc);
|
||||
|
||||
void on_init_dlg(void);
|
||||
void on_paint(HDC hdc);
|
||||
void on_mouse_move(DWORD key, int x, int y);
|
||||
void on_lbutton_down(int x, int y);
|
||||
void on_lbutton_up(int x, int y);
|
||||
void on_combo_sel_changed(int id, int sel);
|
||||
|
||||
public:
|
||||
dlg_gamma(HWND parent, bool color);
|
||||
~dlg_gamma();
|
||||
|
||||
public:
|
||||
void get_gamma(SANE_Gamma* gamma);
|
||||
void set_gamma(const SANE_Gamma* gamma, bool gray);
|
||||
};
|
|
@ -1,315 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgIndicator.h"
|
||||
#include "resource.h"
|
||||
#include "scanned_img.h" // for local_trans
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// dlg_choose_dev
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
|
||||
dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR)
|
||||
, papers_(0), images_(0), err_(false)
|
||||
{
|
||||
create();
|
||||
SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW);
|
||||
|
||||
if (!dlg_base::is_language_pack_default_code_page())
|
||||
{
|
||||
std::wstring text(local_trans::lang_trans_between_hz936(CONST_STRING_SCANNING));
|
||||
|
||||
SetWindowTextW(hwnd(), text.c_str());
|
||||
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_PAPER);
|
||||
set_item_text(IDC_STATIC_PAPER, text.c_str());
|
||||
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_IMAGE);
|
||||
set_item_text(IDC_STATIC_IMAGE, text.c_str());
|
||||
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
|
||||
set_item_text(IDCANCEL, text.c_str());
|
||||
|
||||
int paper = get_width_diff_as_text_length(IDC_STATIC_PAPER),
|
||||
img = get_width_diff_as_text_length(IDC_STATIC_IMAGE),
|
||||
btn = get_width_diff_as_text_length(IDCANCEL),
|
||||
diff = paper >= img + btn ? paper : img + btn;
|
||||
|
||||
if (diff > 0)
|
||||
{
|
||||
RECT r = { 0 };
|
||||
|
||||
GetWindowRect(hwnd(), &r);
|
||||
r.right += diff;
|
||||
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
||||
|
||||
expand_item(IDC_STATIC_PAPER, paper, 0);
|
||||
offset_item(IDC_EDIT_PAPER, paper, 0);
|
||||
|
||||
expand_item(IDC_STATIC_IMAGE, img, 0);
|
||||
offset_item(IDC_EDIT_IMAGE, img, 0);
|
||||
|
||||
offset_item(IDCANCEL, diff - btn, 0);
|
||||
expand_item(IDCANCEL, btn, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
dlg_indicator::~dlg_indicator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
swprintf_s(text, _countof(text) - 1, L"%u", papers_);
|
||||
SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text);
|
||||
SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text);
|
||||
UpdateWindow(hwnd_);
|
||||
break;
|
||||
case WM_USB_PACKET_RECEIVED:
|
||||
papers_++;
|
||||
swprintf_s(text, _countof(text) - 1, L"%u", papers_);
|
||||
SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text);
|
||||
UpdateWindow(hwnd_);
|
||||
break;
|
||||
case WM_IMAGE_RECEIVED:
|
||||
images_++;
|
||||
swprintf_s(text, _countof(text) - 1, L"%u", images_);
|
||||
SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text);
|
||||
UpdateWindow(hwnd_);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_DRAWITEM:
|
||||
if (wp == IDC_STATIC_ERR)
|
||||
{
|
||||
DRAWITEMSTRUCT* ds = (DRAWITEMSTRUCT*)lp;
|
||||
wchar_t text[128] = { 0 };
|
||||
HBRUSH brsh = CreateSolidBrush(GetBkColor(ds->hDC));
|
||||
|
||||
FillRect(ds->hDC, &ds->rcItem, brsh);
|
||||
DeleteObject(brsh);
|
||||
|
||||
GetWindowTextW(ds->hwndItem, text, _countof(text) - 1);
|
||||
SetBkMode(ds->hDC, TRANSPARENT);
|
||||
SetTextColor(ds->hDC, err_ ? RGB(255, 0, 0) : RGB(0, 0, 0));
|
||||
TextOutW(ds->hDC, 0, 0, text, lstrlenW(text));
|
||||
}
|
||||
ret = FALSE;
|
||||
break;
|
||||
case WM_SCAN_WORKING:
|
||||
notify_ui_event(SANE_EVENT_WORKING);
|
||||
break;
|
||||
case WM_SCAN_FINISHED:
|
||||
if (lp)
|
||||
{
|
||||
std::string* str = (std::string*)wp;
|
||||
std::wstring err(local_trans::a2u(str->c_str(), CP_UTF8));
|
||||
|
||||
SetDlgItemTextW(hwnd_, IDC_STATIC_ERR, err.c_str());
|
||||
delete str;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string* str = (std::string*)wp;
|
||||
std::wstring txt(local_trans::lang_trans_between_hz936(CONST_STRING_TOTAL_SCANNED));
|
||||
|
||||
txt += L": " + std::to_wstring(images_);
|
||||
SetDlgItemTextW(hwnd_, IDC_STATIC_ERR, txt.c_str());
|
||||
delete str;
|
||||
SetTimer(hwnd_, 1, 3000, NULL);
|
||||
}
|
||||
SetDlgItemTextW(hwnd_, IDCANCEL, local_trans::lang_trans_between_hz936(CONST_STRING_CLOSE).c_str());
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_PAPER), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_IMAGE), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_EDIT_PAPER), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_EDIT_IMAGE), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_ERR), SW_SHOW);
|
||||
SetWindowTextW(hwnd_, local_trans::lang_trans_between_hz936(CONST_STRING_SCAN_OVER).c_str());
|
||||
UpdateWindow(hwnd_);
|
||||
break;
|
||||
case WM_TIMER:
|
||||
if (wp == 1)
|
||||
{
|
||||
KillTimer(hwnd_, wp);
|
||||
notify_over(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
if (id == IDCANCEL)
|
||||
{
|
||||
notify_over(true);
|
||||
}
|
||||
}
|
||||
void dlg_indicator::notify_over(bool cancel)
|
||||
{
|
||||
notify_ui_event(cancel ? SANE_EVENT_UI_CLOSE_CANCEL : SANE_EVENT_UI_CLOSE_NORMAL);
|
||||
}
|
||||
|
||||
HWND dlg_indicator::window(void)
|
||||
{
|
||||
return hwnd_;
|
||||
}
|
||||
HWND dlg_indicator::parent(void)
|
||||
{
|
||||
return parent_;
|
||||
}
|
||||
void dlg_indicator::notify_data_arrived(bool image)
|
||||
{
|
||||
SendMessage(hwnd_, image ? WM_IMAGE_RECEIVED : WM_USB_PACKET_RECEIVED, 0, 0); // PostMessage 存在消息合并/遗漏的现象,改用Send
|
||||
}
|
||||
void dlg_indicator::notify_scan_over(const char* msg, bool err)
|
||||
{
|
||||
std::string* mstr(new std::string(msg ? msg : ""));
|
||||
|
||||
err_ = err;
|
||||
if (!PostMessage(hwnd_, WM_SCAN_FINISHED, (WPARAM)mstr, (LPARAM)err))
|
||||
{
|
||||
delete mstr;
|
||||
notify_over(false);
|
||||
}
|
||||
}
|
||||
void dlg_indicator::notify_working(void)
|
||||
{
|
||||
PostMessage(hwnd_, WM_SCAN_WORKING, 0, 0);
|
||||
}
|
||||
// CDlgIndicator 消息处理程序
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// dlg_choose_dev
|
||||
///
|
||||
dlg_choose_dev::dlg_choose_dev(HWND parent, const std::vector<DEVQUE>& devs) : dlg_base(parent, IDD_CHOOSE_DEV), item_(-1)
|
||||
{
|
||||
create();
|
||||
|
||||
HWND lst = GetDlgItem(hwnd_, IDC_LIST1);
|
||||
LV_COLUMNW col = { 0 };
|
||||
int ind = 0;
|
||||
std::wstring text(local_trans::lang_trans_between_hz936(CONST_STRING_CHOOSE_DEVICE));
|
||||
|
||||
SetWindowTextW(hwnd(), text.c_str());
|
||||
ListView_SetExtendedListViewStyle(lst, ListView_GetExtendedListViewStyle(lst) | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
|
||||
SetWindowLong(lst, GWL_STYLE, GetWindowLong(lst, GWL_STYLE) | LVS_SINGLESEL);
|
||||
col.mask = LVCF_TEXT | LVCF_WIDTH;
|
||||
col.cx = 180;
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_DEVICE_NAME);
|
||||
col.pszText = &text[0];
|
||||
SendMessageW(lst, LVM_INSERTCOLUMN, ind++, (LPARAM)&col);
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_SERIAL_NUM);
|
||||
col.pszText = &text[0];
|
||||
SendMessageW(lst, LVM_INSERTCOLUMN, ind++, (LPARAM)&col);
|
||||
|
||||
ind = 0;
|
||||
for (const auto& v: devs)
|
||||
{
|
||||
std::wstring n(local_trans::a2u(v.name.c_str(), CP_UTF8)),
|
||||
s(local_trans::a2u(v.sn.c_str(), CP_UTF8));
|
||||
LV_ITEM item = { 0 };
|
||||
int ind = 0;
|
||||
|
||||
item.mask = LVIF_TEXT;
|
||||
item.pszText = &n[0];
|
||||
item.iItem = ListView_GetItemCount(lst);
|
||||
ind = SendMessageW(lst, LVM_INSERTITEMW, 0, (LPARAM)&item);
|
||||
|
||||
item.pszText = &s[0];
|
||||
item.iSubItem = 1;
|
||||
item.iItem = ind;
|
||||
SendMessageW(lst, LVM_SETITEMTEXTW, ind, (LPARAM)&item);
|
||||
if (ind++ == 0)
|
||||
{
|
||||
item_ = 0;
|
||||
ListView_SetItemState(lst, ind, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
||||
SetFocus(lst);
|
||||
}
|
||||
}
|
||||
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
|
||||
set_item_text(IDCANCEL, text.c_str());
|
||||
|
||||
text = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
|
||||
set_item_text(IDOK, text.c_str());
|
||||
}
|
||||
dlg_choose_dev::~dlg_choose_dev()
|
||||
{}
|
||||
|
||||
BOOL dlg_choose_dev::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
handle_notify(wp, (LPNMHDR)lp);
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void dlg_choose_dev::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
if (id == IDOK)
|
||||
{
|
||||
HWND lst = GetDlgItem(hwnd_, IDC_LIST1);
|
||||
if (item_ >= 0 && item_ < ListView_GetItemCount(lst))
|
||||
{
|
||||
wchar_t buf[128] = { 0 };
|
||||
|
||||
ListView_GetItemText(lst, item_, 0, buf, _countof(buf) - 1);
|
||||
sel_ = local_trans::u2a(buf, CP_UTF8);
|
||||
}
|
||||
id = IDCANCEL;
|
||||
}
|
||||
|
||||
if (id == IDCANCEL)
|
||||
{
|
||||
abandon_hold_ = true;
|
||||
PostMessage(hwnd_, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
void dlg_choose_dev::handle_notify(UINT id, LPNMHDR pnhdr)
|
||||
{
|
||||
if (pnhdr->hwndFrom == GetDlgItem(hwnd_, IDC_LIST1))
|
||||
{
|
||||
if (pnhdr->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
LPNMHEADER h = (LPNMHEADER)pnhdr;
|
||||
item_ = h->iItem;
|
||||
}
|
||||
else if (pnhdr->code == NM_DBLCLK)
|
||||
{
|
||||
handle_command(0, IDOK, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string dlg_choose_dev::get_selected_device(void)
|
||||
{
|
||||
return sel_;
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
class dlg_indicator : public dlg_base
|
||||
{
|
||||
unsigned int papers_;
|
||||
unsigned int images_;
|
||||
bool err_;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void notify_over(bool cancel);
|
||||
|
||||
public:
|
||||
dlg_indicator(HWND parent);
|
||||
~dlg_indicator();
|
||||
|
||||
public:
|
||||
HWND window(void);
|
||||
HWND parent(void);
|
||||
void notify_data_arrived(bool image);
|
||||
void notify_scan_over(const char* msg, bool err);
|
||||
void notify_working(void);
|
||||
};
|
||||
|
||||
typedef struct _dev_que
|
||||
{
|
||||
int id; // ID,用户选中后返回该值
|
||||
std::string name; // 设备名称
|
||||
std::string sn; // 设备序列号
|
||||
}DEVQUE;
|
||||
|
||||
class dlg_choose_dev : public dlg_base
|
||||
{
|
||||
std::string sel_;
|
||||
int item_;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void handle_notify(UINT id, LPNMHDR pnhdr);
|
||||
|
||||
public:
|
||||
dlg_choose_dev(HWND parent, const std::vector<DEVQUE>& devs);
|
||||
~dlg_choose_dev();
|
||||
|
||||
public:
|
||||
std::string get_selected_device(void);
|
||||
};
|
|
@ -1,108 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgInput.h"
|
||||
#include "resource.h"
|
||||
#include "scanned_img.h" // for local_trans
|
||||
#include "mem_dc.h"
|
||||
#include "gb_json.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
dlg_input::dlg_input(HWND parent, const wchar_t* init_val) : dlg_base(parent, IDD_INPUT), val_(init_val ? init_val : L"")
|
||||
{
|
||||
create();
|
||||
|
||||
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_INPUT_VAL));
|
||||
|
||||
SetWindowTextW(hwnd(), title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
|
||||
set_item_text(IDCANCEL, title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
|
||||
set_item_text(IDOK, title.c_str());
|
||||
}
|
||||
dlg_input::~dlg_input()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOOL dlg_input::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
on_init_dlg();
|
||||
UpdateWindow(hwnd());
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void dlg_input::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
wchar_t cls[128] = { 0 };
|
||||
|
||||
GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1);
|
||||
if (IS_BUTTON(cls))
|
||||
{
|
||||
if (code == BN_CLICKED)
|
||||
{
|
||||
if (id == IDOK || id == IDCANCEL)
|
||||
{
|
||||
if (id == IDOK)
|
||||
{
|
||||
std::wstring input(dlg_base::get_item_text(IDC_EDIT1));
|
||||
|
||||
if (input.empty())
|
||||
{
|
||||
MessageBoxW(hwnd(), local_trans::lang_trans_between_hz936(CONST_STRING_RE_INPUT).c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_NO_INPUT).c_str(), MB_OK | MB_ICONSTOP);
|
||||
SetFocus(get_item(IDC_EDIT1));
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& v : no_repeats_)
|
||||
{
|
||||
if (v == input)
|
||||
{
|
||||
input += L" " + local_trans::lang_trans_between_hz936(CONST_STRING_ALREADY_EXISTS);
|
||||
::MessageBoxW(hwnd(), input.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_RE_INPUT).c_str(), MB_OK | MB_ICONINFORMATION);
|
||||
SetFocus(get_item(IDC_EDIT1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
val_ = std::move(input);
|
||||
}
|
||||
quit_modal(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IS_EDIT(cls))
|
||||
{
|
||||
//if (code == EN_SETFOCUS)
|
||||
// label_edit_ = (HWND)ctrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dlg_input::on_init_dlg(void)
|
||||
{
|
||||
dlg_base::set_item_text(IDC_EDIT1, val_.c_str());
|
||||
}
|
||||
|
||||
void dlg_input::set_no_repeats(const std::vector<std::wstring>& vals)
|
||||
{
|
||||
no_repeats_ = vals;
|
||||
}
|
||||
std::wstring dlg_input::get_value(void)
|
||||
{
|
||||
return val_;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
|
||||
class dlg_input: public dlg_base
|
||||
{
|
||||
std::vector<std::wstring> no_repeats_;
|
||||
std::wstring val_;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
|
||||
void on_init_dlg(void);
|
||||
|
||||
public:
|
||||
dlg_input(HWND parent, const wchar_t* init_val);
|
||||
~dlg_input();
|
||||
|
||||
public:
|
||||
void set_no_repeats(const std::vector<std::wstring>& vals);
|
||||
std::wstring get_value(void);
|
||||
};
|
1761
sane/DlgPage.cpp
1761
sane/DlgPage.cpp
File diff suppressed because it is too large
Load Diff
228
sane/DlgPage.h
228
sane/DlgPage.h
|
@ -1,228 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <CommCtrl.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sane/sane_ex.h>
|
||||
#include <sane/sane_option_definitions.h>
|
||||
#include "const_str.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
#define FLOAT_FORMAT L"%.2f"
|
||||
#define IS_STR_EQUAL(s1, s2) (wcscmp(s1, s2) == 0)
|
||||
#define IS_EDIT(cls) IS_STR_EQUAL(cls, WC_EDITW)
|
||||
#define IS_COMBOX(cls) IS_STR_EQUAL(cls, WC_COMBOBOXW)
|
||||
#define IS_BUTTON(cls) IS_STR_EQUAL(cls, WC_BUTTONW)
|
||||
#define IS_TRACKBAR(cls) IS_STR_EQUAL(cls, TRACKBAR_CLASSW)
|
||||
#define IS_UPDOWN_ARROW(cls) IS_STR_EQUAL(cls, UPDOWN_CLASSW)
|
||||
|
||||
#define RECT_W(r) (r.right - r.left)
|
||||
#define RECT_H(r) (r.bottom - r.top)
|
||||
|
||||
#define WM_SCAN_WORKING WM_USER + 301 // WPARAM: unused; LPARAM: unsed
|
||||
#define WM_USB_PACKET_RECEIVED WM_USER + 302
|
||||
#define WM_IMAGE_RECEIVED WM_USER + 303
|
||||
#define WM_SCAN_FINISHED WM_USER + 304 // WPARAM: std::string* msg; LPARAM: boo err
|
||||
#define WM_REFRESH_OPTION WM_USER + 311 // WPARAM: source option SN, LPARAM: unused now
|
||||
#define WM_GET_CONFIG_OBJ WM_USER + 312 // WPARAM: bool*, [in]create new if NULL; [out]created, LPARAM: to receive the gb::sane_config_schm* object
|
||||
|
||||
|
||||
extern HMODULE g_my_inst;
|
||||
namespace gb
|
||||
{
|
||||
class sane_config_schm;
|
||||
}
|
||||
|
||||
class dlg_base
|
||||
{
|
||||
int modal_exit_; // set non-ZERO code to exit modal dialog
|
||||
|
||||
protected:
|
||||
HWND hwnd_;
|
||||
HWND parent_;
|
||||
UINT idd_;
|
||||
bool abandon_hold_;
|
||||
void(__stdcall* ui_event_notify_)(int uev, void* sender, void* param);
|
||||
void* ui_notify_param_;
|
||||
static std::wstring prop_name;
|
||||
static BOOL CALLBACK dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||
|
||||
virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp);
|
||||
virtual void on_font_changed(void);
|
||||
void create(void);
|
||||
void notify_ui_event(int ev);
|
||||
gb::sane_config_schm* get_config(bool* create);
|
||||
|
||||
public:
|
||||
dlg_base(HWND parent, UINT idd);
|
||||
virtual ~dlg_base();
|
||||
|
||||
static void screen_2_client(HWND wnd, LPRECT r);
|
||||
static void client_2_screen(HWND wnd, LPRECT r);
|
||||
static bool get_max_size(SIZE& dst, const SIZE& src); // return whether changed dst
|
||||
static bool get_max_size(SIZE& dst, int cx, int cy); // return whether changed dst
|
||||
static int select_combo_text(HWND combo, const wchar_t* text);
|
||||
static std::wstring get_wnd_text(HWND h);
|
||||
static bool is_language_pack_default_code_page(void);
|
||||
static std::wstring get_menu_text(HMENU menu, int ind);
|
||||
static void center_window(HWND wnd, HWND parent);
|
||||
|
||||
static int list_insert_column(HWND list_wnd, const wchar_t* text, int cx = 20, int ind = -1);
|
||||
static int list_insert_item(HWND list_wnd, const wchar_t* text, int ind = -1);
|
||||
static int list_get_item_count(HWND list_wnd);
|
||||
static int list_get_column_count(HWND list_wnd);
|
||||
static std::wstring list_get_text(HWND list_wnd, int ind, int sub = 0);
|
||||
static void list_get_selected_items(HWND list_wnd, std::vector<int>& sels);
|
||||
static int list_set_item_text(HWND list_wnd, int item, int sub_item, const wchar_t* text);
|
||||
|
||||
public:
|
||||
void set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param);
|
||||
HWND hwnd(void);
|
||||
void show(bool visible, bool hold = false);
|
||||
int do_modal(HWND parent);
|
||||
void quit_modal(int non_zero_code);
|
||||
void enable(bool enable);
|
||||
void screen_2_client(LPRECT r);
|
||||
void client_2_screen(LPRECT r);
|
||||
HWND get_item(UINT id);
|
||||
BOOL set_font(HFONT font);
|
||||
HFONT get_font(void);
|
||||
int get_string_width(const wchar_t* str, HWND wnd = NULL);
|
||||
bool get_item_rect(UINT id, LPRECT r, bool client = true);
|
||||
std::wstring get_item_text(UINT id);
|
||||
int get_width_diff_as_text_length(UINT id); //
|
||||
void offset_item(HWND wnd, int dx, int dy);
|
||||
void offset_item(UINT id, int dx, int dy);
|
||||
void expand_item(UINT id, int dx, int dy);
|
||||
bool set_item_text(UINT id, const wchar_t* text);
|
||||
int set_item_fit_to_text(UINT id); // return difference
|
||||
void show_scroll_bar(int bar = SB_VERT, bool show = true);
|
||||
bool track_mouse_hover(void);
|
||||
};
|
||||
|
||||
class tooltip_wnd
|
||||
{
|
||||
HWND hwnd_;
|
||||
HWND parent_;
|
||||
WNDPROC org_proc_;
|
||||
|
||||
typedef struct _tip_ele
|
||||
{
|
||||
HWND ctrl;
|
||||
RECT rect;
|
||||
std::wstring tips;
|
||||
|
||||
struct _tip_ele()
|
||||
{
|
||||
ctrl = NULL;
|
||||
memset(&rect, 0, sizeof(rect));
|
||||
tips = L"";
|
||||
}
|
||||
bool operator==(const HWND& wnd)
|
||||
{
|
||||
return ctrl == wnd;
|
||||
}
|
||||
bool operator==(const RECT& r)
|
||||
{
|
||||
return memcmp(&rect, &r, sizeof(r)) == 0;
|
||||
}
|
||||
}TIPELEM;
|
||||
std::vector<TIPELEM> elements_;
|
||||
|
||||
public:
|
||||
tooltip_wnd();
|
||||
~tooltip_wnd();
|
||||
|
||||
public:
|
||||
bool create(HWND parent);
|
||||
void enable(bool enabled);
|
||||
bool add_tool_tip_for_rect(const RECT& r, const wchar_t* tips);
|
||||
bool add_tool_tip_for_ctrl(HWND ctrl, const wchar_t* tips);
|
||||
bool remove_tool_tip_for_ctrl(HWND ctrl);
|
||||
};
|
||||
|
||||
class dlg_page : public dlg_base
|
||||
{
|
||||
std::wstring name_;
|
||||
SIZE size_;
|
||||
UINT ctrl_id_;
|
||||
POINT pos_;
|
||||
SANEAPI sane_;
|
||||
SANE_Handle dev_;
|
||||
bool done_;
|
||||
std::vector<HWND> ctrls_;
|
||||
tooltip_wnd tips_wnd_;
|
||||
|
||||
int id_dpi_;
|
||||
float dpi_;
|
||||
int id_paper_;
|
||||
std::wstring paper_;
|
||||
|
||||
int id_custom_area_;
|
||||
int id_custom_left_;
|
||||
int id_custom_right_;
|
||||
int id_custom_top_;
|
||||
int id_custom_bottom_;
|
||||
int id_custom_gamma_;
|
||||
|
||||
static std::wstring property_type;
|
||||
static std::wstring property_host;
|
||||
static std::wstring property_size;
|
||||
static UINT dyn_id_base;
|
||||
static int gap_x;
|
||||
static int gap_y;
|
||||
static int spin_w;
|
||||
static int sb_adden;
|
||||
|
||||
SIZE size_view_;
|
||||
int vsb_pos_;
|
||||
int hsb_pos_;
|
||||
bool vsb_;
|
||||
bool hsb_;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void on_font_changed(void) override;
|
||||
void align_second_control(bool ignore_single = false); // align the second control of a option controls
|
||||
|
||||
HWND create_label(int sn, const wchar_t* title, int x, int y, SIZE size);
|
||||
HWND create_slider(int sn, int x, int y, double lower, double upper, double step, double pos, LPSIZE size, bool is_double);
|
||||
HWND create_edit(int sn, int x, int y, int h, int w = 50);
|
||||
HWND create_combox(int sn, int x, int y, std::vector<std::wstring>& vals, const wchar_t* cur_val, LPSIZE size);
|
||||
HWND create_spin(int sn, HWND edit, double pos, double lower, double upper, bool is_double);
|
||||
|
||||
HWND create_control_bool(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
|
||||
HWND create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
|
||||
HWND create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
|
||||
HWND create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
|
||||
HWND create_control_button(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
|
||||
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
BOOL on_notify(int ctrl_id, LPNMHDR pnmh);
|
||||
|
||||
void* value_from_ctrl(HWND ctrl, SANE_Value_Type* type); // call free_ctrl_value to free the returned value, data according to SANE-standard
|
||||
void set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool only_me, bool skip_ctrl = false);
|
||||
void free_ctrl_value(void* val);
|
||||
int find_control_ind(HWND wnd);
|
||||
void control_action(HWND wnd);
|
||||
BOOL on_mouse_wheel(WORD vkey, short delta, short x, short y);
|
||||
void on_vscroll(int pos, int sb_ev);
|
||||
void on_hscroll(int pos, int sb_ev);
|
||||
void on_mouse_hover(int x, int y, int flag);
|
||||
|
||||
public:
|
||||
dlg_page(HWND parent, const wchar_t* name, LPSANEAPI api, SANE_Handle dev);
|
||||
~dlg_page();
|
||||
|
||||
public:
|
||||
bool add_control(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||
void add_control_done(void);
|
||||
SIZE desired_size(void);
|
||||
void show(void);
|
||||
void hide(void);
|
||||
bool refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||
const wchar_t* name(void);
|
||||
void set_view_size(SIZE size);
|
||||
};
|
||||
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
// DlgSaveScheme.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgSaveScheme.h"
|
||||
#include "resource.h"
|
||||
#include "scanned_img.h" // for local_trans
|
||||
#include "gb_json.h"
|
||||
#include "mem_dc.h"
|
||||
|
||||
#include "../../sdk/include/lang/app_language.h"
|
||||
|
||||
#define WIDTH_MARGINS 10
|
||||
|
||||
|
||||
|
||||
dlg_save_scheme::dlg_save_scheme(HWND parent) : dlg_base(parent, IDD_SAVE_SCHEME)
|
||||
{
|
||||
create();
|
||||
|
||||
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_TITLE));
|
||||
int dif = 0;
|
||||
RECT rc = { 0 };
|
||||
|
||||
SetWindowTextW(hwnd(), title.c_str());
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_DISCARD);
|
||||
set_item_text(IDC_RADIO_DISCARD, title.c_str());
|
||||
set_item_fit_to_text(IDC_RADIO_DISCARD);
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_OVERWRITE);
|
||||
set_item_text(IDC_RADIO_OVERWRITE, title.c_str());
|
||||
dif = set_item_fit_to_text(IDC_RADIO_OVERWRITE);
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_NEW);
|
||||
set_item_text(IDC_RADIO_NEW, title.c_str());
|
||||
dif = set_item_fit_to_text(IDC_RADIO_NEW);
|
||||
offset_item(IDC_NAME, dif, 0);
|
||||
GetWindowRect(get_item(IDC_NAME), &rc);
|
||||
if(dif < RECT_W(rc) / 2)
|
||||
expand_item(IDC_NAME, -dif, 0);
|
||||
|
||||
{
|
||||
RECT r = { 0 }, rc = { 0 };
|
||||
|
||||
GetWindowRect(hwnd(), &r);
|
||||
GetWindowRect(get_item(IDC_NAME), &rc);
|
||||
if (rc.right + WIDTH_MARGINS > r.right)
|
||||
{
|
||||
dif = rc.right + WIDTH_MARGINS - r.right;
|
||||
r.right = rc.right + WIDTH_MARGINS;
|
||||
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
||||
offset_item(IDOK, dif / 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
|
||||
set_item_text(IDOK, title.c_str());
|
||||
}
|
||||
dlg_save_scheme::~dlg_save_scheme()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOOL dlg_save_scheme::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
on_init_dlg();
|
||||
UpdateWindow(hwnd());
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
handle_notify(wp, (LPNMHDR)lp);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps = { 0 };
|
||||
HDC hdc = BeginPaint(hwnd(), &ps);
|
||||
{
|
||||
compatible_dc dc(hdc);
|
||||
on_paint(dc.get_dc());
|
||||
}
|
||||
EndPaint(hwnd(), &ps);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void dlg_save_scheme::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
wchar_t cls[128] = { 0 };
|
||||
|
||||
GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1);
|
||||
if (IS_BUTTON(cls))
|
||||
{
|
||||
if (code == BN_CLICKED)
|
||||
{
|
||||
EnableWindow(get_item(IDC_NAME), FALSE);
|
||||
if (id == IDOK)
|
||||
{
|
||||
if (method_ == SAVE_NEW)
|
||||
{
|
||||
std::wstring text(get_wnd_text(get_item(IDC_NAME)));
|
||||
|
||||
if (text.empty() || std::find(existing_.begin(), existing_.end(), text) != existing_.end())
|
||||
{
|
||||
std::wstring info(L""), title(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR));
|
||||
|
||||
if (text.empty())
|
||||
{
|
||||
info = local_trans::lang_trans_between_hz936(CONST_STRING_REINPUT_SCHEME_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = local_trans::lang_trans_between_hz936(CONST_STRING_LEFT_QUOTE) + text
|
||||
+ local_trans::lang_trans_between_hz936(CONST_STRING_RIGHT_QUOTE)
|
||||
+ local_trans::lang_trans_between_hz936(CONST_STRING_REINPUT_WHEN_EXISTING);
|
||||
}
|
||||
EnableWindow(get_item(IDC_NAME), TRUE);
|
||||
MessageBoxW(hwnd(), info.c_str(), title.c_str(), MB_OK);
|
||||
goto_name();
|
||||
return;
|
||||
}
|
||||
|
||||
name_ = std::move(text);
|
||||
}
|
||||
if (method_ == SAVE_DISCARD)
|
||||
log_info((L"Discard changes on scheme '" + name_ + L"'.\r\n").c_str(), 0);
|
||||
else
|
||||
log_info((L"Save changes to scheme '" + name_ + L"'.\r\n").c_str(), 0);
|
||||
quit_modal(id);
|
||||
}
|
||||
else if (id == IDC_RADIO_DISCARD)
|
||||
method_ = SAVE_DISCARD;
|
||||
else if (id == IDC_RADIO_OVERWRITE)
|
||||
method_ = SAVE_OVERWRITE;
|
||||
else if (id == IDC_RADIO_NEW)
|
||||
{
|
||||
method_ = SAVE_NEW;
|
||||
EnableWindow(get_item(IDC_NAME), TRUE);
|
||||
goto_name();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void dlg_save_scheme::handle_notify(UINT id, LPNMHDR pnhdr)
|
||||
{
|
||||
}
|
||||
void dlg_save_scheme::layout(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void dlg_save_scheme::on_init_dlg(void)
|
||||
{
|
||||
check_radio(IDC_RADIO_DISCARD);
|
||||
}
|
||||
void dlg_save_scheme::on_paint(HDC hdc)
|
||||
{
|
||||
}
|
||||
void dlg_save_scheme::goto_name(void)
|
||||
{
|
||||
SendMessageW(get_item(IDC_NAME), EM_SETSEL, 0, -1);
|
||||
SetFocus(get_item(IDC_NAME));
|
||||
}
|
||||
void dlg_save_scheme::check_radio(UINT id, bool check)
|
||||
{
|
||||
SendMessage(get_item(id), BM_SETCHECK, check ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0);
|
||||
}
|
||||
|
||||
|
||||
void dlg_save_scheme::set_info(const wchar_t* name, std::vector<std::wstring>& existing, int mask, const wchar_t* new_name)
|
||||
{
|
||||
bool set_method = false;
|
||||
|
||||
name_ = name;
|
||||
existing_ = existing;
|
||||
set_item_text(IDC_NAME, new_name ? new_name : name);
|
||||
|
||||
{
|
||||
std::wstring schem(local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_OVERWRITE));
|
||||
schem += L" - '";
|
||||
schem += name;
|
||||
schem += L"'";
|
||||
set_item_text(IDC_RADIO_OVERWRITE, schem.c_str());
|
||||
set_item_fit_to_text(IDC_RADIO_OVERWRITE);
|
||||
|
||||
RECT r = { 0 }, rc = { 0 };
|
||||
|
||||
GetWindowRect(get_item(IDC_RADIO_OVERWRITE), &rc);
|
||||
GetWindowRect(hwnd(), &r);
|
||||
if (RECT_W(r) < RECT_W(rc) + WIDTH_MARGINS)
|
||||
{
|
||||
int diff = r.left + RECT_W(rc) + WIDTH_MARGINS - r.right;
|
||||
r.right = r.left + RECT_W(rc) + WIDTH_MARGINS;
|
||||
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
||||
offset_item(IDOK, diff / 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & SAVE_METHOD_MASK(SAVE_DISCARD))
|
||||
{
|
||||
set_method = true;
|
||||
method_ = SAVE_DISCARD;
|
||||
EnableWindow(get_item(IDC_RADIO_DISCARD), TRUE);
|
||||
check_radio(IDC_RADIO_DISCARD);
|
||||
}
|
||||
else
|
||||
EnableWindow(get_item(IDC_RADIO_DISCARD), FALSE);
|
||||
|
||||
if (mask & SAVE_METHOD_MASK(SAVE_OVERWRITE))
|
||||
{
|
||||
if (!set_method)
|
||||
{
|
||||
set_method = true;
|
||||
method_ = SAVE_OVERWRITE;
|
||||
check_radio(IDC_RADIO_OVERWRITE);
|
||||
}
|
||||
EnableWindow(get_item(IDC_RADIO_OVERWRITE), TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(get_item(IDC_RADIO_OVERWRITE), FALSE);
|
||||
|
||||
if (mask & SAVE_METHOD_MASK(SAVE_NEW))
|
||||
{
|
||||
if (!set_method)
|
||||
{
|
||||
set_method = true;
|
||||
method_ = SAVE_NEW;
|
||||
check_radio(IDC_RADIO_NEW);
|
||||
EnableWindow(get_item(IDC_NAME), TRUE);
|
||||
}
|
||||
EnableWindow(get_item(IDC_RADIO_NEW), TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(get_item(IDC_RADIO_NEW), FALSE);
|
||||
}
|
||||
save_method dlg_save_scheme::get_dispose(void)
|
||||
{
|
||||
return method_;
|
||||
}
|
||||
std::wstring dlg_save_scheme::get_name(void)
|
||||
{
|
||||
return name_;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
|
||||
// CDlgSaveScheme 对话框
|
||||
enum save_method
|
||||
{
|
||||
SAVE_DISCARD = 0,
|
||||
SAVE_OVERWRITE,
|
||||
SAVE_NEW,
|
||||
};
|
||||
enum
|
||||
{
|
||||
SAVE_REASON_QUIT_UI = 0,
|
||||
SAVE_REASON_SWITCH_SCHEME,
|
||||
SAVE_REASON_RESTORE,
|
||||
};
|
||||
#define SAVE_METHOD_MASK(m) (1 << m)
|
||||
|
||||
class dlg_save_scheme : public dlg_base
|
||||
{
|
||||
std::vector<std::wstring> existing_;
|
||||
std::wstring name_ = L"";
|
||||
save_method method_ = SAVE_DISCARD;
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void handle_notify(UINT id, LPNMHDR pnhdr);
|
||||
void layout(void);
|
||||
|
||||
void on_init_dlg(void);
|
||||
void on_paint(HDC hdc);
|
||||
void goto_name(void);
|
||||
void check_radio(UINT id, bool check = true);
|
||||
|
||||
public:
|
||||
dlg_save_scheme(HWND parent);
|
||||
~dlg_save_scheme();
|
||||
|
||||
public:
|
||||
void set_info(const wchar_t* name, std::vector<std::wstring>& existing, int mask, const wchar_t* new_name = nullptr);
|
||||
save_method get_dispose(void);
|
||||
std::wstring get_name(void);
|
||||
};
|
|
@ -1,752 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "DlgSetting.h"
|
||||
#include "resource.h"
|
||||
#include "scanned_img.h" // for local_trans
|
||||
#include "DlgPage.h"
|
||||
#include "gb_json.h"
|
||||
|
||||
#include "../../sdk/include/lang/app_language.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
#include "DlgCfgMgr.h"
|
||||
#include "DlgInput.h"
|
||||
#include "DlgSaveScheme.h"
|
||||
|
||||
#define MENU_CMD_0 ((unsigned short)0x8888)
|
||||
|
||||
static IMPLEMENT_OPTION_STRING_COMPARE(cmp_sane_opt);
|
||||
|
||||
|
||||
dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name) : dlg_base(parent, IDD_SETTING)
|
||||
, sane_api_(*api), sane_dev_(dev), with_scan_(with_scan)
|
||||
, papers_(0), images_(0), err_(false), tab_(NULL), cfg_(NULL), cfg_file_(L""), twain_set_(nullptr), twain_schm_(nullptr)
|
||||
, schm_from_empty_(false)
|
||||
{
|
||||
std::wstring setting(local_trans::lang_trans_between_hz936(CONST_STRING_SETTING));
|
||||
|
||||
create();
|
||||
SetWindowTextW(hwnd(), (std::wstring(name) + L" " + setting).c_str());
|
||||
cfg_menu_ = CreatePopupMenu();
|
||||
InsertMenuW(cfg_menu_, 0, MF_BYPOSITION, MENU_CMD_0, local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_CUR_CFG_AS).c_str());
|
||||
InsertMenuA(cfg_menu_, 1, MF_BYPOSITION | MF_SEPARATOR, MENU_CMD_0 + 1, "");
|
||||
}
|
||||
dlg_setting::~dlg_setting()
|
||||
{
|
||||
if (IsWindow(tab_))
|
||||
{
|
||||
for (int i = 0; i < get_tab_count(); ++i)
|
||||
{
|
||||
TCITEMW item = { 0 };
|
||||
|
||||
item.mask = TCIF_PARAM;
|
||||
TabCtrl_GetItem(tab_, i, &item);
|
||||
if (item.lParam)
|
||||
delete (dlg_page*)item.lParam;
|
||||
}
|
||||
DestroyWindow(tab_);
|
||||
}
|
||||
if (twain_schm_)
|
||||
twain_schm_->release();
|
||||
|
||||
cfg_->save(local_trans::u2a(cfg_file_.c_str()).c_str());
|
||||
DestroyMenu(cfg_menu_);
|
||||
}
|
||||
|
||||
BOOL dlg_setting::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
wchar_t text[40] = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
on_init_dialog();
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
ret = on_notify((int)wp, (LPNMHDR)lp);
|
||||
break;
|
||||
case WM_REFRESH_OPTION:
|
||||
refresh_controls((int)wp);
|
||||
break;
|
||||
case WM_GET_CONFIG_OBJ:
|
||||
{
|
||||
gb::sane_config_schm* schm = twain_schm_ ? twain_schm_ : cfg_->get_scheme();
|
||||
if (twain_schm_)
|
||||
twain_schm_->add_ref();
|
||||
if (wp)
|
||||
{
|
||||
if (!schm && *(bool*)wp)
|
||||
{
|
||||
schm = cfg_->create_empty_scheme(true);
|
||||
if (schm)
|
||||
schm->begin_setting();
|
||||
schm_from_empty_ = true;
|
||||
log_info(L"Create a new config scheme for recording user settings.\r\n", 0);
|
||||
}
|
||||
else
|
||||
*(bool*)wp = false;
|
||||
}
|
||||
*((gb::sane_config_schm**)lp) = schm;
|
||||
{
|
||||
std::wstring name(schm ? local_trans::a2u(schm->get_scheme_name().c_str(), CP_UTF8) : L"default");
|
||||
name.insert(0, L"Return scheme '");
|
||||
name += L"' to user.\r\n";
|
||||
log_info(name.c_str(), 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||
{
|
||||
if (ctrl == NULL)
|
||||
{
|
||||
// menu command ...
|
||||
if (id == MENU_CMD_0)
|
||||
{
|
||||
// save current scheme as ...
|
||||
bool new_scheme = false;
|
||||
gb::sane_config_schm* s = twain_schm_ ? twain_schm_ : cfg_->get_scheme();
|
||||
if (!s)
|
||||
{
|
||||
s = cfg_->copy_scheme(nullptr);
|
||||
new_scheme = true;
|
||||
}
|
||||
|
||||
if (twain_schm_)
|
||||
{
|
||||
s->add_ref();
|
||||
twain_schm_->release();
|
||||
twain_schm_ = nullptr;
|
||||
new_scheme = true;
|
||||
}
|
||||
|
||||
if (s)
|
||||
{
|
||||
std::vector<std::wstring> all(get_stored_scheme_names());
|
||||
std::wstring cur(local_trans::a2u(s->get_scheme_name().c_str(), CP_UTF8));
|
||||
dlg_input dlg(hwnd(), cur.c_str());
|
||||
|
||||
dlg.set_no_repeats(all);
|
||||
if (dlg.do_modal(hwnd()) == IDOK)
|
||||
{
|
||||
std::string name(local_trans::u2a(dlg.get_value().c_str(), CP_UTF8));
|
||||
gb::sane_config_schm* n = s;
|
||||
if (new_scheme)
|
||||
{
|
||||
n->add_ref();
|
||||
n->end_setting(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = s->copy();
|
||||
s->end_setting(true);
|
||||
n->end_setting(false);
|
||||
}
|
||||
|
||||
if (cfg_->add_scheme(n, name.c_str()))
|
||||
{
|
||||
cfg_->select_scheme(name.c_str());
|
||||
n->begin_setting();
|
||||
}
|
||||
n->release();
|
||||
}
|
||||
s->release();
|
||||
}
|
||||
}
|
||||
else if(id > MENU_CMD_0 + 1)
|
||||
{
|
||||
// config scheme changed ...
|
||||
std::string schm(local_trans::u2a(dlg_base::get_menu_text(cfg_menu_, id - MENU_CMD_0).c_str(), CP_UTF8));
|
||||
|
||||
log_info((L"Select scheme '" + local_trans::a2u(schm.c_str(), CP_UTF8) + L"' on scheme menu.\r\n").c_str(), 0);
|
||||
|
||||
save_changes_to_cur_scheme(SAVE_REASON_SWITCH_SCHEME);
|
||||
// if (cfg_->get_current_scheme_name() != schm)
|
||||
{
|
||||
gb::sane_config_schm* s = nullptr;
|
||||
|
||||
if (cfg_->select_scheme(schm.c_str()))
|
||||
{
|
||||
s = cfg_->get_scheme();
|
||||
apply_scheme_(s, apply_param_);
|
||||
if (s)
|
||||
{
|
||||
s->begin_setting();
|
||||
s->release();
|
||||
}
|
||||
refresh_controls(-1);
|
||||
// cfg_->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (id == IDOK)
|
||||
{
|
||||
save_changes_to_cur_scheme(SAVE_REASON_QUIT_UI);
|
||||
notify_over();
|
||||
}
|
||||
else if (id == IDC_BUTTON_HELP)
|
||||
{
|
||||
SANE_Int after = 0;
|
||||
SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_help_, SANE_ACTION_SET_VALUE, &after, &after);
|
||||
}
|
||||
else if (id == IDC_BUTTON_RESTORE)
|
||||
{
|
||||
log_info(L"Press 'Restore' button to restore settings\r\n", 0);
|
||||
|
||||
save_changes_to_cur_scheme(SAVE_REASON_RESTORE);
|
||||
|
||||
SANE_Int after = 0;
|
||||
SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_restore_, SANE_ACTION_SET_VALUE, &after, &after);
|
||||
refresh_controls(id_restore_);
|
||||
cfg_->select_scheme(nullptr);
|
||||
}
|
||||
else if (id == IDC_BUTTON_SCAN)
|
||||
{
|
||||
// enable(false);
|
||||
save_changes_to_cur_scheme(SAVE_REASON_QUIT_UI);
|
||||
notify_ui_event(SANE_EVENT_UI_SCAN_COMMAND);
|
||||
}
|
||||
else if (id == IDC_BUTTON_CONFIG_MGR)
|
||||
{
|
||||
dlg_cfg_mgr dlg(cfg_, hwnd());
|
||||
gb::sane_config_schm* prev = cfg_->get_scheme(), * after = nullptr;
|
||||
|
||||
dlg.do_modal(hwnd());
|
||||
after = cfg_->get_scheme();
|
||||
if (prev != after) // refresh settings and UI
|
||||
{
|
||||
{
|
||||
std::wstring info(L"Current scheme has changed from '");
|
||||
if (prev)
|
||||
info += local_trans::a2u(prev->get_scheme_name().c_str(), CP_UTF8) + L"' to '";
|
||||
else
|
||||
info += L"default' to '";
|
||||
if (after)
|
||||
info += local_trans::a2u(after->get_scheme_name().c_str(), CP_UTF8) + L"' in management UI\r\n";
|
||||
else
|
||||
info += L"default' in management UI\r\n";
|
||||
log_info(info.c_str(), 0);
|
||||
}
|
||||
apply_scheme_(after, apply_param_);
|
||||
refresh_controls(-1);
|
||||
}
|
||||
if (prev)
|
||||
prev->release();
|
||||
if (after)
|
||||
after->release();
|
||||
}
|
||||
else if (id == IDC_BUTTON_CONFIG_MENU)
|
||||
{
|
||||
HMENU sub = cfg_menu_; // GetSubMenu(cfg_menu_, 0);
|
||||
int ind = 2; // 0 - save as ...; 1 - separator
|
||||
std::vector<std::string> schemes;
|
||||
|
||||
while (DeleteMenu(sub, 2, MF_BYPOSITION));
|
||||
cfg_->get_all_schemes(schemes);
|
||||
for (auto& v : schemes)
|
||||
{
|
||||
UINT flag = MF_BYPOSITION;
|
||||
|
||||
if (twain_set_ && *twain_set_ == false && v == cfg_->get_current_scheme_name())
|
||||
flag |= MF_CHECKED;
|
||||
InsertMenuW(sub, ind, flag, MENU_CMD_0 + ind, local_trans::a2u(v.c_str(), CP_UTF8).c_str());
|
||||
ind++;
|
||||
}
|
||||
|
||||
RECT r = { 0 };
|
||||
GetWindowRect(get_item(IDC_BUTTON_CONFIG_MENU), &r);
|
||||
TrackPopupMenu(cfg_menu_, TPM_LEFTALIGN | TPM_BOTTOMALIGN, r.left, r.top, 0, hwnd(), NULL);
|
||||
}
|
||||
}
|
||||
void dlg_setting::notify_over(void)
|
||||
{
|
||||
notify_ui_event(SANE_EVENT_UI_CLOSE_SETTING);
|
||||
}
|
||||
void dlg_setting::on_init_dialog(void)
|
||||
{
|
||||
dlg_page* page = NULL;
|
||||
SANE_Int sn = 1;
|
||||
SIZE size = { 0 };
|
||||
RECT r = { 0 }, rme = { 0 };
|
||||
int y = 0;
|
||||
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||
|
||||
while (desc)
|
||||
{
|
||||
if (desc->type == SANE_TYPE_GROUP)
|
||||
{
|
||||
if (page)
|
||||
{
|
||||
page->add_control_done();
|
||||
dlg_base::get_max_size(size, page->desired_size());
|
||||
}
|
||||
page = add_tab(desc->title);
|
||||
}
|
||||
else if (page)
|
||||
{
|
||||
char* buf = new char[desc->size + 4];
|
||||
SANE_Int info = 0;
|
||||
|
||||
memset(buf, 0, desc->size + 4);
|
||||
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
|
||||
page->add_control(sn - 1, desc, buf);
|
||||
delete[] buf;
|
||||
}
|
||||
else if(desc->type == SANE_TYPE_BUTTON)
|
||||
{
|
||||
if (strcmp(SANE_STD_OPT_NAME_HELP, desc->name) == 0)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_HELP), SW_SHOW);
|
||||
id_help_ = sn - 1;
|
||||
}
|
||||
else if (strcmp(SANE_STD_OPT_NAME_RESTORE, desc->name) == 0)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_RESTORE), SW_SHOW);
|
||||
id_restore_ = sn - 1;
|
||||
}
|
||||
}
|
||||
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||
}
|
||||
if (page)
|
||||
{
|
||||
page->add_control_done();
|
||||
dlg_base::get_max_size(size, page->desired_size());
|
||||
}
|
||||
|
||||
if (size.cx || size.cy || IsWindow(tab_))
|
||||
{
|
||||
// resize ...
|
||||
GetClientRect(hwnd(), &rme);
|
||||
if (size.cx < rme.right - rme.left)
|
||||
size.cx = rme.right - rme.left;
|
||||
|
||||
if (IsWindow(tab_))
|
||||
{
|
||||
GetWindowRect(tab_, &r);
|
||||
y = r.bottom - r.top;
|
||||
size.cy += y;
|
||||
r.right = r.left + size.cx;
|
||||
screen_2_client(&r);
|
||||
MoveWindow(tab_, r.left, r.top, r.right - r.left, y, TRUE);
|
||||
}
|
||||
|
||||
RECT desk = { 0 };
|
||||
int diff = 0;
|
||||
|
||||
GetClientRect(GetDesktopWindow(), &desk);
|
||||
GetWindowRect(hwnd(), &r);
|
||||
r.right += size.cx - (rme.right - rme.left);
|
||||
r.bottom += size.cy;
|
||||
if (r.bottom - r.top > desk.bottom - desk.top)
|
||||
{
|
||||
diff = (r.bottom - r.top) - (desk.bottom - desk.top) + 100;
|
||||
r.top = desk.top;
|
||||
r.bottom = desk.bottom - 100;
|
||||
}
|
||||
MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
|
||||
|
||||
size.cy -= diff;
|
||||
for (int i = 0; page = get_page(i); ++i)
|
||||
{
|
||||
MoveWindow(page->hwnd(), 0, y, size.cx, size.cy - y, TRUE);
|
||||
page->set_view_size(size);
|
||||
}
|
||||
|
||||
offset_item(IDC_BUTTON_SCAN, 0, size.cy);
|
||||
offset_item(IDC_BUTTON_CONFIG_MGR, size.cx - RECT_W(rme), size.cy);
|
||||
offset_item(IDC_BUTTON_CONFIG_MENU, size.cx - RECT_W(rme), size.cy);
|
||||
offset_item(IDC_BUTTON_HELP, size.cx - RECT_W(rme), size.cy);
|
||||
offset_item(IDC_BUTTON_RESTORE, size.cx - RECT_W(rme), size.cy);
|
||||
offset_item(IDOK, size.cx - RECT_W(rme), size.cy);
|
||||
|
||||
ShowWindow(get_item(IDC_BUTTON_CONFIG_MGR), SW_SHOW);
|
||||
ShowWindow(get_item(IDC_BUTTON_CONFIG_MENU), SW_SHOW);
|
||||
}
|
||||
if (with_scan_)
|
||||
ShowWindow(get_item(IDC_BUTTON_SCAN), SW_SHOW);
|
||||
|
||||
if (!dlg_base::is_language_pack_default_code_page())
|
||||
{
|
||||
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CFG_MANAGER));
|
||||
|
||||
::SetDlgItemTextW(hwnd(), IDC_BUTTON_CONFIG_MGR, title.c_str());
|
||||
y = set_item_fit_to_text(IDC_BUTTON_CONFIG_MGR);
|
||||
if (y)
|
||||
offset_item(IDC_BUTTON_CONFIG_MGR, -y, 0);
|
||||
|
||||
::SetDlgItemTextW(hwnd(), IDC_BUTTON_SCAN, local_trans::lang_trans_between_hz936(CONST_STRING_SCAN).c_str());
|
||||
::SetDlgItemTextW(hwnd(), IDC_BUTTON_RESTORE, local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE).c_str());
|
||||
::SetDlgItemTextW(hwnd(), IDC_BUTTON_HELP, local_trans::lang_trans_between_hz936(CONST_STRING_HELP).c_str());
|
||||
::SetDlgItemTextW(hwnd(), IDOK, local_trans::lang_trans_between_hz936(CONST_STRING_OK).c_str());
|
||||
}
|
||||
|
||||
select_page(0);
|
||||
UpdateWindow(hwnd());
|
||||
}
|
||||
BOOL dlg_setting::on_notify(int ctrl_id, LPNMHDR pnmh)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (pnmh->hwndFrom == tab_)
|
||||
{
|
||||
if (pnmh->code == TCN_SELCHANGING)
|
||||
ret = FALSE;
|
||||
else if (pnmh->code == TCN_SELCHANGE)
|
||||
select_page(TabCtrl_GetCurSel(tab_));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int dlg_setting::get_tab_count(void)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (IsWindow(tab_))
|
||||
count = TabCtrl_GetItemCount(tab_);
|
||||
|
||||
return count;
|
||||
}
|
||||
dlg_page* dlg_setting::add_tab(const char* utf8_title)
|
||||
{
|
||||
std::wstring title(local_trans::a2u(utf8_title, CP_UTF8));
|
||||
dlg_page *page = new dlg_page(hwnd(), title.c_str(), &sane_api_, sane_dev_);
|
||||
HFONT font = (HFONT)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0);
|
||||
LOGFONTW lf = { 0 };
|
||||
|
||||
GetObjectW(font, sizeof(lf), &lf);
|
||||
page->set_font(font);
|
||||
if (!IsWindow(tab_))
|
||||
{
|
||||
HDC hdc = GetWindowDC(hwnd());
|
||||
SIZE text = { 0 };
|
||||
|
||||
GetTextExtentPointW(hdc, title.c_str(), title.length(), &text);
|
||||
ReleaseDC(hwnd(), hdc);
|
||||
tab_ = CreateWindowW(L"SysTabControl32", L"pages", WS_CHILD | WS_VISIBLE, 0, 0, 100, text.cy + 6, hwnd(), NULL, g_my_inst, NULL);
|
||||
SendMessage(tab_, WM_SETFONT, (WPARAM)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0), 1);
|
||||
SetWindowLong(tab_, GWL_ID, 1234);
|
||||
ShowWindow(tab_, SW_SHOW);
|
||||
}
|
||||
|
||||
TC_ITEMW item = { 0 };
|
||||
|
||||
item.mask = TCIF_PARAM | TCIF_TEXT;
|
||||
item.lParam = (LPARAM)page;
|
||||
item.pszText = &title[0];
|
||||
TabCtrl_InsertItem(tab_, get_tab_count(), &item);
|
||||
page->hide();
|
||||
|
||||
return page;
|
||||
}
|
||||
dlg_page* dlg_setting::get_page(int index)
|
||||
{
|
||||
dlg_page* page = NULL;
|
||||
|
||||
if (IsWindow(tab_) && index >= 0 && index < get_tab_count())
|
||||
{
|
||||
TCITEMW item = { 0 };
|
||||
|
||||
item.mask = TCIF_PARAM;
|
||||
TabCtrl_GetItem(tab_, index, &item);
|
||||
page = (dlg_page*)item.lParam;
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
dlg_page* dlg_setting::get_page(const char* utf8_title)
|
||||
{
|
||||
dlg_page* page = NULL;
|
||||
std::wstring unic(local_trans::a2u(utf8_title, CP_UTF8));
|
||||
|
||||
for (int i = 0; i < get_tab_count(); ++i)
|
||||
{
|
||||
TCITEMW item = { 0 };
|
||||
wchar_t buf[80] = { 0 };
|
||||
|
||||
item.mask = TCIF_TEXT | TCIF_PARAM;
|
||||
item.pszText = buf;
|
||||
item.cchTextMax = _countof(buf) - 1;
|
||||
TabCtrl_GetItem(tab_, i, &item);
|
||||
if (unic == buf)
|
||||
{
|
||||
page = (dlg_page*)item.lParam;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
dlg_page* dlg_setting::select_page(int index)
|
||||
{
|
||||
dlg_page* ret = NULL, *cur = NULL;
|
||||
|
||||
for (int i = 0; cur = get_page(i); ++i)
|
||||
{
|
||||
if (i == index)
|
||||
{
|
||||
ret = cur;
|
||||
cur->show();
|
||||
}
|
||||
else
|
||||
cur->hide();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void dlg_setting::refresh_controls(int src_sn)
|
||||
{
|
||||
int sn = 1;
|
||||
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||
|
||||
while (desc)
|
||||
{
|
||||
char* buf = new char[desc->size + 8];
|
||||
SANE_Int info = 0;
|
||||
dlg_page* page = NULL;
|
||||
memset(buf, 0, desc->size + 8);
|
||||
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
|
||||
for (int i = 0; page = get_page(i); ++i)
|
||||
{
|
||||
if (page->refresh(sn - 1, desc, buf))
|
||||
break;
|
||||
}
|
||||
delete[] buf;
|
||||
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||
}
|
||||
}
|
||||
void dlg_setting::save_changes_to_cur_scheme(int reason)
|
||||
{
|
||||
// discard, overwrite, new
|
||||
int items = 0;
|
||||
bool changed = false;
|
||||
std::vector<std::wstring> now(get_stored_scheme_names());
|
||||
|
||||
if (!cfg_)
|
||||
return;
|
||||
|
||||
if (twain_set_ && reason != SAVE_REASON_QUIT_UI)
|
||||
*twain_set_ = false;
|
||||
|
||||
if (twain_schm_)
|
||||
{
|
||||
changed = twain_schm_->has_changed(&items);
|
||||
if (changed)
|
||||
{
|
||||
dlg_save_scheme dlg(hwnd());
|
||||
std::wstring sug(L"");
|
||||
|
||||
sug = local_trans::a2u(twain_schm_->auto_gen_scheme_name(local_trans::lang_trans_between_hz936, nullptr, false).c_str(), CP_UTF8);
|
||||
dlg.set_info(local_trans::a2u(twain_schm_->get_scheme_name().c_str(), CP_UTF8).c_str(), now
|
||||
, SAVE_METHOD_MASK(SAVE_DISCARD) | SAVE_METHOD_MASK(SAVE_NEW),
|
||||
sug.c_str());
|
||||
dlg.do_modal(hwnd());
|
||||
if(dlg.get_dispose() == SAVE_NEW)
|
||||
{
|
||||
std::string name(local_trans::u2a(dlg.get_name().c_str(), CP_UTF8));
|
||||
if (cfg_->add_scheme(twain_schm_, name.c_str()) &&
|
||||
reason == SAVE_REASON_QUIT_UI)
|
||||
{
|
||||
cfg_->select_scheme(name.c_str());
|
||||
if (twain_set_)
|
||||
*twain_set_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
twain_schm_->release();
|
||||
twain_schm_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gb::sane_config_schm* schm = cfg_->get_scheme();
|
||||
if (schm)
|
||||
{
|
||||
changed = schm->has_changed(&items);
|
||||
if (changed)
|
||||
{
|
||||
if (schm_from_empty_)
|
||||
schm->end_setting(false);
|
||||
else
|
||||
{
|
||||
dlg_save_scheme dlg(hwnd());
|
||||
std::wstring name(local_trans::a2u(schm->get_scheme_name().c_str(), CP_UTF8)),
|
||||
suggest(local_trans::a2u(schm->auto_gen_scheme_name(local_trans::lang_trans_between_hz936, nullptr, false).c_str(), CP_UTF8));
|
||||
|
||||
dlg.set_info(name.c_str(), now, SAVE_METHOD_MASK(SAVE_DISCARD) | SAVE_METHOD_MASK(SAVE_OVERWRITE) | SAVE_METHOD_MASK(SAVE_NEW)
|
||||
, suggest.c_str());
|
||||
dlg.do_modal(hwnd());
|
||||
|
||||
int dispose = dlg.get_dispose();
|
||||
if (dispose == SAVE_NEW)
|
||||
{
|
||||
std::string uname(local_trans::u2a(dlg.get_name().c_str(), CP_UTF8));
|
||||
gb::sane_config_schm* s = schm->copy();
|
||||
|
||||
schm->end_setting(true);
|
||||
s->end_setting(false);
|
||||
cfg_->add_scheme(s, uname.c_str());
|
||||
s->release();
|
||||
if (reason == SAVE_REASON_QUIT_UI)
|
||||
cfg_->select_scheme(uname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
schm->end_setting(dispose == SAVE_DISCARD);
|
||||
if (dispose == SAVE_DISCARD && reason == SAVE_REASON_QUIT_UI && twain_set_)
|
||||
{
|
||||
std::wstring info(local_trans::a2u(schm->get_scheme_name().c_str(), CP_UTF8));
|
||||
|
||||
info.insert(0, L"User discard the changes on scheme '");
|
||||
info += L"' and will quit UI, set temporary scheme flag!\r\n";
|
||||
log_info(info.c_str(), 0);
|
||||
|
||||
*twain_set_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
schm->release();
|
||||
}
|
||||
}
|
||||
schm_from_empty_ = false;
|
||||
}
|
||||
|
||||
void dlg_setting::set_config(gb::scanner_cfg* cfg, const wchar_t* file, void(__stdcall* apply)(gb::sane_config_schm*, void*), void* param, bool* twain_set)
|
||||
{
|
||||
cfg_ = cfg;
|
||||
cfg_file_ = file;
|
||||
apply_scheme_ = apply;
|
||||
apply_param_ = param;
|
||||
twain_set_ = twain_set;
|
||||
|
||||
if (twain_set && *twain_set && cfg_)
|
||||
{
|
||||
// create a temporary scheme because of APP has changed the setting after we applied the store scheme ...
|
||||
twain_schm_ = new gb::sane_config_schm(cfg_);
|
||||
|
||||
int sn = 1;
|
||||
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||
|
||||
while (desc)
|
||||
{
|
||||
if (desc->type != SANE_TYPE_BUTTON && desc->type != SANE_TYPE_GROUP)
|
||||
{
|
||||
char* buf = new char[desc->size + 8];
|
||||
SANE_Int info = 0;
|
||||
dlg_page* page = NULL;
|
||||
memset(buf, 0, desc->size + 8);
|
||||
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
|
||||
if (desc->type == SANE_TYPE_STRING)
|
||||
{
|
||||
std::string defl(to_default_language(buf, nullptr));
|
||||
twain_schm_->config_changed(sn - 1, defl.c_str(), defl.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = desc->size;
|
||||
switch (desc->type)
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
len = sizeof(SANE_Bool);
|
||||
break;
|
||||
case SANE_TYPE_INT:
|
||||
len = sizeof(SANE_Int);
|
||||
break;
|
||||
case SANE_TYPE_FIXED:
|
||||
len = sizeof(SANE_Fixed);
|
||||
break;
|
||||
}
|
||||
twain_schm_->config_changed(sn - 1, buf, len);
|
||||
}
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||
}
|
||||
twain_schm_->has_changed(&sn);
|
||||
twain_schm_->auto_gen_scheme_name(local_trans::lang_trans_between_hz936, nullptr);
|
||||
twain_schm_->begin_setting();
|
||||
if(sn)
|
||||
{
|
||||
std::wstring name(local_trans::a2u(cfg_->get_current_scheme_name().c_str(), CP_UTF8));
|
||||
name.insert(0, L"TWAIN-app has changed " + std::to_wstring(sn) + L" setting(s) after we applied stored scheme '");
|
||||
name += L"'\r\n";
|
||||
log_info(name.c_str(), 0);
|
||||
}
|
||||
}
|
||||
else if(cfg_)
|
||||
{
|
||||
gb::sane_config_schm* schm = cfg_->get_scheme();
|
||||
if (schm)
|
||||
{
|
||||
schm->begin_setting();
|
||||
schm->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
HWND dlg_setting::window(void)
|
||||
{
|
||||
return hwnd_;
|
||||
}
|
||||
HWND dlg_setting::parent(void)
|
||||
{
|
||||
return parent_;
|
||||
}
|
||||
//void dlg_setting::show(void)
|
||||
//{
|
||||
// RECT rp, r, desk;
|
||||
//
|
||||
// if (IsWindow(parent_))
|
||||
// GetWindowRect(parent_, &rp);
|
||||
// else
|
||||
// GetWindowRect(GetDesktopWindow(), &rp);
|
||||
// GetWindowRect(hwnd_, &r);
|
||||
// GetWindowRect(GetDesktopWindow(), &desk);
|
||||
//
|
||||
// rp.left += (rp.right - rp.left - (r.right - r.left)) / 2;
|
||||
// rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2;
|
||||
// if (rp.top > desk.bottom)
|
||||
// rp.top = desk.bottom - (r.bottom - r.top);
|
||||
// if (rp.top < desk.top)
|
||||
// rp.top = desk.top;
|
||||
// if (rp.left > desk.right)
|
||||
// rp.left = desk.right - (rp.right - rp.left);
|
||||
// if (rp.left < desk.left)
|
||||
// rp.left = desk.left;
|
||||
// SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
// UpdateWindow(hwnd_);
|
||||
//}
|
||||
void dlg_setting::hide(void)
|
||||
{
|
||||
ShowWindow(hwnd_, SW_HIDE);
|
||||
}
|
||||
void dlg_setting::notify_scan_over(void)
|
||||
{
|
||||
enable(true);
|
||||
}
|
||||
std::vector<std::wstring> dlg_setting::get_stored_scheme_names(void)
|
||||
{
|
||||
std::vector<std::string> now;
|
||||
std::vector<std::wstring> wnow;
|
||||
|
||||
if (cfg_)
|
||||
{
|
||||
cfg_->get_all_schemes(now);
|
||||
for (auto& v : now)
|
||||
wnow.push_back(local_trans::a2u(v.c_str(), CP_UTF8));
|
||||
}
|
||||
|
||||
return std::move(wnow);
|
||||
}
|
||||
// CDlgIndicator 消息处理程序
|
|
@ -1,73 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sane/sane_ex.h>
|
||||
|
||||
#include "DlgPage.h"
|
||||
|
||||
// CDlgIndicator 对话框
|
||||
//#define USE_SOLE_WIN_THREAD
|
||||
|
||||
#ifdef USE_SOLE_WIN_THREAD
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace gb
|
||||
{
|
||||
class scanner_cfg;
|
||||
}
|
||||
class dlg_setting : public dlg_base
|
||||
{
|
||||
SANEAPI sane_api_;
|
||||
SANE_Handle sane_dev_;
|
||||
bool with_scan_;
|
||||
unsigned int papers_;
|
||||
unsigned int images_;
|
||||
bool err_;
|
||||
int id_help_;
|
||||
int id_restore_;
|
||||
gb::scanner_cfg *cfg_;
|
||||
std::wstring cfg_file_;
|
||||
bool *twain_set_;
|
||||
gb::sane_config_schm* twain_schm_;
|
||||
bool schm_from_empty_;
|
||||
|
||||
HMENU cfg_menu_;
|
||||
void(__stdcall* apply_scheme_)(gb::sane_config_schm*, void*);
|
||||
void* apply_param_;
|
||||
|
||||
HWND tab_;
|
||||
|
||||
#ifdef USE_SOLE_WIN_THREAD
|
||||
std::unique_ptr<std::thread> thread_;
|
||||
#endif
|
||||
|
||||
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||
void notify_over(void);
|
||||
void on_init_dialog(void);
|
||||
BOOL on_notify(int ctrl_id, LPNMHDR pnmh);
|
||||
int get_tab_count(void);
|
||||
dlg_page* add_tab(const char* utf8_title);
|
||||
dlg_page* get_page(int index);
|
||||
dlg_page* get_page(const char* utf8_title);
|
||||
dlg_page* select_page(int index);
|
||||
void refresh_controls(int src_sn);
|
||||
void save_changes_to_cur_scheme(int reason);
|
||||
|
||||
public:
|
||||
dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name);
|
||||
~dlg_setting();
|
||||
|
||||
public:
|
||||
void set_config(gb::scanner_cfg* cfg, const wchar_t* file, void(__stdcall* apply)(gb::sane_config_schm*, void*), void* param, bool* twain_set = nullptr);
|
||||
HWND window(void);
|
||||
HWND parent(void);
|
||||
//void show(void);
|
||||
void hide(void);
|
||||
void notify_scan_over(void);
|
||||
std::vector<std::wstring> get_stored_scheme_names(void);
|
||||
};
|
|
@ -1,94 +0,0 @@
|
|||
// For: const string list
|
||||
//
|
||||
// Date: 2023-02-07
|
||||
//
|
||||
// Format: all strings are defined in unicode
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CONST_STRING_CUSTOM_AREA L"\u81EA\u5B9A\u4E49\u626B\u63CF\u533A\u57DF"
|
||||
#define CONST_STRING_UNIT L"\u5355\u4F4D"
|
||||
#define CONST_STRING_UNIT_MM L"\u6BEB\u7C73"
|
||||
#define CONST_STRING_UNIT_INCH L"\u82F1\u5BF8"
|
||||
#define CONST_STRING_UNIT_PIXEL L"\u50CF\u7D20"
|
||||
#define CONST_STRING_AREA_SET L"\u533A\u57DF\u8BBE\u7F6E"
|
||||
#define CONST_STRING_LEFT L"\u5DE6"
|
||||
#define CONST_STRING_TOP L"\u4E0A"
|
||||
#define CONST_STRING_WIDTH L"\u5BBD"
|
||||
#define CONST_STRING_HEIGHT L"\u9AD8"
|
||||
#define CONST_STRING_RESTORE_AREA L"\u6062\u590D\u533A\u57DF"
|
||||
#define CONST_STRING_OK L"\u786E\u5B9A"
|
||||
#define CONST_STRING_CANCEL L"\u53D6\u6D88"
|
||||
#define CONST_STRING_MULTIPLE L"\u00d7"
|
||||
#define CONST_STRING_OPT_PAPER L"\u7EB8\u5F20\u5C3A\u5BF8"
|
||||
|
||||
#define CONST_STRING_CFG_MANAGER L"\u914D\u7F6E\u7BA1\u7406"
|
||||
#define CONST_STRING_CFG_SCHEME L"\u914D\u7F6E\u65B9\u6848"
|
||||
#define CONST_STRING_DEL_SELECTED L"\u5220\u9664\u9009\u4E2D\u9879"
|
||||
#define CONST_STRING_DEL_ALL L"\u5168\u90E8\u5220\u9664"
|
||||
#define CONST_STRING_CFG_CONTENT L"\u914D\u7F6E\u5185\u5BB9"
|
||||
#define CONST_STRING_CFG_NAME L"\u914D\u7F6E\u540D\u79F0"
|
||||
|
||||
#define CONST_STRING_CUSTOM_TONE L"\u81EA\u5B9A\u4E49\u8272\u8C03\u66F2\u7EBF"
|
||||
#define CONST_STRING_TONE_SCHEME L"\u8272\u8C03\u65B9\u6848"
|
||||
#define CONST_STRING_COLOR_CHANNEL L"\u989C\u8272\u901A\u9053"
|
||||
#define CONST_STRING_INITIALIZE L"\u521D\u59CB\u5316"
|
||||
#define CONST_STRING_INPUT L"\u8F93\u5165"
|
||||
#define CONST_STRING_OUTPUT L"\u8F93\u51FA"
|
||||
#define CONST_STRING_CUSTOM L"\u81EA\u5B9A\u4E49"
|
||||
#define CONST_STRING_NEG_PHOTO L"\u8d1f\u7247"
|
||||
#define CONST_STRING_COLOR_NEG_PHOTO L"\u5f69\u8272\u8d1f\u7247"
|
||||
#define CONST_STRING_DARKER L"\u8f83\u6697"
|
||||
#define CONST_STRING_BRIGHTER L"\u8f83\u4eae"
|
||||
#define CONST_STRING_RED L"\u7ea2"
|
||||
#define CONST_STRING_GREEN L"\u7eff"
|
||||
#define CONST_STRING_BLUE L"\u84dd"
|
||||
#define CONST_STRING_GRAY L"\u7070"
|
||||
|
||||
#define CONST_STRING_SCANNING L"\u6B63\u5728\u626B\u63CF\u2026\u2026"
|
||||
#define CONST_STRING_PAPER L"\u7EB8\u5F20"
|
||||
#define CONST_STRING_IMAGE L"\u56FE\u7247"
|
||||
#define CONST_STRING_TOTAL_SCANNED L"\u603b\u8ba1\u626b\u63cf\u56fe\u7247"
|
||||
#define CONST_STRING_CLOSE L"\u5173\u95ed"
|
||||
#define CONST_STRING_SCAN_OVER L"\u626b\u63cf\u7ed3\u675f"
|
||||
|
||||
#define CONST_STRING_CHOOSE_DEVICE L"\u8BF7\u9009\u62E9\u8BBE\u5907"
|
||||
#define CONST_STRING_DEVICE_NAME L"\u8BBE\u5907\u540D\u79F0"
|
||||
#define CONST_STRING_SERIAL_NUM L"\u5E8F\u5217\u53F7"
|
||||
|
||||
#define CONST_STRING_INPUT_VAL L"\u8BF7\u8F93\u5165\u65B0\u503C"
|
||||
#define CONST_STRING_RE_INPUT L"\u8BF7\u91CD\u65B0\u8F93\u5165"
|
||||
#define CONST_STRING_NO_INPUT L"\u6CA1\u6709\u8F93\u5165\u5185\u5BB9"
|
||||
#define CONST_STRING_ALREADY_EXISTS L"\u5DF2\u7ECF\u5B58\u5728"
|
||||
|
||||
#define CONST_STRING_NOT_SUPPORT_SET L"\u6B64\u8BBE\u5907\u4E0D\u652F\u6301\u5C06"
|
||||
#define CONST_STRING_SET_TO_BE L"\u8BBE\u7F6E\u4E3A"
|
||||
#define CONST_STRING_PARAMETER_ERROR L"\u53C2\u6570\u9519\u8BEF"
|
||||
#define CONST_STRING_PARAMETER_ORIGIN L"\u539F\u53C2\u6570"
|
||||
#define CONST_STRING_PARAMETER_INEXACT L"\u4E0D\u7CBE\u786E\u6216\u8BBE\u5907\u4E0D\u652F\u6301\uFF0C\u5DF2\u8C03\u6574\u4E3A"
|
||||
#define CONST_STRING_PARAMETER_ADJUSTED L"\u53C2\u6570\u8C03\u6574"
|
||||
#define CONST_STRING_SET_AREA L"\u8bbe\u7f6e\u533a\u57df"
|
||||
#define CONST_STRING_SET_TONE L"\u8bbe\u7f6e\u8272\u8c03\u66f2\u7ebf"
|
||||
|
||||
#define CONST_STRING_SETTING L"\u8BBE\u7F6E"
|
||||
#define CONST_STRING_SAVE_CUR_CFG_AS L"\u5F53\u524D\u914D\u7F6E\u53E6\u5B58\u4E3A"
|
||||
#define CONST_STRING_SCAN L"\u626B\u63CF"
|
||||
#define CONST_STRING_RESTORE L"\u6062\u590D\u9ED8\u8BA4\u503C"
|
||||
#define CONST_STRING_HELP L"\u5E2E\u52A9"
|
||||
|
||||
|
||||
|
||||
#define CONST_STRING_OPEN_FAILED L"\u6253\u5F00\u5931\u8D25"
|
||||
#define CONST_STRING_START_FAILED L"\u542F\u52A8\u5931\u8D25"
|
||||
#define CONST_STRING_ERROR L"\u9519\u8BEF"
|
||||
|
||||
|
||||
#define CONST_STRING_SAVE_TITLE L"\u5F53\u524D\u914D\u7F6E\u5DF2\u7ECF\u66F4\u6539\uFF0C\u8BF7\u9009\u62E9\u4FDD\u5B58\u65B9\u5F0F"
|
||||
#define CONST_STRING_SAVE_DISCARD L"\u4E0D\u4FDD\u5B58\uFF0C\u4EC5\u7528\u4E8E\u8BE5\u6B21\u626B\u63CF\u6216\u653E\u5F03\u66F4\u6539"
|
||||
#define CONST_STRING_SAVE_OVERWRITE L"\u8986\u76D6\u73B0\u6709\u65B9\u6848"
|
||||
#define CONST_STRING_SAVE_NEW L"\u4FDD\u5B58\u4E3A\u65B0\u65B9\u6848"
|
||||
#define CONST_STRING_REINPUT_SCHEME_NAME L"\u8BF7\u8F93\u5165\u65B0\u914D\u7F6E\u65B9\u6848\u540D\u79F0\u3002"
|
||||
#define CONST_STRING_LEFT_QUOTE L"\u201C"
|
||||
#define CONST_STRING_RIGHT_QUOTE L"\u201D"
|
||||
#define CONST_STRING_REINPUT_WHEN_EXISTING L"\u5DF2\u7ECF\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002"
|
2038
sane/gb_json.cpp
2038
sane/gb_json.cpp
File diff suppressed because it is too large
Load Diff
313
sane/gb_json.h
313
sane/gb_json.h
|
@ -1,313 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
#include "../../code_device/hgsane/cJSON.h"
|
||||
#define PATH_SYMBOL "\\"
|
||||
#else
|
||||
#include "cJSON.h"
|
||||
#define PATH_SYMBOL "/"
|
||||
#define NULL nullptr
|
||||
#define DWORD_PTR char*
|
||||
#define _countof(a) sizeof(a) / sizeof(a[0])
|
||||
#endif
|
||||
|
||||
//
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
namespace gb
|
||||
{
|
||||
class scanner_cfg;
|
||||
class refer
|
||||
{
|
||||
volatile long ref_;
|
||||
|
||||
protected:
|
||||
refer();
|
||||
virtual ~refer();
|
||||
|
||||
public:
|
||||
long add_ref(void);
|
||||
long release(void);
|
||||
};
|
||||
|
||||
|
||||
class json : public refer
|
||||
{
|
||||
enum val_type
|
||||
{
|
||||
VAL_TYPE_NULL = 0,
|
||||
VAL_TYPE_BOOL,
|
||||
VAL_TYPE_INT,
|
||||
VAL_TYPE_FLOAT,
|
||||
VAL_TYPE_STRING,
|
||||
VAL_TYPE_OBJECT,
|
||||
VAL_TYPE_ARRAY,
|
||||
};
|
||||
val_type type_;
|
||||
std::string key_;
|
||||
union
|
||||
{
|
||||
bool bval;
|
||||
int nval;
|
||||
double dval;
|
||||
}simple_val_;
|
||||
std::string strval_;
|
||||
std::vector<json*> arr_val_;
|
||||
size_t cur_child_;
|
||||
|
||||
static std::string object_key(json* jsn);
|
||||
static std::string array_key(json* jsn);
|
||||
|
||||
void from_cjson(cJSON* cj);
|
||||
json* find_child(const char* key, bool remove = false);
|
||||
|
||||
public:
|
||||
json(char* json_txt = 0);
|
||||
|
||||
protected:
|
||||
json(const char* key, bool val);
|
||||
json(const char* key, int val);
|
||||
json(const char* key, double val);
|
||||
json(const char* key, const char* val);
|
||||
json(json& r);
|
||||
~json();
|
||||
|
||||
public:
|
||||
// parse/un-parse ...
|
||||
void copy_from(json& r);
|
||||
bool attach_text(char* json_txt);
|
||||
void clear(bool as_array = false);
|
||||
std::string to_string(void);
|
||||
|
||||
// attributes ...
|
||||
std::string& key(void);
|
||||
bool is_array(void);
|
||||
bool is_leaf_node(void); // whether this object is a leaf node contains final value
|
||||
|
||||
// value access ...
|
||||
bool get_value(const char* key, bool& val);
|
||||
bool get_value(const char* key, int& val);
|
||||
bool get_value(const char* key, double& val);
|
||||
bool get_value(const char* key, std::string& val);
|
||||
bool get_value(const char* key, json*& val);
|
||||
|
||||
// enumeration ...
|
||||
size_t children(void); // return children count if was object or array, or else -1 returned
|
||||
json* child(size_t ind);
|
||||
json* first_child(void);
|
||||
json* next_child(void);
|
||||
|
||||
// change the item matching 'key', otherwise add a new item
|
||||
bool set_value(const char* key, bool val);
|
||||
bool set_value(const char* key, int val);
|
||||
bool set_value(const char* key, double val);
|
||||
bool set_value(const char* key, const char* val);
|
||||
bool set_value(const char* key, json* val);
|
||||
|
||||
// operator+= only for array
|
||||
json& operator+=(bool val);
|
||||
json& operator+=(int val);
|
||||
json& operator+=(double val);
|
||||
json& operator+=(const char* val);
|
||||
json& operator+=(json* val);
|
||||
|
||||
// remove item
|
||||
json& operator-=(int ind);
|
||||
bool remove(const char* key);
|
||||
bool remove(json* child);
|
||||
bool remove(int ind);
|
||||
|
||||
// position management
|
||||
int index(json* child);
|
||||
int index_move_to(json* child, int ind);
|
||||
|
||||
// leaf node value ...
|
||||
bool value(bool& val);
|
||||
bool value(int& val);
|
||||
bool value(double& val);
|
||||
bool value(std::string& val);
|
||||
json& operator=(bool val);
|
||||
json& operator=(int val);
|
||||
json& operator=(double val);
|
||||
json& operator=(const char* val);
|
||||
};
|
||||
|
||||
class base64
|
||||
{
|
||||
char base64_ind_[128];
|
||||
char base64_char_[80];
|
||||
char padding_char_;
|
||||
|
||||
bool is_valid_base64_table(const char* table);
|
||||
bool initialize_base64_table(const char* table);
|
||||
|
||||
public:
|
||||
base64();
|
||||
~base64();
|
||||
|
||||
public:
|
||||
bool set_base64_table(const char* table = NULL);
|
||||
std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true);
|
||||
std::string decode(const char* data, size_t bytes);
|
||||
};
|
||||
|
||||
// NOTE: 2021-01-28 all stored string value are in default language (i.e. Chinese-Simplified), user should call app_language::to_default_language/from_default_language for real value
|
||||
class sane_config_schm : public refer
|
||||
{
|
||||
std::string scheme_name_;
|
||||
scanner_cfg *scanner_;
|
||||
std::string file_;
|
||||
json* jsn_;
|
||||
json* bkp_;
|
||||
json* def_val_; // name_id: id, name_val: val
|
||||
bool in_setting_;
|
||||
|
||||
void clear();
|
||||
std::string default_value(const char* name);
|
||||
|
||||
protected:
|
||||
~sane_config_schm();
|
||||
|
||||
public:
|
||||
sane_config_schm(scanner_cfg* scanner = nullptr);
|
||||
|
||||
static std::string opt_data_appendix_;
|
||||
static std::string opt_def_id_appendix_;
|
||||
static std::string opt_def_val_appendix_;
|
||||
static std::string opt_def_type_appendix_;
|
||||
static std::string opt_def_title_appendix_;
|
||||
|
||||
static bool hex(unsigned char ch, unsigned char* val);
|
||||
static bool hex_char(const char* data, unsigned char* val);
|
||||
static std::string to_hex_letter(const char* data, size_t bytes);
|
||||
static std::string from_hex_letter(const char* data, size_t bytes);
|
||||
static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true
|
||||
static void set_default_value(json* jsn, int id, const char* name, const char* title, void* data, size_t bytes, int type);
|
||||
static int option_name_2_id(json* jsn, const char* name);
|
||||
static int option_type(json* jsn, const char* name);
|
||||
static std::string option_title(json* jsn, const char* name);
|
||||
static std::string option_default_value(json* jsn, const char* name);
|
||||
static std::string sane_option_value_2_string(void* val, size_t bytes, int type);
|
||||
|
||||
|
||||
public:
|
||||
sane_config_schm* copy(void);
|
||||
bool load_from_file(const char* file);
|
||||
bool load_from_mem(const char* mem, bool in_b64 = true);
|
||||
bool save_to(const char* file);
|
||||
void set_default_value(int sn, const char* name, const char* title, const char* val, size_t bytes, int type);
|
||||
bool first_config(std::string& name, std::string& val);
|
||||
bool next_config(std::string& name, std::string& val);
|
||||
bool get_config(const char* name, std::string& val);
|
||||
void begin_setting(bool restore = false);
|
||||
void config_changed(const char* name, const char* val, size_t bytes, bool extra = false);
|
||||
void config_changed(int sn, const char* val, size_t bytes, bool extra = false);
|
||||
void remove_config(const char* name);
|
||||
void set_value(const char* name, const char* val, size_t bytes, bool extra = false);
|
||||
bool has_changed(int* items = nullptr);
|
||||
void end_setting(bool cancel);
|
||||
int id_from_name(const char* name);
|
||||
std::string to_text_stream(bool b64 = true, bool with_ver = true);
|
||||
std::string get_version(void);
|
||||
std::string get_scheme_name(void);
|
||||
void set_scheme_name(const char* name);
|
||||
|
||||
std::string auto_gen_scheme_name(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param, bool replace_name = true);
|
||||
};
|
||||
|
||||
class scanner_cfg : public refer
|
||||
{
|
||||
// format: in base64
|
||||
//
|
||||
// {
|
||||
// "global": {
|
||||
// "ver": "4.33",
|
||||
// "cur": -1
|
||||
// },
|
||||
// "scheme_1": sane_config_schm*,
|
||||
// "scheme_2": sane_config_schm*,
|
||||
// "scheme_3": sane_config_schm*,
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
std::string path_;
|
||||
std::string scanner_name_; // scanner type: HUAGOSCAN G100 - 0100
|
||||
json *global_; // version, current scheme, ...
|
||||
json *opt_default_value_;
|
||||
|
||||
const char* (__stdcall* lang_trans_)(const char*, bool/*true - default language to cur language*/, void*);
|
||||
void* lang_param_;
|
||||
|
||||
typedef struct _cfg_schm
|
||||
{
|
||||
std::string name;
|
||||
bool should_rename;
|
||||
sane_config_schm* schm;
|
||||
|
||||
struct _cfg_schm()
|
||||
{
|
||||
name = "";
|
||||
should_rename = false;
|
||||
schm = nullptr;
|
||||
}
|
||||
bool operator==(const char* n)
|
||||
{
|
||||
return name == n;
|
||||
}
|
||||
}CFGSCHM;
|
||||
std::vector<CFGSCHM> schemes_;
|
||||
|
||||
static const char* __stdcall language_trans(const char* in, bool from_def, void* param);
|
||||
|
||||
void clear(void);
|
||||
void init_version(void);
|
||||
void init_select(void);
|
||||
const char* trans_language(const char* in, bool from_default);
|
||||
|
||||
protected:
|
||||
~scanner_cfg();
|
||||
|
||||
public:
|
||||
scanner_cfg();
|
||||
|
||||
typedef struct _update_func
|
||||
{
|
||||
void(* trans_number)(const char* name, std::string& val, void* param);
|
||||
const char* (* title2name)(const char* title, void* param);
|
||||
std::string discard_msg; // update failed items ...
|
||||
void* func_param;
|
||||
}UDF, *LPUDF;
|
||||
static bool update(const char* file, LPUDF func);
|
||||
|
||||
static std::string global_name_;
|
||||
static std::string cur_sel_;
|
||||
static std::string default_setting_name_;
|
||||
|
||||
public:
|
||||
int load_file(const char* file);
|
||||
int load_mem(const char* mem);
|
||||
int save(const char* file = nullptr);
|
||||
void set_language_transform(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param);
|
||||
|
||||
json* get_option_default_value(void);
|
||||
void get_all_schemes(std::vector<std::string>& schemes); // return all schemes name queue, the first is always be 'Default settings'
|
||||
sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore
|
||||
sane_config_schm* create_empty_scheme(bool selected); // create an empty scheme and add to scheme queue
|
||||
std::string get_current_scheme_name(void);
|
||||
std::string to_text_stream(void);
|
||||
void set_default_value(int id, const char* name, const char* title, void* data, size_t bytes, int type);
|
||||
int option_value_type(const char* name);
|
||||
std::string option_title(const char* name);
|
||||
bool remove_scheme(const char* scheme_name);
|
||||
void remove_all_schemes(void);
|
||||
bool select_scheme(const char* scheme_name);
|
||||
|
||||
sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore
|
||||
bool add_scheme(sane_config_schm* schm, const char* name = nullptr, bool should_rename = false);
|
||||
bool rename_scheme(const char* from, const char* to);
|
||||
};
|
||||
};
|
2195
sane/huagaotwain.cpp
2195
sane/huagaotwain.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +0,0 @@
|
|||
#pragma once
|
||||
#include "huagao/hgscanner_error.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include "sane_option_trans.h"
|
||||
#include "s2t_api.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// DlgIndicator.cpp: 实现文件
|
||||
//
|
||||
|
||||
#include "mem_dc.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// compatible_dc
|
||||
compatible_dc::compatible_dc(HDC src) : src_(src), old_(NULL)
|
||||
{
|
||||
HWND hwnd = WindowFromDC(src);
|
||||
RECT r = { 0 };
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
hwnd = GetDesktopWindow();
|
||||
GetWindowRect(hwnd, &r);
|
||||
size_.cx = r.right - r.left;
|
||||
size_.cy = r.bottom - r.top;
|
||||
bmp_ = CreateCompatibleBitmap(src, size_.cx, size_.cy);
|
||||
hdc_ = CreateCompatibleDC(src);
|
||||
old_ = (HBITMAP)SelectObject(hdc_, bmp_);
|
||||
BitBlt(hdc_, 0, 0, size_.cx, size_.cy, src, 0, 0, SRCCOPY);
|
||||
}
|
||||
compatible_dc::~compatible_dc()
|
||||
{
|
||||
BitBlt(src_, 0, 0, size_.cx, size_.cy, hdc_, 0, 0, SRCCOPY);
|
||||
SelectObject(hdc_, old_);
|
||||
DeleteObject(bmp_);
|
||||
DeleteDC(hdc_);
|
||||
}
|
||||
|
||||
HDC compatible_dc::get_dc()
|
||||
{
|
||||
return hdc_;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
class compatible_dc
|
||||
{
|
||||
HBITMAP bmp_;
|
||||
HBITMAP old_;
|
||||
HDC hdc_;
|
||||
HDC src_;
|
||||
SIZE size_;
|
||||
|
||||
public:
|
||||
compatible_dc(HDC src);
|
||||
~compatible_dc();
|
||||
|
||||
public:
|
||||
HDC get_dc(void);
|
||||
};
|
457
sane/s2t_api.h
457
sane/s2t_api.h
|
@ -1,457 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
//
|
||||
// For: interface definition for SANE to TWAIN
|
||||
//
|
||||
// Date: 2022-06-08
|
||||
//
|
||||
|
||||
#include <Windows.h>
|
||||
#include <sane/sane_ex.h>
|
||||
#include <huagao/hgscanner_error.h>
|
||||
#include <string>
|
||||
|
||||
#define COM_API_DECLARE(ret, decl) virtual ret __stdcall decl = 0
|
||||
#define COM_API_DECLARE_NON_PURE(ret, decl) virtual ret __stdcall decl
|
||||
#define COM_API_OVERRIDE(ret, decl) virtual ret __stdcall decl override
|
||||
#define COM_API_IMPLEMENT(cls, ret, decl) ret __stdcall cls##::decl
|
||||
|
||||
#define SANE_OPTION_ID_API(opt) COM_API_DECLARE(int, sane_opt_id_##opt(void)) // -1 is none
|
||||
#define SANE_OPTION_ID_OVERRIDE(opt) COM_API_OVERRIDE(int, sane_opt_id_##opt(void))
|
||||
#define SANE_OPTION_IMPLEMENT(cls, opt) int __stdcall cls##::sane_opt_id_##opt(void)
|
||||
|
||||
#define SANE_OPTION_ID_API_EX(opt) COM_API_DECLARE(int, sane_opt_id_ex_##opt(void)) // -1 is none
|
||||
#define SANE_OPTION_ID_OVERRIDE_EX(opt) COM_API_OVERRIDE(int, sane_opt_id_ex_##opt(void))
|
||||
#define SANE_OPTION_IMPLEMENT_EX(cls, opt) int __stdcall cls##::sane_opt_id_ex_##opt(void)
|
||||
|
||||
|
||||
#define ALIGN_MEMORY(n, align) ((n + align - 1) / (align) * (align))
|
||||
#define _TO_UNICODE_(str) L##str
|
||||
#define UNICODE_STR(str) _TO_UNICODE_(str)
|
||||
|
||||
#define TWPT_AUTOMATIC_COLOR 0x0a0c
|
||||
#define AUTO_MATIC_ROTATE 123.456f
|
||||
#define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .000001
|
||||
|
||||
enum value_limit
|
||||
{
|
||||
VAL_LIMIT_NONE = 0, //
|
||||
VAL_LIMIT_ENUM, //
|
||||
VAL_LIMIT_RANGE, //
|
||||
};
|
||||
enum value_role
|
||||
{
|
||||
VAL_ROLE_NONE = 0, // this value is no role but an item of the option only
|
||||
VAL_ROLE_DEFAULT = 0x01, // this value is the default value of the option
|
||||
VAL_ROLE_CURRENT = 0x02, // this value is the current value of the option
|
||||
VAL_ROLE_LOWER = 0x04, // the lower value of a VAL_LIMIT_RANGE
|
||||
VAL_ROLE_UPPER = 0x08, // the upper value of a VAL_LIMIT_RANGE
|
||||
VAL_ROLE_STEP = 0x10, // the step value of a VAL_LIMIT_RANGE
|
||||
};
|
||||
enum value_type
|
||||
{
|
||||
VAL_TYPE_NONE = 0,
|
||||
VAL_TYPE_BOOL, // bool
|
||||
VAL_TYPE_INT, // int
|
||||
VAL_TYPE_FLOAT, // float
|
||||
VAL_TYPE_STR, // char*
|
||||
VAL_TYPE_BUTTON, // a button
|
||||
};
|
||||
enum color_value // 除最后一项外,其余与Twpp::PixelType值保持一致
|
||||
{
|
||||
COLOR_BW = 0,
|
||||
COLOR_GRAY,
|
||||
COLOR_RGB,
|
||||
COLOR_AUTO_MATCH = TWPT_AUTOMATIC_COLOR,
|
||||
};
|
||||
enum paper_value // 与Twpp::PaperSize保持一致
|
||||
{
|
||||
PAPER_A4 = 1,
|
||||
PAPER_16K = 1,
|
||||
PAPER_LETTER = 3,
|
||||
PAPER_LEGAL = 4,
|
||||
PAPER_A5 = 5,
|
||||
PAPER_B4 = 6,
|
||||
PAPER_B6 = 7,
|
||||
PAPER_A3 = 11,
|
||||
PAPER_8K = 11,
|
||||
PAPER_A6 = 13,
|
||||
PAPER_B5 = 29,
|
||||
PAPER_STATEMENT = 52, // 匹配原始尺寸
|
||||
PAPER_MAXSIZE = 54, // 最大扫描尺寸
|
||||
|
||||
// 以下为未匹配选项
|
||||
PAPER_DOUBLE_LETTER = 103,
|
||||
PAPER_MAXSIZE_CROP = 154, // 最大扫描尺寸自动裁切
|
||||
PAPER_TRIPPLE = 111, // 三联试卷
|
||||
};
|
||||
enum filter_value // 除色选项
|
||||
{
|
||||
FILTER_NONE = 0,
|
||||
FILTER_RED,
|
||||
FILTER_GREEN,
|
||||
FILTER_BLUE,
|
||||
};
|
||||
enum enhance_value // 颜色增强选项
|
||||
{
|
||||
ENHANCE_NONE = 0,
|
||||
ENHANCE_RED,
|
||||
ENHANCE_GREEN,
|
||||
ENHANCE_BLUE,
|
||||
};
|
||||
enum sharpen_value
|
||||
{
|
||||
SHARPEN_NONE = 0,
|
||||
SHARPEN_SHARPEN,
|
||||
SHARPEN_SHARPEN_MORE,
|
||||
SHARPEN_BLUR,
|
||||
SHARPEN_BLUR_MORE,
|
||||
};
|
||||
enum multiout_value
|
||||
{
|
||||
MULTI_OUT_NONE = -1,
|
||||
MULTI_OUT_ALL,
|
||||
MULTI_OUT_COLOR_GRAY,
|
||||
MULTI_OUT_COLOR_BW,
|
||||
MULTI_OUT_GRAY_BW,
|
||||
};
|
||||
enum twain_xfer
|
||||
{
|
||||
TWAIN_XFER_Native = 0, // BITMAPINFOHEADER + bits
|
||||
TWAIN_XFER_File = 1, // BITMAPFILEHEADER + TWAIN_XFER_Native
|
||||
TWAIN_XFER_Memory = 2, // to be implementing ...
|
||||
};
|
||||
|
||||
typedef bool(__stdcall* set_opt_value)(void* val, value_role role, value_limit limit, void* param); // return false to stop the callback
|
||||
struct __declspec(novtable) IRef
|
||||
{
|
||||
COM_API_DECLARE(long, add_ref(void));
|
||||
COM_API_DECLARE(long, release(void));
|
||||
};
|
||||
struct __declspec(novtable) IScanImg : public IRef
|
||||
{
|
||||
COM_API_DECLARE(int, width(void));
|
||||
COM_API_DECLARE(int, line_bytes(void));
|
||||
COM_API_DECLARE(int, height(void));
|
||||
COM_API_DECLARE(int, depth(void));
|
||||
COM_API_DECLARE(int, channel(void));
|
||||
COM_API_DECLARE(int, dpi(void));
|
||||
COM_API_DECLARE(SANE_Frame, type(void));
|
||||
COM_API_DECLARE(unsigned int, bytes(void));
|
||||
COM_API_DECLARE(unsigned int, header_size(void));
|
||||
COM_API_DECLARE(unsigned char*, data(unsigned long long off, unsigned int *bytes));
|
||||
COM_API_DECLARE(int, read(void* buf, size_t* bytes, unsigned long long off = 0));
|
||||
COM_API_DECLARE(const char*, file(void));
|
||||
COM_API_DECLARE(void, keep_file(bool keep));
|
||||
COM_API_DECLARE(void, copy_header(SANE_Parameters* head));
|
||||
COM_API_DECLARE(int, image_status(void));
|
||||
};
|
||||
struct __declspec(novtable) ISaneInvoker : public IRef
|
||||
{
|
||||
COM_API_DECLARE(int, start(void));
|
||||
COM_API_DECLARE(int, stop(void));
|
||||
COM_API_DECLARE(int, get_event(void));
|
||||
COM_API_DECLARE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
|
||||
COM_API_DECLARE(bool, wait_image(DWORD milliseconds = -1));
|
||||
COM_API_DECLARE(int, get_scanned_images(DWORD milliseconds = 0));
|
||||
COM_API_DECLARE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz
|
||||
COM_API_DECLARE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL));
|
||||
COM_API_DECLARE(bool, is_online(void));
|
||||
COM_API_DECLARE(bool, is_paper_on(void));
|
||||
COM_API_DECLARE(int, last_error(void));
|
||||
|
||||
// Function: 获取配置项信息
|
||||
//
|
||||
// Parameter: sn - 配置项索引
|
||||
//
|
||||
// type - 配置项数据类型
|
||||
//
|
||||
// limit - 配置项限制类型
|
||||
//
|
||||
// bytes - *type 为 VAL_TYPE_STR时,需要的最小空间字节数
|
||||
COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes));
|
||||
|
||||
COM_API_DECLARE(bool, get_value(int sn, set_opt_value, void* param));
|
||||
COM_API_DECLARE(int, set_value(int sn, void* val));
|
||||
COM_API_DECLARE(int, convert_image(SANE_ImageFormatConvert* conv));
|
||||
COM_API_DECLARE(void, free_buffer(void* buf, int len));
|
||||
|
||||
// SANE options ID ...
|
||||
SANE_OPTION_ID_API(color_correction); // 2023-02-24 15:31:19 色偏校正
|
||||
SANE_OPTION_ID_API(fold_type); // 2023-02-24 15:28:47 对折模式
|
||||
SANE_OPTION_ID_API(is_multiout); // 多流输出
|
||||
SANE_OPTION_ID_API(multiout_type); // 多流输出类型
|
||||
SANE_OPTION_ID_API(color_mode); // 颜色模式
|
||||
SANE_OPTION_ID_API(erase_color); // 除色或增强
|
||||
SANE_OPTION_ID_API(erase_multiout_red); // 多流输出除红
|
||||
SANE_OPTION_ID_API(erase_paper_red); // 试卷除红
|
||||
SANE_OPTION_ID_API(is_erase_background); // 背景移除
|
||||
SANE_OPTION_ID_API(background_color_range); // 背景色彩范围
|
||||
SANE_OPTION_ID_API(sharpen); // 锐化与模糊
|
||||
SANE_OPTION_ID_API(erase_morr); // 除摩尔纹
|
||||
SANE_OPTION_ID_API(erase_grids); // 除网纹
|
||||
SANE_OPTION_ID_API(error_extend); // 错误扩散
|
||||
SANE_OPTION_ID_API(is_noise_modify); // 噪点优化
|
||||
SANE_OPTION_ID_API(noise_threshold); // 噪点优化尺寸
|
||||
SANE_OPTION_ID_API(paper); // 纸张尺寸
|
||||
SANE_OPTION_ID_API(is_custom_area); // 自定义扫描区域
|
||||
SANE_OPTION_ID_API(curstom_area_l); // 自定义扫描区域 左
|
||||
SANE_OPTION_ID_API(curstom_area_r); // 自定义扫描区域 右
|
||||
SANE_OPTION_ID_API(curstom_area_t); // 自定义扫描区域 上
|
||||
SANE_OPTION_ID_API(curstom_area_b); // 自定义扫描区域 下
|
||||
SANE_OPTION_ID_API(is_size_check); // 尺寸检测
|
||||
SANE_OPTION_ID_API(page); // 扫描页面
|
||||
SANE_OPTION_ID_API(blank_page_threshold); // 跳过空白页灵敏度
|
||||
SANE_OPTION_ID_API(resolution); // 分辨率
|
||||
SANE_OPTION_ID_API(image_quality); // 图像质量
|
||||
SANE_OPTION_ID_API(is_swap); // 交换正反面
|
||||
SANE_OPTION_ID_API(is_split); // 图像拆分
|
||||
SANE_OPTION_ID_API(is_auto_deskew); // 自动纠偏
|
||||
SANE_OPTION_ID_API(is_custom_gamma); // 自定义gamma
|
||||
SANE_OPTION_ID_API(bright); // 亮度
|
||||
SANE_OPTION_ID_API(contrast); // 对比度
|
||||
SANE_OPTION_ID_API(gamma); // gamma
|
||||
SANE_OPTION_ID_API(is_erase_black_frame); // 消除黑框
|
||||
SANE_OPTION_ID_API(deep_sample); // 深色样张
|
||||
SANE_OPTION_ID_API(threshold); // 阈值
|
||||
SANE_OPTION_ID_API(anti_noise); // 背景抗噪等级
|
||||
SANE_OPTION_ID_API(margin); // 边缘缩进
|
||||
SANE_OPTION_ID_API(fill_background); // 背景填充方式
|
||||
SANE_OPTION_ID_API(is_anti_permeate); // 防止渗透
|
||||
SANE_OPTION_ID_API(anti_permeate_level); // 防止渗透等级
|
||||
SANE_OPTION_ID_API(is_erase_hole); // 穿孔移除
|
||||
SANE_OPTION_ID_API(search_hole_range); // 穿孔搜索范围
|
||||
SANE_OPTION_ID_API(is_filling_color); // 色彩填充
|
||||
SANE_OPTION_ID_API(is_ultrasonic_check); // 超声波检测
|
||||
SANE_OPTION_ID_API(is_check_staple); // 装订检测
|
||||
SANE_OPTION_ID_API(scan_mode); // 扫描张数
|
||||
SANE_OPTION_ID_API(scan_count); // 扫描数量
|
||||
SANE_OPTION_ID_API(text_direction); // 文稿方向
|
||||
SANE_OPTION_ID_API(is_rotate_bkg180); // 背面旋转180度
|
||||
SANE_OPTION_ID_API(is_check_dogear); // 折角检测
|
||||
SANE_OPTION_ID_API(dogear_size); // 折角检测大小
|
||||
SANE_OPTION_ID_API(is_check_skew); // 歪斜检测
|
||||
SANE_OPTION_ID_API(skew_range); // 歪斜容忍度
|
||||
SANE_OPTION_ID_API(black_white_threshold); // 二值化图像阈值
|
||||
SANE_OPTION_ID_API(is_photo_mode); // 照片模式
|
||||
SANE_OPTION_ID_API(double_feed_handle); // 双张图片处理
|
||||
SANE_OPTION_ID_API(scan_when_paper_on); // 待纸扫描
|
||||
SANE_OPTION_ID_API(feed_strength); // 分纸强度
|
||||
SANE_OPTION_ID_API(power_scheme); // 休眠时间
|
||||
SANE_OPTION_ID_API(is_auto_strength); // 自动搓纸强度
|
||||
SANE_OPTION_ID_API(feed_strength_value); // 自动搓纸强度设定值
|
||||
SANE_OPTION_ID_API(is_reverse_bw); // 黑白图像反色输出
|
||||
SANE_OPTION_ID_API(is_erase_hole_l); // 穿孔移除 - 左
|
||||
SANE_OPTION_ID_API(search_hole_range_l); // 穿孔搜索范围 - 左
|
||||
SANE_OPTION_ID_API(is_erase_hole_r); // 穿孔移除 - 右
|
||||
SANE_OPTION_ID_API(search_hole_range_r); // 穿孔搜索范围 - 右
|
||||
SANE_OPTION_ID_API(is_erase_hole_t); // 穿孔移除 - 上
|
||||
SANE_OPTION_ID_API(search_hole_range_t); // 穿孔搜索范围 - 上
|
||||
SANE_OPTION_ID_API(is_erase_hole_b); // 穿孔移除 - 下
|
||||
SANE_OPTION_ID_API(search_hole_range_b); // 穿孔搜索范围 - 下
|
||||
SANE_OPTION_ID_API(fold_direction); // 对折模式
|
||||
|
||||
// SANE-ex option ID:
|
||||
SANE_OPTION_ID_API_EX(multiout_type); // int
|
||||
SANE_OPTION_ID_API_EX(auto_color_type); // int
|
||||
SANE_OPTION_ID_API_EX(color_mode); // int
|
||||
SANE_OPTION_ID_API_EX(sharpen); // int
|
||||
SANE_OPTION_ID_API_EX(paper); // paper_value
|
||||
SANE_OPTION_ID_API_EX(paper_lateral); // bool
|
||||
SANE_OPTION_ID_API_EX(auto_paper_size); // bool
|
||||
SANE_OPTION_ID_API_EX(is_paper_auto_crop); // bool
|
||||
SANE_OPTION_ID_API_EX(text_direction); // float 90, 180, ..., -1 is auto-text-direction
|
||||
SANE_OPTION_ID_API_EX(duplex); // bool
|
||||
SANE_OPTION_ID_API_EX(fill_background); // bool true - 凸多边形
|
||||
SANE_OPTION_ID_API_EX(discard_blank_page); // bool
|
||||
SANE_OPTION_ID_API_EX(discard_blank_receipt); // bool
|
||||
SANE_OPTION_ID_API_EX(is_page_fold); // bool
|
||||
SANE_OPTION_ID_API_EX(color_filter); // int (filter_value)
|
||||
SANE_OPTION_ID_API_EX(color_enhance); // int (enhance_value)
|
||||
|
||||
SANE_OPTION_ID_API_EX(final_compression); // int
|
||||
SANE_OPTION_ID_API_EX(final_format); // SANE_FinalImgFormat
|
||||
SANE_OPTION_ID_API_EX(serial); // std::string
|
||||
SANE_OPTION_ID_API_EX(to_be_scan); // bool
|
||||
SANE_OPTION_ID_API_EX(scan_with_hole); // bool
|
||||
SANE_OPTION_ID_API_EX(device_code); // std::string
|
||||
SANE_OPTION_ID_API_EX(power); // int
|
||||
SANE_OPTION_ID_API_EX(hardware_version); // std::string
|
||||
SANE_OPTION_ID_API_EX(ip); // std::string
|
||||
|
||||
// ui ...
|
||||
COM_API_DECLARE(bool, ui_show_main(HWND parent));
|
||||
COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
|
||||
COM_API_DECLARE(bool, ui_show_progress(HWND parent));
|
||||
COM_API_DECLARE(void, ui_hide(void));
|
||||
COM_API_DECLARE(bool, ui_is_ok(void));
|
||||
|
||||
// twain
|
||||
COM_API_DECLARE(void, twain_set_transfer(twain_xfer xfer));
|
||||
COM_API_DECLARE(void, twain_set_compression(SANE_CompressionType compression, void* detail = NULL));
|
||||
COM_API_DECLARE(int, twain_get_config(char* buf, size_t* len));
|
||||
COM_API_DECLARE(int, twain_set_config(char* buf, size_t len));
|
||||
};
|
||||
|
||||
struct delete_scanner
|
||||
{
|
||||
void operator()(ISaneInvoker* p)
|
||||
{
|
||||
p->release();
|
||||
}
|
||||
};
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
namespace sane_opts
|
||||
{
|
||||
enum
|
||||
{
|
||||
RANGE_POS_CURRENT = 0,
|
||||
RANGE_POS_DEFAULT,
|
||||
RANGE_POS_ENUM_BEGIN,
|
||||
RANGE_POS_LOWER = RANGE_POS_ENUM_BEGIN,
|
||||
RANGE_POS_UPPER,
|
||||
RANGE_POS_STEP,
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class get_opts
|
||||
{
|
||||
public:
|
||||
// 0 - cur val; 1 - def val;
|
||||
//
|
||||
// LIST: 2 - elements ...
|
||||
//
|
||||
// RANGE: 2 - lower; 3 - upper; 4 - step
|
||||
T range[5];
|
||||
value_limit lmt_;
|
||||
|
||||
std::vector<T>* lvs_;
|
||||
value_limit* limit_;
|
||||
|
||||
public:
|
||||
get_opts(value_limit* limit, std::vector<T>* ls) : limit_(limit), lvs_(ls)
|
||||
{}
|
||||
~get_opts()
|
||||
{}
|
||||
|
||||
void re_order(void)
|
||||
{
|
||||
if (limit_)
|
||||
*limit_ = lmt_;
|
||||
|
||||
if (lmt_ == VAL_LIMIT_RANGE || lmt_ == VAL_LIMIT_NONE)
|
||||
{
|
||||
if (lvs_)
|
||||
{
|
||||
lvs_->clear();
|
||||
for (size_t i = 0; i < _countof(range); ++i)
|
||||
lvs_->push_back(range[i]);
|
||||
}
|
||||
}
|
||||
else if(lvs_)
|
||||
{
|
||||
lvs_->insert(lvs_->begin(), range[RANGE_POS_DEFAULT]);
|
||||
lvs_->insert(lvs_->begin(), range[RANGE_POS_CURRENT]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
bool __stdcall set_opt_value(void* val, value_role role, value_limit limit, void* param)
|
||||
{
|
||||
get_opts<T>* v = (get_opts<T>*)param;
|
||||
bool go = true;
|
||||
|
||||
v->lmt_ = limit;
|
||||
if (role & VAL_ROLE_CURRENT)
|
||||
{
|
||||
v->range[RANGE_POS_CURRENT] = *(T*)val;
|
||||
}
|
||||
if (role & VAL_ROLE_DEFAULT)
|
||||
{
|
||||
v->range[RANGE_POS_DEFAULT] = *(T*)val;
|
||||
}
|
||||
if (role & VAL_ROLE_LOWER)
|
||||
{
|
||||
v->range[RANGE_POS_LOWER] = *(T*)val;
|
||||
}
|
||||
if (role & VAL_ROLE_UPPER)
|
||||
{
|
||||
v->range[RANGE_POS_UPPER] = *(T*)val;
|
||||
}
|
||||
|
||||
if (role & VAL_ROLE_STEP)
|
||||
{
|
||||
v->range[RANGE_POS_STEP] = *(T*)val;
|
||||
}
|
||||
else if (v->lvs_)
|
||||
v->lvs_->push_back(*(T*)val);
|
||||
|
||||
return go;
|
||||
}
|
||||
}
|
||||
|
||||
#define GET_SANE_OPT(type, object, id_name, limit, vct) \
|
||||
{ \
|
||||
int ind = object->sane_opt_id_##id_name##(); \
|
||||
sane_opts::get_opts<type> op(limit, vct); \
|
||||
if(ind > 0) \
|
||||
object->get_value(ind, sane_opts::set_opt_value<type>, &op);\
|
||||
else \
|
||||
return capUnsupported(); \
|
||||
op.re_order(); \
|
||||
}
|
||||
|
||||
#define SET_SANE_OPT(ret, object, id_name, val) \
|
||||
{ \
|
||||
int ind = object->sane_opt_id_##id_name##(); \
|
||||
if(ind > 0) \
|
||||
ret = object->set_value(ind, val); \
|
||||
else \
|
||||
{ \
|
||||
ret = SCANNER_ERR_INVALID_PARAMETER; \
|
||||
load_sane_util::log_info((std::wstring(L"Fatal: property '") + L###id_name + L"' not found !!!\r\n").c_str(), 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
typedef unsigned int SCANNERID;
|
||||
#define MAKE_SCANNER_ID(pid, vid) MAKELONG(pid, vid)
|
||||
#define GET_SCANNER_PID(sid) LOWORD(sid)
|
||||
#define GET_SCANNER_VID(sid) HIWORD(sid)
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#ifdef EXPORT_SANE_API
|
||||
__declspec(dllexport)
|
||||
#else
|
||||
__declspec(dllimport)
|
||||
#endif
|
||||
int __stdcall initialize(void* reserve);
|
||||
#ifdef EXPORT_SANE_API
|
||||
__declspec(dllexport)
|
||||
#else
|
||||
__declspec(dllimport)
|
||||
#endif
|
||||
int __stdcall open_scanner(SCANNERID scanner_id, ISaneInvoker** invoker);
|
||||
#ifdef EXPORT_SANE_API
|
||||
__declspec(dllexport)
|
||||
#else
|
||||
__declspec(dllimport)
|
||||
#endif
|
||||
bool __stdcall is_scanner_online(SCANNERID scanner_id);
|
||||
#ifdef EXPORT_SANE_API
|
||||
__declspec(dllexport)
|
||||
#else
|
||||
__declspec(dllimport)
|
||||
#endif
|
||||
int __stdcall uninitialize(void* reserve);
|
||||
#ifdef EXPORT_SANE_API
|
||||
__declspec(dllexport)
|
||||
#else
|
||||
__declspec(dllimport)
|
||||
#endif
|
||||
void __stdcall log_info(const wchar_t* info, int level);
|
||||
}
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
LIBRARY sane
|
||||
EXPORTS
|
||||
initialize
|
||||
open_scanner
|
||||
is_scanner_online
|
||||
uninitialize
|
||||
log_info
|
||||
sane_hgsane_init
|
||||
sane_hgsane_exit
|
||||
sane_hgsane_get_devices
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
<LibraryPath>$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -84,6 +85,7 @@
|
|||
<LibraryPath>$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
|
@ -91,6 +93,7 @@
|
|||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include;$(SolutionDir)..\..\code_device\include\;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -98,6 +101,7 @@
|
|||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include;$(SolutionDir)..\..\code_device\include\;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -118,8 +122,10 @@
|
|||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
copy /y "$(TargetPath)" "C:\Windows\twain_32\HuaGoTwain"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -144,8 +150,9 @@
|
|||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -164,8 +171,10 @@
|
|||
<ModuleDefinitionFile>$(ProjectDir)sane.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
copy /y "$(TargetPath)" "C:\Program Files\HuaGoScan"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -189,8 +198,9 @@
|
|||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
@ -199,19 +209,6 @@
|
|||
<ClCompile Include="..\..\code_device\hgsane\main.c" />
|
||||
<ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" />
|
||||
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" />
|
||||
<ClCompile Include="DlgArea.cpp" />
|
||||
<ClCompile Include="DlgCfgMgr.cpp" />
|
||||
<ClCompile Include="DlgGamma.cpp" />
|
||||
<ClCompile Include="DlgIndicator.cpp" />
|
||||
<ClCompile Include="DlgInput.cpp" />
|
||||
<ClCompile Include="DlgPage.cpp" />
|
||||
<ClCompile Include="DlgSaveScheme.cpp" />
|
||||
<ClCompile Include="DlgSetting.cpp" />
|
||||
<ClCompile Include="gb_json.cpp" />
|
||||
<ClCompile Include="mem_dc.cpp" />
|
||||
<ClCompile Include="sane_option_trans.cpp" />
|
||||
<ClCompile Include="scanned_img.cpp" />
|
||||
<ClCompile Include="scanner.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\code_device\hgsane\cJSON.h" />
|
||||
|
@ -226,22 +223,7 @@
|
|||
<ClInclude Include="..\..\sdk\include\sane\sanei_debug.h" />
|
||||
<ClInclude Include="..\..\sdk\include\sane\sane_ex.h" />
|
||||
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" />
|
||||
<ClInclude Include="const_str.h" />
|
||||
<ClInclude Include="DlgArea.h" />
|
||||
<ClInclude Include="DlgCfgMgr.h" />
|
||||
<ClInclude Include="DlgGamma.h" />
|
||||
<ClInclude Include="DlgIndicator.h" />
|
||||
<ClInclude Include="DlgInput.h" />
|
||||
<ClInclude Include="DlgPage.h" />
|
||||
<ClInclude Include="DlgSaveScheme.h" />
|
||||
<ClInclude Include="DlgSetting.h" />
|
||||
<ClInclude Include="gb_json.h" />
|
||||
<ClInclude Include="mem_dc.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="s2t_api.h" />
|
||||
<ClInclude Include="sane_option_trans.h" />
|
||||
<ClInclude Include="scanned_img.h" />
|
||||
<ClInclude Include="scanner.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="sane.def" />
|
||||
|
|
|
@ -13,12 +13,6 @@
|
|||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="sane2twain">
|
||||
<UniqueIdentifier>{8ae15a45-410d-4611-b852-f82b64bb1fcc}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sane2twain\UI">
|
||||
<UniqueIdentifier>{5c86255e-570e-4921-9c62-c98d05edcab4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\code_device\hgsane\cJSON.c">
|
||||
|
@ -36,45 +30,6 @@
|
|||
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sane_option_trans.cpp">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="scanned_img.cpp">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="scanner.cpp">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgIndicator.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgSetting.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgPage.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgArea.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mem_dc.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgGamma.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gb_json.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgCfgMgr.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgInput.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgSaveScheme.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\code_device\hgsane\cJSON.h">
|
||||
|
@ -113,54 +68,9 @@
|
|||
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="s2t_api.h">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sane_option_trans.h">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="scanned_img.h">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="scanner.h">
|
||||
<Filter>sane2twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgIndicator.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgSetting.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgPage.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgArea.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mem_dc.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgGamma.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gb_json.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgCfgMgr.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgInput.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="const_str.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgSaveScheme.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="sane.def">
|
||||
|
|
|
@ -1,300 +0,0 @@
|
|||
#include "sane_option_trans.h"
|
||||
#include <Windows.h>
|
||||
#include <sane/sane_option_definitions.h>
|
||||
|
||||
#include "../../sdk/include/lang/app_language.h"
|
||||
|
||||
namespace sane_opt_trans
|
||||
{
|
||||
static struct
|
||||
{
|
||||
int twain_id;
|
||||
const char* opt_val;
|
||||
}
|
||||
g_color_mode_map[] = {{COLOR_BW, OPTION_VALUE_YSMS_HB}
|
||||
, {COLOR_GRAY, OPTION_VALUE_YSMS_256JHD}
|
||||
, {COLOR_RGB, OPTION_VALUE_YSMS_24WCS}
|
||||
, {COLOR_AUTO_MATCH, OPTION_VALUE_YSMS_YSZDSB}
|
||||
},
|
||||
g_multiout_map[] = { {MULTI_OUT_NONE, "\346\227\240"}
|
||||
, {MULTI_OUT_ALL, OPTION_VALUE_DLSCLX_CS_HD_HB}
|
||||
, {MULTI_OUT_COLOR_GRAY, OPTION_VALUE_DLSCLX_CS_HD}
|
||||
, {MULTI_OUT_COLOR_BW, OPTION_VALUE_DLSCLX_CS_HB}
|
||||
, {MULTI_OUT_GRAY_BW, OPTION_VALUE_DLSCLX_HD_HB}
|
||||
},
|
||||
g_enhance_map[] = { {ENHANCE_NONE, OPTION_VALUE_HDHHBTX_CSYZQ_BCS}
|
||||
, {ENHANCE_RED, OPTION_VALUE_HDHHBTX_CSYZQ_HSZQ}
|
||||
, {ENHANCE_GREEN, OPTION_VALUE_HDHHBTX_CSYZQ_LSZQ}
|
||||
, {ENHANCE_BLUE, OPTION_VALUE_HDHHBTX_CSYZQ_LANSEZENGQIANG}
|
||||
},
|
||||
g_filter_map[] = { {FILTER_NONE, OPTION_VALUE_HDHHBTX_CSYZQ_BCS}
|
||||
, {FILTER_RED, OPTION_VALUE_HDHHBTX_CSYZQ_CHS}
|
||||
, {FILTER_GREEN, OPTION_VALUE_HDHHBTX_CSYZQ_CLS}
|
||||
, {FILTER_BLUE, OPTION_VALUE_HDHHBTX_CSYZQ_CHULANSE}
|
||||
},
|
||||
g_auto_color_map[] = { {0, OPTION_VALUE_YSMS_HB}
|
||||
, {1, OPTION_VALUE_YSMS_256JHD}
|
||||
},
|
||||
g_sharpen_map[] = { {SHARPEN_NONE, OPTION_VALUE_RHYMH_W}
|
||||
, {SHARPEN_SHARPEN, OPTION_VALUE_RHYMH_RH}
|
||||
, {SHARPEN_SHARPEN_MORE, OPTION_VALUE_RHYMH_JYBRH}
|
||||
, {SHARPEN_BLUR, OPTION_VALUE_RHYMH_MH}
|
||||
, {SHARPEN_BLUR_MORE, OPTION_VALUE_RHYMH_JYBMH}
|
||||
},
|
||||
g_paper_map[] = { {PAPER_LETTER, OPTION_VALUE_ZZCC_Letter}
|
||||
, {PAPER_LEGAL, OPTION_VALUE_ZZCC_LEGAL}
|
||||
//, {PAPER_8K, OPTION_VALUE_ZZCC_8K}
|
||||
//, {PAPER_16K, OPTION_VALUE_ZZCC_16K}
|
||||
, {PAPER_A3, OPTION_VALUE_ZZCC_A3}
|
||||
, {PAPER_A4, OPTION_VALUE_ZZCC_A4}
|
||||
, {PAPER_A5, OPTION_VALUE_ZZCC_A5}
|
||||
, {PAPER_A6, OPTION_VALUE_ZZCC_A6}
|
||||
, {PAPER_B4, OPTION_VALUE_ZZCC_B4}
|
||||
, {PAPER_B5, OPTION_VALUE_ZZCC_B5}
|
||||
, {PAPER_B6, OPTION_VALUE_ZZCC_B6}
|
||||
, {PAPER_STATEMENT, OPTION_VALUE_ZZCC_PPYSCC}
|
||||
, {PAPER_MAXSIZE, OPTION_VALUE_ZZCC_ZDSMCC}
|
||||
, {PAPER_MAXSIZE_CROP, OPTION_VALUE_ZZCC_ZDSMCCZDCQ}
|
||||
, {PAPER_DOUBLE_LETTER, OPTION_VALUE_ZZCC_DoubleLetter}
|
||||
, {PAPER_TRIPPLE, OPTION_VALUE_ZZCC_SLSJ}
|
||||
}
|
||||
;
|
||||
#define VALUE_FROM_TWAIN(arr, val) \
|
||||
for (int i = 0; i < _countof(arr); ++i) \
|
||||
{ \
|
||||
if (arr[i].twain_id == val) \
|
||||
return from_default_language(arr[i].opt_val, NULL); \
|
||||
}
|
||||
#define VALUE_TO_TWAIN(arr, val) \
|
||||
for (int i = 0; i < _countof(arr); ++i) \
|
||||
{ \
|
||||
if (strcmp(from_default_language(arr[i].opt_val, NULL), val) == 0) \
|
||||
return arr[i].twain_id; \
|
||||
}
|
||||
|
||||
const char* color_mode_from_twain(int val)
|
||||
{
|
||||
VALUE_FROM_TWAIN(g_color_mode_map, val);
|
||||
|
||||
return OPTION_VALUE_YSMS_YSZDSB;
|
||||
}
|
||||
int color_mode_to_twain(const char* val)
|
||||
{
|
||||
VALUE_TO_TWAIN(g_color_mode_map, val);
|
||||
|
||||
return COLOR_AUTO_MATCH;
|
||||
}
|
||||
|
||||
const char* multiout_value_from_twain(int val)
|
||||
{
|
||||
VALUE_FROM_TWAIN(g_multiout_map, val);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
int multiout_value_to_twain(const char* val)
|
||||
{
|
||||
VALUE_TO_TWAIN(g_multiout_map, val);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* filter_enhance_value_from_twain(int val, bool filter)
|
||||
{
|
||||
if (filter)
|
||||
{
|
||||
for (int i = 0; i < _countof(g_filter_map); ++i)
|
||||
{
|
||||
if (g_filter_map[i].twain_id == val)
|
||||
return from_default_language(g_filter_map[i].opt_val, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _countof(g_enhance_map); ++i)
|
||||
{
|
||||
if (g_enhance_map[i].twain_id == val)
|
||||
return from_default_language(g_enhance_map[i].opt_val, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return from_default_language(OPTION_VALUE_HDHHBTX_CSYZQ_BCS, NULL);
|
||||
}
|
||||
int filter_enhance_value_to_twain(const char* val, bool* is_filter)
|
||||
{
|
||||
bool type = false;
|
||||
const char* hz = to_default_language(val, NULL);
|
||||
|
||||
if (!is_filter)
|
||||
is_filter = &type;
|
||||
|
||||
*is_filter = true;
|
||||
for (int i = 0; i < _countof(g_filter_map); ++i)
|
||||
{
|
||||
if (strcmp(g_filter_map[i].opt_val, hz) == 0)
|
||||
return g_filter_map[i].twain_id;
|
||||
}
|
||||
*is_filter = false;
|
||||
for (int i = 0; i < _countof(g_enhance_map); ++i)
|
||||
{
|
||||
if (strcmp(g_enhance_map[i].opt_val, hz) == 0)
|
||||
return g_enhance_map[i].twain_id;
|
||||
}
|
||||
|
||||
return ENHANCE_NONE;
|
||||
}
|
||||
|
||||
const char* text_direction_from_twain(float val)
|
||||
{
|
||||
while (val < .0f)
|
||||
val += 360.0f;
|
||||
while (val > 360.0f)
|
||||
val -= 360.0f;
|
||||
|
||||
if (60.0f < val && val < 120.0f)
|
||||
return from_default_language(OPTION_VALUE_WGFX_90, NULL);
|
||||
else if (150.0f < val && val < 210.0f)
|
||||
return from_default_language(OPTION_VALUE_WGFX_180, NULL);
|
||||
else if (240.0f < val && val < 300.0f)
|
||||
return from_default_language(OPTION_VALUE_WGFX__90, NULL);
|
||||
else if (330.0f < val || val < 30.0f)
|
||||
return from_default_language(OPTION_VALUE_WGFX_0, NULL);
|
||||
else
|
||||
return from_default_language(OPTION_VALUE_WGFX_ZDWBFXSB, NULL);
|
||||
}
|
||||
float text_direction_to_twain(const char* val)
|
||||
{
|
||||
const char* hz = to_default_language(val, NULL);
|
||||
if (strcmp(hz, OPTION_VALUE_WGFX_90) == 0)
|
||||
return 90.0f;
|
||||
else if (strcmp(hz, OPTION_VALUE_WGFX_180) == 0)
|
||||
return 180.0f;
|
||||
else if (strcmp(hz, OPTION_VALUE_WGFX__90) == 0)
|
||||
return 270.0f;
|
||||
else if (strcmp(hz, OPTION_VALUE_WGFX_0) == 0)
|
||||
return .0f;
|
||||
else
|
||||
return AUTO_MATIC_ROTATE;
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
const char* normal;
|
||||
const char* lateral;
|
||||
}g_lateral_map[] =
|
||||
{ {OPTION_VALUE_ZZCC_A4, OPTION_VALUE_ZZCC_A4HX}
|
||||
, {OPTION_VALUE_ZZCC_16K, OPTION_VALUE_ZZCC_16KHX}
|
||||
, {OPTION_VALUE_ZZCC_A5, OPTION_VALUE_ZZCC_A5HX}
|
||||
, {OPTION_VALUE_ZZCC_A6, OPTION_VALUE_ZZCC_A6HX}
|
||||
, {OPTION_VALUE_ZZCC_B5, OPTION_VALUE_ZZCC_B5HX}
|
||||
, {OPTION_VALUE_ZZCC_B6, OPTION_VALUE_ZZCC_B6HX}
|
||||
, {OPTION_VALUE_ZZCC_Letter, OPTION_VALUE_ZZCC_LetterHX}
|
||||
};
|
||||
|
||||
const char* paper_from_twain(int val)
|
||||
{
|
||||
VALUE_FROM_TWAIN(g_paper_map, val);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
int paper_to_twain(const char* val)
|
||||
{
|
||||
VALUE_TO_TWAIN(g_paper_map, val);
|
||||
|
||||
return -1;
|
||||
}
|
||||
const char* switch_paper_lateral(const char* val)
|
||||
{
|
||||
const char* hz = to_default_language(val, NULL);
|
||||
for (int i = 0; i < _countof(g_lateral_map); ++i)
|
||||
{
|
||||
if (strcmp(g_lateral_map[i].normal, hz) == 0)
|
||||
return from_default_language(g_lateral_map[i].lateral, NULL);
|
||||
else if (strcmp(g_lateral_map[i].lateral, hz) == 0)
|
||||
return from_default_language(g_lateral_map[i].normal, NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
bool is_paper_lateral(const char* val)
|
||||
{
|
||||
const char* hz = to_default_language(val, NULL);
|
||||
for (int i = 0; i < _countof(g_lateral_map); ++i)
|
||||
{
|
||||
if (strcmp(g_lateral_map[i].lateral, hz) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* auto_color_type_from_twain(int val)
|
||||
{
|
||||
VALUE_FROM_TWAIN(g_color_mode_map, val);
|
||||
|
||||
return from_default_language(OPTION_VALUE_YSMS_24WCS, NULL);
|
||||
}
|
||||
int auto_color_type_to_twain(const char* val)
|
||||
{
|
||||
VALUE_TO_TWAIN(g_color_mode_map, val);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* sharpen_from_twain(int val)
|
||||
{
|
||||
VALUE_FROM_TWAIN(g_sharpen_map, val);
|
||||
|
||||
return from_default_language(OPTION_VALUE_RHYMH_W, NULL);
|
||||
}
|
||||
int sharpen_to_twain(const char* val)
|
||||
{
|
||||
VALUE_TO_TWAIN(g_sharpen_map, val);
|
||||
|
||||
return SHARPEN_NONE;
|
||||
}
|
||||
|
||||
struct {
|
||||
int twain;
|
||||
int sane;
|
||||
}
|
||||
g_compression_map[] = { {0, SANE_COMPRESSION_NONE}
|
||||
, {5, SANE_COMPRESSION_GROUP4}
|
||||
}
|
||||
;
|
||||
#define INT_FROM_TWAIN(arr, val) \
|
||||
for (int i = 0; i < _countof(arr); ++i) \
|
||||
{ \
|
||||
if (arr[i].twain == val) \
|
||||
return arr[i].sane; \
|
||||
}
|
||||
#define INT_TO_TWAIN(arr, val) \
|
||||
for (int i = 0; i < _countof(arr); ++i) \
|
||||
{ \
|
||||
if (arr[i].sane == val) \
|
||||
return arr[i].twain; \
|
||||
}
|
||||
|
||||
int compression_from_twain(int val)
|
||||
{
|
||||
INT_FROM_TWAIN(g_compression_map, val);
|
||||
|
||||
return SANE_COMPRESSION_NONE;
|
||||
}
|
||||
int compression_to_twain(int val)
|
||||
{
|
||||
INT_TO_TWAIN(g_compression_map, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
std::vector<int> support_image_types(void)
|
||||
{
|
||||
std::vector<int> it;
|
||||
|
||||
it.push_back(SANE_IMAGE_TYPE_BMP);
|
||||
it.push_back(SANE_IMAGE_TYPE_TIFF);
|
||||
it.push_back(SANE_IMAGE_TYPE_JFIF);
|
||||
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// utilities for transfroming options between TWAIN and sane ...
|
||||
//
|
||||
// Date: 2022-04-14
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "s2t_api.h"
|
||||
|
||||
namespace sane_opt_trans
|
||||
{
|
||||
const char* color_mode_from_twain(int val);
|
||||
int color_mode_to_twain(const char* val);
|
||||
|
||||
const char* multiout_value_from_twain(int val);
|
||||
int multiout_value_to_twain(const char* val);
|
||||
|
||||
const char* filter_enhance_value_from_twain(int val, bool filter);
|
||||
int filter_enhance_value_to_twain(const char* val, bool* is_filter);
|
||||
|
||||
const char* text_direction_from_twain(float val);
|
||||
float text_direction_to_twain(const char* val);
|
||||
|
||||
const char* paper_from_twain(int val);
|
||||
int paper_to_twain(const char* val);
|
||||
|
||||
const char* switch_paper_lateral(const char* val);
|
||||
bool is_paper_lateral(const char* val);
|
||||
|
||||
const char* auto_color_type_from_twain(int val);
|
||||
int auto_color_type_to_twain(const char* val);
|
||||
|
||||
const char* sharpen_from_twain(int val);
|
||||
int sharpen_to_twain(const char* val);
|
||||
|
||||
int compression_from_twain(int val);
|
||||
int compression_to_twain(int val);
|
||||
|
||||
std::vector<int> support_image_types(void);
|
||||
}
|
||||
|
|
@ -1,795 +0,0 @@
|
|||
#include "scanned_img.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
|
||||
#include "../../code_device/hgsane/sane_hg_mdw.h"
|
||||
#include "../../sdk/include/lang/app_language.h"
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
namespace local_trans
|
||||
{
|
||||
std::string u2a(const wchar_t* u, UINT cp)
|
||||
{
|
||||
std::string a("");
|
||||
|
||||
if (u)
|
||||
{
|
||||
char * ansi = NULL;
|
||||
int len = 0;
|
||||
|
||||
len = WideCharToMultiByte(cp, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
|
||||
ansi = new char[len + 2];
|
||||
len = WideCharToMultiByte(cp, 0, u, lstrlenW(u), ansi, len, NULL, NULL);
|
||||
ansi[len--] = 0;
|
||||
a = ansi;
|
||||
delete[] ansi;
|
||||
}
|
||||
|
||||
return std::move(a);
|
||||
}
|
||||
std::wstring a2u(const char* asc, UINT cp)
|
||||
{
|
||||
std::wstring u(L"");
|
||||
|
||||
if (asc)
|
||||
{
|
||||
wchar_t *buf = NULL;
|
||||
int len = 0;
|
||||
|
||||
len = MultiByteToWideChar(cp, 0, asc, lstrlenA(asc), NULL, 0);
|
||||
buf = new wchar_t[len + 2];
|
||||
len = MultiByteToWideChar(cp, 0, asc, lstrlenA(asc), buf, len);
|
||||
buf[len--] = 0;
|
||||
u = buf;
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
return std::move(u);
|
||||
}
|
||||
|
||||
std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz)
|
||||
{
|
||||
std::string a(u2a(in, CP_UTF8));
|
||||
|
||||
if (from_hz)
|
||||
a = from_default_language(a.c_str(), nullptr);
|
||||
else
|
||||
a = to_default_language(a.c_str(), nullptr);
|
||||
|
||||
return std::move(a2u(a.c_str(), CP_UTF8));
|
||||
}
|
||||
const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param)
|
||||
{
|
||||
return from_hz ? from_default_language(in, nullptr) : to_default_language(in, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class refer
|
||||
refer::refer() : ref_(1)
|
||||
{}
|
||||
refer::~refer()
|
||||
{}
|
||||
|
||||
COM_API_IMPLEMENT(refer, long, add_ref(void))
|
||||
{
|
||||
return InterlockedIncrement(&ref_);
|
||||
}
|
||||
COM_API_IMPLEMENT(refer, long, release(void))
|
||||
{
|
||||
long ref = InterlockedDecrement(&ref_);
|
||||
|
||||
if (ref == 0)
|
||||
delete this;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class mapping_buf
|
||||
const unsigned int max_mem_block = 2 * 1024 * 1024;
|
||||
extern void __stdcall log_info(const wchar_t* info, int level);
|
||||
|
||||
mapping_buf::mapping_buf() : bytes_(0), offset_(0), mapped_bytes_(0), map_(NULL), buf_(NULL), file_(""), rmv_file_(true), page_size_(0), is_mem_(false)
|
||||
{
|
||||
SYSTEM_INFO si = { 0 };
|
||||
|
||||
GetSystemInfo(&si);
|
||||
page_size_ = si.dwPageSize;
|
||||
map_unit_ = si.dwAllocationGranularity;
|
||||
}
|
||||
mapping_buf::~mapping_buf()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void mapping_buf::init_map(const char* file, unsigned long long size)
|
||||
{
|
||||
HANDLE f = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (size)
|
||||
{
|
||||
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (f != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
unsigned long long total = size - 1;
|
||||
LONG* p32 = (LONG*)&total;
|
||||
*p32 = SetFilePointer(f, *p32, p32 + 1, FILE_BEGIN);
|
||||
total++;
|
||||
if (total == size)
|
||||
{
|
||||
DWORD wrote = 1;
|
||||
WriteFile(f, "\0", 1, &wrote, NULL);
|
||||
map_ = CreateFileMapping(f, NULL, PAGE_READWRITE, p32[1], p32[0], NULL);
|
||||
}
|
||||
CloseHandle(f);
|
||||
if (!map_)
|
||||
DeleteFileA(file);
|
||||
}
|
||||
|
||||
{
|
||||
std::wstring info(local_trans::a2u(file));
|
||||
wchar_t buf[80] = { 0 };
|
||||
|
||||
swprintf_s(buf, _countof(buf) - 1, L"Mapping %u bytes to file: ", size);
|
||||
log_info((buf + info + L"\r\n").c_str(), 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (f != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD* p32 = (DWORD*)&size;
|
||||
*p32 = GetFileSize(f, p32 + 1);
|
||||
map_ = CreateFileMapping(f, NULL, PAGE_READWRITE, p32[1], p32[0], NULL);
|
||||
CloseHandle(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (map_)
|
||||
{
|
||||
bytes_ = size;
|
||||
file_ = file;
|
||||
buffer(0, NULL);
|
||||
if (!map_)
|
||||
close();
|
||||
}
|
||||
}
|
||||
void mapping_buf::close(void)
|
||||
{
|
||||
if (buf_)
|
||||
{
|
||||
if (is_mem_)
|
||||
delete[] buf_;
|
||||
else
|
||||
UnmapViewOfFile(buf_);
|
||||
}
|
||||
buf_ = NULL;
|
||||
if (map_)
|
||||
CloseHandle(map_);
|
||||
map_ = NULL;
|
||||
if (rmv_file_ && file_.length())
|
||||
DeleteFileA(file_.c_str());
|
||||
file_ = "";
|
||||
bytes_ = offset_ = 0;
|
||||
mapped_bytes_ = 0;
|
||||
rmv_file_ = true;
|
||||
is_mem_ = false;
|
||||
}
|
||||
void mapping_buf::map(void)
|
||||
{
|
||||
DWORD* off = (DWORD*)&offset_;
|
||||
|
||||
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, off[1], off[0], mapped_bytes_);
|
||||
if (!buf_)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
mapped_bytes_ /= map_unit_;
|
||||
mapped_bytes_ *= map_unit_;
|
||||
while (mapped_bytes_ > map_unit_)
|
||||
{
|
||||
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, off[1], off[0], mapped_bytes_);
|
||||
if (buf_)
|
||||
break;
|
||||
mapped_bytes_ /= 2;
|
||||
}
|
||||
if (!buf_)
|
||||
mapped_bytes_ = 0;
|
||||
}
|
||||
}
|
||||
void mapping_buf::set_buffer(unsigned char*& buf, unsigned long long off, unsigned int* bytes)
|
||||
{
|
||||
buf = buf_ + (off - offset_);
|
||||
if (bytes)
|
||||
*bytes = mapped_bytes_ - (unsigned int)(off - offset_);
|
||||
}
|
||||
|
||||
unsigned char* mapping_buf::allocate(const wchar_t* file, unsigned long long size, bool force_file)
|
||||
{
|
||||
close();
|
||||
|
||||
std::string ansi(local_trans::u2a(file));
|
||||
if (force_file || size >= 100 * 1024 * 1024 || PathFileExistsW(file))
|
||||
{
|
||||
init_map(ansi.c_str(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
buf_ = new unsigned char[(unsigned int)size];
|
||||
is_mem_ = true;
|
||||
bytes_ = size;
|
||||
mapped_bytes_ = (unsigned int)size;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
is_mem_ = false;
|
||||
init_map(ansi.c_str(), size);
|
||||
}
|
||||
}
|
||||
|
||||
return buf_;
|
||||
}
|
||||
unsigned char* mapping_buf::buffer(unsigned long long off, unsigned int* bytes)
|
||||
{
|
||||
unsigned int size = bytes ? *bytes : 1 * 1024 * 1024 * 1024;
|
||||
unsigned char* buf = NULL;
|
||||
|
||||
if (size > bytes_ - offset_)
|
||||
size = (unsigned int)(bytes_ - offset_);
|
||||
|
||||
if (buf_ && off >= offset_ && size + (off - offset_) <= mapped_bytes_)
|
||||
{
|
||||
set_buffer(buf, off, bytes);
|
||||
}
|
||||
else if (!is_mem_)
|
||||
{
|
||||
if (off < bytes_)
|
||||
{
|
||||
if (buf_)
|
||||
UnmapViewOfFile(buf_);
|
||||
|
||||
offset_ = off / map_unit_ * map_unit_;
|
||||
mapped_bytes_ = (unsigned int)(bytes_ - offset_);
|
||||
map();
|
||||
if (buf_)
|
||||
set_buffer(buf, off, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
bool mapping_buf::save(const void* data, size_t* bytes, unsigned long long off)
|
||||
{
|
||||
unsigned int len = *bytes, total = 0;
|
||||
unsigned char* buf = buffer(off, &len);
|
||||
bool ret = false;
|
||||
const char* src = (const char*)data;
|
||||
|
||||
while (buf)
|
||||
{
|
||||
if (len >= *bytes - total)
|
||||
{
|
||||
memcpy(buf, src, *bytes - total);
|
||||
total = *bytes;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
memcpy(buf, src, len);
|
||||
total += len;
|
||||
off += len;
|
||||
src += len;
|
||||
len = *bytes - total;
|
||||
buf = buffer(off, &len);
|
||||
}
|
||||
*bytes = total;
|
||||
|
||||
return ret;
|
||||
}
|
||||
bool mapping_buf::save(unsigned long long off, mapping_buf* mbuf, unsigned long long src_off)
|
||||
{
|
||||
size_t len = (unsigned int)(mbuf->bytes() - src_off);
|
||||
unsigned char* buf = mbuf->buffer(src_off, (unsigned int*)&len);
|
||||
bool ret = false;
|
||||
|
||||
while (buf && save(buf, &len, off))
|
||||
{
|
||||
off += len;
|
||||
src_off += len;
|
||||
if (src_off >= mbuf->bytes())
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
len = (unsigned int)(mbuf->bytes() - src_off);
|
||||
buf = mbuf->buffer(src_off, (unsigned int*)&len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int mapping_buf::read(void* buf, size_t* bytes, unsigned long long off)
|
||||
{
|
||||
if (!bytes)
|
||||
return SCANNER_ERR_INVALID_PARAMETER;
|
||||
|
||||
unsigned int len = *bytes, total = 0;
|
||||
unsigned char *src = buffer(off, &len),
|
||||
*dst = (unsigned char*)buf;
|
||||
int ret = SCANNER_ERR_OUT_OF_RANGE;
|
||||
|
||||
while (src)
|
||||
{
|
||||
if (len >= *bytes - total)
|
||||
{
|
||||
memcpy(dst, src, *bytes - total);
|
||||
total = *bytes;
|
||||
ret = SCANNER_ERR_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(dst, src, len);
|
||||
total += len;
|
||||
off += len;
|
||||
len = *bytes - total;
|
||||
src = buffer(off, &len);
|
||||
}
|
||||
*bytes = total;
|
||||
|
||||
return ret;
|
||||
}
|
||||
void mapping_buf::unmap()
|
||||
{
|
||||
if (!is_mem_)
|
||||
{
|
||||
if (buf_)
|
||||
UnmapViewOfFile(buf_);
|
||||
buf_ = NULL;
|
||||
offset_ = 0;
|
||||
mapped_bytes_ = 0;
|
||||
}
|
||||
}
|
||||
void mapping_buf::set_remove_file_when_destroyed(bool rmv)
|
||||
{
|
||||
rmv_file_ = rmv;
|
||||
}
|
||||
const char* mapping_buf::file(void)
|
||||
{
|
||||
return is_mem_ ? "" : file_.c_str();
|
||||
}
|
||||
unsigned long long mapping_buf::bytes(void)
|
||||
{
|
||||
return bytes_;
|
||||
}
|
||||
unsigned long long mapping_buf::offset(void)
|
||||
{
|
||||
return offset_;
|
||||
}
|
||||
unsigned int mapping_buf::mapped_bytes(void)
|
||||
{
|
||||
return mapped_bytes_;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class scanned_img
|
||||
scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi
|
||||
, const wchar_t* tmp_file, twain_xfer xfer
|
||||
, SANE_FinalImgFormat *fmt) : head_(head), dpi_(dpi), header_size_(0), file_(tmp_file ? tmp_file : L"")
|
||||
, dev_(dev), status_(SANE_Image_Statu_OK)
|
||||
{
|
||||
if (fmt)
|
||||
fmt_ = *fmt;
|
||||
else
|
||||
{
|
||||
fmt_.img_format = SANE_IMAGE_TYPE_BMP;
|
||||
fmt_.detail = 0;
|
||||
}
|
||||
|
||||
size_t bytes = line_bytes() * height();
|
||||
std::string h(file_header(fmt_.img_format, (float)dpi, xfer));
|
||||
unsigned char* dst = NULL;
|
||||
bool ok = false;
|
||||
|
||||
data_ = new mapping_buf();
|
||||
header_size_ = h.length();
|
||||
dst = data_->allocate(tmp_file, bytes + h.length());
|
||||
if (dst)
|
||||
{
|
||||
unsigned long long off = 0, total = 0;
|
||||
bytes = h.length();
|
||||
if (data_->save(h.c_str(), &bytes, off))
|
||||
{
|
||||
unsigned int len = line_bytes();
|
||||
unsigned long long line = line_bytes();
|
||||
|
||||
if (xfer == TWAIN_XFER_Memory)
|
||||
line *= -1;
|
||||
else
|
||||
off = data_->bytes() - line;
|
||||
dst = data_->buffer(off, &len);
|
||||
|
||||
int want_to_read = head_.bytes_per_line, rcv = 0, dif = line_bytes() - head_.bytes_per_line;
|
||||
while (dst)
|
||||
{
|
||||
int r = want_to_read > (int)(len) - rcv ? (int)(len)- rcv : want_to_read;
|
||||
int ret = hg_sane_middleware::instance()->read(dev, dst + rcv, &r);
|
||||
total += r;
|
||||
if (ret != SANE_STATUS_GOOD)
|
||||
break;
|
||||
|
||||
want_to_read -= r;
|
||||
rcv += r;
|
||||
if (want_to_read == 0)
|
||||
{
|
||||
want_to_read = head_.bytes_per_line;
|
||||
off -= line;
|
||||
len = line_bytes();
|
||||
rcv = 0;
|
||||
dst = data_->buffer(off, &len);
|
||||
total += dif;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = want_to_read;
|
||||
dst = data_->buffer(off + rcv, &len);
|
||||
}
|
||||
}
|
||||
ok = total + h.length() + dif == data_->bytes();
|
||||
}
|
||||
}
|
||||
do_result(ok, xfer);
|
||||
}
|
||||
scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
|
||||
, twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0)
|
||||
, file_(tmp_file ? tmp_file : L""), dev_(dev), status_(SANE_Image_Statu_OK)
|
||||
{
|
||||
if (fmt)
|
||||
fmt_ = *fmt;
|
||||
else
|
||||
{
|
||||
fmt_.img_format = SANE_IMAGE_TYPE_BMP;
|
||||
fmt_.detail = 0;
|
||||
}
|
||||
|
||||
size_t bytes = line_bytes() * head.lines;
|
||||
std::string h(file_header(fmt_.img_format, (float)dpi, xfer));
|
||||
unsigned char* dst = NULL, *src = (unsigned char*)data;
|
||||
bool ok = false;
|
||||
|
||||
header_size_ = h.length();
|
||||
data_ = new mapping_buf();
|
||||
bytes += header_size_;
|
||||
dst = data_->allocate(tmp_file, bytes);
|
||||
bytes = h.length();
|
||||
if (dst && data_->save(h.c_str(), &bytes, 0))
|
||||
{
|
||||
unsigned long long off = bytes, line_l = line_bytes();
|
||||
unsigned int buf_len = line_bytes(), row = 0;
|
||||
if (xfer == TWAIN_XFER_Memory)
|
||||
line_l *= -1;
|
||||
else
|
||||
off = data_->bytes() - line_l;
|
||||
for (; row < (unsigned int)head.lines; ++row)
|
||||
{
|
||||
bytes = head.bytes_per_line;
|
||||
if (!data_->save(src, &bytes, off))
|
||||
break;
|
||||
off -= line_l;
|
||||
src += head.bytes_per_line;
|
||||
}
|
||||
ok = row == head.lines;
|
||||
}
|
||||
do_result(ok, xfer);
|
||||
}
|
||||
scanned_img::~scanned_img()
|
||||
{
|
||||
if (data_)
|
||||
delete data_;
|
||||
}
|
||||
|
||||
void scanned_img::set_image_status(SANE_Image_Statu status)
|
||||
{
|
||||
status_ = status;
|
||||
}
|
||||
|
||||
std::string scanned_img::file_header(SANE_ImageType type, float resolution, twain_xfer xfer)
|
||||
{
|
||||
std::string h("");
|
||||
|
||||
if (type == SANE_IMAGE_TYPE_BMP && xfer != TWAIN_XFER_Memory)
|
||||
{
|
||||
BITMAPINFOHEADER bih = { 0 };
|
||||
int pal_size = 0;
|
||||
|
||||
bih.biSize = sizeof(bih);
|
||||
bih.biWidth = width();
|
||||
bih.biBitCount = depth();
|
||||
bih.biSizeImage = line_bytes() * height();
|
||||
bih.biPlanes = 1;
|
||||
bih.biHeight = height();
|
||||
bih.biCompression = BI_RGB;
|
||||
bih.biXPelsPerMeter = bih.biYPelsPerMeter = (LONG)(resolution * 39.37f + .5f);
|
||||
|
||||
if (bih.biBitCount == 1)
|
||||
pal_size = 2 * sizeof(int);
|
||||
else if (bih.biBitCount == 8)
|
||||
pal_size = 256 * sizeof(int);
|
||||
|
||||
if (xfer == TWAIN_XFER_File)
|
||||
{
|
||||
BITMAPFILEHEADER fh = { 0 };
|
||||
fh.bfType = MAKEWORD('B', 'M');
|
||||
fh.bfSize = sizeof(fh) + bih.biSizeImage + sizeof(bih) + pal_size;
|
||||
fh.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size;
|
||||
|
||||
h = std::string((char*)&fh, sizeof(fh));
|
||||
}
|
||||
|
||||
h += std::string((char*)&bih, sizeof(bih));
|
||||
if (bih.biBitCount == 1)
|
||||
{
|
||||
int pal[] = { 0, 0x0ffffff };
|
||||
h += std::string((char*)pal, pal_size);
|
||||
}
|
||||
else if (bih.biBitCount == 8)
|
||||
{
|
||||
static unsigned int g_bmp8_pallete[256] = { 0 };
|
||||
if (g_bmp8_pallete[1] == 0)
|
||||
{
|
||||
for (int i = 1; i < _countof(g_bmp8_pallete); ++i)
|
||||
g_bmp8_pallete[i] = MAKELONG(MAKEWORD(i, i), MAKEWORD(i, 0));
|
||||
}
|
||||
h += std::string((char*)g_bmp8_pallete, pal_size);
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
void scanned_img::do_result(bool ok, twain_xfer xfer)
|
||||
{
|
||||
if (ok)
|
||||
{
|
||||
if (fmt_.img_format == SANE_IMAGE_TYPE_BMP &&
|
||||
fmt_.compress.compression == SANE_COMPRESSION_GROUP4 &&
|
||||
xfer == TWAIN_XFER_Memory)
|
||||
{
|
||||
// convert to black-white ...
|
||||
std::string head(file_header(SANE_IMAGE_TYPE_BMP, (float)dpi_, TWAIN_XFER_File));
|
||||
size_t size = head.length();
|
||||
mapping_buf* buf = new mapping_buf();
|
||||
std::wstring file(file_ + L".tmp");
|
||||
unsigned long long off = 0;
|
||||
|
||||
if (buf->allocate(file.c_str(), size + data_->bytes(), true) &&
|
||||
buf->save(head.c_str(), &size, off))
|
||||
{
|
||||
if (buf->save(size, data_))
|
||||
{
|
||||
SANE_ImageFormatConvert conv;
|
||||
std::string sf(local_trans::u2a(file.c_str()));
|
||||
|
||||
buf->unmap();
|
||||
conv.src.data = sf.c_str();
|
||||
conv.src.data_len = sf.length();
|
||||
conv.src.fmt.img_format = SANE_IMAGE_TYPE_BMP;
|
||||
conv.src.fmt.compress.compression = SANE_COMPRESSION_NONE;
|
||||
conv.src.is_file = SANE_TRUE;
|
||||
|
||||
conv.dst.data = NULL;
|
||||
conv.dst.data_len = 0;
|
||||
conv.dst.fmt.img_format = SANE_IMAGE_TYPE_BMP;
|
||||
conv.dst.fmt.compress.compression = SANE_COMPRESSION_GROUP4;
|
||||
conv.dst.fmt.compress.detail = NULL;
|
||||
conv.dst.is_file = false;
|
||||
if (hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, &conv, NULL) == SANE_STATUS_GOOD)
|
||||
{
|
||||
delete data_;
|
||||
data_ = new mapping_buf();
|
||||
size = conv.dst.data_len;
|
||||
data_->allocate(file_.c_str(), conv.dst.data_len);
|
||||
data_->save(conv.dst.data, &size, 0);
|
||||
hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_FREE_MEMORY, (void*)conv.dst.data, &conv.dst.data_len);
|
||||
head_.format = SANE_FRAME_GRAY;
|
||||
head_.depth = 1;
|
||||
head_.bytes_per_line = (head_.pixels_per_line + 7) / 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf)
|
||||
delete buf;
|
||||
}
|
||||
else if (fmt_.img_format == SANE_IMAGE_TYPE_BMP
|
||||
&& channel() == 3
|
||||
&& xfer != TWAIN_XFER_Memory)
|
||||
{
|
||||
// swap RGB
|
||||
swap_rgb();
|
||||
}
|
||||
data_->unmap();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete data_;
|
||||
data_ = NULL;
|
||||
header_size_ = 0;
|
||||
}
|
||||
}
|
||||
void scanned_img::swap_rgb(void)
|
||||
{
|
||||
unsigned long long off = 0;
|
||||
unsigned int line = line_bytes(), len = line;
|
||||
unsigned char* dst = NULL;
|
||||
|
||||
for (int i = 0; i < height(); ++i)
|
||||
{
|
||||
int l = head_.bytes_per_line, cur = 0;
|
||||
|
||||
off = i * line + header_size_;
|
||||
while (l > 0)
|
||||
{
|
||||
len = l;
|
||||
dst = data_->buffer(off + cur, &len);
|
||||
if (!dst)
|
||||
break;
|
||||
if (len > (unsigned int)l)
|
||||
len = l;
|
||||
len /= 3;
|
||||
for (int pos = 0; pos < (int)len; ++pos)
|
||||
{
|
||||
unsigned char uc = dst[pos * 3 + 0];
|
||||
dst[pos * 3 + 0] = dst[pos * 3 + 2];
|
||||
dst[pos * 3 + 2] = uc;
|
||||
}
|
||||
l -= len * 3;
|
||||
cur += len * 3;
|
||||
}
|
||||
if (!dst)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IRef
|
||||
COM_API_IMPLEMENT(scanned_img, long, add_ref(void))
|
||||
{
|
||||
return refer::add_ref();
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, long, release(void))
|
||||
{
|
||||
return refer::release();
|
||||
}
|
||||
|
||||
// IScanImg
|
||||
COM_API_IMPLEMENT(scanned_img, int, width(void))
|
||||
{
|
||||
return head_.pixels_per_line;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, line_bytes(void))
|
||||
{
|
||||
if (fmt_.img_format == SANE_IMAGE_TYPE_BMP && head_.depth >= 8)
|
||||
return (head_.bytes_per_line + 3) / 4 * 4;
|
||||
else
|
||||
return head_.bytes_per_line;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, height(void))
|
||||
{
|
||||
return head_.lines;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, depth(void))
|
||||
{
|
||||
if (head_.format == SANE_FRAME_RGB)
|
||||
return head_.depth * 3;
|
||||
else
|
||||
return head_.depth;
|
||||
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, channel(void))
|
||||
{
|
||||
return head_.format == SANE_FRAME_RGB ? 3 : 1;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, dpi(void))
|
||||
{
|
||||
return dpi_;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, SANE_Frame, type(void))
|
||||
{
|
||||
return head_.format;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, unsigned int, bytes(void))
|
||||
{
|
||||
return data_ ? (unsigned int)data_->bytes() : 0;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, unsigned int, header_size(void))
|
||||
{
|
||||
return header_size_;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, unsigned char*, data(unsigned long long off, unsigned int* bytes))
|
||||
{
|
||||
return data_ ? data_->buffer(off, bytes) : NULL;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, read(void* buf, size_t* bytes, unsigned long long off))
|
||||
{
|
||||
return data_ ? data_->read(buf, bytes, off) : SCANNER_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
COM_API_IMPLEMENT(scanned_img, const char*, file(void))
|
||||
{
|
||||
if (data_)
|
||||
return data_->file();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, void, keep_file(bool keep))
|
||||
{
|
||||
if (data_)
|
||||
data_->set_remove_file_when_destroyed(!keep);
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, void, copy_header(SANE_Parameters* head))
|
||||
{
|
||||
*head = head_;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanned_img, int, image_status(void))
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class safe_img_queue
|
||||
safe_img_queue::safe_img_queue()
|
||||
{}
|
||||
safe_img_queue::~safe_img_queue()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void __stdcall safe_img_queue::access_image(scanned_img* img)
|
||||
{
|
||||
img->add_ref();
|
||||
}
|
||||
void __stdcall safe_img_queue::free_image(scanned_img* img)
|
||||
{
|
||||
img->release();
|
||||
}
|
||||
|
||||
bool safe_img_queue::get_header(SANE_Parameters* header, size_t* bytes, int* dpi)
|
||||
{
|
||||
scanned_img *img = take(false, &safe_img_queue::access_image);
|
||||
bool ok = false;
|
||||
|
||||
if (bytes)
|
||||
*bytes = 0;
|
||||
if (img)
|
||||
{
|
||||
if(header)
|
||||
img->copy_header(header);
|
||||
if(bytes)
|
||||
*bytes = img->bytes();
|
||||
if (dpi)
|
||||
*dpi = img->dpi();
|
||||
ok = true;
|
||||
img->release();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
void safe_img_queue::clear()
|
||||
{
|
||||
safe_queue<scanned_img*>::clear(&safe_img_queue::free_image);
|
||||
}
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
#pragma once
|
||||
#include "s2t_api.h"
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
class refer : public IRef
|
||||
{
|
||||
volatile long ref_;
|
||||
|
||||
protected:
|
||||
refer();
|
||||
virtual ~refer();
|
||||
|
||||
// IRef
|
||||
public:
|
||||
COM_API_OVERRIDE(long, add_ref(void));
|
||||
COM_API_OVERRIDE(long, release(void));
|
||||
};
|
||||
|
||||
class mapping_buf
|
||||
{
|
||||
unsigned long long bytes_;
|
||||
unsigned long long offset_;
|
||||
unsigned int page_size_;
|
||||
unsigned int map_unit_;
|
||||
unsigned int mapped_bytes_;
|
||||
HANDLE map_;
|
||||
bool is_mem_;
|
||||
unsigned char* buf_;
|
||||
std::string file_;
|
||||
bool rmv_file_;
|
||||
|
||||
void init_map(const char* file, unsigned long long size);
|
||||
void close(void);
|
||||
void map(void);
|
||||
void set_buffer(unsigned char*& buf, unsigned long long off, unsigned int* bytes);
|
||||
|
||||
public:
|
||||
mapping_buf();
|
||||
~mapping_buf();
|
||||
|
||||
public:
|
||||
unsigned char* allocate(const wchar_t* file, unsigned long long size = 0, bool force_file = false);
|
||||
unsigned char* buffer(unsigned long long off, unsigned int* bytes);
|
||||
bool save(const void* data, size_t* bytes, unsigned long long off);
|
||||
bool save(unsigned long long off, mapping_buf* mbuf, unsigned long long src_off = 0);
|
||||
int read(void* buf, size_t* bytes, unsigned long long off);
|
||||
void unmap();
|
||||
void set_remove_file_when_destroyed(bool rmv);
|
||||
const char* file(void);
|
||||
unsigned long long bytes(void);
|
||||
unsigned long long offset(void);
|
||||
unsigned int mapped_bytes(void);
|
||||
};
|
||||
class scanned_img : public IScanImg, virtual public refer
|
||||
{
|
||||
SANE_Parameters head_;
|
||||
mapping_buf* data_;
|
||||
int dpi_;
|
||||
SANE_Handle dev_;
|
||||
std::wstring file_;
|
||||
unsigned int header_size_;
|
||||
SANE_FinalImgFormat fmt_;
|
||||
|
||||
SANE_Image_Statu status_;
|
||||
|
||||
std::string file_header(SANE_ImageType type, float resolution, twain_xfer xfer);
|
||||
void do_result(bool ok, twain_xfer xfer);
|
||||
void swap_rgb(void);
|
||||
|
||||
public:
|
||||
scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi, const wchar_t* tmp_file
|
||||
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
|
||||
scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
|
||||
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
|
||||
|
||||
void set_image_status(SANE_Image_Statu status);
|
||||
|
||||
protected:
|
||||
~scanned_img();
|
||||
|
||||
// IRef
|
||||
public:
|
||||
COM_API_OVERRIDE(long, add_ref(void));
|
||||
COM_API_OVERRIDE(long, release(void));
|
||||
|
||||
// IScanImg
|
||||
public:
|
||||
COM_API_OVERRIDE(int, width(void));
|
||||
COM_API_OVERRIDE(int, line_bytes(void));
|
||||
COM_API_OVERRIDE(int, height(void));
|
||||
COM_API_OVERRIDE(int, depth(void));
|
||||
COM_API_OVERRIDE(int, channel(void));
|
||||
COM_API_OVERRIDE(int, dpi(void));
|
||||
COM_API_OVERRIDE(SANE_Frame, type(void));
|
||||
COM_API_OVERRIDE(unsigned int, bytes(void));
|
||||
COM_API_OVERRIDE(unsigned int, header_size(void));
|
||||
COM_API_OVERRIDE(unsigned char*, data(unsigned long long off, unsigned int* bytes));
|
||||
COM_API_OVERRIDE(int, read(void* buf, size_t* bytes, unsigned long long off = 0));
|
||||
COM_API_OVERRIDE(const char*, file(void));
|
||||
COM_API_OVERRIDE(void, keep_file(bool keep));
|
||||
COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head));
|
||||
COM_API_OVERRIDE(int, image_status(void));
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class safe_queue
|
||||
{
|
||||
typedef struct _t_and_size
|
||||
{
|
||||
size_t bytes;
|
||||
T t;
|
||||
}TNS;
|
||||
std::mutex lock_;
|
||||
std::vector<TNS> queue_;
|
||||
size_t bytes_;
|
||||
T empty_;
|
||||
|
||||
public:
|
||||
safe_queue() : bytes_(0)
|
||||
{}
|
||||
virtual ~safe_queue()
|
||||
{}
|
||||
|
||||
public:
|
||||
size_t count(size_t* bytes = NULL)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
if (bytes)
|
||||
*bytes = bytes_;
|
||||
|
||||
return queue_.size();
|
||||
}
|
||||
bool save(T v, size_t bytes)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
TNS tns = { bytes, v };
|
||||
|
||||
queue_.push_back(tns);
|
||||
bytes_ += bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
T take(bool remove = true, void(__stdcall* first)(T) = NULL)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
TNS t;
|
||||
|
||||
if (queue_.size())
|
||||
{
|
||||
t = queue_[0];
|
||||
if (remove)
|
||||
{
|
||||
queue_.erase(queue_.begin());
|
||||
bytes_ -= t.bytes;
|
||||
}
|
||||
if (first)
|
||||
first(t.t);
|
||||
}
|
||||
else
|
||||
t.t = empty_;
|
||||
|
||||
return t.t;
|
||||
}
|
||||
void clear(void(__stdcall* tfree)(T) = NULL)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
if (tfree)
|
||||
{
|
||||
for (auto& v : queue_)
|
||||
tfree(v.t);
|
||||
}
|
||||
queue_.clear();
|
||||
bytes_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class safe_img_queue : public safe_queue<scanned_img*>
|
||||
{
|
||||
static void __stdcall access_image(scanned_img* img);
|
||||
static void __stdcall free_image(scanned_img* img);
|
||||
|
||||
public:
|
||||
safe_img_queue();
|
||||
~safe_img_queue();
|
||||
|
||||
public:
|
||||
bool get_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL);
|
||||
void clear();
|
||||
};
|
||||
|
||||
namespace local_trans
|
||||
{
|
||||
std::string u2a(const wchar_t* unic, UINT cp = CP_ACP);
|
||||
std::wstring a2u(const char* asc, UINT cp = CP_ACP);
|
||||
|
||||
std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz = true);
|
||||
const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param);
|
||||
}
|
3239
sane/scanner.cpp
3239
sane/scanner.cpp
File diff suppressed because it is too large
Load Diff
330
sane/scanner.h
330
sane/scanner.h
|
@ -1,330 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "scanned_img.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#define SANE_OPTION_ID(name) \
|
||||
SANE_OPTION_ID_OVERRIDE(name); \
|
||||
int name##_id_ = -1;
|
||||
#define SANE_OPTION_ID_IMPLEMENT(name) \
|
||||
SANE_OPTION_IMPLEMENT(scanner, name) \
|
||||
{ \
|
||||
return name##_id_; \
|
||||
}
|
||||
|
||||
#define EX_HANDLER_PROTO(name) \
|
||||
int name(int base_id, void* data, set_opt_value setv)
|
||||
#define EX_OPTION_HANDLER_DECL(name) EX_HANDLER_PROTO(handle_ex_##name)
|
||||
#define EX_OPTION_HANDLER_IMPL(name) EX_HANDLER_PROTO(scanner::handle_ex_##name)
|
||||
|
||||
#define EXTENSION_ID_BASE 0x300
|
||||
|
||||
#include "DlgPage.h"
|
||||
class dlg_indicator;
|
||||
class dlg_setting;
|
||||
namespace gb
|
||||
{
|
||||
class scanner_cfg;
|
||||
}
|
||||
|
||||
class scanner : public ISaneInvoker, virtual public refer
|
||||
{
|
||||
SANE_Handle handle_;
|
||||
SCANNERID id_;
|
||||
int err_;
|
||||
int ex_id_;
|
||||
int prev_start_result_;
|
||||
int dpi_;
|
||||
unsigned int img_ind_;
|
||||
std::wstring scanner_name_;
|
||||
std::wstring tmp_path_;
|
||||
std::wstring cfg_path_;
|
||||
std::string scan_msg_;
|
||||
bool scan_err_;
|
||||
volatile bool is_ui_wait_img_;
|
||||
volatile bool is_scanning_;
|
||||
volatile bool user_cancel_;
|
||||
twain_xfer xfer_;
|
||||
safe_img_queue images_;
|
||||
size_t max_img_mem_;
|
||||
safe_queue<int> events_; //如果有界面,则全部保存从界面传回的消息;否则只保存开始扫描和结束扫描的事件
|
||||
int ev_cnt_;
|
||||
SANE_FinalImgFormat img_fmt_;
|
||||
std::unique_ptr<dlg_indicator> indicator_;
|
||||
std::unique_ptr<dlg_setting> setting_;
|
||||
gb::scanner_cfg* cfg_;
|
||||
bool twain_set_;
|
||||
SANEAPI sane_api_;
|
||||
|
||||
int(__stdcall* scanner_ev_handler_)(int, void*);
|
||||
void* evh_param_;
|
||||
HWND app_wnd_; // for MessageBox
|
||||
|
||||
void transport_config_file(void);
|
||||
void update_config(void);
|
||||
void load_config(const wchar_t* file);
|
||||
void save_config(const wchar_t* file);
|
||||
void apply_config(void);
|
||||
void on_ui_event(int uev, void* sender);
|
||||
std::string choose_scanner(const std::vector<std::string>& scanners);
|
||||
int open(void);
|
||||
int close(void);
|
||||
int init_options_id(void);
|
||||
int control_read_string(int code, std::string& ret);
|
||||
|
||||
void extension_none(int id);
|
||||
void extension_multiout_type(int id);
|
||||
void extension_color_mode(int id);
|
||||
void extension_sharpen(int id);
|
||||
void extension_paper(int id);
|
||||
void extension_fill_bkg_method(int id);
|
||||
void extension_text_direction(int id);
|
||||
void extension_page(int id);
|
||||
void extension_erase_color(int id);
|
||||
|
||||
bool get_option_value_with_parent(int sn, set_opt_value setv, void* param); // return true if handled
|
||||
bool set_option_value_with_parent(int sn, void* data, int* err); // return true if handled sn
|
||||
int set_option_value(int sn, SANE_Value_Type type, int size, void* data);
|
||||
int set_is_multiout(bool enable);
|
||||
|
||||
typedef struct _ex_api
|
||||
{
|
||||
unsigned int ind;
|
||||
unsigned int base_ind;
|
||||
int(scanner::* ex_api)(int, void*, set_opt_value);
|
||||
bool operator==(const int& id)
|
||||
{
|
||||
return ind == id;
|
||||
}
|
||||
}EXAPI;
|
||||
std::vector<EXAPI> ex_opts_;
|
||||
typedef std::vector<EXAPI>::iterator EXAPIPOS;
|
||||
EXAPIPOS find_ex_api(int op_id);
|
||||
void apply_scheme(gb::sane_config_schm* schm);
|
||||
;
|
||||
EX_OPTION_HANDLER_DECL(multiout);
|
||||
EX_OPTION_HANDLER_DECL(auto_color_type);
|
||||
EX_OPTION_HANDLER_DECL(color_mode);
|
||||
EX_OPTION_HANDLER_DECL(sharpen); // int
|
||||
EX_OPTION_HANDLER_DECL(paper);
|
||||
EX_OPTION_HANDLER_DECL(paper_lateral);
|
||||
EX_OPTION_HANDLER_DECL(auto_paper_size);
|
||||
EX_OPTION_HANDLER_DECL(auto_paper_crop);
|
||||
EX_OPTION_HANDLER_DECL(text_direction);
|
||||
EX_OPTION_HANDLER_DECL(duplex);
|
||||
EX_OPTION_HANDLER_DECL(fill_background); // bool true - 凸多边形
|
||||
EX_OPTION_HANDLER_DECL(discard_blank_page);
|
||||
EX_OPTION_HANDLER_DECL(discard_blank_receipt);
|
||||
EX_OPTION_HANDLER_DECL(page_fold);
|
||||
EX_OPTION_HANDLER_DECL(color_filter);
|
||||
EX_OPTION_HANDLER_DECL(color_enhance);
|
||||
|
||||
EX_OPTION_HANDLER_DECL(final_compression); // int
|
||||
EX_OPTION_HANDLER_DECL(final_format); // SANE_FinalImgFormat
|
||||
EX_OPTION_HANDLER_DECL(serial); // std::string
|
||||
EX_OPTION_HANDLER_DECL(to_be_scan); // bool
|
||||
EX_OPTION_HANDLER_DECL(scan_with_hole); // bool
|
||||
EX_OPTION_HANDLER_DECL(device_code); // std::string
|
||||
EX_OPTION_HANDLER_DECL(power); // int
|
||||
EX_OPTION_HANDLER_DECL(hardware_version); // std::string
|
||||
EX_OPTION_HANDLER_DECL(ip); // std::string
|
||||
EX_OPTION_HANDLER_DECL(erase_hole);
|
||||
EX_OPTION_HANDLER_DECL(search_hole_range);
|
||||
|
||||
|
||||
template<class T>
|
||||
bool set_cur_and_def_value(T cur, T def, set_opt_value setv, void* param)
|
||||
{
|
||||
if (cur == def)
|
||||
return setv(&cur, (value_role)(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param);
|
||||
else if (setv(&cur, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param))
|
||||
return setv(&def, VAL_ROLE_DEFAULT, VAL_LIMIT_NONE, param);
|
||||
|
||||
return false;
|
||||
}
|
||||
template<class S, class T>
|
||||
void set_value_range(S cur, S def, S l, S u, S s, set_opt_value setv, void* param, T(__stdcall* to_t)(S))
|
||||
{
|
||||
T v = to_t(cur);
|
||||
while (setv(&v, VAL_ROLE_CURRENT, VAL_LIMIT_RANGE, param))
|
||||
{
|
||||
v = to_t(def);
|
||||
if (!setv(&v, VAL_ROLE_DEFAULT, VAL_LIMIT_RANGE, param))
|
||||
break;
|
||||
|
||||
v = to_t(l);
|
||||
if (!setv(&v, VAL_ROLE_LOWER, VAL_LIMIT_RANGE, param))
|
||||
break;
|
||||
v = to_t(u);
|
||||
if (!setv(&v, VAL_ROLE_UPPER, VAL_LIMIT_RANGE, param))
|
||||
break;
|
||||
v = to_t(s);
|
||||
setv(&v, VAL_ROLE_STEP, VAL_LIMIT_RANGE, param);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int __stdcall to_int(SANE_Int v);
|
||||
static float __stdcall to_float(SANE_Fixed v);
|
||||
static void __stdcall ui_callback(int uev, void* sender, void* param);
|
||||
static bool is_option_float(int sn, void* param);
|
||||
static void __stdcall apply_scheme(gb::sane_config_schm* schm, void* param);
|
||||
|
||||
public:
|
||||
scanner(SCANNERID id);
|
||||
protected:
|
||||
~scanner();
|
||||
|
||||
public:
|
||||
static bool is_belong_serial(int vid, int pid, SCANNERID serial);
|
||||
static void get_scanner_name(SCANNERID id, std::vector<std::string>& names);
|
||||
static value_type from_sane_type(SANE_Value_Type type);
|
||||
static value_limit from_sane_constraint(SANE_Constraint_Type type);
|
||||
static int control_read_string(SANE_Handle hdev, int code, std::string& str);
|
||||
|
||||
// IRef
|
||||
public:
|
||||
COM_API_OVERRIDE(long, add_ref(void));
|
||||
COM_API_OVERRIDE(long, release(void));
|
||||
|
||||
// ISaneInvoker
|
||||
public:
|
||||
COM_API_OVERRIDE(int, start(void));
|
||||
COM_API_OVERRIDE(int, stop(void));
|
||||
COM_API_OVERRIDE(int, get_event(void));
|
||||
COM_API_OVERRIDE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
|
||||
COM_API_OVERRIDE(bool, wait_image(DWORD milliseconds = -1));
|
||||
COM_API_OVERRIDE(int, get_scanned_images(DWORD milliseconds = 0));
|
||||
COM_API_OVERRIDE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz
|
||||
COM_API_OVERRIDE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = NULL, int* dpi = NULL));
|
||||
COM_API_OVERRIDE(bool, is_online(void));
|
||||
COM_API_OVERRIDE(bool, is_paper_on(void));
|
||||
COM_API_OVERRIDE(int, last_error(void));
|
||||
COM_API_OVERRIDE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes));
|
||||
COM_API_OVERRIDE(bool, get_value(int sn, set_opt_value, void* param));
|
||||
COM_API_OVERRIDE(int, set_value(int sn, void* val));
|
||||
COM_API_OVERRIDE(int, convert_image(SANE_ImageFormatConvert* conv));
|
||||
COM_API_OVERRIDE(void, free_buffer(void* buf, int len));
|
||||
|
||||
// SANE options ID ...
|
||||
SANE_OPTION_ID(color_correction); // 2023-02-24 15:31:19 色偏校正
|
||||
SANE_OPTION_ID(fold_type); // 2023-02-24 15:28:46 对折模式
|
||||
SANE_OPTION_ID(is_multiout);
|
||||
SANE_OPTION_ID(multiout_type);
|
||||
SANE_OPTION_ID(color_mode);
|
||||
SANE_OPTION_ID(erase_color);
|
||||
SANE_OPTION_ID(erase_multiout_red);
|
||||
SANE_OPTION_ID(erase_paper_red);
|
||||
SANE_OPTION_ID(is_erase_background);
|
||||
SANE_OPTION_ID(background_color_range);
|
||||
SANE_OPTION_ID(sharpen);
|
||||
SANE_OPTION_ID(erase_morr);
|
||||
SANE_OPTION_ID(erase_grids); // 除网纹
|
||||
SANE_OPTION_ID(error_extend);
|
||||
SANE_OPTION_ID(is_noise_modify);
|
||||
SANE_OPTION_ID(noise_threshold);
|
||||
SANE_OPTION_ID(paper);
|
||||
SANE_OPTION_ID(is_custom_area);
|
||||
SANE_OPTION_ID(curstom_area_l);
|
||||
SANE_OPTION_ID(curstom_area_r);
|
||||
SANE_OPTION_ID(curstom_area_t);
|
||||
SANE_OPTION_ID(curstom_area_b);
|
||||
SANE_OPTION_ID(is_size_check);
|
||||
SANE_OPTION_ID(page);
|
||||
SANE_OPTION_ID(blank_page_threshold); // 跳过空白页灵敏度
|
||||
SANE_OPTION_ID(resolution);
|
||||
SANE_OPTION_ID(image_quality);
|
||||
SANE_OPTION_ID(is_swap); // 交换正反面
|
||||
SANE_OPTION_ID(is_split); // 图像拆分
|
||||
SANE_OPTION_ID(is_auto_deskew); // 自动纠偏
|
||||
SANE_OPTION_ID(is_custom_gamma);
|
||||
SANE_OPTION_ID(bright);
|
||||
SANE_OPTION_ID(contrast);
|
||||
SANE_OPTION_ID(gamma);
|
||||
SANE_OPTION_ID(is_erase_black_frame); // bool
|
||||
SANE_OPTION_ID(deep_sample);
|
||||
SANE_OPTION_ID(threshold);
|
||||
SANE_OPTION_ID(anti_noise); // 抗噪等级
|
||||
SANE_OPTION_ID(margin);
|
||||
SANE_OPTION_ID(fill_background);
|
||||
SANE_OPTION_ID(is_anti_permeate);
|
||||
SANE_OPTION_ID(anti_permeate_level);
|
||||
SANE_OPTION_ID(is_erase_hole);
|
||||
SANE_OPTION_ID(search_hole_range);
|
||||
SANE_OPTION_ID(is_filling_color); // 色彩填充
|
||||
SANE_OPTION_ID(is_ultrasonic_check);
|
||||
SANE_OPTION_ID(is_check_staple);
|
||||
SANE_OPTION_ID(scan_mode); // 扫描张数
|
||||
SANE_OPTION_ID(scan_count); // 扫描数量
|
||||
SANE_OPTION_ID(text_direction);
|
||||
SANE_OPTION_ID(is_rotate_bkg180);
|
||||
SANE_OPTION_ID(is_check_dogear);
|
||||
SANE_OPTION_ID(dogear_size);
|
||||
SANE_OPTION_ID(is_check_skew);
|
||||
SANE_OPTION_ID(skew_range);
|
||||
SANE_OPTION_ID(black_white_threshold); // 二值化图像阈值
|
||||
SANE_OPTION_ID(is_photo_mode); // 照片模式
|
||||
SANE_OPTION_ID(double_feed_handle); // 双张图片处理
|
||||
SANE_OPTION_ID(scan_when_paper_on); // 待纸扫描
|
||||
SANE_OPTION_ID(feed_strength); // 分纸强度
|
||||
SANE_OPTION_ID(power_scheme); // 休眠时间
|
||||
SANE_OPTION_ID(is_auto_strength); // 自动搓纸强度
|
||||
SANE_OPTION_ID(feed_strength_value); // 自动搓纸强度设定值
|
||||
SANE_OPTION_ID(is_reverse_bw); // 黑白图像反色输出
|
||||
SANE_OPTION_ID(is_erase_hole_l); // 穿孔移除 - 左
|
||||
SANE_OPTION_ID(search_hole_range_l); // 穿孔搜索范围 - 左
|
||||
SANE_OPTION_ID(is_erase_hole_r); // 穿孔移除 - 右
|
||||
SANE_OPTION_ID(search_hole_range_r); // 穿孔搜索范围 - 右
|
||||
SANE_OPTION_ID(is_erase_hole_t); // 穿孔移除 - 上
|
||||
SANE_OPTION_ID(search_hole_range_t); // 穿孔搜索范围 - 上
|
||||
SANE_OPTION_ID(is_erase_hole_b); // 穿孔移除 - 下
|
||||
SANE_OPTION_ID(search_hole_range_b); // 穿孔搜索范围 - 下
|
||||
SANE_OPTION_ID(fold_direction); // 对折模式
|
||||
|
||||
// SANE-ex option ID:
|
||||
SANE_OPTION_ID(ex_multiout_type); // int
|
||||
SANE_OPTION_ID(ex_auto_color_type); // int
|
||||
SANE_OPTION_ID(ex_color_mode); // int
|
||||
SANE_OPTION_ID(ex_sharpen); // int
|
||||
SANE_OPTION_ID(ex_paper); // paper_value
|
||||
SANE_OPTION_ID(ex_paper_lateral); // bool
|
||||
SANE_OPTION_ID(ex_auto_paper_size); // bool
|
||||
SANE_OPTION_ID(ex_is_paper_auto_crop); // bool
|
||||
SANE_OPTION_ID(ex_text_direction); // float 90, 180, ..., -1 is auto-text-direction
|
||||
SANE_OPTION_ID(ex_duplex); // bool
|
||||
SANE_OPTION_ID(ex_fill_background); // bool true - 凸多边形
|
||||
SANE_OPTION_ID(ex_discard_blank_page); // bool
|
||||
SANE_OPTION_ID(ex_discard_blank_receipt); // bool
|
||||
SANE_OPTION_ID(ex_is_page_fold); // bool
|
||||
SANE_OPTION_ID(ex_color_filter); // int (filter_value)
|
||||
SANE_OPTION_ID(ex_color_enhance); // int (enhance_value)
|
||||
SANE_OPTION_ID(ex_final_compression); // int
|
||||
SANE_OPTION_ID(ex_final_format); // SANE_FinalImgFormat
|
||||
SANE_OPTION_ID(ex_serial); // std::string
|
||||
SANE_OPTION_ID(ex_to_be_scan); // bool
|
||||
SANE_OPTION_ID(ex_scan_with_hole); // bool
|
||||
SANE_OPTION_ID(ex_device_code); // std::string
|
||||
SANE_OPTION_ID(ex_power); // int
|
||||
SANE_OPTION_ID(ex_hardware_version); // std::string
|
||||
SANE_OPTION_ID(ex_ip); // std::string
|
||||
|
||||
// ui ...
|
||||
COM_API_OVERRIDE(bool, ui_show_main(HWND parent));
|
||||
COM_API_OVERRIDE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
|
||||
COM_API_OVERRIDE(bool, ui_show_progress(HWND parent));
|
||||
COM_API_OVERRIDE(void, ui_hide(void));
|
||||
COM_API_OVERRIDE(bool, ui_is_ok(void));
|
||||
|
||||
// twain
|
||||
COM_API_OVERRIDE(void, twain_set_transfer(twain_xfer xfer));
|
||||
COM_API_OVERRIDE(void, twain_set_compression(SANE_CompressionType compression, void* detail = NULL));
|
||||
COM_API_OVERRIDE(int, twain_get_config(char* buf, size_t* len));
|
||||
COM_API_OVERRIDE(int, twain_set_config(char* buf, size_t len));
|
||||
|
||||
// methods:
|
||||
public:
|
||||
int handle_device_event(int ev_code, void* data, unsigned int* len);
|
||||
};
|
77
sane/ui.cpp
77
sane/ui.cpp
|
@ -1,77 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "huagaotwain.h" // for sane_invoker::load_dll
|
||||
|
||||
|
||||
twain_ui::twain_ui(const wchar_t* path) : path_(path), dll_(NULL)
|
||||
, show_(NULL), hide_(NULL), event_(NULL), hui_(NULL)
|
||||
, good_(false)
|
||||
{
|
||||
good_ = load();
|
||||
}
|
||||
twain_ui::~twain_ui()
|
||||
{
|
||||
if (hui_ && hide_)
|
||||
hide_(hui_);
|
||||
|
||||
if (dll_)
|
||||
FreeLibrary(dll_);
|
||||
}
|
||||
|
||||
bool twain_ui::load()
|
||||
{
|
||||
std::wstring dll(path_ + L"\\huagaoui.dll");
|
||||
|
||||
sane_invoker::load_dll(dll.c_str(), &dll_);
|
||||
if (!dll_)
|
||||
return false;
|
||||
|
||||
show_ = (ui_show_api)GetProcAddress(dll_, "ui_show");
|
||||
hide_ = (ui_hide_api)GetProcAddress(dll_, "ui_hide");
|
||||
event_ = (handle_event_api)GetProcAddress(dll_, "handle_event");
|
||||
|
||||
return show_ && hide_ && event_;
|
||||
}
|
||||
|
||||
void twain_ui::show_main_ui(LPSANEAPI api)
|
||||
{
|
||||
type_ = UITYPE::UI_MAIN;
|
||||
if (show_)
|
||||
hui_ = show_(UITYPE::UI_MAIN, api);
|
||||
}
|
||||
void twain_ui::show_setting_ui(LPSANEAPI api, bool with_scan)
|
||||
{
|
||||
if (show_)
|
||||
{
|
||||
type_ = with_scan ? UITYPE::UI_SETTING_AND_SCAN : UITYPE::UI_SETTING;
|
||||
hui_ = show_(type_, api);
|
||||
}
|
||||
}
|
||||
void twain_ui::show_progress_ui(LPSANEAPI api)
|
||||
{
|
||||
type_ = UITYPE::UI_PROGRESS;
|
||||
if (show_)
|
||||
hui_ = show_(UITYPE::UI_PROGRESS, api);
|
||||
}
|
||||
void twain_ui::hide_ui(void)
|
||||
{
|
||||
if (hui_ && hide_)
|
||||
hide_(hui_);
|
||||
hui_ = NULL;
|
||||
}
|
||||
void twain_ui::handle_sane_event(int sane_ev, void* data, unsigned int* len)
|
||||
{
|
||||
if (event_)
|
||||
event_((SANE_Event)sane_ev, data, len);
|
||||
}
|
||||
|
||||
bool twain_ui::is_ok(void)
|
||||
{
|
||||
return good_;
|
||||
}
|
||||
|
||||
bool twain_ui::is_progress_ui_showing(void)
|
||||
{
|
||||
return type_ == UITYPE::UI_PROGRESS;
|
||||
}
|
34
sane/ui.h
34
sane/ui.h
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include "huagao/huagao_ui.h"
|
||||
|
||||
|
||||
class twain_ui
|
||||
{
|
||||
HMODULE dll_;
|
||||
ui_show_api show_;
|
||||
ui_hide_api hide_;
|
||||
handle_event_api event_;
|
||||
ui_handle hui_;
|
||||
std::wstring path_;
|
||||
bool good_;
|
||||
UITYPE type_;
|
||||
|
||||
bool load(void);
|
||||
|
||||
public:
|
||||
twain_ui(const wchar_t* path);
|
||||
~twain_ui();
|
||||
|
||||
public:
|
||||
void show_main_ui(LPSANEAPI api);
|
||||
void show_setting_ui(LPSANEAPI api, bool with_scan);
|
||||
void show_progress_ui(LPSANEAPI api);
|
||||
void hide_ui(void);
|
||||
void handle_sane_event(int sane_ev, void* data, unsigned int* len);
|
||||
|
||||
bool is_ok(void);
|
||||
bool is_progress_ui_showing(void);
|
||||
};
|
|
@ -4,10 +4,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
VisualStudioVersion = 16.0.33214.272
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sane", "..\sane\sane.vcxproj", "{6EEC8A02-7F98-4422-8ED6-2434D43BD1E1}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9ED4B425-73E0-423E-9712-455E777481B4} = {9ED4B425-73E0-423E-9712-455E777481B4}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanner", "..\device\scanner.vcxproj", "{9ED4B425-73E0-423E-9712-455E777481B4}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{7776AB6D-6296-4F7A-A6ED-E9A4D6290DD9} = {7776AB6D-6296-4F7A-A6ED-E9A4D6290DD9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twain", "..\twain\twain.vcxproj", "{C3B47CE2-27CE-4509-AB59-3C0F194F0FCE}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6EEC8A02-7F98-4422-8ED6-2434D43BD1E1} = {6EEC8A02-7F98-4422-8ED6-2434D43BD1E1}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "setup", "setup", "{F6774650-403F-476C-8373-2EA8D4AF06FF}"
|
||||
EndProject
|
||||
|
|
|
@ -1,246 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "load_sane.h"
|
||||
#include <string>
|
||||
#include <shellapi.h> // for SHFileOperationW
|
||||
#include "../../sdk/include/huagao/brand.h"
|
||||
|
||||
#pragma comment(lib, "shell32.lib")
|
||||
|
||||
namespace load_sane_util
|
||||
{
|
||||
static std::wstring sane_path(L"");
|
||||
static HMODULE sane_module(NULL);
|
||||
static int (__stdcall* sane_inst)(SCANNERID, ISaneInvoker**) = NULL;
|
||||
static int(__stdcall* is_on)(SCANNERID) = NULL;
|
||||
static int(__stdcall* init)(void*) = NULL;
|
||||
static int(__stdcall* uninit)(void*) = NULL;
|
||||
static void(__stdcall* log)(const wchar_t*, int) = NULL;
|
||||
|
||||
static std::string u2m(const wchar_t* u, int page)
|
||||
{
|
||||
char* ansi = NULL;
|
||||
int len = 0;
|
||||
std::string mb("");
|
||||
|
||||
len = WideCharToMultiByte(page, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
|
||||
ansi = new char[len + 2];
|
||||
len = WideCharToMultiByte(page, 0, u, lstrlenW(u), ansi, len, NULL, NULL);
|
||||
ansi[len--] = 0;
|
||||
mb = ansi;
|
||||
delete[] ansi;
|
||||
|
||||
return mb;
|
||||
}
|
||||
static std::wstring m2u(const char* m, int page)
|
||||
{
|
||||
wchar_t* unic = NULL;
|
||||
int len = 0;
|
||||
std::wstring u(L"");
|
||||
|
||||
len = MultiByteToWideChar(page, 0, m, lstrlenA(m), NULL, 0);
|
||||
unic = new wchar_t[len + 2];
|
||||
len = MultiByteToWideChar(page, 0, m, lstrlenA(m), unic, len);
|
||||
unic[len--] = 0;
|
||||
u = unic;
|
||||
delete[] unic;
|
||||
|
||||
return u;
|
||||
}
|
||||
static std::wstring reg_read(HKEY root, const wchar_t* path, const wchar_t* name)
|
||||
{
|
||||
HKEY key = NULL;
|
||||
|
||||
RegOpenKeyW(root, path, &key);
|
||||
if (!key)
|
||||
return L"";
|
||||
|
||||
wchar_t* buf = NULL;
|
||||
DWORD len = 0;
|
||||
DWORD type = REG_SZ;
|
||||
std::wstring ret(L"");
|
||||
|
||||
RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len);
|
||||
if (len)
|
||||
{
|
||||
buf = new wchar_t[len + 4];
|
||||
memset(buf, 0, (len + 4) * sizeof(*buf));
|
||||
RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len);
|
||||
ret = buf;
|
||||
delete[] buf;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static std::wstring reg_get_app_installing_path(std::wstring* rp = NULL)
|
||||
{
|
||||
std::wstring path(m2u(PRODUCT_VENDOR, CP_ACP)), key(L"DriverPath");
|
||||
|
||||
path.insert(0, L"Software\\");
|
||||
path += L"Scan";
|
||||
|
||||
if (sizeof(void*) != 4)
|
||||
key += L"64";
|
||||
|
||||
if (rp)
|
||||
*rp = path + L"\\" + key;
|
||||
|
||||
return reg_read(HKEY_LOCAL_MACHINE, path.c_str(), key.c_str());
|
||||
}
|
||||
static int load_dll(const wchar_t* path_dll, HMODULE* dll)
|
||||
{
|
||||
HMODULE h = LoadLibraryW(path_dll);
|
||||
int ret = GetLastError();
|
||||
wchar_t info[128] = { 0 };
|
||||
|
||||
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
|
||||
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str());
|
||||
if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT))
|
||||
{
|
||||
std::wstring dir(path_dll);
|
||||
size_t pos = dir.rfind(L'\\');
|
||||
wchar_t path[MAX_PATH] = { 0 };
|
||||
|
||||
GetDllDirectoryW(_countof(path) - 1, path);
|
||||
if (pos != std::wstring::npos)
|
||||
dir.erase(pos);
|
||||
OutputDebugStringW((L"[TWAIN]Load: try change directory to " + dir + L"\r\n").c_str());
|
||||
SetDllDirectoryW(dir.c_str());
|
||||
h = LoadLibraryW(path_dll);
|
||||
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
ret = GetLastError();
|
||||
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
|
||||
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str());
|
||||
OutputDebugStringW((L"[TWAIN]Load: restore directory to " + std::wstring(path) + L"\r\n").c_str());
|
||||
SetDllDirectoryW(path);
|
||||
}
|
||||
|
||||
if (dll)
|
||||
*dll = h;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool initialize(HMODULE me)
|
||||
{
|
||||
std::wstring reg_path(L"");
|
||||
bool ret = false;
|
||||
sane_path = reg_get_app_installing_path(®_path);
|
||||
if (!sane_path.empty())
|
||||
{
|
||||
sane_path += L"\\sane.dll";
|
||||
load_dll(sane_path.c_str(), &sane_module);
|
||||
if (sane_module)
|
||||
{
|
||||
*((FARPROC*)&init) = GetProcAddress(sane_module, "initialize");
|
||||
*((FARPROC*)&sane_inst) = GetProcAddress(sane_module, "open_scanner");
|
||||
*((FARPROC*)&is_on) = GetProcAddress(sane_module, "is_scanner_online");
|
||||
*((FARPROC*)&uninit) = GetProcAddress(sane_module, "uninitialize");
|
||||
*((FARPROC*)&log) = GetProcAddress(sane_module, "log_info");
|
||||
ret = is_ok();
|
||||
if (ret)
|
||||
ret = init(NULL) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
MessageBoxW(NULL, (reg_path + L": " + sane_path).c_str(), L"Load scanner driver failed:", MB_OK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
bool is_ok(void)
|
||||
{
|
||||
wchar_t info[128] = { 0 };
|
||||
swprintf_s(info, _countof(info) - 1, L"[TWAIN]Load: sane_inst: %s, is_on: %s, init: %s, uninit: %s\r\n"
|
||||
, sane_inst != NULL ? "ok" : "not found"
|
||||
, is_on != NULL ? "ok" : "not found"
|
||||
, init != NULL ? "ok" : "not found"
|
||||
, uninit != NULL ? "ok" : "not found");
|
||||
|
||||
return sane_inst != NULL && is_on != NULL && init != NULL && uninit != NULL;
|
||||
}
|
||||
bool is_online(SCANNERID guid)
|
||||
{
|
||||
if (is_on)
|
||||
return is_on(guid);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
ISaneInvoker* open(SCANNERID guid, int* err)
|
||||
{
|
||||
ISaneInvoker* ret = NULL;
|
||||
int code = 0;
|
||||
|
||||
if (!err)
|
||||
err = &code;
|
||||
|
||||
if (sane_inst)
|
||||
*err = sane_inst(guid, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
void uninitialize(void)
|
||||
{
|
||||
sane_inst = NULL;
|
||||
is_on = NULL;
|
||||
init = NULL;
|
||||
log = NULL;
|
||||
|
||||
if (uninit)
|
||||
uninit(NULL);
|
||||
uninit = NULL;
|
||||
|
||||
if (sane_module)
|
||||
{
|
||||
FreeLibrary(sane_module);
|
||||
sane_module = NULL;
|
||||
}
|
||||
sane_path = L"";
|
||||
sane_inst = NULL;
|
||||
}
|
||||
void log_info(const wchar_t* info, int level)
|
||||
{
|
||||
if (log)
|
||||
log(info, level);
|
||||
}
|
||||
|
||||
std::string utf82ansi(const char* utf8)
|
||||
{
|
||||
return u2m(m2u(utf8, CP_UTF8).c_str(), CP_ACP);
|
||||
}
|
||||
std::string ansi2utf8(const char* ansi)
|
||||
{
|
||||
return u2m(m2u(ansi, CP_ACP).c_str(), CP_UTF8);
|
||||
}
|
||||
std::wstring ansi2unic(const char* ansi)
|
||||
{
|
||||
return m2u(ansi, CP_ACP);
|
||||
}
|
||||
|
||||
int move_file(const char* from, const char* to)
|
||||
{
|
||||
return move_file(ansi2unic(from).c_str(), ansi2unic(to).c_str());
|
||||
}
|
||||
int move_file(const wchar_t* from, const wchar_t* to)
|
||||
{
|
||||
SHFILEOPSTRUCTW fo = { 0 };
|
||||
int ret = 0;
|
||||
std::wstring _from(from), _to(to ? to : L"");
|
||||
|
||||
if (wcsicmp(from, to) == 0)
|
||||
return 0;
|
||||
|
||||
_from += std::wstring((wchar_t*)&ret, 2); // ended with double '\0'
|
||||
fo.pFrom = &_from[0];
|
||||
_to += std::wstring((wchar_t*)&ret, 2); // ended with double '\0'
|
||||
fo.pTo = &_to[0];
|
||||
fo.fFlags = FOF_NO_UI | FOF_NO_CONNECTED_ELEMENTS; // 614 | 2000
|
||||
fo.wFunc = FO_MOVE;
|
||||
|
||||
ret = SHFileOperationW(&fo);
|
||||
if (ret == /*DE_SAMEFILE*/0x71)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// utility for loading sane component ...
|
||||
|
||||
#include "../sane/s2t_api.h"
|
||||
#include <string>
|
||||
|
||||
namespace load_sane_util
|
||||
{
|
||||
bool initialize(HMODULE me);
|
||||
bool is_ok(void);
|
||||
bool is_online(SCANNERID guid);
|
||||
ISaneInvoker* open(SCANNERID guid, int* err);
|
||||
void uninitialize(void);
|
||||
void log_info(const wchar_t* info, int level);
|
||||
|
||||
std::string utf82ansi(const char* utf8);
|
||||
std::string ansi2utf8(const char* ansi);
|
||||
std::wstring ansi2unic(const char* ansi);
|
||||
|
||||
int move_file(const char* from, const char* to);
|
||||
int move_file(const wchar_t* from, const wchar_t* to);
|
||||
};
|
||||
|
|
@ -77,32 +77,36 @@
|
|||
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain400.ds</TargetName>
|
||||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain200.ds</TargetName>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain400.ds</TargetName>
|
||||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain200.ds</TargetName>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain400.ds</TargetName>
|
||||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain100.ds</TargetName>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<LibraryPath>$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>huagaotwain400.ds</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -119,16 +123,14 @@
|
|||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>$(ProjectDir)twain.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
<AdditionalDependencies>advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(TargetPath)" C:\Windows\twain_32\HuagoTwain\$(TargetName) /y
|
||||
move /Y "$(TargetPath)" "$(OutputPath)$(TargetName)"
|
||||
mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(OutputPath)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(OutputPath)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
<Command>move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)"
|
||||
copy /y "$(TargetDir)$(TargetName)" "C:\Windows\twain_32\HuaGoTwain"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -147,16 +149,14 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf
|
|||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>$(ProjectDir)twain.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
<AdditionalDependencies>advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(TargetPath)" C:\Windows\twain_64\HuagoTwain\$(TargetName) /y
|
||||
move /Y "$(TargetPath)" "$(OutputPath)$(TargetName)"
|
||||
mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(OutputPath)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(OutputPath)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
|
||||
<Command>move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)"
|
||||
copy /y "$(TargetDir)$(TargetName)" "C:\Windows\twain_64\HuaGoTwain"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -177,12 +177,13 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>$(ProjectDir)twain.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
<AdditionalDependencies>advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -204,16 +205,26 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>$(ProjectDir)twain.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
<AdditionalDependencies>advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
<Command>move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
|
||||
move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\code_device\twain\huagaods.hpp" />
|
||||
<ClInclude Include="..\..\code_device\twain\s2t_api.h" />
|
||||
<ClInclude Include="..\..\code_device\twain\sane_helper.h" />
|
||||
<ClInclude Include="..\..\code_device\twain\sane_option_trans.h" />
|
||||
<ClInclude Include="..\..\code_device\twain\scanned_img.h" />
|
||||
<ClInclude Include="..\..\code_device\twain\scanner.h" />
|
||||
<ClInclude Include="..\..\code_device\twain\utils.h" />
|
||||
<ClInclude Include="..\..\sdk\include\huagao\brand.h" />
|
||||
<ClInclude Include="..\..\sdk\include\twain\twain.h" />
|
||||
<ClInclude Include="..\..\sdk\include\twain\twain_2.4.h" />
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp.hpp" />
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\application.hpp" />
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\audio.hpp" />
|
||||
|
@ -254,27 +265,54 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf
|
|||
<ClInclude Include="..\..\sdk\include\twain\twpp\userinterface.hpp" />
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\utils.hpp" />
|
||||
<ClInclude Include="..\sane\s2t_api.h" />
|
||||
<ClInclude Include="load_sane.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="twain\huagaods.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\code_device\twain\huagaods.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\sane_helper.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\sane_option_trans.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\scanned_img.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\scanner.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\utils.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="load_sane.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="twain\huagaods.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="twain.def" />
|
||||
|
|
|
@ -5,37 +5,49 @@
|
|||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="twain">
|
||||
<UniqueIdentifier>{668e9513-f6db-4f9d-9e0e-76cb8b5b7882}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="twain\twpp">
|
||||
<UniqueIdentifier>{df21031b-938a-4a08-ae64-e869e2586201}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Headers">
|
||||
<UniqueIdentifier>{89716198-13ed-4593-819e-97f4426c7baa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Sources">
|
||||
<UniqueIdentifier>{6d97172d-832d-4c93-ad0e-92fdf76af26b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="imports">
|
||||
<UniqueIdentifier>{d0f46d55-47e2-4b28-98e4-37435c417da3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Headers\twain">
|
||||
<UniqueIdentifier>{ccf8d5b8-eea9-4223-87d3-6edea662380f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Headers\twain\twpp">
|
||||
<UniqueIdentifier>{904bc294-9f58-4953-85d2-8cbd009a978f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="twain\huagaods.cpp">
|
||||
<Filter>twain</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="load_sane.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
<ClCompile Include="..\..\code_device\twain\huagaods.cpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\sane_helper.cpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\sane_option_trans.cpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\scanned_img.cpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\scanner.cpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code_device\twain\utils.cpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="twain\huagaods.hpp">
|
||||
<Filter>twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
|
@ -48,128 +60,152 @@
|
|||
<ClInclude Include="..\sane\s2t_api.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="load_sane.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\huagao\brand.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\application.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\huagaods.hpp">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\audio.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\s2t_api.h">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\capability.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\sane_helper.h">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\cie.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\sane_option_trans.h">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\curveresponse.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\scanned_img.h">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\customdata.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\scanner.h">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\datasource.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\code_device\twain\utils.h">
|
||||
<Filter>imports</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\deviceevent.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twain.h">
|
||||
<Filter>Headers\twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\element8.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\enums.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\env.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\event.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\exception.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\extimageinfo.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\filesystem.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\fix32.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\frame.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\identity.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imageinfo.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imagelayout.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imagememxfer.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imagenativexfer.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\internal.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\jpegcompression.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\memory.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\memoryops.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\palette8.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\passthrough.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\pendingxfers.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\setupfilexfer.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\setupmemxfer.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\status.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\strings.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\twglue.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\types.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\typesops.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\userinterface.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\utils.hpp">
|
||||
<Filter>twain\twpp</Filter>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twain_2.4.h">
|
||||
<Filter>Headers\twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp.hpp">
|
||||
<Filter>twain</Filter>
|
||||
<Filter>Headers\twain</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\application.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\audio.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\capability.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\cie.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\curveresponse.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\customdata.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\datasource.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\deviceevent.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\element8.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\enums.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\env.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\event.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\exception.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\extimageinfo.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\filesystem.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\fix32.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\frame.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\identity.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imageinfo.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imagelayout.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imagememxfer.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\imagenativexfer.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\internal.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\jpegcompression.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\memory.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\memoryops.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\palette8.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\passthrough.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\pendingxfers.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\setupfilexfer.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\setupmemxfer.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\status.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\strings.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\twglue.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\types.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\typesops.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\userinterface.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\sdk\include\twain\twpp\utils.hpp">
|
||||
<Filter>Headers\twain\twpp</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,144 +0,0 @@
|
|||
#ifndef SIMPLEDS_HPP
|
||||
#define SIMPLEDS_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <atlstr.h>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include "twpp.hpp"
|
||||
#include "../load_sane.h"
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct hash<Twpp::CapType> {
|
||||
size_t operator()(Twpp::CapType cap) const {
|
||||
return hash<Twpp::UInt16>()(static_cast<Twpp::UInt16>(cap));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class twain_ui;
|
||||
|
||||
enum scanner_status
|
||||
{
|
||||
SCANNER_STATUS_NOT_INIT = 0, // has not call identityOpenDs or called identityCloseDs
|
||||
SCANNER_STATUS_READY, // called identityOpenDs
|
||||
SCANNER_STATUS_SCAN_1, // scanner_->start() should be called
|
||||
SCANNER_STATUS_SCANNING, // received SANE_EVENT_WORKING
|
||||
SCANNER_STATUS_STOPPED, // received SANE_EVENT_SCAN_FINISHED
|
||||
};
|
||||
class huagao_ds : public Twpp::SourceFromThis<huagao_ds> {
|
||||
std::unordered_map<Twpp::CapType, std::function<Twpp::Result(Twpp::Msg msg, Twpp::Capability& data)>> m_caps;
|
||||
std::unordered_map<Twpp::CapType, Twpp::MsgSupport> m_query;
|
||||
std::unique_ptr <ISaneInvoker, delete_scanner> scanner_;
|
||||
Twpp::SetupFileXfer m_fileXfer;
|
||||
Twpp::XferMech m_capXferMech = Twpp::XferMech::Native;
|
||||
std::unique_ptr<std::thread> memoryinfo;
|
||||
bool m_memoryfalg = true;
|
||||
bool m_bFeederEnabled = true;
|
||||
bool m_bAutoFeed = true;
|
||||
HANDLE singleton_ = NULL;
|
||||
Twpp::Bool m_autoscan = true;
|
||||
int automaticcolortype_ = 0;
|
||||
bool multi_out_ = false;
|
||||
bool m_bIndicator = true;
|
||||
int m_jpegQuality = 80;
|
||||
Twpp::Compression m_compression = Twpp::Compression::None;
|
||||
SANE_Parameters* cur_head_;
|
||||
int dpi_;
|
||||
int scanner_status_;
|
||||
bool xfer_ready_failed_;
|
||||
bool log_all_triple_;
|
||||
bool app_trigger_event_;
|
||||
|
||||
int count_;
|
||||
static std::string get_hidedlg_path(void);
|
||||
static void showmsg(const char* msg, int err);
|
||||
static int __stdcall on_scanner_event(int ev, void* param);
|
||||
|
||||
void CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value = "");
|
||||
Twpp::Result capCommon(const Twpp::Identity& origin, Twpp::Msg msg, Twpp::Capability& data);
|
||||
Twpp::Result showTwainUI(Twpp::UserInterface& data, bool bUiOnly = false);
|
||||
void init_support_caps(void);
|
||||
void init_support_caps_ex(void);
|
||||
std::wstring get_config_file(void);
|
||||
std::wstring get_config_value(const wchar_t* sec, const wchar_t* key);
|
||||
DWORD get_config_number(const wchar_t* sec, const wchar_t* key);
|
||||
int handle_scanner_event(int ev, bool from_event_proc = true);
|
||||
int get_scanned_image_count(DWORD timeout);
|
||||
void trigger_ProcessEvent(Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg);
|
||||
|
||||
typedef struct _pending_xfer
|
||||
{
|
||||
IScanImg* img;
|
||||
unsigned int off;
|
||||
|
||||
struct _pending_xfer() : img(NULL), off(0)
|
||||
{}
|
||||
void clear(void)
|
||||
{
|
||||
if (img)
|
||||
img->release();
|
||||
img = NULL;
|
||||
off = 0;
|
||||
}
|
||||
}PENDXFER;
|
||||
PENDXFER pending_xfer_;
|
||||
|
||||
public:
|
||||
huagao_ds();
|
||||
virtual ~huagao_ds();
|
||||
|
||||
static const Twpp::Identity& defaultIdentity() noexcept;
|
||||
static Twpp::Result selectIdentity(Twpp::Identity& ident) noexcept;
|
||||
static Twpp::ConditionCode condition_code_from_hg_error(int hgerr);
|
||||
|
||||
// SourceFromThis interface
|
||||
protected:
|
||||
typedef Twpp::SourceFromThis<huagao_ds> Base;
|
||||
|
||||
virtual Twpp::Result capabilityGet(const Twpp::Identity& origin, Twpp::Capability& data) override;
|
||||
virtual Twpp::Result capabilityGetCurrent(const Twpp::Identity& origin, Twpp::Capability& data) override;
|
||||
virtual Twpp::Result capabilityGetDefault(const Twpp::Identity& origin, Twpp::Capability& data) override;
|
||||
virtual Twpp::Result capabilityQuerySupport(const Twpp::Identity& origin, Twpp::Capability& data) override;
|
||||
virtual Twpp::Result capabilityReset(const Twpp::Identity& origin, Twpp::Capability& data) override;
|
||||
virtual Twpp::Result capabilityResetAll(const Twpp::Identity& origin) override;
|
||||
virtual Twpp::Result capabilitySet(const Twpp::Identity& origin, Twpp::Capability& data) override;
|
||||
virtual Twpp::Result eventProcess(const Twpp::Identity& origin, Twpp::Event& data) override;
|
||||
virtual Twpp::Result deviceEventGet(const Twpp::Identity& origin, Twpp::DeviceEvent& data) override;
|
||||
virtual Twpp::Result identityOpenDs(const Twpp::Identity& origin) override;
|
||||
virtual Twpp::Result identityCloseDs(const Twpp::Identity& origin) override;
|
||||
virtual Twpp::Result pendingXfersGet(const Twpp::Identity& origin, Twpp::PendingXfers& data) override;
|
||||
virtual Twpp::Result pendingXfersEnd(const Twpp::Identity& origin, Twpp::PendingXfers& data) override;
|
||||
virtual Twpp::Result pendingXfersReset(const Twpp::Identity& origin, Twpp::PendingXfers& data) override;
|
||||
virtual Twpp::Result setupMemXferGet(const Twpp::Identity& origin, Twpp::SetupMemXfer& data) override;
|
||||
virtual Twpp::Result userInterfaceDisable(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
|
||||
virtual Twpp::Result userInterfaceEnable(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
|
||||
virtual Twpp::Result userInterfaceEnableUiOnly(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
|
||||
virtual Twpp::Result extImageInfoGet(const Twpp::Identity& origin, Twpp::ExtImageInfo& data) override;
|
||||
virtual Twpp::Result imageInfoGet(const Twpp::Identity& origin, Twpp::ImageInfo& data) override;
|
||||
virtual Twpp::Result imageLayoutGet(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;
|
||||
virtual Twpp::Result imageLayoutGetDefault(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;
|
||||
virtual Twpp::Result imageLayoutSet(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;
|
||||
virtual Twpp::Result imageLayoutReset(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;
|
||||
virtual Twpp::Result imageMemXferGet(const Twpp::Identity& origin, Twpp::ImageMemXfer& data) override;
|
||||
virtual Twpp::Result imageNativeXferGet(const Twpp::Identity& origin, Twpp::ImageNativeXfer& data) override;
|
||||
virtual Twpp::Result pendingXfersStopFeeder(const Twpp::Identity& origin, Twpp::PendingXfers& data) override;
|
||||
virtual Twpp::Result imageFileXferGet(const Twpp::Identity& origin) override;
|
||||
virtual Twpp::Result setupFileXferGet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override;
|
||||
virtual Twpp::Result setupFileXferGetDefault(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override;
|
||||
virtual Twpp::Result setupFileXferSet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override;
|
||||
virtual Twpp::Result setupFileXferReset(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override;
|
||||
virtual Twpp::Result call(const Twpp::Identity& origin, Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg, void* data) override;
|
||||
virtual Twpp::Result customDataGet(const Twpp::Identity& origin, Twpp::CustomData& data) override;
|
||||
virtual Twpp::Result customDataSet(const Twpp::Identity& origin, Twpp::CustomData& data) override;
|
||||
|
||||
public:
|
||||
void SetResoluton(const char* path, int resolution);
|
||||
};
|
||||
|
||||
#endif // SIMPLEDS_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_TWPP_HPP
|
||||
#define TWPP_DETAIL_FILE_TWPP_HPP
|
||||
|
||||
#include "twpp/env.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "twpp/utils.hpp"
|
||||
|
||||
#include "twpp/types.hpp"
|
||||
#include "twpp/strings.hpp"
|
||||
#include "twpp/fix32.hpp"
|
||||
#include "twpp/frame.hpp"
|
||||
#include "twpp/exception.hpp"
|
||||
#include "twpp/typesops.hpp"
|
||||
|
||||
#include "twpp/memoryops.hpp"
|
||||
#include "twpp/memory.hpp"
|
||||
|
||||
#include "twpp/enums.hpp"
|
||||
#include "twpp/status.hpp"
|
||||
#include "twpp/identity.hpp"
|
||||
#include "twpp/imageinfo.hpp"
|
||||
#include "twpp/imagelayout.hpp"
|
||||
#include "twpp/deviceevent.hpp"
|
||||
#include "twpp/element8.hpp"
|
||||
|
||||
#include "twpp/audio.hpp"
|
||||
#include "twpp/capability.hpp"
|
||||
#include "twpp/customdata.hpp"
|
||||
#include "twpp/cie.hpp"
|
||||
#include "twpp/curveresponse.hpp"
|
||||
#include "twpp/event.hpp"
|
||||
#include "twpp/extimageinfo.hpp"
|
||||
#include "twpp/filesystem.hpp"
|
||||
#include "twpp/imagememxfer.hpp"
|
||||
#include "twpp/imagenativexfer.hpp"
|
||||
#include "twpp/internal.hpp"
|
||||
#include "twpp/jpegcompression.hpp"
|
||||
#include "twpp/palette8.hpp"
|
||||
#include "twpp/passthrough.hpp"
|
||||
#include "twpp/pendingxfers.hpp"
|
||||
#include "twpp/setupfilexfer.hpp"
|
||||
#include "twpp/setupmemxfer.hpp"
|
||||
#include "twpp/userinterface.hpp"
|
||||
|
||||
#if !defined(TWPP_IS_DS)
|
||||
# include "twpp/application.hpp"
|
||||
#else
|
||||
# include "twpp/datasource.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(TWPP_NO_NOTES)
|
||||
# if !defined(TWPP_IS_DS)
|
||||
# pragma message ("note: using APPLICATION version of TWPP library, define TWPP_IS_DS before including twpp.hpp if you want DATA SOURCE version")
|
||||
# if defined(TWPP_DETAIL_OS_WIN32)
|
||||
# pragma message ("note: place the following into your module-definition (.def) file: EXPORTS DS_Entry @1")
|
||||
# endif
|
||||
# else
|
||||
# pragma message ("note: using DATA SOURCE version of TWPP library, undefine TWPP_IS_DS if you want APPLICATION version")
|
||||
# pragma message ("note: make sure to place TWPP_ENTRY(<your-source-class-type>) macro in exactly one source file")
|
||||
# endif
|
||||
# if defined(TWPP_DETAIL_OS_MAC)
|
||||
# pragma message "warning: Str32, Str64, Str128 and Str255 are not null-terminated"
|
||||
# endif
|
||||
# pragma message ("note: to disable notes and warnings, define TWPP_NO_NOTES before including TWPP header")
|
||||
#endif
|
||||
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_TWPP_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_AUDIO_HPP
|
||||
#define TWPP_DETAIL_FILE_AUDIO_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Information about current audio transfer.
|
||||
/// ArgType::AudioInfo
|
||||
class AudioInfo {
|
||||
|
||||
public:
|
||||
/// Creates empty audio info.
|
||||
constexpr AudioInfo() noexcept :
|
||||
m_name(), m_reserved(){}
|
||||
|
||||
/// Creates audio info with set name of audio data.
|
||||
explicit constexpr AudioInfo(const Str255& name, UInt32 reserved = 0) noexcept :
|
||||
m_name(name), m_reserved(reserved){}
|
||||
|
||||
/// Name of audio data.
|
||||
constexpr const Str255& name() const noexcept{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/// Name of audio data.
|
||||
Str255& name() noexcept{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
constexpr UInt32 reserved() const noexcept{
|
||||
return m_reserved;
|
||||
}
|
||||
|
||||
void setReserved(UInt32 reserved) noexcept{
|
||||
m_reserved = reserved;
|
||||
}
|
||||
|
||||
private:
|
||||
Str255 m_name;
|
||||
UInt32 m_reserved;
|
||||
|
||||
};
|
||||
|
||||
/// Owner of audio transfer handle.
|
||||
class AudioNativeXfer {
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
using Data = Detail::Lock<typename std::decay<T>::type>;
|
||||
|
||||
template<typename T>
|
||||
using ConstData = Detail::Lock<const typename std::decay<T>::type>;
|
||||
|
||||
|
||||
/// Creates an empty handle owner.
|
||||
AudioNativeXfer() noexcept :
|
||||
m_handle(){}
|
||||
|
||||
/// Creates a memory area of desired size for audio native transfer.
|
||||
/// \throw std::bad_alloc
|
||||
explicit AudioNativeXfer(UInt32 size) :
|
||||
m_handle(Detail::alloc(size)){}
|
||||
|
||||
/// Audio data.
|
||||
template<typename T = void>
|
||||
Data<T> data() noexcept{
|
||||
return m_handle.lock<typename std::decay<T>::type>();
|
||||
}
|
||||
|
||||
/// Audio data.
|
||||
template<typename T = void>
|
||||
ConstData<T> data() const noexcept{
|
||||
return m_handle.lock<const typename std::decay<T>::type>();
|
||||
}
|
||||
|
||||
/// Releases the owned handle.
|
||||
/// The user becomes responsible for freeing the handle.
|
||||
Handle release() noexcept{
|
||||
return m_handle.release();
|
||||
}
|
||||
|
||||
private:
|
||||
Detail::UniqueHandle m_handle;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_AUDIO_HPP
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_CIE_HPP
|
||||
#define TWPP_DETAIL_FILE_CIE_HPP
|
||||
|
||||
#if 0
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Part of CieColor structure.
|
||||
class CiePoint {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized cie point.
|
||||
constexpr CiePoint() noexcept :
|
||||
m_x(), m_y(), m_z(){}
|
||||
|
||||
/// Creates cie point with desired values.
|
||||
constexpr CiePoint(Fix32 x, Fix32 y, Fix32 z) noexcept :
|
||||
m_x(x), m_y(y), m_z(z){}
|
||||
|
||||
/// X value of CIE space.
|
||||
constexpr Fix32 x() const noexcept{
|
||||
return m_x;
|
||||
}
|
||||
|
||||
/// Y value of CIE space.
|
||||
constexpr Fix32 y() const noexcept{
|
||||
return m_y;
|
||||
}
|
||||
|
||||
/// Z value of CIE space.
|
||||
constexpr Fix32 z() const noexcept{
|
||||
return m_z;
|
||||
}
|
||||
|
||||
/// Sets x value of CIE space.
|
||||
void setX(Fix32 x) noexcept{
|
||||
m_x = x;
|
||||
}
|
||||
|
||||
/// Sets y value of CIE space.
|
||||
void setY(Fix32 y) noexcept{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
/// Sets z value of CIE space.
|
||||
void setZ(Fix32 z) noexcept{
|
||||
m_z = z;
|
||||
}
|
||||
|
||||
private:
|
||||
Fix32 m_x;
|
||||
Fix32 m_y;
|
||||
Fix32 m_z;
|
||||
|
||||
};
|
||||
|
||||
/// Defines parameters for channel transformations.
|
||||
/// Part of TransformStage.
|
||||
class DecodeFunction {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized decode function.
|
||||
constexpr DecodeFunction() noexcept{}
|
||||
|
||||
/// Creates initialized decode function.
|
||||
constexpr DecodeFunction(
|
||||
Fix32 startIn,
|
||||
Fix32 breakIn,
|
||||
Fix32 endIn,
|
||||
Fix32 startOut,
|
||||
Fix32 breakOut,
|
||||
Fix32 endOut,
|
||||
Fix32 gamma,
|
||||
Fix32 sampleCount
|
||||
) noexcept :
|
||||
m_startIn(startIn), m_breakIn(breakIn), m_endIn(endIn),
|
||||
m_startOut(startOut), m_breakOut(breakOut), m_endOut(endOut),
|
||||
m_gamma(gamma), m_sampleCount(sampleCount){}
|
||||
|
||||
/// Starting input value.
|
||||
constexpr Fix32 startIn() const noexcept{
|
||||
return m_startIn;
|
||||
}
|
||||
|
||||
/// Sets starting input value.
|
||||
void setStartIn(Fix32 startIn) noexcept{
|
||||
m_startIn = startIn;
|
||||
}
|
||||
|
||||
/// Ending input value.
|
||||
constexpr Fix32 breakIn() const noexcept{
|
||||
return m_breakIn;
|
||||
}
|
||||
|
||||
/// Sets ending input value.
|
||||
void setBreakIn(Fix32 breakIn) noexcept{
|
||||
m_breakIn = breakIn;
|
||||
}
|
||||
|
||||
/// Input value when to switch from linear to gamma transformation.
|
||||
constexpr Fix32 endIn() const noexcept{
|
||||
return m_endIn;
|
||||
}
|
||||
|
||||
/// Sets input value when to switch from linear to gamma transformation.
|
||||
void setEndIn(Fix32 endIn) noexcept{
|
||||
m_endIn = endIn;
|
||||
}
|
||||
|
||||
/// Starting output value.
|
||||
constexpr Fix32 startOut() const noexcept{
|
||||
return m_startOut;
|
||||
}
|
||||
|
||||
/// Sets starting output value.
|
||||
void setStartOut(Fix32 startOut) noexcept{
|
||||
m_startOut = startOut;
|
||||
}
|
||||
|
||||
/// Ending output value.
|
||||
constexpr Fix32 breakOut() const noexcept{
|
||||
return m_breakOut;
|
||||
}
|
||||
|
||||
/// Sets ending output value.
|
||||
void setBreakOut(Fix32 breakOut) noexcept{
|
||||
m_breakOut = breakOut;
|
||||
}
|
||||
|
||||
/// Output value when to switch from linear to gamma transformation.
|
||||
constexpr Fix32 endOut() const noexcept{
|
||||
return m_endOut;
|
||||
}
|
||||
|
||||
/// Sets output value when to switch from linear to gamma transformation.
|
||||
void setEndOut(Fix32 endOut) noexcept{
|
||||
m_endOut = endOut;
|
||||
}
|
||||
|
||||
/// Constant, exponential used in gamma funciton.
|
||||
constexpr Fix32 gamma() const noexcept{
|
||||
return m_gamma;
|
||||
}
|
||||
|
||||
/// Sets constant, exponential used in gamma funciton.
|
||||
void setGamma(Fix32 gamma) noexcept{
|
||||
m_gamma = gamma;
|
||||
}
|
||||
|
||||
/// Number of samples in lookup table.
|
||||
constexpr Fix32 sampleCount() const noexcept{
|
||||
return m_sampleCount;
|
||||
}
|
||||
|
||||
/// Sets number of samples in lookup table.
|
||||
void setSampleCount(Fix32 sampleCount) noexcept{
|
||||
m_sampleCount = sampleCount;
|
||||
}
|
||||
|
||||
private:
|
||||
Fix32 m_startIn;
|
||||
Fix32 m_breakIn;
|
||||
Fix32 m_endIn;
|
||||
Fix32 m_startOut;
|
||||
Fix32 m_breakOut;
|
||||
Fix32 m_endOut;
|
||||
Fix32 m_gamma;
|
||||
Fix32 m_sampleCount;
|
||||
|
||||
};
|
||||
|
||||
/// Parameters of ABC or LMN transformations.
|
||||
/// Refer to manual for more information about members.
|
||||
class TransformStage {
|
||||
|
||||
public:
|
||||
typedef std::array<DecodeFunction, 3> Decode;
|
||||
typedef std::array<std::array<Fix32, 3>, 3> Mix;
|
||||
|
||||
constexpr TransformStage() noexcept :
|
||||
m_decode(), m_mix(){}
|
||||
|
||||
constexpr TransformStage(const Decode& decode) noexcept :
|
||||
m_decode(decode), m_mix(){}
|
||||
|
||||
constexpr TransformStage(const Mix& mix) noexcept :
|
||||
m_decode(), m_mix(mix){}
|
||||
|
||||
constexpr TransformStage(const Decode& decode, const Mix& mix) noexcept :
|
||||
m_decode(decode), m_mix(mix){}
|
||||
|
||||
constexpr const Decode& decode() const noexcept{
|
||||
return m_decode;
|
||||
}
|
||||
|
||||
Decode& decode() noexcept{
|
||||
return m_decode;
|
||||
}
|
||||
|
||||
constexpr const Mix& mix() const noexcept{
|
||||
return m_mix;
|
||||
}
|
||||
|
||||
Mix& mix() noexcept{
|
||||
return m_mix;
|
||||
}
|
||||
|
||||
private:
|
||||
Decode m_decode;
|
||||
Mix m_mix;
|
||||
|
||||
};
|
||||
|
||||
namespace Unsupported {
|
||||
|
||||
// TODO CieColor
|
||||
/// Cie color
|
||||
/// Currently stub, more info required.
|
||||
struct CieColor {
|
||||
UInt16 m_colorSpace;
|
||||
Bool m_lowEndian;
|
||||
Bool m_deviceDependent;
|
||||
Int32 m_versionNumber;
|
||||
TransformStage m_stageAbc;
|
||||
TransformStage m_stageLmn;
|
||||
CiePoint m_whitePoint;
|
||||
CiePoint m_blackPoint;
|
||||
CiePoint m_whitePaper;
|
||||
CiePoint m_blackInk;
|
||||
Fix32 m_samples[1]; // <- how many elements? how to use?
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_CIE_HPP
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_CURVERESPONSE_HPP
|
||||
#define TWPP_DETAIL_FILE_CURVERESPONSE_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
/// Base response class.
|
||||
class CurveResponse {
|
||||
|
||||
public:
|
||||
CurveResponse() noexcept{}
|
||||
|
||||
/// Creates a new (Rgb|Gray)Response with default elements, make sure that info.bitsPerPixel() is <= 8.
|
||||
/// \throw RangeException When info.bitsPerPixel() is negative or greater than 8.
|
||||
explicit CurveResponse(const ImageInfo& info) : CurveResponse(info.bitsPerPixel()){}
|
||||
|
||||
/// Creates a new (Rgb|Gray)Response with default elements, make sure that bitsPerPixel is <= 8.
|
||||
/// \throw RangeException When bitsPerPixel is negative or greater than 8.
|
||||
explicit CurveResponse(Int16 bitsPerPixel){
|
||||
if (bitsPerPixel <= 0 || bitsPerPixel > 8){
|
||||
throw RangeException();
|
||||
}
|
||||
|
||||
UInt16 size = 1 << static_cast<UInt16>(bitsPerPixel);
|
||||
m_data.reset(new Element8[size]);
|
||||
for (UInt16 i = 0; i < size; i++){
|
||||
m_data[i] = Element8(static_cast<UInt8>(i)); // 0..255 max
|
||||
}
|
||||
}
|
||||
|
||||
/// Array of size `2^ImageInfo.bitesPerPixel()`, up to 256 elements (2^8)
|
||||
Element8* data() noexcept{
|
||||
return m_data.get();
|
||||
}
|
||||
|
||||
/// Array of size `2^ImageInfo.bitesPerPixel()`, up to 256 elements (2^8)
|
||||
const Element8* data() const noexcept{
|
||||
return m_data.get();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Element8[]> m_data;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// Rgb response class.
|
||||
class RgbResponse : public Detail::CurveResponse {
|
||||
|
||||
public:
|
||||
RgbResponse() noexcept{}
|
||||
|
||||
/// Creates a new RgbResponse with default elements, make sure that info.bitesPerPixel() is <= 8.
|
||||
/// \throw RangeException When info.bitsPerPixel() is negative or greater than 8.
|
||||
explicit RgbResponse(const ImageInfo& info) :
|
||||
Detail::CurveResponse(info) {}
|
||||
|
||||
/// Creates a new RgbResponse with default elements, make sure that bitsPerPixel is <= 8.
|
||||
/// \throw RangeException When bitsPerPixel is negative or greater than 8.
|
||||
explicit RgbResponse(Int16 bitsPerPixel) :
|
||||
Detail::CurveResponse(bitsPerPixel) {}
|
||||
|
||||
};
|
||||
|
||||
/// Gray response class.
|
||||
class GrayResponse : public Detail::CurveResponse {
|
||||
|
||||
public:
|
||||
GrayResponse() noexcept{}
|
||||
|
||||
/// Creates a new GrayResponse with default elements, make sure that info.bitesPerPixel() is <= 8.
|
||||
/// \throw RangeException When info.bitsPerPixel() is negative or greater than 8.
|
||||
explicit GrayResponse(const ImageInfo& info) :
|
||||
Detail::CurveResponse(info) {}
|
||||
|
||||
/// Creates a new GrayResponse with default elements, make sure that bitsPerPixel is <= 8.
|
||||
/// \throw RangeException When bitsPerPixel is negative or greater than 8.
|
||||
explicit GrayResponse(Int16 bitsPerPixel) :
|
||||
Detail::CurveResponse(bitsPerPixel) {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_CURVERESPONSE_HPP
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_CUSTOMDATA_HPP
|
||||
#define TWPP_DETAIL_FILE_CUSTOMDATA_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure for sending custom data to source or application.
|
||||
class CustomData {
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
using Data = typename Detail::Lock<T>;
|
||||
|
||||
/// Creates empty custom data.
|
||||
CustomData() noexcept :
|
||||
m_size(0), m_handle(){}
|
||||
|
||||
/// Creates custom data with allocated memory.
|
||||
/// \throw std::bad_alloc
|
||||
explicit CustomData(UInt32 size) :
|
||||
m_size(size), m_handle(Detail::alloc(size)){}
|
||||
|
||||
/// Locks and returns pointer to custom data memory.
|
||||
template<typename T = void>
|
||||
Data<T> lock() const noexcept{
|
||||
return Data<T>(m_handle.get());
|
||||
}
|
||||
|
||||
/// The size of contained memory block.
|
||||
UInt32 size() const noexcept{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
UInt32 m_size;
|
||||
Detail::UniqueHandle m_handle;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_CUSTOMDATA_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,251 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_DEVICEEVENT_HPP
|
||||
#define TWPP_DETAIL_FILE_DEVICEEVENT_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Information about event sent by source.
|
||||
class DeviceEvent {
|
||||
|
||||
public:
|
||||
/// Event type.
|
||||
enum class Type : UInt16 { // Capability->UInt16, DeviceEvent->UInt32
|
||||
CheckAutomaticCapture = 0,
|
||||
CheckBattery = 1,
|
||||
CheckDeviceOnline = 2,
|
||||
CheckFlash = 3,
|
||||
CheckPowerSupply = 4,
|
||||
CheckResolution = 5,
|
||||
DeviceAdded = 6,
|
||||
DeviceOffline = 7,
|
||||
DeviceReady = 8,
|
||||
DeviceRemoved = 9,
|
||||
ImageCaptured = 10,
|
||||
ImageDeleted = 11,
|
||||
PaperDoubleFeed = 12,
|
||||
PaperJam = 13,
|
||||
LampFailure = 14,
|
||||
PowerSave = 15,
|
||||
PowerSaveNotify = 16,
|
||||
CustomEvents = 0x8000
|
||||
};
|
||||
|
||||
/// Creates event with only type and device name set.
|
||||
static constexpr DeviceEvent simple(Type type, const Str255& deviceName) noexcept;
|
||||
|
||||
/// Creates event for checking battery.
|
||||
static constexpr DeviceEvent checkBattery(
|
||||
const Str255& deviceName,
|
||||
UInt32 batteryMinutes,
|
||||
Int16 batteryPercentage
|
||||
) noexcept;
|
||||
|
||||
/// Creates event for checking power supply.
|
||||
static constexpr DeviceEvent checkPowerSupply(
|
||||
const Str255& deviceName,
|
||||
PowerSupply powerSupply
|
||||
) noexcept;
|
||||
|
||||
/// Creates event for checking resolution.
|
||||
static constexpr DeviceEvent checkResolution(
|
||||
const Str255& deviceName,
|
||||
Fix32 xres,
|
||||
Fix32 yres
|
||||
) noexcept;
|
||||
|
||||
/// Creates event for checking flash settings.
|
||||
static constexpr DeviceEvent checkFlash(
|
||||
const Str255& deviceName,
|
||||
Flash flash
|
||||
) noexcept;
|
||||
|
||||
/// Creates event for checking number of images camera is going to capture.
|
||||
static constexpr DeviceEvent checkAutomaticCapture(
|
||||
const Str255& deviceName,
|
||||
UInt32 autoCapture,
|
||||
UInt32 timeBeforeFirstCapture,
|
||||
UInt32 timeBetweenCaptures
|
||||
) noexcept;
|
||||
|
||||
/// Creates uninitialized deice event.
|
||||
constexpr DeviceEvent() noexcept :
|
||||
m_type(static_cast<UInt32>(Type::CheckAutomaticCapture)), m_batteryMinutes(0),
|
||||
m_batteryPercent(0), m_powerSupply(static_cast<Int32>(PowerSupply::External)),
|
||||
m_flashUsed(static_cast<UInt32>(Flash::None)), m_autoCapture(0),
|
||||
m_timeBeforeFirstCapture(0), m_timeBetweenCaptures(0){}
|
||||
|
||||
/// Event type.
|
||||
constexpr Type type() const noexcept{
|
||||
return static_cast<Type>(m_type);
|
||||
}
|
||||
|
||||
/// Name of the device that sent the event.
|
||||
constexpr const Str255& deviceName() const noexcept{
|
||||
return m_deviceName;
|
||||
}
|
||||
|
||||
/// Minutes of battery power remaining.
|
||||
/// Valid only for Type::CheckBattery.
|
||||
constexpr UInt32 batteryMinutes() const noexcept{
|
||||
return m_batteryMinutes;
|
||||
}
|
||||
|
||||
/// Percentage of battery power remaining.
|
||||
/// Valid only for Type::CheckBattery.
|
||||
constexpr Int16 batteryPercentage() const noexcept{
|
||||
return m_batteryPercent;
|
||||
}
|
||||
|
||||
/// Power supply in use.
|
||||
/// Valid only for Type::CheckPowerSupply.
|
||||
constexpr PowerSupply powerSupply() const noexcept{
|
||||
return static_cast<PowerSupply>(m_powerSupply);
|
||||
}
|
||||
|
||||
/// X resolution.
|
||||
/// Valif only for Type::CheckResolution.
|
||||
constexpr Fix32 xResolution() const noexcept{
|
||||
return m_xres;
|
||||
}
|
||||
|
||||
/// Y resolution.
|
||||
/// Valid only for Type::CheckResolution.
|
||||
constexpr Fix32 yResolution() const noexcept{
|
||||
return m_yres;
|
||||
}
|
||||
|
||||
/// Flash settings.
|
||||
/// Valid only for Type::CheckFlash.
|
||||
constexpr Flash flash() const noexcept{
|
||||
return static_cast<Flash>(m_flashUsed);
|
||||
}
|
||||
|
||||
/// Number of images camera will capture.
|
||||
/// Valid only for Type::CheckAutomaticCapture.
|
||||
constexpr UInt32 automaticCapture() const noexcept{
|
||||
return m_autoCapture;
|
||||
}
|
||||
|
||||
/// Number of seconds before first capture.
|
||||
/// Valid only for Type::CheckAutomaticCapture.
|
||||
constexpr UInt32 timeBeforeFirstCapture() const noexcept{
|
||||
return m_timeBeforeFirstCapture;
|
||||
}
|
||||
|
||||
/// Number of 1/100-seconds between captures.
|
||||
/// Valid only for Type::CheckAutomaticCapture.
|
||||
constexpr UInt32 timeBetweenCaptures() const noexcept{
|
||||
return m_timeBetweenCaptures;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr DeviceEvent(
|
||||
Type type,
|
||||
const Str255& deviceName,
|
||||
UInt32 batteryMinutes,
|
||||
Int16 batteryPercentage,
|
||||
PowerSupply powerSupply,
|
||||
Fix32 xres,
|
||||
Fix32 yres,
|
||||
Flash flash,
|
||||
UInt32 autoCapture,
|
||||
UInt32 tbfc,
|
||||
UInt32 tbc
|
||||
) noexcept :
|
||||
m_type(static_cast<UInt32>(type)), m_deviceName(deviceName),
|
||||
m_batteryMinutes(batteryMinutes), m_batteryPercent(batteryPercentage),
|
||||
m_powerSupply(static_cast<Int32>(powerSupply)), m_xres(xres), m_yres(yres),
|
||||
m_flashUsed(static_cast<UInt32>(flash)), m_autoCapture(autoCapture),
|
||||
m_timeBeforeFirstCapture(tbfc), m_timeBetweenCaptures(tbc){}
|
||||
|
||||
UInt32 m_type;
|
||||
Str255 m_deviceName;
|
||||
UInt32 m_batteryMinutes;
|
||||
Int16 m_batteryPercent;
|
||||
Int32 m_powerSupply;
|
||||
Fix32 m_xres;
|
||||
Fix32 m_yres;
|
||||
UInt32 m_flashUsed;
|
||||
UInt32 m_autoCapture;
|
||||
UInt32 m_timeBeforeFirstCapture;
|
||||
UInt32 m_timeBetweenCaptures;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
// must be defined outside the class because of msvc2015
|
||||
constexpr inline DeviceEvent DeviceEvent::simple(Type type, const Str255& deviceName) noexcept{
|
||||
return DeviceEvent(type, deviceName, 0, 0, PowerSupply::External, Fix32(), Fix32(), Flash::None, 0, 0, 0);
|
||||
}
|
||||
|
||||
constexpr inline DeviceEvent DeviceEvent::checkBattery(
|
||||
const Str255& deviceName,
|
||||
UInt32 batteryMinutes,
|
||||
Int16 batteryPercentage
|
||||
) noexcept{
|
||||
return DeviceEvent(Type::CheckBattery, deviceName, batteryMinutes, batteryPercentage, PowerSupply::External, Fix32(), Fix32(), Flash::None, 0, 0, 0);
|
||||
}
|
||||
|
||||
constexpr inline DeviceEvent DeviceEvent::checkPowerSupply(
|
||||
const Str255& deviceName,
|
||||
PowerSupply powerSupply
|
||||
) noexcept{
|
||||
return DeviceEvent(Type::CheckPowerSupply, deviceName, 0, 0, powerSupply, Fix32(), Fix32(), Flash::None, 0, 0, 0);
|
||||
}
|
||||
|
||||
constexpr inline DeviceEvent DeviceEvent::checkResolution(
|
||||
const Str255& deviceName,
|
||||
Fix32 xres,
|
||||
Fix32 yres
|
||||
) noexcept{
|
||||
return DeviceEvent(Type::CheckResolution, deviceName, 0, 0, PowerSupply::External, xres, yres, Flash::None, 0, 0, 0);
|
||||
}
|
||||
|
||||
constexpr inline DeviceEvent DeviceEvent::checkFlash(
|
||||
const Str255& deviceName,
|
||||
Flash flash
|
||||
) noexcept{
|
||||
return DeviceEvent(Type::CheckFlash, deviceName, 0, 0, PowerSupply::External, Fix32(), Fix32(), flash, 0, 0, 0);
|
||||
}
|
||||
|
||||
constexpr inline DeviceEvent DeviceEvent::checkAutomaticCapture(
|
||||
const Str255& deviceName,
|
||||
UInt32 autoCapture,
|
||||
UInt32 timeBeforeFirstCapture,
|
||||
UInt32 timeBetweenCaptures
|
||||
) noexcept{
|
||||
return DeviceEvent(Type::CheckAutomaticCapture, deviceName, 0, 0, PowerSupply::External,
|
||||
Fix32(), Fix32(), Flash::None, autoCapture, timeBeforeFirstCapture, timeBetweenCaptures);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_DEVICEEVENT_HPP
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_ELEMENT8_HPP
|
||||
#define TWPP_DETAIL_FILE_ELEMENT8_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Element in a palette consisting of 3 parts (RGB, CMY, ...)
|
||||
/// in the order of the type alphabetic representation.
|
||||
class Element8 {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized element.
|
||||
constexpr Element8() noexcept :
|
||||
m_index(0), m_channel1(0), m_channel2(0), m_channel3(0){}
|
||||
|
||||
/// Creates zero-initialized element with specified index.
|
||||
explicit constexpr Element8(UInt8 index) noexcept :
|
||||
m_index(index), m_channel1(0), m_channel2(0), m_channel3(0){}
|
||||
|
||||
/// Creates element with set channels.
|
||||
constexpr Element8(
|
||||
UInt8 channel1,
|
||||
UInt8 channel2,
|
||||
UInt8 channel3
|
||||
) noexcept :
|
||||
m_index(0), m_channel1(channel1), m_channel2(channel2),
|
||||
m_channel3(channel3){}
|
||||
|
||||
/// Creates element with set channels at index.
|
||||
constexpr Element8(
|
||||
UInt8 index,
|
||||
UInt8 channel1,
|
||||
UInt8 channel2,
|
||||
UInt8 channel3
|
||||
) noexcept :
|
||||
m_index(index), m_channel1(channel1), m_channel2(channel2),
|
||||
m_channel3(channel3){}
|
||||
|
||||
/// Index of the element in palette.
|
||||
constexpr UInt8 index() const noexcept{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
/// Sets index of the element in palette.
|
||||
void setIndex(UInt8 index) noexcept{
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
/// Channel 1 information.
|
||||
constexpr UInt8 channel1() const noexcept{
|
||||
return m_channel1;
|
||||
}
|
||||
|
||||
/// Sets channel 1 information.
|
||||
void setChannel1(UInt8 channel1) noexcept{
|
||||
m_channel1 = channel1;
|
||||
}
|
||||
|
||||
/// Channel 2 information.
|
||||
constexpr UInt8 channel2() const noexcept{
|
||||
return m_channel2;
|
||||
}
|
||||
|
||||
/// Sets channel 2 information.
|
||||
void setChannel2(UInt8 channel2) noexcept{
|
||||
m_channel2 = channel2;
|
||||
}
|
||||
|
||||
/// Channel 3 information.
|
||||
constexpr UInt8 channel3() const noexcept{
|
||||
return m_channel3;
|
||||
}
|
||||
|
||||
/// Sets channel 3 information.
|
||||
void setChannel3(UInt8 channel3) noexcept{
|
||||
m_channel3 = channel3;
|
||||
}
|
||||
|
||||
private:
|
||||
UInt8 m_index;
|
||||
UInt8 m_channel1;
|
||||
UInt8 m_channel2;
|
||||
UInt8 m_channel3;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_ELEMENT8_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,356 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_ENV_HPP
|
||||
#define TWPP_DETAIL_FILE_ENV_HPP
|
||||
|
||||
// =============
|
||||
// Twpp specific
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
enum {
|
||||
ProtoMajor = 2,
|
||||
ProtoMinor = 3,
|
||||
Dsm2 = 0x10000000L,
|
||||
App2 = 0x20000000L,
|
||||
Ds2 = 0x40000000L
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(TWPP_IS_DS)
|
||||
# define TWPP_DETAIL_IS_DS 1
|
||||
#else
|
||||
# define TWPP_DETAIL_IS_DS 0
|
||||
#endif
|
||||
|
||||
|
||||
// ===========
|
||||
// OS specific
|
||||
|
||||
// Windows
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
|
||||
# define TWPP_DETAIL_OS_WIN 1
|
||||
# if defined(WIN64) || defined(_WIN64)
|
||||
# define TWPP_DETAIL_OS_WIN64 1
|
||||
# else
|
||||
# define TWPP_DETAIL_OS_WIN32 1
|
||||
# endif
|
||||
# if !defined(WIN32_LEAN_AND_MEAN)
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# if !defined(NOMINMAX)
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
extern "C" {
|
||||
# include <windows.h>
|
||||
}
|
||||
# define TWPP_DETAIL_CALLSTYLE PASCAL
|
||||
# define TWPP_DETAIL_EXPORT __declspec(dllexport)
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
typedef HANDLE RawHandle;
|
||||
|
||||
|
||||
namespace DsmLibOs {
|
||||
|
||||
typedef HMODULE Handle;
|
||||
static constexpr const Handle nullHandle = nullptr;
|
||||
|
||||
template<typename T>
|
||||
static inline T resolve(Handle h) noexcept{
|
||||
return reinterpret_cast<T>(::GetProcAddress(h, "DSM_Entry"));
|
||||
}
|
||||
|
||||
# if defined(TWPP_DETAIL_OS_WIN32)
|
||||
static inline Handle load(bool old) noexcept{
|
||||
if (old){
|
||||
auto h = ::LoadLibraryA("TWAIN_32.dll");
|
||||
if (!h){
|
||||
h = ::LoadLibraryA("TWAINDSM.dll");
|
||||
}
|
||||
|
||||
return h;
|
||||
} else {
|
||||
auto h = ::LoadLibraryA("TWAINDSM.dll");
|
||||
if (!h){
|
||||
h = ::LoadLibraryA("TWAIN_32.dll");
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
||||
# else
|
||||
static inline Handle load(bool) noexcept{
|
||||
return ::LoadLibraryA("TWAINDSM.dll");
|
||||
}
|
||||
# endif
|
||||
|
||||
static inline void unload(Handle h) noexcept{
|
||||
::FreeLibrary(h);
|
||||
}
|
||||
|
||||
} // namespace DsmLibOs
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
} // namespace Twpp
|
||||
|
||||
|
||||
// Mac OS
|
||||
#elif defined(__APPLE__)
|
||||
# pragma message "No testing has been done on this platform, this framework might not work correctly."
|
||||
# define TWPP_DETAIL_OS_MAC 1
|
||||
# include <limits>
|
||||
extern "C" {
|
||||
# include <objc/objc.h>
|
||||
# include <objc/objc-runtime.h>
|
||||
# include <objc/NSObjCRuntime.h>
|
||||
# include <CoreServices/CoreServices.h>
|
||||
# include <dlfcn.h>
|
||||
}
|
||||
# define TWPP_DETAIL_CALLSTYLE pascal
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
typedef Handle RawHandle;
|
||||
|
||||
|
||||
namespace DsmLibOs {
|
||||
|
||||
typedef void* Handle;
|
||||
static constexpr const Handle nullHandle = nullptr;
|
||||
|
||||
template<typename T>
|
||||
static inline T resolve(Handle h) noexcept{
|
||||
return reinterpret_cast<T>(::dlsym(h, "DSM_Entry"));
|
||||
}
|
||||
|
||||
static inline Handle load(bool) noexcept{
|
||||
return ::dlopen("/System/Library/Frameworks/TWAIN.framework/TWAIN", RTLD_LAZY);
|
||||
}
|
||||
|
||||
static inline void unload(Handle h) noexcept{
|
||||
::dlclose(h);
|
||||
}
|
||||
|
||||
} // namespace DsmLibOs
|
||||
|
||||
template<typename>
|
||||
struct MacStatic {
|
||||
|
||||
static const ::Class g_autoreleasePool;
|
||||
static const ::SEL g_release;
|
||||
static const ::SEL g_alloc;
|
||||
static const ::SEL g_init;
|
||||
|
||||
static const ::SEL g_nextEvent;
|
||||
static const ::SEL g_postEvent;
|
||||
static const ::SEL g_sendEvent;
|
||||
static const ::id g_app;
|
||||
static const ::id g_distantFuture;
|
||||
|
||||
static const ::Class g_event;
|
||||
static const ::SEL g_otherEventWithType;
|
||||
|
||||
};
|
||||
|
||||
template<typename Dummy> const ::Class MacStatic<Dummy>::g_autoreleasePool = objc_getClass("NSAutoreleasePool");
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_release = sel_registerName("release");
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_alloc = sel_registerName("alloc");
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_init = sel_registerName("init");
|
||||
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_nextEvent = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:");
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_postEvent = sel_registerName("postEvent:atStart:");
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_sendEvent = sel_registerName("sendEvent:");
|
||||
template<typename Dummy> const ::id MacStatic<Dummy>::g_app = objc_msgSend(reinterpret_cast<::id>(objc_getClass("NSApplication")), sel_registerName("sharedApplication"));
|
||||
template<typename Dummy> const ::id MacStatic<Dummy>::g_distantFuture = objc_msgSend(reinterpret_cast<::id>(objc_getClass("NSDate")), sel_registerName("distantFuture"));
|
||||
|
||||
template<typename Dummy> const ::Class MacStatic<Dummy>::g_event = objc_getClass("NSEvent");
|
||||
template<typename Dummy> const ::SEL MacStatic<Dummy>::g_otherEventWithType = sel_registerName("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:");
|
||||
|
||||
class NSAutoreleasePool {
|
||||
|
||||
public:
|
||||
NSAutoreleasePool() noexcept :
|
||||
m_id(createPool()) {}
|
||||
|
||||
~NSAutoreleasePool(){
|
||||
release();
|
||||
}
|
||||
|
||||
NSAutoreleasePool(const NSAutoreleasePool&) = delete;
|
||||
NSAutoreleasePool& operator=(const NSAutoreleasePool&) = delete;
|
||||
|
||||
NSAutoreleasePool(NSAutoreleasePool&& o) noexcept :
|
||||
m_id(o.m_id){
|
||||
|
||||
o.m_id = nullptr;
|
||||
}
|
||||
|
||||
NSAutoreleasePool& operator=(NSAutoreleasePool&& o) noexcept{
|
||||
if (this != &o){
|
||||
release();
|
||||
std::swap(m_id, o.m_id);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void release() noexcept{
|
||||
if (m_id != nullptr){
|
||||
objc_msgSend(m_id, MacStatic<void>::g_release);
|
||||
m_id = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static ::id createPool() noexcept{
|
||||
auto poolId = objc_msgSend(reinterpret_cast<::id>(MacStatic<void>::g_autoreleasePool), MacStatic<void>::g_alloc);
|
||||
return objc_msgSend(poolId, MacStatic<void>::g_init);
|
||||
}
|
||||
|
||||
::id m_id;
|
||||
|
||||
};
|
||||
|
||||
namespace NSLoop {
|
||||
|
||||
static constexpr ::NSUInteger NSAnyEventMask = std::numeric_limits<::NSUInteger>::max();
|
||||
static constexpr ::NSUInteger NSApplicationDefined = 15;
|
||||
|
||||
static void processEvent() noexcept{
|
||||
auto event = objc_msgSend(MacStatic<void>::g_app, MacStatic<void>::g_nextEvent, NSAnyEventMask, MacStatic<void>::g_distantFuture, kCFRunLoopDefaultMode, YES);
|
||||
objc_msgSend(MacStatic<void>::g_app, MacStatic<void>::g_sendEvent, event);
|
||||
}
|
||||
|
||||
static void postDummy() noexcept{
|
||||
auto event = objc_msgSend(reinterpret_cast<::id>(MacStatic<void>::g_event), MacStatic<void>::g_otherEventWithType, NSApplicationDefined, nullptr, 1, 0.0, 0, nullptr, static_cast<short>(0), 0, 0);
|
||||
objc_msgSend(MacStatic<void>::g_app, MacStatic<void>::g_postEvent, event, NO);
|
||||
}
|
||||
|
||||
} // namespace NSLoop
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
} // namespace Twpp
|
||||
|
||||
// Linux
|
||||
#elif defined(__linux__)
|
||||
# warning "No testing has been done on this platform, this framework might not work correctly."
|
||||
# define TWPP_DETAIL_OS_LINUX 1
|
||||
extern "C" {
|
||||
# include <dlfcn.h>
|
||||
}
|
||||
# define TWPP_DETAIL_CALLSTYLE
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
typedef void* RawHandle;
|
||||
|
||||
|
||||
namespace DsmLibOs {
|
||||
|
||||
typedef void* Handle;
|
||||
static constexpr const Handle nullHandle = nullptr;
|
||||
|
||||
template<typename T>
|
||||
static inline T resolve(Handle h) noexcept{
|
||||
return reinterpret_cast<T>(::dlsym(h, "DSM_Entry"));
|
||||
}
|
||||
|
||||
static inline Handle load(bool) noexcept{
|
||||
return ::dlopen("libtwaindsm.so", RTLD_LAZY);
|
||||
}
|
||||
|
||||
static inline void unload(Handle h) noexcept{
|
||||
::dlclose(h);
|
||||
}
|
||||
|
||||
} // namespace DsmLibOs
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
} // namespace Twpp
|
||||
|
||||
// fail everything else
|
||||
#else
|
||||
# error "unsupported platform, supports only Windows, Mac OS and Linux"
|
||||
#endif
|
||||
|
||||
|
||||
// =================
|
||||
// compiler specific
|
||||
|
||||
// MSVC
|
||||
#if defined(_MSC_VER)
|
||||
# define TWPP_DETAIL_PACK_BEGIN \
|
||||
__pragma(pack (push, beforeTwpp)) \
|
||||
__pragma(pack (2))
|
||||
# define TWPP_DETAIL_PACK_END __pragma(pack (pop, beforeTwpp));
|
||||
|
||||
// GNU or CLang
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
# if defined(TWPP_DETAIL_OS_MAC)
|
||||
# define TWPP_DETAIL_PACK_BEGIN _Pragma("options align = power")
|
||||
# define TWPP_DETAIL_PACK_END _Pragma("options align = reset")
|
||||
# else
|
||||
# define TWPP_DETAIL_PACK_BEGIN \
|
||||
_Pragma("pack (push, beforeTwpp)") \
|
||||
_Pragma("pack (2)")
|
||||
# define TWPP_DETAIL_PACK_END _Pragma("pack (pop, beforeTwpp)")
|
||||
# endif
|
||||
# if !defined(TWPP_DETAIL_EXPORT)
|
||||
# define TWPP_DETAIL_EXPORT __attribute__((__visibility__("default")))
|
||||
# endif
|
||||
|
||||
// Borland
|
||||
#elif defined(__BORLAND__) || defined(__BORLANDC__) || defined(__CODEGEARC__)
|
||||
# define TWPP_DETAIL_PACK_BEGIN _Pragma("option -a2")
|
||||
# define TWPP_DETAIL_PACK_END _Pragma("option -a")
|
||||
|
||||
// fail everything else
|
||||
#else
|
||||
# error "unsupported compiler, please define your own TWPP_DETAIL_PACK_BEGIN and TWPP_DETAIL_PACK_END and possibly TWPP_DETAIL_EXPORT in twpp/env.hpp and send me your patch"
|
||||
#endif
|
||||
|
||||
|
||||
#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1900) // msvc2015
|
||||
# error "C++11 or later is required"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_ENV_HPP
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_EVENT_HPP
|
||||
#define TWPP_DETAIL_FILE_EVENT_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Loop event on Windows.
|
||||
/// Used while waiting for transfer.
|
||||
/// See manual for more info.
|
||||
class Event {
|
||||
|
||||
public:
|
||||
constexpr Event() noexcept :
|
||||
m_event(nullptr), m_msg(Msg::Null){}
|
||||
|
||||
constexpr Event(void* event, Msg msg) noexcept :
|
||||
m_event(event), m_msg(msg){}
|
||||
|
||||
constexpr void* event() const noexcept{
|
||||
return m_event;
|
||||
}
|
||||
|
||||
void setEvent(void* event) noexcept{
|
||||
m_event = event;
|
||||
}
|
||||
|
||||
constexpr Msg message() const noexcept{
|
||||
return m_msg;
|
||||
}
|
||||
|
||||
void setMessage(Msg msg) noexcept{
|
||||
m_msg = msg;
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_event;
|
||||
Msg m_msg;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_EVENT_HPP
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef TWPP_DETAIL_FILE_EXCEPTION_HPP
|
||||
#define TWPP_DETAIL_FILE_EXCEPTION_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
/// Base class of TWPP exceptions.
|
||||
class Exception : public std::exception {
|
||||
|
||||
public:
|
||||
virtual const char* what() const noexcept override{
|
||||
return "General TWPP error.";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Invalid type exception.
|
||||
/// Used when an invalid or unsupported type identifier is used.
|
||||
class TypeException : public Exception {
|
||||
|
||||
public:
|
||||
virtual const char* what() const noexcept override{
|
||||
return "Invalid type.";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Value out of valid range exception.
|
||||
class RangeException : Exception {
|
||||
|
||||
public:
|
||||
virtual const char* what() const noexcept override{
|
||||
return "Value out of allowed range.";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_EXCEPTION_HPP
|
||||
|
|
@ -1,547 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_EXTIMAGEINFO_HPP
|
||||
#define TWPP_DETAIL_FILE_EXTIMAGEINFO_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
/// Mapping of info type to type identifier and data type.
|
||||
template<InfoId id> struct Ext {};
|
||||
template<> struct Ext<InfoId::BarCodeCount> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeConfidence> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeRotation> {static constexpr const Type twty = Type::UInt32; typedef BarCodeRotation DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeTextLength> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeText> {static constexpr const Type twty = Type::Handle; typedef char DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeX> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeY> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::BarCodeType> {static constexpr const Type twty = Type::UInt32; typedef BarCodeType DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::DeShadeCount> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeTop> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeLeft> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeHeight> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeWidth> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeSize> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeBlackCountOld> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeBlackCountNew> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeBlackRlMin> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeBlackRlMax> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeWhiteCountOld> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeWhiteCountNew> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeWhiteRlMin> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadeWhiteRlMax> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DeShadEWhiteRlAve> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::SpecklesRemoved> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::BlackSpecklesRemoved> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::WhiteSpecklesRemoved> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::HorzLineCount> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::HorzLineXCoord> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::HorzLineYCoord> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::HorzLineLength> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::HorzLineThickness> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::VertLineCount> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::VertLineXCoord> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::VertLineYCoord> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::VertLineLength> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::VertLineThickness> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::PatchCode> {static constexpr const Type twty = Type::UInt32; typedef PatchCode DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::DeskewStatus> {static constexpr const Type twty = Type::UInt32; typedef DeskewStatus DataType;};
|
||||
template<> struct Ext<InfoId::SkewOriginalAngle> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewFinalAngle> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewConfidence> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowX1> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowY1> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowX2> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowY2> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowX3> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowY3> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowX4> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::SkewWindowY4> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::EndorsedText> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::FormConfidence> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::FormTemplateMatch> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
template<> struct Ext<InfoId::FormTemplatePageMatch> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::FormHorzDocOffset> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::FormVertDocOffset> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::BookName> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
template<> struct Ext<InfoId::ChapterNumber> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::DocumentNumber> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::PageNumber> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::Camera> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
template<> struct Ext<InfoId::FrameNumber> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::Frame> {static constexpr const Type twty = Type::Frame; typedef Frame DataType;};
|
||||
template<> struct Ext<InfoId::PixelFlavor> {static constexpr const Type twty = Type::UInt16; typedef PixelFlavor DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::IccProfile> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
template<> struct Ext<InfoId::LastSegment> {static constexpr const Type twty = Type::Bool; typedef Bool DataType;};
|
||||
template<> struct Ext<InfoId::SegmentNumber> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::MagType> {static constexpr const Type twty = Type::UInt16; typedef MagType DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::FileSystemSource> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
template<> struct Ext<InfoId::ImageMerged> {static constexpr const Type twty = Type::Bool; typedef Bool DataType;};
|
||||
template<> struct Ext<InfoId::MagData> {static constexpr const Type twty = Type::Str255; typedef char DataType;}; // NOTE: InfoId::MagData may also contain Handle
|
||||
template<> struct Ext<InfoId::MagDataLength> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
template<> struct Ext<InfoId::PageSide> {static constexpr const Type twty = Type::UInt16; typedef PageSide DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::PaperCount> {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;};
|
||||
|
||||
template<> struct Ext<InfoId::PrinterText> {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;};
|
||||
|
||||
}
|
||||
|
||||
class Info;
|
||||
class ExtImageInfo;
|
||||
|
||||
namespace Detail {
|
||||
|
||||
static Handle handleItem(Info& info) noexcept;
|
||||
|
||||
static void deleteInfo(Info& info) noexcept;
|
||||
|
||||
}
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Extended image information entry.
|
||||
class Info {
|
||||
|
||||
friend class ExtImageInfo;
|
||||
friend Handle Detail::handleItem(Info& info) noexcept;
|
||||
friend void Detail::deleteInfo(Info& info) noexcept;
|
||||
static constexpr const UInt32 DATA_HANDLE_THRESHOLD = sizeof(UIntPtr); // NOTE: specification says 4 bytes, yet pointer size makes more sense
|
||||
|
||||
public:
|
||||
template<typename DataType>
|
||||
class Items {
|
||||
|
||||
friend class Info;
|
||||
|
||||
public:
|
||||
typedef Detail::MaybeLock<DataType> Data;
|
||||
|
||||
constexpr Items() noexcept :
|
||||
m_parent(nullptr){}
|
||||
|
||||
Items(const Items&) = default;
|
||||
Items& operator=(const Items&) = default;
|
||||
|
||||
Items(Items&&) = default;
|
||||
Items& operator=(Items&&) = default;
|
||||
|
||||
operator bool() const noexcept{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
Data at(UInt32 i) const{
|
||||
if (m_parent->hasDataHandle() && m_parent->type() == Type::Handle){
|
||||
return reinterpret_cast<Handle*>(m_data.data())[i];
|
||||
} else {
|
||||
return reinterpret_cast<DataType*>(m_data.data() + i * typeSize(m_parent->type()));
|
||||
}
|
||||
}
|
||||
|
||||
Data operator[](UInt32 i) const{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
private:
|
||||
Items(Info& parent, Detail::MaybeLock<char> data) noexcept :
|
||||
m_parent(&parent), m_data(data){}
|
||||
|
||||
Info* m_parent;
|
||||
Detail::MaybeLock<char> m_data;
|
||||
// [items] <=> !(big and handle)
|
||||
// [handles]->handles*[items] <=> big and handle (this should teoretically not happen)
|
||||
|
||||
};
|
||||
|
||||
Info(const Info&) = delete;
|
||||
Info& operator=(const Info&) = delete;
|
||||
|
||||
Info(Info&&) = delete;
|
||||
Info& operator=(Info&&) = delete;
|
||||
|
||||
/// Information type ID.
|
||||
InfoId id() const noexcept{
|
||||
return m_infoId;
|
||||
}
|
||||
|
||||
/// Information data type ID.
|
||||
Type type() const noexcept{
|
||||
return m_itemType;
|
||||
}
|
||||
|
||||
/// Number of items in this entry.
|
||||
UInt16 size() const noexcept{
|
||||
return m_numItems;
|
||||
}
|
||||
|
||||
/// Allocates space for the supplied number of items.
|
||||
/// Allocating handles is not supported.
|
||||
/// \tparam id Information type ID. Data types are set accordingly.
|
||||
/// \param count Number of items to allocate.
|
||||
/// \throw TypeException When `type` is handle or invalid.
|
||||
/// \throw std::bad_alloc
|
||||
template<InfoId id>
|
||||
void allocSimple(UInt16 count = 1){
|
||||
allocSimple(Detail::Ext<id>::twty, count);
|
||||
}
|
||||
|
||||
/// Allocates space for the supplied number of items.
|
||||
/// Allocating handles is not supported.
|
||||
/// \param type Data type ID.
|
||||
/// \param count Number of items to allocate.
|
||||
/// \throw TypeException When `type` is handle or invalid.
|
||||
/// \throw std::bad_alloc
|
||||
void allocSimple(Type type, UInt16 count = 1){
|
||||
if (type == Type::Handle){
|
||||
throw TypeException();
|
||||
}
|
||||
|
||||
if (type == m_itemType && count == m_numItems){
|
||||
return;
|
||||
}
|
||||
|
||||
auto itemSize = typeSize(type);
|
||||
|
||||
bool big = hasDataHandle(type, count);
|
||||
// [items] <=> !big
|
||||
// handle->[items] <=> big
|
||||
|
||||
Detail::UniqueHandle newItem;
|
||||
if (big){
|
||||
newItem = Detail::alloc(itemSize * count);
|
||||
}
|
||||
|
||||
Detail::deleteInfo(*this);
|
||||
|
||||
if (big){
|
||||
*Detail::alias_cast<Handle*>(&m_item) = newItem.release();
|
||||
}
|
||||
|
||||
m_itemType = type;
|
||||
m_numItems = count;
|
||||
}
|
||||
|
||||
/// Allocates a single memory area owned by a handle.
|
||||
/// Info type changes to handle.
|
||||
/// \param itemSize Number of bytes to allocate.
|
||||
/// \throw std::bad_alloc
|
||||
void allocHandle(UInt32 itemSize){
|
||||
// handle->[chars]
|
||||
auto newItem = Detail::UniqueHandle(Detail::alloc(itemSize));
|
||||
|
||||
Detail::deleteInfo(*this);
|
||||
*Detail::alias_cast<Handle*>(&m_item) = newItem.release();
|
||||
|
||||
m_itemType = Type::Handle;
|
||||
m_numItems = 1;
|
||||
}
|
||||
|
||||
/// Status of this entry.
|
||||
ReturnCode returnCode() const noexcept{
|
||||
return m_returnCode;
|
||||
}
|
||||
|
||||
/// Sets status of this entry.
|
||||
void setReturnCode(ReturnCode rc) noexcept{
|
||||
m_returnCode = rc;
|
||||
}
|
||||
|
||||
/// Returns items contained in this entry.
|
||||
/// \tparam type ID of the internal data type.
|
||||
/// \tparam DataType Exported data type.
|
||||
/// \throw TypeException When types don't match.
|
||||
template<Type type, typename DataType>
|
||||
Items<DataType> items(){
|
||||
if (type != m_itemType || (type != Type::Handle && typeSize(type) != sizeof(DataType))){
|
||||
throw TypeException();
|
||||
}
|
||||
|
||||
return itemsPriv<DataType>();
|
||||
}
|
||||
|
||||
/// Returns items contained in this entry.
|
||||
/// \tparam type ID of the internal data type.
|
||||
/// \throw TypeException When types don't match.
|
||||
template<Type type>
|
||||
Items<typename Detail::Twty<type>::Type> items(){
|
||||
if (type != m_itemType){
|
||||
throw TypeException();
|
||||
}
|
||||
|
||||
return itemsPriv<typename Detail::Twty<type>::Type>();
|
||||
}
|
||||
|
||||
/// Returns items contained in this entry.
|
||||
/// \tparam id Information type ID. Data types are set accordingly.
|
||||
/// \throw TypeException When types don't match.
|
||||
template<InfoId id>
|
||||
Items<typename Detail::Ext<id>::DataType> items(){
|
||||
if (Detail::Ext<id>::twty != m_itemType){
|
||||
throw TypeException();
|
||||
}
|
||||
|
||||
return itemsPriv<typename Detail::Ext<id>::DataType>();
|
||||
}
|
||||
|
||||
private:
|
||||
bool hasDataHandle() const{
|
||||
return hasDataHandle(type(), size());
|
||||
}
|
||||
|
||||
static bool hasDataHandle(Type type, UInt16 size){
|
||||
return type != Type::DontCare && size * typeSize(type) > DATA_HANDLE_THRESHOLD;
|
||||
}
|
||||
|
||||
template<typename DataType>
|
||||
Items<DataType> itemsPriv(){
|
||||
bool big = hasDataHandle();
|
||||
bool handle = m_itemType == Type::Handle;
|
||||
|
||||
Detail::MaybeLock<char> lock;
|
||||
if (!big && !handle){
|
||||
lock = Detail::alias_cast<char*>(&m_item);
|
||||
} else {
|
||||
lock = *Detail::alias_cast<Handle*>(&m_item);
|
||||
}
|
||||
|
||||
return {*this, std::move(lock)};
|
||||
}
|
||||
|
||||
template<typename T, std::size_t len>
|
||||
static bool arrContains(const T(& arr)[len], const T& val) noexcept{
|
||||
for (std::size_t i = 0; i < len; i++){
|
||||
if (arr[i] == val){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
InfoId m_infoId;
|
||||
Type m_itemType;
|
||||
UInt16 m_numItems;
|
||||
ReturnCode m_returnCode;
|
||||
UIntPtr m_item;
|
||||
// [items] <=> !big and !handle
|
||||
// handle->[items] <=> big xor handle
|
||||
// handle->[handles]->handles*[items] <=> big and handle (this should teoretically not happen)
|
||||
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
|
||||
static inline Handle handleItem(Info& info) noexcept{
|
||||
return Handle(*Detail::alias_cast<Handle::Raw*>(&info.m_item));
|
||||
}
|
||||
|
||||
static inline void deleteInfo(Info& info) noexcept{
|
||||
bool big = isType(info.type()) && info.hasDataHandle();
|
||||
bool handle = info.type() == Type::Handle;
|
||||
|
||||
// [items] <=> !big and !handle
|
||||
// handle->[items] <=> big xor handle
|
||||
// handle->[handles]->handles*[items] <=> big and handle (this should teoretically not happen)
|
||||
|
||||
if (big && handle){
|
||||
Detail::Lock<Handle> lock(handleItem(info));
|
||||
for (UInt16 i = 0; i < info.size(); i++){
|
||||
Detail::free(lock.data()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (big || handle){
|
||||
Detail::free(handleItem(info));
|
||||
}
|
||||
}
|
||||
|
||||
struct ExtImageInfoData {
|
||||
UInt32 m_numInfos;
|
||||
Info m_infos[1];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TWPP_DETAIL_PACK_END
|
||||
/// Extended image information.
|
||||
/// Application sends list of info IDs,
|
||||
/// source sets their data.
|
||||
class ExtImageInfo {
|
||||
|
||||
public:
|
||||
typedef Info* iterator;
|
||||
typedef const Info* const_iterator;
|
||||
|
||||
/// Creates an invalid object.
|
||||
ExtImageInfo() noexcept {}
|
||||
|
||||
/// Creates a new structure for all supplied info IDs.
|
||||
/// Sources must not call this constructor, they
|
||||
/// are required to fill data in existing instance.
|
||||
/// \param ids List of requested info IDs to be filled in by the source.
|
||||
ExtImageInfo(std::initializer_list<InfoId> ids) :
|
||||
m_data(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]()) {
|
||||
|
||||
d()->m_numInfos = static_cast<UInt32>(ids.size());
|
||||
|
||||
Info* infos = d()->m_infos;
|
||||
|
||||
UInt32 i = 0;
|
||||
for (auto id : ids) {
|
||||
auto& info = infos[i];
|
||||
i++;
|
||||
|
||||
info.m_infoId = id;
|
||||
info.m_itemType = Type::DontCare;
|
||||
}
|
||||
}
|
||||
void set_data(const std::list<InfoId>& ids) noexcept {
|
||||
m_data.reset(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]);
|
||||
|
||||
d()->m_numInfos = static_cast<UInt32>(ids.size());
|
||||
|
||||
Info* infos = d()->m_infos;
|
||||
UInt32 i = 0;
|
||||
for (const auto id : ids) {
|
||||
auto& info = infos[i];
|
||||
i++;
|
||||
|
||||
info.m_infoId = id;
|
||||
info.m_itemType = Type::DontCare;
|
||||
}
|
||||
}
|
||||
|
||||
ExtImageInfo(ExtImageInfo&&) = default;
|
||||
ExtImageInfo& operator=(ExtImageInfo&&) = default;
|
||||
|
||||
operator bool() const noexcept{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
bool isValid() const noexcept{
|
||||
return static_cast<bool>(m_data);
|
||||
}
|
||||
|
||||
/// Number of requested entries.
|
||||
UInt32 size() const noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_numInfos;
|
||||
}
|
||||
|
||||
/// Information entry.
|
||||
Info& at(UInt32 i) noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_infos[i];
|
||||
}
|
||||
|
||||
/// Information entry.
|
||||
const Info& at(UInt32 i) const noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_infos[i];
|
||||
}
|
||||
|
||||
Info& operator[](UInt32 i) noexcept{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
const Info& operator[](UInt32 i) const noexcept{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
|
||||
iterator begin() noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_infos;
|
||||
}
|
||||
|
||||
const_iterator begin() const noexcept{
|
||||
return cbegin();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_infos;
|
||||
}
|
||||
|
||||
iterator end() noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_infos + d()->m_numInfos;
|
||||
}
|
||||
|
||||
const_iterator end() const noexcept{
|
||||
return cend();
|
||||
}
|
||||
|
||||
const_iterator cend() const noexcept{
|
||||
assert(isValid());
|
||||
return d()->m_infos + d()->m_numInfos;
|
||||
}
|
||||
|
||||
private:
|
||||
Detail::ExtImageInfoData* d() noexcept{
|
||||
return reinterpret_cast<Detail::ExtImageInfoData*>(m_data.get());
|
||||
}
|
||||
|
||||
Detail::ExtImageInfoData* d() const noexcept{
|
||||
return reinterpret_cast<Detail::ExtImageInfoData*>(m_data.get());
|
||||
}
|
||||
|
||||
struct Deleter {
|
||||
void operator()(char* ptr) noexcept{
|
||||
Detail::ExtImageInfoData* data = reinterpret_cast<Detail::ExtImageInfoData*>(ptr);
|
||||
if (data){
|
||||
for (UInt32 i = 0; i < data->m_numInfos; i++){
|
||||
Detail::deleteInfo(data->m_infos[i]);
|
||||
}
|
||||
|
||||
delete [] ptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<char[], Deleter> m_data;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_EXTIMAGEINFO_HPP
|
||||
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_FILESYSTEM_HPP
|
||||
#define TWPP_DETAIL_FILE_FILESYSTEM_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure representing device filesystem and operations on it.
|
||||
class FileSystem {
|
||||
|
||||
public:
|
||||
/// Type of file.
|
||||
enum class Type : Int32 {
|
||||
Camera = 0,
|
||||
CameraTop = 1,
|
||||
CameraBottom = 2,
|
||||
CameraPreview = 3,
|
||||
Domain = 4,
|
||||
Host = 5,
|
||||
Directory = 6,
|
||||
Image = 7,
|
||||
Unknown = 8
|
||||
};
|
||||
|
||||
/// Creates uninitialized file system.
|
||||
constexpr FileSystem() noexcept :
|
||||
m_context(nullptr), m_recursiveBool(), m_fileType(Type::Camera), m_size(),
|
||||
m_freeSpace(), m_newImageSize(), m_numberOfFiles(), m_numberOfSnippets(),
|
||||
m_deviceGroupMask(), m_reserved(){}
|
||||
|
||||
/// Creates file system with input and output paths and optional context.
|
||||
constexpr FileSystem(const Str255& inputPath, const Str255& outputPath, void* context = nullptr) noexcept :
|
||||
m_inputPath(inputPath), m_outputPath(outputPath), m_context(context),
|
||||
m_recursiveBool(), m_fileType(Type::Camera), m_size(), m_freeSpace(), m_newImageSize(),
|
||||
m_numberOfFiles(), m_numberOfSnippets(), m_deviceGroupMask(), m_reserved(){}
|
||||
|
||||
/// Input or source file.
|
||||
constexpr const Str255& inputPath() const noexcept{
|
||||
return m_inputPath;
|
||||
}
|
||||
|
||||
/// Sets input or source file.
|
||||
void setInputPath(const Str255& path) noexcept{
|
||||
m_inputPath = path;
|
||||
}
|
||||
|
||||
/// Operation result, or destination file.
|
||||
constexpr const Str255& outputPath() const noexcept{
|
||||
return m_outputPath;
|
||||
}
|
||||
|
||||
/// Sets operation result, or destination file.
|
||||
void setOutputPath(const Str255& path) noexcept{
|
||||
m_outputPath = path;
|
||||
}
|
||||
|
||||
/// Source specific context.
|
||||
constexpr void* context() const noexcept{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
/// Sets source specific context.
|
||||
void setContext(void* context) noexcept{
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
/// Whether the operation is recursive.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::Delete.
|
||||
constexpr Bool recursive() const noexcept{
|
||||
return m_recursiveBool;
|
||||
}
|
||||
|
||||
/// Sets whether the operation is recursive.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::Delete.
|
||||
void setRecursive(Bool recursive) noexcept{
|
||||
m_recursiveBool = recursive;
|
||||
}
|
||||
|
||||
/// File type.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
constexpr Type type() const noexcept{
|
||||
return m_fileType;
|
||||
}
|
||||
|
||||
/// Sets file type.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
void setType(Type type) noexcept{
|
||||
m_fileType = type;
|
||||
}
|
||||
|
||||
/// Number of bytes of the entry.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
constexpr UInt32 size() const noexcept{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/// Sets number of bytes of the entry.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
void setSize(UInt32 size) noexcept{
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
/// Creation date of the file.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
/// YYYY/MM/DD HH:mm:SS:sss
|
||||
constexpr const Str32& createdTimeDate() const noexcept{
|
||||
return m_createdTimeDate;
|
||||
}
|
||||
|
||||
/// Sets creation date of the file.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
/// YYYY/MM/DD HH:mm:SS:sss
|
||||
void setCreatedTimeDate(const Str32& val) noexcept{
|
||||
m_createdTimeDate = val;
|
||||
}
|
||||
|
||||
/// Modification date of the file.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
/// YYYY/MM/DD HH:mm:SS:sss
|
||||
constexpr const Str32& modifiedTimeDate() const noexcept{
|
||||
return m_modifiedTimeDate;
|
||||
}
|
||||
|
||||
/// Sets modification date of the file.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
/// YYYY/MM/DD HH:mm:SS:sss
|
||||
void setModifiedTimeDate(const Str32& val) noexcept{
|
||||
m_modifiedTimeDate = val;
|
||||
}
|
||||
|
||||
/// Number of bytes left on the device.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
constexpr UInt32 freeSpace() const noexcept{
|
||||
return m_freeSpace;
|
||||
}
|
||||
|
||||
/// Sets number of bytes left on the device.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
void setFreeSpace(UInt32 freeSpace) noexcept{
|
||||
m_freeSpace = freeSpace;
|
||||
}
|
||||
|
||||
/// Estimated image size in bytes.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
constexpr Int32 newImageSize() const noexcept{
|
||||
return m_newImageSize;
|
||||
}
|
||||
|
||||
/// Sets estimated image size in bytes.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
void setNewImageSize(Int32 newImageSize) noexcept{
|
||||
m_newImageSize = newImageSize;
|
||||
}
|
||||
|
||||
/// Total number of files including subdirectories.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
constexpr UInt32 files() const noexcept{
|
||||
return m_numberOfFiles;
|
||||
}
|
||||
|
||||
/// Sets total number of files including subdirectories.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
void setFiles(UInt32 files) noexcept{
|
||||
m_numberOfFiles = files;
|
||||
}
|
||||
|
||||
/// Number of audio snippets.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
constexpr UInt32 snippets() const noexcept{
|
||||
return m_numberOfSnippets;
|
||||
}
|
||||
|
||||
/// Sets number of audio snippets.
|
||||
/// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext.
|
||||
void snippets(UInt32 snippets) noexcept{
|
||||
m_numberOfSnippets = snippets;
|
||||
}
|
||||
|
||||
/// See manual for explanation of this field, `DeviceGroupMask`.
|
||||
constexpr UInt32 groupMask() const noexcept{
|
||||
return m_deviceGroupMask;
|
||||
}
|
||||
|
||||
/// See manual for explanation of this field, `DeviceGroupMask`.
|
||||
void groupMask(UInt32 groupMask) noexcept{
|
||||
m_deviceGroupMask = groupMask;
|
||||
}
|
||||
|
||||
private:
|
||||
void unused() const{
|
||||
Detail::unused(m_reserved);
|
||||
}
|
||||
|
||||
Str255 m_inputPath;
|
||||
Str255 m_outputPath;
|
||||
void* m_context;
|
||||
|
||||
// Copy, Delete
|
||||
union {
|
||||
int m_recursive;
|
||||
Bool m_recursiveBool;
|
||||
};
|
||||
|
||||
// GetInfo
|
||||
Type m_fileType;
|
||||
UInt32 m_size;
|
||||
Str32 m_createdTimeDate;
|
||||
Str32 m_modifiedTimeDate;
|
||||
UInt32 m_freeSpace;
|
||||
Int32 m_newImageSize;
|
||||
UInt32 m_numberOfFiles;
|
||||
UInt32 m_numberOfSnippets;
|
||||
UInt32 m_deviceGroupMask;
|
||||
Int8 m_reserved[508];
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_FILESYSTEM_HPP
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_FIX32_HPP
|
||||
#define TWPP_DETAIL_FILE_FIX32_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
static constexpr inline Int32 floatToValue(float val){
|
||||
return static_cast<Int32>(
|
||||
(val >= 0.0f) ?
|
||||
(val * 65536.0f + 0.5f) :
|
||||
(val * 65536.0f - 0.5f)
|
||||
);
|
||||
}
|
||||
|
||||
static constexpr inline Int16 floatToWhole(float val){
|
||||
return static_cast<Int16>(floatToValue(val) >> 16);
|
||||
}
|
||||
|
||||
static constexpr inline UInt16 floatToFrac(float val){
|
||||
return static_cast<UInt16>(floatToValue(val) & 0xFFFF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// TWAIN fixed point fractional type.
|
||||
/// The fractional part has resolution of 1/65536.
|
||||
class Fix32 {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized fixed type.
|
||||
constexpr Fix32() noexcept :
|
||||
m_whole(0), m_frac(0){}
|
||||
|
||||
/// Creates fixed type from float at compile time if possible.
|
||||
constexpr Fix32(float value) noexcept :
|
||||
m_whole(Detail::floatToWhole(value)), m_frac(Detail::floatToFrac(value)){}
|
||||
|
||||
/// Creates fixed type from whole and fractional parts.
|
||||
/// The fractional part has resolution of 1/65536.
|
||||
constexpr Fix32(Int16 whole, UInt16 frac) noexcept :
|
||||
m_whole(whole), m_frac(frac){}
|
||||
|
||||
|
||||
/// Whole part of this fixed type.
|
||||
constexpr Int16 whole() const noexcept{
|
||||
return m_whole;
|
||||
}
|
||||
|
||||
/// Sets whole part of this fixed type.
|
||||
void setWhole(Int16 whole) noexcept{
|
||||
m_whole = whole;
|
||||
}
|
||||
|
||||
/// Fractional part of this fixed type.
|
||||
/// Resolution of 1/65536.
|
||||
constexpr UInt16 frac() const noexcept{
|
||||
return m_frac;
|
||||
}
|
||||
|
||||
/// Sets fractional part of this fixed type.
|
||||
/// Resolution of 1/65536.
|
||||
void setFrac(UInt16 frac) noexcept{
|
||||
m_frac = frac;
|
||||
}
|
||||
|
||||
explicit constexpr operator float() const noexcept{
|
||||
return m_whole + m_frac / 65536.0f;
|
||||
}
|
||||
|
||||
constexpr float toFloat() const noexcept{
|
||||
return m_whole + m_frac / 65536.0f;
|
||||
}
|
||||
|
||||
constexpr Fix32 operator-() const noexcept{
|
||||
return -toFloat();
|
||||
}
|
||||
|
||||
private:
|
||||
Int16 m_whole;
|
||||
UInt16 m_frac;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
namespace Detail {
|
||||
|
||||
static inline constexpr Fix32 fix32AddHelper(Int32 frac, Int16 whole){
|
||||
return frac < 65536 ? Fix32(whole, frac) : Fix32(whole + 1, frac - 65536);
|
||||
}
|
||||
|
||||
static inline constexpr Fix32 fix32SubHelper(Int32 frac, Int16 whole){
|
||||
return frac >= 0 ? Fix32(whole, frac) : Fix32(whole - 1, frac + 65536);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline constexpr bool operator>(Fix32 a, Fix32 b) noexcept{
|
||||
return a.whole() > b.whole() || (a.whole() == b.whole() && a.frac() > b.frac());
|
||||
}
|
||||
|
||||
static inline constexpr bool operator<(Fix32 a, Fix32 b) noexcept{
|
||||
return a.whole() < b.whole() || (a.whole() == b.whole() && a.frac() < b.frac());
|
||||
}
|
||||
|
||||
static inline constexpr bool operator>=(Fix32 a, Fix32 b) noexcept{
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
static inline constexpr bool operator<=(Fix32 a, Fix32 b) noexcept{
|
||||
return !(a > b);
|
||||
}
|
||||
|
||||
static inline constexpr bool operator==(Fix32 a, Fix32 b) noexcept{
|
||||
return a.whole() == b.whole() && a.frac() == b.frac();
|
||||
}
|
||||
|
||||
static inline constexpr bool operator!=(Fix32 a, Fix32 b) noexcept{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
static inline constexpr Fix32 operator+(Fix32 a, Fix32 b) noexcept{
|
||||
return Detail::fix32AddHelper(static_cast<Int32>(a.frac()) + b.frac(), a.whole() + b.whole());
|
||||
}
|
||||
|
||||
static inline constexpr Fix32 operator-(Fix32 a, Fix32 b) noexcept{
|
||||
return Detail::fix32SubHelper(static_cast<Int32>(a.frac()) - b.frac(), a.whole() - b.whole());
|
||||
}
|
||||
|
||||
static inline constexpr Fix32 operator*(Fix32 a, Fix32 b) noexcept{
|
||||
return Fix32(static_cast<float>(a) * static_cast<float>(b));
|
||||
}
|
||||
|
||||
static inline constexpr Fix32 operator/(Fix32 a, Fix32 b) noexcept{ // wonder about zero b
|
||||
return Fix32(static_cast<float>(a) / static_cast<float>(b));
|
||||
}
|
||||
|
||||
static inline Fix32& operator+=(Fix32& a, Fix32 b) noexcept{
|
||||
return a = a + b;
|
||||
}
|
||||
|
||||
static inline Fix32& operator-=(Fix32& a, Fix32 b) noexcept{
|
||||
return a = a - b;
|
||||
}
|
||||
|
||||
static inline Fix32& operator*=(Fix32& a, Fix32 b) noexcept{
|
||||
return a = a * b;
|
||||
}
|
||||
|
||||
static inline Fix32& operator/=(Fix32& a, Fix32 b) noexcept{ // wonder about zero b
|
||||
return a = a / b;
|
||||
}
|
||||
|
||||
namespace Literals {
|
||||
|
||||
static inline constexpr Fix32 operator "" _fix(long double val) noexcept{
|
||||
return Fix32(static_cast<float>(val));
|
||||
}
|
||||
|
||||
static inline constexpr Fix32 operator "" _fix(unsigned long long val) noexcept{
|
||||
return Fix32(static_cast<float>(val));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_FIX32_HPP
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_FRAME_HPP
|
||||
#define TWPP_DETAIL_FILE_FRAME_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Section of an image to retrieve.
|
||||
class Frame {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized frame.
|
||||
constexpr Frame() noexcept{}
|
||||
|
||||
/// Creates frame with set top-left and bottom-right corners.
|
||||
constexpr Frame(Fix32 left, Fix32 top, Fix32 right, Fix32 bottom) noexcept :
|
||||
m_left(left), m_top(top), m_right(right), m_bottom(bottom){}
|
||||
|
||||
/// Left position of the image frame.
|
||||
constexpr Fix32 left() const noexcept{
|
||||
return m_left;
|
||||
}
|
||||
|
||||
/// Sets left position of the image frame.
|
||||
void setLeft(Fix32 left) noexcept{
|
||||
m_left = left;
|
||||
}
|
||||
|
||||
/// Top position of the image frame.
|
||||
constexpr Fix32 top() const noexcept{
|
||||
return m_top;
|
||||
}
|
||||
|
||||
/// Sets top position of the image frame.
|
||||
void setTop(Fix32 top) noexcept{
|
||||
m_top = top;
|
||||
}
|
||||
|
||||
/// Right position of the image frame.
|
||||
constexpr Fix32 right() const noexcept{
|
||||
return m_right;
|
||||
}
|
||||
|
||||
/// Sets right position of the image frame.
|
||||
void setRight(Fix32 right) noexcept{
|
||||
m_right = right;
|
||||
}
|
||||
|
||||
/// Bottom position of the image frame.
|
||||
constexpr Fix32 bottom() const noexcept{
|
||||
return m_bottom;
|
||||
}
|
||||
|
||||
/// Sets bottom position of the image frame.
|
||||
void setBottom(Fix32 bottom) noexcept{
|
||||
m_bottom = bottom;
|
||||
}
|
||||
|
||||
private:
|
||||
Fix32 m_left;
|
||||
Fix32 m_top;
|
||||
Fix32 m_right;
|
||||
Fix32 m_bottom;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
static constexpr inline bool operator==(const Frame& a, const Frame& b) noexcept{
|
||||
return a.left() == b.left() && a.top() == b.top() && a.right() == b.right() && a.bottom() == b.bottom();
|
||||
}
|
||||
|
||||
static constexpr inline bool operator!=(const Frame& a, const Frame& b) noexcept{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_FRAME_HPP
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_IDENTITY_HPP
|
||||
#define TWPP_DETAIL_FILE_IDENTITY_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
static constexpr const UInt32 identV2 = TWPP_DETAIL_IS_DS ? Detail::Ds2 : Detail::App2;
|
||||
|
||||
}
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Source or application version information.
|
||||
class Version {
|
||||
|
||||
public:
|
||||
/// Creates default-initialized version.
|
||||
constexpr Version() noexcept :
|
||||
m_majorNum(0), m_minorNum(0), m_language(Language::English),
|
||||
m_country(Country::UnitedKingdom){}
|
||||
|
||||
/// Creates version initialized with supplied values.
|
||||
constexpr Version(
|
||||
UInt16 majorNumber,
|
||||
UInt16 minorNumber,
|
||||
Language language,
|
||||
Country country,
|
||||
const Str32& info = Str32()) noexcept :
|
||||
m_majorNum(majorNumber), m_minorNum(minorNumber), m_language(language),
|
||||
m_country(country), m_info(info){}
|
||||
|
||||
/// Major version number of the source or application.
|
||||
constexpr UInt16 majorNumber() const noexcept{
|
||||
return m_majorNum;
|
||||
}
|
||||
|
||||
/// Sets major version number of the source or application.
|
||||
void setMajorNumber(UInt16 major) noexcept{
|
||||
m_majorNum = major;
|
||||
}
|
||||
|
||||
/// Minor version number of the source or application.
|
||||
constexpr UInt16 minorNumber() const noexcept{
|
||||
return m_minorNum;
|
||||
}
|
||||
|
||||
/// Sets minor version number of the source or application.
|
||||
void setMinorNumber(UInt16 minor) noexcept{
|
||||
m_minorNum = minor;
|
||||
}
|
||||
|
||||
/// Language of the source or application.
|
||||
constexpr Language language() const noexcept{
|
||||
return m_language;
|
||||
}
|
||||
|
||||
/// Sets language of the source or application.
|
||||
void setLanguage(Language language) noexcept{
|
||||
m_language = language;
|
||||
}
|
||||
|
||||
/// Original country of the source or application.
|
||||
constexpr Country country() const noexcept{
|
||||
return m_country;
|
||||
}
|
||||
|
||||
/// Set original country of the source or application.
|
||||
void setCountry(Country country) noexcept{
|
||||
m_country = country;
|
||||
}
|
||||
|
||||
/// Additional version information of the source or application.
|
||||
constexpr const Str32& info() const noexcept{
|
||||
return m_info;
|
||||
}
|
||||
|
||||
/// Sets additional version information of the source or application.
|
||||
void setInfo(const Str32& info) noexcept{
|
||||
m_info = info;
|
||||
}
|
||||
|
||||
private:
|
||||
UInt16 m_majorNum;
|
||||
UInt16 m_minorNum;
|
||||
Language m_language;
|
||||
Country m_country;
|
||||
Str32 m_info;
|
||||
|
||||
};
|
||||
|
||||
/// Source or application identity.
|
||||
/// Uniquely identifies an endpoint.
|
||||
class Identity {
|
||||
|
||||
public:
|
||||
typedef
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
void*
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
UInt32
|
||||
#else
|
||||
# error "Identity::Id for your platform here"
|
||||
#endif
|
||||
Id;
|
||||
|
||||
/// Creates default-initialized identity.
|
||||
/// ID is set to zero.
|
||||
/// TWAIN protocol is always Detail::ProtoMajor and Detail::ProtoMinor.
|
||||
/// Supported group always contains DG::Control and V2.
|
||||
constexpr Identity() noexcept :
|
||||
m_id(), m_protoMaj(Detail::ProtoMajor), m_protoMin(Detail::ProtoMinor),
|
||||
m_groups(DataGroup::Control | Detail::identV2){}
|
||||
|
||||
/// Creates identity initialized with supplied values.
|
||||
/// ID is set to zero.
|
||||
/// TWAIN protocol is always Detail::ProtoMajor and Detail::ProtoMinor.
|
||||
/// Supported group always contains DG::Control and V2.
|
||||
constexpr Identity(
|
||||
const Version& version,
|
||||
DataGroup group,
|
||||
const Str32& manufacturer,
|
||||
const Str32& productFamily,
|
||||
const Str32& productName) noexcept :
|
||||
m_id(), m_version(version), m_protoMaj(Detail::ProtoMajor),
|
||||
m_protoMin(Detail::ProtoMinor), m_groups(DataGroup::Control | group | Detail::identV2),
|
||||
m_manuf(manufacturer), m_prodFamily(productFamily), m_prodName(productName){}
|
||||
|
||||
/// Creates identity initialized with supplied values.
|
||||
constexpr Identity(
|
||||
Id id,
|
||||
const Version& version,
|
||||
UInt16 protoMajor,
|
||||
UInt16 protoMinor,
|
||||
UInt32 groups,
|
||||
const Str32& manufacturer,
|
||||
const Str32& productFamily,
|
||||
const Str32& productName) noexcept :
|
||||
m_id(id), m_version(version), m_protoMaj(protoMajor), m_protoMin(protoMinor),
|
||||
m_groups(groups), m_manuf(manufacturer), m_prodFamily(productFamily),
|
||||
m_prodName(productName){}
|
||||
|
||||
/// DSM-supplied ID of this identity.
|
||||
constexpr Id id() const{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/// Version information.
|
||||
constexpr const Version& version() const noexcept{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
/// Whether a data group is supported.
|
||||
constexpr bool supports(DataGroup group) const noexcept{
|
||||
return (m_groups & group) != 0;
|
||||
}
|
||||
|
||||
/// Whether this is V2 application.
|
||||
constexpr bool isAppV2() const noexcept{
|
||||
return (m_groups & Detail::App2) != 0;
|
||||
}
|
||||
|
||||
/// Whether this is V2 DSM.
|
||||
constexpr bool isDsmV2() const noexcept{
|
||||
return (m_groups & Detail::Dsm2) != 0;
|
||||
}
|
||||
|
||||
/// Whether this is V2 source.
|
||||
constexpr bool isDsV2() const noexcept{
|
||||
return (m_groups & Detail::Ds2) != 0;
|
||||
}
|
||||
|
||||
/// The manufacturer.
|
||||
/// Manufacturer and product name uniquely identify a source.
|
||||
constexpr const Str32& manufacturer() const noexcept{
|
||||
return m_manuf;
|
||||
}
|
||||
|
||||
/// The product name.
|
||||
/// Manufacturer and product name uniquely identify a source.
|
||||
constexpr const Str32& productName() const noexcept{
|
||||
return m_prodName;
|
||||
}
|
||||
|
||||
/// The product family.
|
||||
constexpr const Str32& productFamily() const noexcept{
|
||||
return m_prodFamily;
|
||||
}
|
||||
|
||||
/// Raw data group flags.
|
||||
constexpr UInt32 dataGroupsRaw() const noexcept{
|
||||
return m_groups;
|
||||
}
|
||||
|
||||
/// TWAIN protocol major version.
|
||||
constexpr UInt16 protocolMajor() const noexcept{
|
||||
return m_protoMaj;
|
||||
}
|
||||
|
||||
/// TWAIN protocol minor version.
|
||||
constexpr UInt16 protocolMinor() const noexcept{
|
||||
return m_protoMin;
|
||||
}
|
||||
|
||||
private:
|
||||
Id m_id;
|
||||
Version m_version;
|
||||
UInt16 m_protoMaj;
|
||||
UInt16 m_protoMin;
|
||||
UInt32 m_groups;
|
||||
Str32 m_manuf;
|
||||
Str32 m_prodFamily;
|
||||
Str32 m_prodName;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_IDENTITY_HPP
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_IMAGEINFO_HPP
|
||||
#define TWPP_DETAIL_FILE_IMAGEINFO_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Contains information about transfered image.
|
||||
class ImageInfo {
|
||||
|
||||
typedef Detail::FixedArray<Int16, 8> BitsPerSampleImpl;
|
||||
|
||||
public:
|
||||
typedef Int16 BitsPerSample[8];
|
||||
|
||||
/// Creates zero-initialized info.
|
||||
constexpr ImageInfo() noexcept :
|
||||
m_imgWidth(0), m_imgHeight(0), m_spp(0), m_bps(), m_bpp(0),
|
||||
m_planar(0), m_pixelType(PixelType::BlackWhite), m_compression(Compression::None){}
|
||||
|
||||
/// Creates info with supplied values.
|
||||
template<std::size_t inputSize>
|
||||
constexpr ImageInfo(
|
||||
Fix32 xResolution,
|
||||
Fix32 yResolution,
|
||||
Int32 width,
|
||||
Int32 height,
|
||||
Int16 samplesPerPixel,
|
||||
const Int16(& bitsPerSample)[inputSize],
|
||||
Int16 bitsPerPixel,
|
||||
Bool planar,
|
||||
PixelType pixelType,
|
||||
Compression compression
|
||||
) noexcept :
|
||||
m_xres(xResolution), m_yres(yResolution), m_imgWidth(width), m_imgHeight(height),
|
||||
m_spp(samplesPerPixel), m_bps(bitsPerSample), m_bpp(bitsPerPixel), m_planar(planar),
|
||||
m_pixelType(pixelType), m_compression(compression){}
|
||||
|
||||
/// X-axis resolution of the image.
|
||||
constexpr Fix32 xResolution() const noexcept{
|
||||
return m_xres;
|
||||
}
|
||||
|
||||
/// Sets x-axis resolution of the image.
|
||||
void setXResolution(Fix32 xres) noexcept{
|
||||
m_xres = xres;
|
||||
}
|
||||
|
||||
/// Y-axis resolution of the image.
|
||||
constexpr Fix32 yResolution() const noexcept{
|
||||
return m_yres;
|
||||
}
|
||||
|
||||
/// Sets y-axis resolution of the image.
|
||||
void setYResolution(Fix32 yres) noexcept{
|
||||
m_yres = yres;
|
||||
}
|
||||
|
||||
/// Image width in pixels.
|
||||
constexpr Int32 width() const noexcept{
|
||||
return m_imgWidth;
|
||||
}
|
||||
|
||||
/// Sets image width in pixels.
|
||||
void setWidth(Int32 width) noexcept{
|
||||
m_imgWidth = width;
|
||||
}
|
||||
|
||||
/// Image height in pixels.
|
||||
constexpr Int32 height() const noexcept{
|
||||
return m_imgHeight;
|
||||
}
|
||||
|
||||
/// Sets image height in pixels.
|
||||
void setHeight(Int32 height) noexcept{
|
||||
m_imgHeight = height;
|
||||
}
|
||||
|
||||
/// Samples per single pixel.
|
||||
constexpr Int16 samplesPerPixel() const noexcept{
|
||||
return m_spp;
|
||||
}
|
||||
|
||||
/// Sets samples per single pixel.
|
||||
void setSamplesPerPixel(Int16 spp) noexcept{
|
||||
m_spp = spp;
|
||||
}
|
||||
|
||||
/// Array of bits per sample.
|
||||
/// Contains `samplesPerPixel` entries.
|
||||
constexpr const BitsPerSample& bitsPerSample() const noexcept{
|
||||
return m_bps.array();
|
||||
}
|
||||
|
||||
/// Array of bits per sample.
|
||||
/// Contains `samplesPerPixel` entries.
|
||||
BitsPerSample& bitsPerSample() noexcept{
|
||||
return m_bps.array();
|
||||
}
|
||||
|
||||
/// Total number of bits per pixel.
|
||||
/// This should be true: bitsPerPixel = SUM[i=0..samplesPerPixel-1](bitsPerSample[i])
|
||||
constexpr Int16 bitsPerPixel() const noexcept{
|
||||
return m_bpp;
|
||||
}
|
||||
|
||||
/// Sets total number of bits per pixel.
|
||||
/// This should be true: bitsPerPixel = SUM[i=0..samplesPerPixel-1](bitsPerSample[i])
|
||||
void setBitsPerPixel(Int16 bpp) noexcept{
|
||||
m_bpp = bpp;
|
||||
}
|
||||
|
||||
/// Whether the image is planar (consists of several sample planes) or is chunky
|
||||
/// (samples are transferes in one plane and are interlaced).
|
||||
constexpr Bool planar() const noexcept{
|
||||
return m_planar;
|
||||
}
|
||||
|
||||
/// Sets whether the image is planar (consists of several sample planes) or is chunky
|
||||
/// (samples are transferes in one plane and are interlaced).
|
||||
void setPlanar(Bool planar) noexcept{
|
||||
m_planar = planar;
|
||||
}
|
||||
|
||||
/// The type of image.
|
||||
constexpr PixelType pixelType() const noexcept{
|
||||
return m_pixelType;
|
||||
}
|
||||
|
||||
/// Sets the type of image.
|
||||
void setPixelType(PixelType pixelType) noexcept{
|
||||
m_pixelType = pixelType;
|
||||
}
|
||||
|
||||
/// Image compression.
|
||||
constexpr Compression compression() const noexcept{
|
||||
return m_compression;
|
||||
}
|
||||
|
||||
/// Sets image compression.
|
||||
void compression(Compression compression) noexcept{
|
||||
m_compression = compression;
|
||||
}
|
||||
|
||||
private:
|
||||
Fix32 m_xres;
|
||||
Fix32 m_yres;
|
||||
Int32 m_imgWidth;
|
||||
Int32 m_imgHeight;
|
||||
Int16 m_spp;
|
||||
BitsPerSampleImpl m_bps;
|
||||
Int16 m_bpp;
|
||||
Bool m_planar;
|
||||
PixelType m_pixelType;
|
||||
Compression m_compression;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_IMAGEINFO_HPP
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_IMAGELAYOUT_HPP
|
||||
#define TWPP_DETAIL_FILE_IMAGELAYOUT_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Provides image size and its position on the scanner and information about order of the image.
|
||||
class ImageLayout {
|
||||
|
||||
public:
|
||||
/// Creates layout.
|
||||
constexpr ImageLayout(
|
||||
const Frame& frame = Frame(),
|
||||
UInt32 documentNumber = 1,
|
||||
UInt32 pageNumber = 1,
|
||||
UInt32 frameNumber = 1
|
||||
) noexcept :
|
||||
m_frame(frame), m_docNumber(documentNumber),
|
||||
m_pageNumber(pageNumber), m_frameNumber(frameNumber){}
|
||||
|
||||
/// The image frame.
|
||||
constexpr const Frame& frame() const noexcept{
|
||||
return m_frame;
|
||||
}
|
||||
|
||||
/// Sets the image frame.
|
||||
void setFrame(const Frame& frame) noexcept{
|
||||
m_frame = frame;
|
||||
}
|
||||
|
||||
/// Number of the document, set by source.
|
||||
constexpr UInt32 documentNumber() const noexcept{
|
||||
return m_docNumber;
|
||||
}
|
||||
|
||||
/// Sets number of the document.
|
||||
void setDocumentNumber(UInt32 documentNumber) noexcept{
|
||||
m_docNumber = documentNumber;
|
||||
}
|
||||
|
||||
/// Number of the page, set by source.
|
||||
constexpr UInt32 pageNumber() const noexcept{
|
||||
return m_pageNumber;
|
||||
}
|
||||
|
||||
/// Sets number of the page.
|
||||
void setPageNumber(UInt32 pageNumber) noexcept{
|
||||
m_pageNumber = pageNumber;
|
||||
}
|
||||
|
||||
/// Number of the frame, set by source.
|
||||
constexpr UInt32 frameNumber() const noexcept{
|
||||
return m_frameNumber;
|
||||
}
|
||||
|
||||
/// Sets number of the frame.
|
||||
void setFrameNumber(UInt32 frameNumber) noexcept{
|
||||
m_frameNumber = frameNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
Frame m_frame;
|
||||
UInt32 m_docNumber;
|
||||
UInt32 m_pageNumber;
|
||||
UInt32 m_frameNumber;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_IMAGELAYOUT_HPP
|
|
@ -1,207 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_IMAGEMEMXFER_HPP
|
||||
#define TWPP_DETAIL_FILE_IMAGEMEMXFER_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
namespace Detail {
|
||||
|
||||
/// Structure holding the information and data of memory and memory file transfers.
|
||||
class ImageMemXferImpl {
|
||||
|
||||
public:
|
||||
/// Creates a zero-initialized structure without any memory.
|
||||
ImageMemXferImpl() noexcept :
|
||||
m_compression(Compression::None), m_bytesPerRow(0), m_columns(0), m_rows(0),
|
||||
m_xoff(0), m_yoff(0), m_bytesWritten(0){}
|
||||
|
||||
/// Creates an initialized structure from the supplied values and memory.
|
||||
/// The ownership of the memory is taken over.
|
||||
ImageMemXferImpl(
|
||||
Compression compression,
|
||||
UInt32 bytesPerRow,
|
||||
UInt32 columns,
|
||||
UInt32 rows,
|
||||
UInt32 xOffset,
|
||||
UInt32 yOffset,
|
||||
UInt32 bytesWritten,
|
||||
Memory memory
|
||||
) noexcept :
|
||||
m_compression(compression), m_bytesPerRow(bytesPerRow),
|
||||
m_columns(columns), m_rows(rows), m_xoff(xOffset), m_yoff(yOffset),
|
||||
m_bytesWritten(bytesWritten), m_memory(std::move(memory)){}
|
||||
|
||||
/// Compression used in the transfer.
|
||||
Compression compression() const noexcept{
|
||||
return m_compression;
|
||||
}
|
||||
|
||||
/// Sets compression used in the transfer.
|
||||
void setCompression(Compression compression) noexcept{
|
||||
m_compression = compression;
|
||||
}
|
||||
|
||||
/// Number of bytes per single row.
|
||||
UInt32 bytesPerRow() const noexcept{
|
||||
return m_bytesPerRow;
|
||||
}
|
||||
|
||||
/// Sets number of bytes per single row.
|
||||
void setBytesPerRow(UInt32 bytesPerRow) noexcept{
|
||||
m_bytesPerRow = bytesPerRow;
|
||||
}
|
||||
|
||||
/// Number of columns in the transfer.
|
||||
UInt32 columns() const noexcept{
|
||||
return m_columns;
|
||||
}
|
||||
|
||||
/// Sets number of columns in the transfer.
|
||||
void setColumns(UInt32 columns) noexcept{
|
||||
m_columns = columns;
|
||||
}
|
||||
|
||||
/// Number of rows in the transfer.
|
||||
UInt32 rows() const noexcept{
|
||||
return m_rows;
|
||||
}
|
||||
|
||||
/// Sets number of rows in the transfer.
|
||||
void setRows(UInt32 rows) noexcept{
|
||||
m_rows = rows;
|
||||
}
|
||||
|
||||
/// X offset from top-left corner in pixels of the image data in the transfer.
|
||||
UInt32 xOffset() const noexcept{
|
||||
return m_xoff;
|
||||
}
|
||||
|
||||
/// Sets X offset from top-left corner in pixels of the image data in the transfer.
|
||||
void setXOffset(UInt32 xOffset) noexcept{
|
||||
m_xoff = xOffset;
|
||||
}
|
||||
|
||||
/// Y offset from top-left corner in pixels of the image data in the transfer.
|
||||
UInt32 yOffset() const noexcept{
|
||||
return m_yoff;
|
||||
}
|
||||
|
||||
/// Sets Y offset from top-left corner in pixels of the image data in the transfer.
|
||||
void setYOffset(UInt32 yOffset) noexcept{
|
||||
m_yoff = yOffset;
|
||||
}
|
||||
|
||||
/// Number of bytes in this transfer, always contains whole rows or tiles.
|
||||
UInt32 bytesWritten() const noexcept{
|
||||
return m_bytesWritten;
|
||||
}
|
||||
|
||||
/// Sets number of bytes in this transfer.
|
||||
void setBytesWritten(UInt32 bytesWritten) noexcept{
|
||||
m_bytesWritten = bytesWritten;
|
||||
}
|
||||
|
||||
/// Contained memory structure.
|
||||
const Memory& memory() const noexcept{
|
||||
return m_memory;
|
||||
}
|
||||
|
||||
/// Contained memory structure.
|
||||
Memory& memory() noexcept{
|
||||
return m_memory;
|
||||
}
|
||||
|
||||
private:
|
||||
Compression m_compression;
|
||||
UInt32 m_bytesPerRow;
|
||||
UInt32 m_columns;
|
||||
UInt32 m_rows;
|
||||
UInt32 m_xoff;
|
||||
UInt32 m_yoff;
|
||||
UInt32 m_bytesWritten;
|
||||
Memory m_memory;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// Structure holding the information and data of memory transfer.
|
||||
class ImageMemXfer : public Detail::ImageMemXferImpl {
|
||||
|
||||
public:
|
||||
/// Creates a zero-initialized structure without any memory.
|
||||
ImageMemXfer() noexcept : Detail::ImageMemXferImpl(){}
|
||||
|
||||
/// Creates an initialized structure from the supplied values and memory.
|
||||
/// The ownership of the memory is taken over.
|
||||
ImageMemXfer(
|
||||
Compression compression,
|
||||
UInt32 bytesPerRow,
|
||||
UInt32 columns,
|
||||
UInt32 rows,
|
||||
UInt32 xOffset,
|
||||
UInt32 yOffset,
|
||||
UInt32 bytesWritten,
|
||||
Memory memory
|
||||
) noexcept : Detail::ImageMemXferImpl(
|
||||
compression, bytesPerRow, columns, rows, xOffset,
|
||||
yOffset, bytesWritten, std::move(memory)){}
|
||||
|
||||
};
|
||||
|
||||
/// Structure holding the information and data of memory file transfer.
|
||||
class ImageMemFileXfer : public Detail::ImageMemXferImpl {
|
||||
|
||||
public:
|
||||
/// Creates a zero-initialized structure without any memory.
|
||||
ImageMemFileXfer() noexcept : Detail::ImageMemXferImpl(){}
|
||||
|
||||
/// Creates an initialized structure from the supplied values and memory.
|
||||
/// The ownership of the memory is taken over.
|
||||
ImageMemFileXfer(
|
||||
Compression compression,
|
||||
UInt32 bytesPerRow,
|
||||
UInt32 columns,
|
||||
UInt32 rows,
|
||||
UInt32 xOffset,
|
||||
UInt32 yOffset,
|
||||
UInt32 bytesWritten,
|
||||
Memory memory
|
||||
) noexcept : Detail::ImageMemXferImpl(
|
||||
compression, bytesPerRow, columns, rows, xOffset,
|
||||
yOffset, bytesWritten, std::move(memory)){}
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_IMAGEMEMXFER_HPP
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_IMAGENATIVEXFER_HPP
|
||||
#define TWPP_DETAIL_FILE_IMAGENATIVEXFER_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure holding native transfer image handle.
|
||||
class ImageNativeXfer {
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
using Data = Detail::Lock<typename std::decay<T>::type>;
|
||||
|
||||
template<typename T>
|
||||
using ConstData = Detail::Lock<const typename std::decay<T>::type>;
|
||||
|
||||
|
||||
/// Creates empty, invalid native transfer.
|
||||
ImageNativeXfer() noexcept :
|
||||
m_handle(){}
|
||||
|
||||
/// Creates a new ImageNativeXfer object from a handle.
|
||||
/// The ownership of the handle is taken over.
|
||||
explicit ImageNativeXfer(Handle h) :
|
||||
m_handle(h){}
|
||||
|
||||
/// Creates uninitialized native image with defines size in bytes.
|
||||
/// \throw std::bad_alloc
|
||||
explicit ImageNativeXfer(UInt32 size) :
|
||||
m_handle(Detail::alloc(size)){}
|
||||
|
||||
/// Data of this native transfer.
|
||||
/// Actual type depends on system and source.
|
||||
/// Windows sources use BMP format without file header, version varies.
|
||||
/// Linux uses TIFF, version varies.
|
||||
/// Mac uses QuickDraw Picture.
|
||||
template<typename T = void>
|
||||
Data<T> data() noexcept{
|
||||
return m_handle.lock<typename std::decay<T>::type>();
|
||||
}
|
||||
|
||||
/// Data of this native transfer.
|
||||
/// Actual type depends on system and source.
|
||||
/// Windows sources use BMP format without file header, version varies.
|
||||
/// Linux uses TIFF, version varies.
|
||||
/// Mac uses QuickDraw Picture.
|
||||
template<typename T = void>
|
||||
ConstData<T> data() const noexcept{
|
||||
return m_handle.lock<const typename std::decay<T>::type>();
|
||||
}
|
||||
|
||||
operator bool() const noexcept{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/// Releases the contained handle, making user responsible for freeing it.
|
||||
Handle release() noexcept{
|
||||
return m_handle.release();
|
||||
}
|
||||
|
||||
private:
|
||||
Detail::UniqueHandle m_handle;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_IMAGENATIVEXFER_HPP
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_INTERNAL_HPP
|
||||
#define TWPP_DETAIL_FILE_INTERNAL_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
struct AudioFileXfer {};
|
||||
struct ImageFileXfer {};
|
||||
typedef Memory IccProfileMemory;
|
||||
|
||||
namespace Detail {
|
||||
|
||||
typedef ReturnCode (TWPP_DETAIL_CALLSTYLE* DsmEntry)(
|
||||
Identity* origin,
|
||||
Identity* dest,
|
||||
DataGroup dg,
|
||||
Dat dat,
|
||||
Msg msg,
|
||||
void* data
|
||||
);
|
||||
|
||||
typedef DsmEntry CallBackFunc;
|
||||
|
||||
typedef
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
void*
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
UInt32
|
||||
#else
|
||||
# error "CallBackConstant for your platform here"
|
||||
#endif
|
||||
CallBackConstant;
|
||||
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
struct EntryPoint {
|
||||
constexpr EntryPoint() noexcept :
|
||||
m_size(sizeof(EntryPoint)), m_entry(nullptr), m_alloc(nullptr),
|
||||
m_free(nullptr), m_lock(nullptr), m_unlock(nullptr){}
|
||||
|
||||
UInt32 m_size;
|
||||
DsmEntry m_entry;
|
||||
MemAlloc m_alloc;
|
||||
MemFree m_free;
|
||||
MemLock m_lock;
|
||||
MemUnlock m_unlock;
|
||||
};
|
||||
|
||||
struct CallBack {
|
||||
|
||||
constexpr CallBack(CallBackFunc func, CallBackConstant constant, Msg msg) noexcept :
|
||||
m_func(func), m_constant(constant), m_msg(msg){}
|
||||
|
||||
CallBackFunc m_func;
|
||||
CallBackConstant m_constant;
|
||||
Msg m_msg;
|
||||
|
||||
};
|
||||
|
||||
struct CallBack2 {
|
||||
|
||||
constexpr CallBack2(CallBackFunc func, UIntPtr constant, Msg msg) noexcept :
|
||||
m_func(func), m_constant(constant), m_msg(msg){}
|
||||
|
||||
CallBackFunc m_func;
|
||||
UIntPtr m_constant;
|
||||
Msg m_msg;
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
/// Manages DSM dll/so/framework connection.
|
||||
class DsmLib {
|
||||
|
||||
public:
|
||||
constexpr DsmLib() noexcept :
|
||||
m_handle(DsmLibOs::nullHandle){}
|
||||
|
||||
~DsmLib(){
|
||||
unload();
|
||||
}
|
||||
|
||||
DsmLib(const DsmLib&) = delete;
|
||||
DsmLib& operator=(const DsmLib&) = delete;
|
||||
|
||||
DsmLib(DsmLib&& o) noexcept :
|
||||
m_handle(o.m_handle){
|
||||
|
||||
o.m_handle = DsmLibOs::nullHandle;
|
||||
}
|
||||
|
||||
DsmLib& operator=(DsmLib&& o) noexcept{
|
||||
if (&o != this){
|
||||
unload();
|
||||
|
||||
m_handle = o.m_handle;
|
||||
o.m_handle = DsmLibOs::nullHandle;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const noexcept{
|
||||
return m_handle != DsmLibOs::nullHandle;
|
||||
}
|
||||
|
||||
bool load(bool preferOld = false) noexcept{
|
||||
m_handle = DsmLibOs::load(preferOld);
|
||||
return m_handle != DsmLibOs::nullHandle;
|
||||
}
|
||||
|
||||
void unload() noexcept{
|
||||
if (m_handle != DsmLibOs::nullHandle){
|
||||
DsmLibOs::unload(m_handle);
|
||||
m_handle = DsmLibOs::nullHandle;
|
||||
}
|
||||
}
|
||||
|
||||
DsmEntry resolve() const noexcept{
|
||||
return DsmLibOs::resolve<DsmEntry>(m_handle);
|
||||
}
|
||||
|
||||
private:
|
||||
DsmLibOs::Handle m_handle;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_INTERNAL_HPP
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_JPEGCOMPRESSION_HPP
|
||||
#define TWPP_DETAIL_FILE_JPEGCOMPRESSION_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// See manual for more info.
|
||||
class JpegCompression {
|
||||
|
||||
public:
|
||||
typedef UInt16 UInt16Arr4[4];
|
||||
typedef Memory MemoryArr2[2];
|
||||
typedef Memory MemoryArr4[4];
|
||||
|
||||
JpegCompression() noexcept :
|
||||
m_colorSpace(PixelType::BlackWhite), m_subSampling(0x10001000), m_components(0),
|
||||
m_restartFrequency(0), m_quantMap(), m_huffmanMap(){}
|
||||
|
||||
template<
|
||||
std::size_t quantTableMapSize,
|
||||
std::size_t quantTableSize,
|
||||
std::size_t huffmanTableMapSize,
|
||||
std::size_t huffmanDcSize,
|
||||
std::size_t huffmanAcSize
|
||||
>
|
||||
JpegCompression(
|
||||
PixelType colorSpace,
|
||||
UInt32 subSampling,
|
||||
UInt16 components,
|
||||
UInt16 restartFrequency,
|
||||
const UInt16(& quantTableMap)[quantTableMapSize],
|
||||
Memory(& quantTable)[quantTableSize],
|
||||
const UInt16(& huffmanTableMap)[huffmanTableMapSize],
|
||||
Memory(& huffmanDc)[huffmanDcSize],
|
||||
Memory(& huffmanAc)[huffmanAcSize]
|
||||
) noexcept :
|
||||
m_colorSpace(colorSpace),
|
||||
m_subSampling(subSampling),
|
||||
m_components(components),
|
||||
m_restartFrequency(restartFrequency),
|
||||
m_quantMap(quantTableMap),
|
||||
m_huffmanMap(huffmanTableMap){
|
||||
|
||||
for (std::size_t i = 0; i < quantTableSize; i++){
|
||||
m_quantTable[i] = std::move(quantTable[i]);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < huffmanDcSize; i++){
|
||||
m_huffmanDc[i] = std::move(huffmanDc[i]);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < huffmanAcSize; i++){
|
||||
m_huffmanAc[i] = std::move(huffmanAc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PixelType pixelType() const noexcept{
|
||||
return m_colorSpace;
|
||||
}
|
||||
|
||||
void setPixelType(PixelType pixelType) noexcept{
|
||||
m_colorSpace = pixelType;
|
||||
}
|
||||
|
||||
UInt32 subSampling() const noexcept{
|
||||
return m_subSampling;
|
||||
}
|
||||
|
||||
void setSubSampling(UInt32 subSampling) noexcept{
|
||||
m_subSampling = subSampling;
|
||||
}
|
||||
|
||||
UInt16 components() const noexcept{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
void setComponents(UInt16 components) noexcept{
|
||||
m_components = components;
|
||||
}
|
||||
|
||||
UInt16 restartFrequency() const noexcept{
|
||||
return m_restartFrequency;
|
||||
}
|
||||
|
||||
void setRestartFrequency(UInt16 restartFrequency) noexcept{
|
||||
m_restartFrequency = restartFrequency;
|
||||
}
|
||||
|
||||
const UInt16Arr4& quantTableMap() const noexcept{
|
||||
return m_quantMap.array();
|
||||
}
|
||||
|
||||
UInt16Arr4& quantTableMap() noexcept{
|
||||
return m_quantMap.array();
|
||||
}
|
||||
|
||||
const MemoryArr4& quantTable() const noexcept{
|
||||
return m_quantTable;
|
||||
}
|
||||
|
||||
MemoryArr4& quantTable() noexcept{
|
||||
return m_quantTable;
|
||||
}
|
||||
|
||||
const UInt16Arr4& huffmanTableMap() const noexcept{
|
||||
return m_huffmanMap.array();
|
||||
}
|
||||
|
||||
UInt16Arr4& huffmanTableMap() noexcept{
|
||||
return m_huffmanMap.array();
|
||||
}
|
||||
|
||||
const MemoryArr2& huffmanDc() const noexcept{
|
||||
return m_huffmanDc;
|
||||
}
|
||||
|
||||
MemoryArr2& huffmanDc() noexcept{
|
||||
return m_huffmanDc;
|
||||
}
|
||||
|
||||
const MemoryArr2& huffmanAc() const noexcept{
|
||||
return m_huffmanAc;
|
||||
}
|
||||
|
||||
MemoryArr2& huffmanAc() noexcept{
|
||||
return m_huffmanAc;
|
||||
}
|
||||
|
||||
private:
|
||||
PixelType m_colorSpace;
|
||||
UInt32 m_subSampling;
|
||||
UInt16 m_components;
|
||||
UInt16 m_restartFrequency;
|
||||
Detail::FixedArray<UInt16, 4> m_quantMap;
|
||||
MemoryArr4 m_quantTable;
|
||||
Detail::FixedArray<UInt16, 4> m_huffmanMap;
|
||||
MemoryArr2 m_huffmanDc;
|
||||
MemoryArr2 m_huffmanAc;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_JPEGCOMPRESSION_HPP
|
|
@ -1,194 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_MEMORY_HPP
|
||||
#define TWPP_DETAIL_FILE_MEMORY_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
namespace Flags {
|
||||
|
||||
enum {
|
||||
AppOwns = 0x0001,
|
||||
DsmOwns = 0x0002,
|
||||
DsOwns = 0x0004,
|
||||
Pointer = 0x0008,
|
||||
Handle = 0x0010
|
||||
};
|
||||
|
||||
|
||||
#if !defined(TWPP_IS_DS)
|
||||
static constexpr const UInt32 thisOwns = AppOwns;
|
||||
static constexpr const UInt32 otherOwns = DsOwns;
|
||||
#else
|
||||
static constexpr const UInt32 thisOwns = DsOwns;
|
||||
static constexpr const UInt32 otherOwns = AppOwns;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Holds and potentially owns a block of memory using either pointer or handle.
|
||||
class Memory {
|
||||
|
||||
public:
|
||||
typedef Detail::MaybeLock<char> Data;
|
||||
typedef Detail::MaybeLock<const char> ConstData;
|
||||
|
||||
/// Creates an empty memory.
|
||||
constexpr Memory() noexcept :
|
||||
m_flags(0), m_size(0), m_data(nullptr){}
|
||||
|
||||
/// Creates a memory block of supplied size.
|
||||
/// \throw std::bad_alloc
|
||||
explicit Memory(UInt32 size) :
|
||||
m_flags(Detail::Flags::thisOwns | Detail::Flags::Handle), m_size(size),
|
||||
m_data(Detail::alloc(size).raw()){}
|
||||
|
||||
/// Creates a new memory object from Handle.
|
||||
/// The memory ownership is taken over.
|
||||
/// \param h The handle, see thisOwns for more information about memory ownership.
|
||||
/// \param size Size of the memory in bytes, that handle h manages.
|
||||
/// \param thisOwns {
|
||||
/// If true, this object frees the memory once it goes out of scope.
|
||||
///
|
||||
/// If false the memory is not freed, and MUST be passed to the other side
|
||||
/// (APP->DS or DS->APP) of the connection, that will free it.
|
||||
/// }
|
||||
Memory(Handle h, UInt32 size, bool thisOwns = true) noexcept :
|
||||
m_flags((thisOwns ? Detail::Flags::thisOwns : Detail::Flags::otherOwns) | Detail::Flags::Handle),
|
||||
m_size(size),
|
||||
m_data(h.raw()){}
|
||||
|
||||
/// Creates a memory object from container.
|
||||
/// The memory object does NOT take over the ownership of the data.
|
||||
/// Make sure the container is destroyed after the memory object is.
|
||||
template<typename Container>
|
||||
explicit Memory(const Container& container) noexcept :
|
||||
m_flags(Detail::Flags::thisOwns | Detail::Flags::Pointer),
|
||||
m_size(sizeof(Container::value_type) * container.size()),
|
||||
m_data(container.data()){}
|
||||
|
||||
/// Creates a memory object from pointer.
|
||||
/// The memory object does NOT take over the ownership of the data.
|
||||
/// Make sure the data is destroyed after the memory object is.
|
||||
constexpr Memory(void* data, UInt32 size) noexcept :
|
||||
m_flags(Detail::Flags::thisOwns | Detail::Flags::Pointer), m_size(size),
|
||||
m_data(data){}
|
||||
|
||||
~Memory(){
|
||||
freePriv();
|
||||
}
|
||||
|
||||
Memory(const Memory& o) = delete;
|
||||
Memory& operator=(const Memory& o) = delete;
|
||||
|
||||
Memory(Memory&& o) noexcept :
|
||||
m_flags(o.m_flags), m_size(o.m_size), m_data(o.m_data)
|
||||
{
|
||||
o.m_flags = 0;
|
||||
o.m_size = 0;
|
||||
o.m_data = nullptr;
|
||||
}
|
||||
|
||||
Memory& operator=(Memory&& o) noexcept{
|
||||
if (&o != this){
|
||||
freePriv();
|
||||
|
||||
m_flags = o.m_flags;
|
||||
m_size = o.m_size;
|
||||
m_data = o.m_data;
|
||||
|
||||
o.m_flags = 0;
|
||||
o.m_size = 0;
|
||||
o.m_data = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// The data in this memory block.
|
||||
ConstData data() const noexcept{
|
||||
return m_flags & Detail::Flags::Handle ?
|
||||
ConstData(Handle(static_cast<Handle::Raw>(m_data))) :
|
||||
ConstData(static_cast<const char*>(m_data));
|
||||
}
|
||||
|
||||
/// The data in this memory block.
|
||||
Data data() noexcept{
|
||||
return m_flags & Detail::Flags::Handle ?
|
||||
Data(Handle(static_cast<Handle::Raw>(m_data))) :
|
||||
Data(static_cast<char*>(m_data));
|
||||
}
|
||||
|
||||
/// Number of bytes in the memory block.
|
||||
UInt32 size() const noexcept{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/// In case of handle, frees memory regardless its owner; does nothing otherwise (pointer).
|
||||
/// Potentially unsafe operation.
|
||||
void free(){
|
||||
if (m_flags & Detail::Flags::Handle){
|
||||
Handle h(static_cast<Handle::Raw>(m_data));
|
||||
if (h){
|
||||
Detail::free(h);
|
||||
}
|
||||
|
||||
m_size = 0;
|
||||
m_data = nullptr;
|
||||
m_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void freePriv(){
|
||||
if (m_flags & Detail::Flags::thisOwns){
|
||||
if (m_flags & Detail::Flags::Handle){
|
||||
Detail::free(Handle(static_cast<Handle::Raw>(m_data)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 m_flags;
|
||||
UInt32 m_size;
|
||||
void* m_data;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_MEMORY_HPP
|
||||
|
|
@ -1,439 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_MEMORYOPS_HPP
|
||||
#define TWPP_DETAIL_FILE_MEMORYOPS_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef Handle::Raw (TWPP_DETAIL_CALLSTYLE* MemAlloc)(UInt32 size);
|
||||
typedef void (TWPP_DETAIL_CALLSTYLE* MemFree)(Handle::Raw handle);
|
||||
typedef void* (TWPP_DETAIL_CALLSTYLE* MemLock)(Handle::Raw handle);
|
||||
typedef void (TWPP_DETAIL_CALLSTYLE* MemUnlock)(Handle::Raw handle);
|
||||
|
||||
}
|
||||
|
||||
// templates behave as if they were defined in at most one module
|
||||
// ideal for storing static data
|
||||
template<typename Dummy>
|
||||
struct GlobalMemFuncs {
|
||||
|
||||
#if defined(TWPP_DETAIL_OS_WIN)
|
||||
static Handle::Raw TWPP_DETAIL_CALLSTYLE defAlloc(UInt32 size){
|
||||
return ::GlobalAlloc(GHND, size);
|
||||
}
|
||||
|
||||
static void TWPP_DETAIL_CALLSTYLE defFree(Handle::Raw handle){
|
||||
::GlobalFree(handle);
|
||||
}
|
||||
|
||||
static void* TWPP_DETAIL_CALLSTYLE defLock(Handle::Raw handle){
|
||||
return ::GlobalLock(handle);
|
||||
}
|
||||
|
||||
static void TWPP_DETAIL_CALLSTYLE defUnlock(Handle::Raw handle){
|
||||
::GlobalUnlock(handle);
|
||||
}
|
||||
#elif defined(TWPP_DETAIL_OS_MAC)
|
||||
static Handle::Raw TWPP_DETAIL_CALLSTYLE defAlloc(UInt32 size){
|
||||
return ::NewHandle(size);
|
||||
}
|
||||
|
||||
static void TWPP_DETAIL_CALLSTYLE defFree(Handle::Raw handle){
|
||||
::DisposeHandle(handle);
|
||||
}
|
||||
|
||||
static void* TWPP_DETAIL_CALLSTYLE defLock(Handle::Raw handle){
|
||||
return *handle;
|
||||
}
|
||||
|
||||
static void TWPP_DETAIL_CALLSTYLE defUnlock(Handle::Raw){
|
||||
// noop
|
||||
}
|
||||
#elif !defined(TWPP_DETAIL_OS_LINUX) // Linux doesnt need default functions
|
||||
# error "default memory functions for your platform here"
|
||||
#endif
|
||||
|
||||
static MemAlloc alloc;
|
||||
static MemFree free;
|
||||
static MemLock lock;
|
||||
static MemUnlock unlock;
|
||||
|
||||
#if defined(TWPP_IS_DS)
|
||||
static Handle doNotFreeHandle;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_MAC)
|
||||
template<typename Dummy>
|
||||
MemAlloc GlobalMemFuncs<Dummy>::alloc = GlobalMemFuncs<Dummy>::defAlloc;
|
||||
|
||||
template<typename Dummy>
|
||||
MemFree GlobalMemFuncs<Dummy>::free = GlobalMemFuncs<Dummy>::defFree;
|
||||
|
||||
template<typename Dummy>
|
||||
MemLock GlobalMemFuncs<Dummy>::lock = GlobalMemFuncs<Dummy>::defLock;
|
||||
|
||||
template<typename Dummy>
|
||||
MemUnlock GlobalMemFuncs<Dummy>::unlock = GlobalMemFuncs<Dummy>::defUnlock;
|
||||
#elif defined(TWPP_DETAIL_OS_LINUX)
|
||||
template<typename Dummy>
|
||||
MemAlloc GlobalMemFuncs<Dummy>::alloc = nullptr;
|
||||
|
||||
template<typename Dummy>
|
||||
MemFree GlobalMemFuncs<Dummy>::free = nullptr;
|
||||
|
||||
template<typename Dummy>
|
||||
MemLock GlobalMemFuncs<Dummy>::lock = nullptr;
|
||||
|
||||
template<typename Dummy>
|
||||
MemUnlock GlobalMemFuncs<Dummy>::unlock = nullptr;
|
||||
#else
|
||||
# error "default memory functions setup for your platform here"
|
||||
#endif
|
||||
|
||||
#if defined(TWPP_IS_DS)
|
||||
template<typename Dummy>
|
||||
Handle GlobalMemFuncs<Dummy>::doNotFreeHandle;
|
||||
#endif
|
||||
|
||||
inline static void setMemFuncs(MemAlloc alloc, MemFree free, MemLock lock, MemUnlock unlock) noexcept{
|
||||
GlobalMemFuncs<void>::alloc = alloc;
|
||||
GlobalMemFuncs<void>::free = free;
|
||||
GlobalMemFuncs<void>::lock = lock;
|
||||
GlobalMemFuncs<void>::unlock = unlock;
|
||||
}
|
||||
|
||||
inline static void resetMemFuncs() noexcept{
|
||||
#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_MAC)
|
||||
GlobalMemFuncs<void>::alloc = GlobalMemFuncs<void>::defAlloc;
|
||||
GlobalMemFuncs<void>::free = GlobalMemFuncs<void>::defFree;
|
||||
GlobalMemFuncs<void>::lock = GlobalMemFuncs<void>::defLock;
|
||||
GlobalMemFuncs<void>::unlock = GlobalMemFuncs<void>::defUnlock;
|
||||
#elif defined(TWPP_DETAIL_OS_LINUX)
|
||||
GlobalMemFuncs<void>::alloc = nullptr;
|
||||
GlobalMemFuncs<void>::free = nullptr;
|
||||
GlobalMemFuncs<void>::lock = nullptr;
|
||||
GlobalMemFuncs<void>::unlock = nullptr;
|
||||
#else
|
||||
# error "resetMemFuncs for your platform here"
|
||||
#endif
|
||||
}
|
||||
|
||||
inline static Handle alloc(UInt32 size){
|
||||
auto h = GlobalMemFuncs<void>::alloc(size);
|
||||
if (!h){
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return Handle(h);
|
||||
}
|
||||
|
||||
inline static void* lock(Handle handle) noexcept{
|
||||
return GlobalMemFuncs<void>::lock(handle.raw());
|
||||
}
|
||||
|
||||
inline static void unlock(Handle handle) noexcept{
|
||||
GlobalMemFuncs<void>::unlock(handle.raw());
|
||||
}
|
||||
|
||||
inline static void free(Handle handle) noexcept{
|
||||
GlobalMemFuncs<void>::free(handle.raw());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T* typeLock(Handle handle) noexcept{
|
||||
return static_cast<T*>(lock(handle));
|
||||
}
|
||||
|
||||
/// A lock that can contain either handle or raw pointer.
|
||||
/// Locks and unlocks handle, noop for pointer.
|
||||
template<typename T>
|
||||
class MaybeLock {
|
||||
|
||||
public:
|
||||
constexpr MaybeLock() noexcept :
|
||||
m_handle(), m_pointer(nullptr){}
|
||||
|
||||
MaybeLock(Handle h) noexcept :
|
||||
m_handle(h), m_pointer(typeLock<T>(h)){}
|
||||
|
||||
constexpr MaybeLock(T* ptr) noexcept :
|
||||
m_handle(), m_pointer(ptr){}
|
||||
|
||||
~MaybeLock(){
|
||||
unlock();
|
||||
}
|
||||
|
||||
MaybeLock(const MaybeLock& o) noexcept :
|
||||
m_handle(o.m_handle), m_pointer(o.m_handle ? typeLock<T>(o.m_handle) : o.m_pointer){}
|
||||
|
||||
MaybeLock& operator=(const MaybeLock& o) noexcept{
|
||||
if (&o != this){
|
||||
unlock();
|
||||
|
||||
m_handle = o.m_handle;
|
||||
m_pointer = m_handle ? typeLock<T>(m_handle) : o.m_pointer;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
MaybeLock(MaybeLock&& o) noexcept :
|
||||
m_handle(o.m_handle), m_pointer(o.m_pointer){
|
||||
|
||||
o.m_handle = Handle();
|
||||
o.m_pointer = nullptr;
|
||||
}
|
||||
|
||||
MaybeLock& operator=(MaybeLock&& o) noexcept{
|
||||
if (&o != this){
|
||||
unlock();
|
||||
|
||||
m_handle = o.m_handle;
|
||||
m_pointer = o.m_pointer;
|
||||
|
||||
o.m_handle = Handle();
|
||||
o.m_pointer = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* data() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
operator T*() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
T* operator->() noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
T* operator->() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
bool hasData() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
operator bool() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
private:
|
||||
void unlock() noexcept{
|
||||
if (m_handle){
|
||||
Detail::unlock(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Handle m_handle;
|
||||
T* m_pointer;
|
||||
|
||||
};
|
||||
|
||||
/// Simple handle lock.
|
||||
/// Locks on creation and unlocks on destruction.
|
||||
template<typename T>
|
||||
class Lock {
|
||||
|
||||
public:
|
||||
constexpr Lock() noexcept :
|
||||
m_handle(), m_pointer(nullptr){}
|
||||
|
||||
Lock(Handle h) noexcept :
|
||||
m_handle(h), m_pointer(typeLock<T>(h)){}
|
||||
|
||||
~Lock(){
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
Lock(const Lock& o) noexcept :
|
||||
m_handle(o.m_handle), m_pointer(typeLock<T>(o.m_handle)){}
|
||||
|
||||
Lock& operator=(const Lock& o) noexcept{
|
||||
if (&o != this){
|
||||
unlock();
|
||||
|
||||
m_handle = o.m_handle;
|
||||
m_pointer = typeLock<T>(m_handle);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Lock(Lock&& o) noexcept :
|
||||
m_handle(o.m_handle), m_pointer(o.m_pointer){
|
||||
|
||||
o.m_handle = Handle();
|
||||
o.m_pointer = nullptr;
|
||||
}
|
||||
|
||||
Lock& operator=(Lock&& o) noexcept{
|
||||
if (&o != this){
|
||||
unlock();
|
||||
|
||||
m_handle = o.m_handle;
|
||||
m_pointer = o.m_pointer;
|
||||
|
||||
o.m_handle = Handle();
|
||||
o.m_pointer = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
T* data() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
operator T*() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
T* operator->() noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
T* operator->() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
bool hasData() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
operator bool() const noexcept{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
private:
|
||||
void unlock() noexcept{
|
||||
if (m_handle){
|
||||
Detail::unlock(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Handle m_handle;
|
||||
T* m_pointer;
|
||||
|
||||
};
|
||||
|
||||
/// Owns a handle and frees it upon destruction,
|
||||
/// unless `release` is called beforehand.
|
||||
class UniqueHandle {
|
||||
|
||||
public:
|
||||
constexpr UniqueHandle(Handle h = Handle()) noexcept :
|
||||
m_handle(h){}
|
||||
|
||||
~UniqueHandle(){
|
||||
free();
|
||||
}
|
||||
|
||||
UniqueHandle(const UniqueHandle&) = delete;
|
||||
UniqueHandle& operator=(const UniqueHandle&) = delete;
|
||||
|
||||
UniqueHandle(UniqueHandle&& o) noexcept :
|
||||
m_handle(o.m_handle){
|
||||
|
||||
o.m_handle = Handle();
|
||||
}
|
||||
|
||||
UniqueHandle& operator=(UniqueHandle&& o) noexcept{
|
||||
if (&o != this){
|
||||
free();
|
||||
|
||||
m_handle = o.m_handle;
|
||||
|
||||
o.m_handle = Handle();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const noexcept{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/// The contained handle.
|
||||
Handle get() noexcept{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/// The contained handle.
|
||||
Handle get() const noexcept{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/// Releases the contained handle, making the user responsible for freeing it.
|
||||
Handle release() noexcept{
|
||||
Handle ret = m_handle;
|
||||
m_handle = Handle();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Lock<T> lock() const{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
private:
|
||||
void free() noexcept{
|
||||
#if defined(TWPP_IS_DS)
|
||||
if (m_handle && m_handle != GlobalMemFuncs<void>::doNotFreeHandle){
|
||||
#else
|
||||
if (m_handle){
|
||||
#endif
|
||||
Detail::free(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Handle m_handle;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_MEMORYOPS_HPP
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_PALETTE8_HPP
|
||||
#define TWPP_DETAIL_FILE_PALETTE8_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
// specialization for Element8
|
||||
// we also want to set index of the element when placing it inside array
|
||||
template<std::size_t arraySize, UInt8... i>
|
||||
struct FixedArrayData<Element8, arraySize, IndexList<i...> > {
|
||||
|
||||
static constexpr Element8 updateIndex(UInt8 index, const Element8& e) noexcept{
|
||||
return Element8(index, e.channel1(), e.channel2(), e.channel3());
|
||||
}
|
||||
|
||||
template<std::size_t inputSize>
|
||||
constexpr FixedArrayData(const Element8(& arr)[inputSize]) noexcept :
|
||||
m_arr{updateIndex(i, FixedArrayFlat<Element8, arraySize>(arr)[i])...}{}
|
||||
|
||||
constexpr FixedArrayData() noexcept :
|
||||
m_arr{Element8(i)...}{}
|
||||
|
||||
Element8 m_arr[arraySize];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Palette information for memory transfers
|
||||
class Palette8 {
|
||||
|
||||
public:
|
||||
enum class Type : UInt16 {
|
||||
Rgb = 0,
|
||||
Gray = 1,
|
||||
Cmy = 2
|
||||
};
|
||||
|
||||
typedef Element8 Element8Arr256[256];
|
||||
|
||||
/// Creates an uninitialized palette.
|
||||
constexpr Palette8() noexcept :
|
||||
m_size(0), m_type(Type::Rgb), m_colors(){}
|
||||
|
||||
/// Creates a palette with the supplied type and elements.
|
||||
template<std::size_t inputSize>
|
||||
constexpr Palette8(Type type, const Element8(& colors)[inputSize]) noexcept :
|
||||
m_size(inputSize), m_type(type),
|
||||
m_colors(colors){
|
||||
|
||||
static_assert(inputSize <= 256, "too many colors");
|
||||
}
|
||||
|
||||
/// Creates a palette with the supplied type and elements from container.
|
||||
/// \throw RangeException When there are more than 256 colors.
|
||||
template<typename Container>
|
||||
Palette8(Type type, const Container& colors) :
|
||||
m_size(static_cast<UInt16>(colors.size())), m_type(type){
|
||||
|
||||
if (colors.size() > 256){
|
||||
throw RangeException();
|
||||
}
|
||||
|
||||
auto& array = m_colors.array();
|
||||
for (UInt16 i = 0; i < m_size; i++){
|
||||
array[i] = colors[i];
|
||||
array[i].setIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a palette with the supplied type and elements.
|
||||
/// \throw RangeException When there are more than 256 colors.
|
||||
Palette8(Type type, const Element8* colors, UInt16 size) :
|
||||
m_size(size), m_type(type){
|
||||
|
||||
if (m_size > 256){
|
||||
throw RangeException();
|
||||
}
|
||||
|
||||
auto& array = m_colors.array();
|
||||
for (UInt16 i = 0; i < m_size; i++){
|
||||
array[i] = colors[i];
|
||||
array[i].setIndex(static_cast<UInt8>(i)); // 0..255 max
|
||||
}
|
||||
}
|
||||
|
||||
/// Number of elements in the palette.
|
||||
constexpr UInt16 size() const noexcept{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/// Type of palette data.
|
||||
constexpr Type type() const noexcept{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/// Array of palette elements.
|
||||
constexpr const Element8Arr256& colors() const noexcept{
|
||||
return m_colors.array();
|
||||
}
|
||||
|
||||
private:
|
||||
UInt16 m_size;
|
||||
Type m_type;
|
||||
Detail::FixedArray<Element8, 256> m_colors;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_PALETTE8_HPP
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_PASSTHROUGH_HPP
|
||||
#define TWPP_DETAIL_FILE_PASSTHROUGH_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure for raw comminication with device in source.
|
||||
/// See manual for more information, DAT_PASSTHRU, MSG_PASSTHRU.
|
||||
class PassThrough {
|
||||
|
||||
public:
|
||||
enum class Direction : Int32 {
|
||||
Get = 1,
|
||||
Set = 2
|
||||
};
|
||||
|
||||
constexpr PassThrough(
|
||||
void* command,
|
||||
UInt32 commandSize,
|
||||
Direction direction,
|
||||
void* data,
|
||||
UInt32 dataSize,
|
||||
UInt32 dataXfered
|
||||
) noexcept :
|
||||
m_cmd(command), m_cmdSize(commandSize),
|
||||
m_direction(direction),
|
||||
m_data(data), m_dataSize(dataSize), m_dataXfered(dataXfered){}
|
||||
|
||||
constexpr void* command() const noexcept{
|
||||
return m_cmd;
|
||||
}
|
||||
|
||||
constexpr UInt32 commandSize() const noexcept{
|
||||
return m_cmdSize;
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
void setCommand(const Container& command) noexcept{
|
||||
m_cmd = command.data();
|
||||
m_cmdSize = sizeof(Container::value_type) * command.size();
|
||||
}
|
||||
|
||||
void setCommand(void* command, UInt32 size) noexcept{
|
||||
m_cmd = command;
|
||||
m_cmdSize = size;
|
||||
}
|
||||
|
||||
constexpr Direction direction() const noexcept{
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
void setDirection(Direction direction) noexcept{
|
||||
m_direction = direction;
|
||||
}
|
||||
|
||||
constexpr void* data() const noexcept{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
constexpr UInt32 dataSize() const noexcept{
|
||||
return m_dataSize;
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
void setData(const Container& data) noexcept{
|
||||
m_data = data.data();
|
||||
m_dataSize = sizeof(Container::value_type) * data.size();
|
||||
m_dataXfered = 0;
|
||||
}
|
||||
|
||||
void setData(void* data, UInt32 dataSize) noexcept{
|
||||
m_data = data;
|
||||
m_dataSize = dataSize;
|
||||
m_dataXfered = 0;
|
||||
}
|
||||
|
||||
constexpr UInt32 dataXfered() const noexcept{
|
||||
return m_dataXfered;
|
||||
}
|
||||
|
||||
void setDataXfered(Int32 dataXfered) noexcept{
|
||||
m_dataXfered = dataXfered;
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_cmd;
|
||||
UInt32 m_cmdSize;
|
||||
Direction m_direction;
|
||||
void* m_data;
|
||||
UInt32 m_dataSize;
|
||||
UInt32 m_dataXfered;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_PASSTHROUGH_HPP
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_PENDINGXFERS_HPP
|
||||
#define TWPP_DETAIL_FILE_PENDINGXFERS_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Reports number of pending images, transfers.
|
||||
class PendingXfers {
|
||||
|
||||
public:
|
||||
/// Job control settings.
|
||||
enum class JobPatch : UInt32 {
|
||||
None = 0x0000,
|
||||
MidSeparator = 0x0001,
|
||||
P1 = 0x0002,
|
||||
P2 = 0x0003,
|
||||
P3 = 0x0004,
|
||||
P4 = 0x0005,
|
||||
P6 = 0x0006,
|
||||
PT = 0x0007
|
||||
};
|
||||
|
||||
/// Creates object to report number of pending transfers.
|
||||
/// \param count Number of pending transfers.
|
||||
/// \param patch Job control settings.
|
||||
constexpr PendingXfers(UInt16 count = 0, JobPatch patch = JobPatch::None) noexcept :
|
||||
m_count(count), m_eoj(patch){}
|
||||
|
||||
/// Number of pending images/transfers.
|
||||
constexpr UInt16 count() const noexcept{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// Sets number of pending images/transfers.
|
||||
void setCount(UInt16 count) noexcept{
|
||||
m_count = count;
|
||||
}
|
||||
|
||||
/// Job control settings.
|
||||
constexpr JobPatch jobPatch() const noexcept{
|
||||
return m_eoj;
|
||||
}
|
||||
|
||||
/// Sets job control settings.
|
||||
void setJobPatch(JobPatch eoj) noexcept{
|
||||
m_eoj = eoj;
|
||||
}
|
||||
|
||||
private:
|
||||
UInt16 m_count;
|
||||
JobPatch m_eoj;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_PENDINGXFERS_HPP
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_SETUPFILEXFER_HPP
|
||||
#define TWPP_DETAIL_FILE_SETUPFILEXFER_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure for setting up file transfer.
|
||||
class SetupFileXfer {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized instance.
|
||||
constexpr SetupFileXfer() noexcept :
|
||||
m_format(ImageFileFormat::Tiff), m_volRefNum(0){}
|
||||
|
||||
/// Creates instance with set file path and format.
|
||||
/// And volume reference number on Mac OS.
|
||||
/// \param filePath Path to transfered file.
|
||||
/// \param format File format.
|
||||
/// \param vrn Volume reference number. Mac OS only.
|
||||
constexpr SetupFileXfer(
|
||||
const Str255& filePath,
|
||||
ImageFileFormat format,
|
||||
Int16 vrn
|
||||
#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
= -1
|
||||
#elif !defined(TWPP_DETAIL_OS_MAC)
|
||||
# error "Volume reference number for your platform here"
|
||||
#endif
|
||||
) noexcept :
|
||||
m_filePath(filePath), m_format(format),
|
||||
m_volRefNum(vrn){}
|
||||
|
||||
/// Path to transfered file.
|
||||
constexpr const Str255& filePath() const noexcept{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
/// Sets path to transfered file.
|
||||
void setFilePath(const Str255& filePath) noexcept{
|
||||
m_filePath = filePath;
|
||||
}
|
||||
|
||||
/// Format of the transfered file.
|
||||
constexpr ImageFileFormat format() const noexcept{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
/// Sets format of the transfered file.
|
||||
void setFormat(ImageFileFormat format) noexcept{
|
||||
m_format = format;
|
||||
}
|
||||
|
||||
/// Volume reference number.
|
||||
/// Mac OS only.
|
||||
constexpr Int16 volumeReferenceNumber() const noexcept{
|
||||
return m_volRefNum;
|
||||
}
|
||||
|
||||
/// Sets volume reference number.
|
||||
/// Mac OS only.
|
||||
void setVolumeReferenceNumber(Int16 volumeReferenceNumber) noexcept{
|
||||
m_volRefNum = volumeReferenceNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
Str255 m_filePath;
|
||||
ImageFileFormat m_format;
|
||||
Int16 m_volRefNum;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_SETUPFILEXFER_HPP
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_SETUPMEMXFER_HPP
|
||||
#define TWPP_DETAIL_FILE_SETUPMEMXFER_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure for setting up memory transfer.
|
||||
class SetupMemXfer {
|
||||
|
||||
public:
|
||||
/// Creates zero-initialized instance.
|
||||
constexpr SetupMemXfer() noexcept :
|
||||
m_minSize(0), m_maxSize(0), m_prefSize(0){}
|
||||
|
||||
/// Creates an initialized instance with set minimal, maximal and preferred sizes.
|
||||
/// Must be true, or the behaviour is undefined: minSize <= preferredSize <= maxSize
|
||||
constexpr SetupMemXfer(
|
||||
UInt32 minSize,
|
||||
UInt32 maxSize,
|
||||
UInt32 preferredSize
|
||||
) noexcept :
|
||||
m_minSize(minSize), m_maxSize(maxSize), m_prefSize(preferredSize){}
|
||||
|
||||
/// Minimal supported buffer size in bytes.
|
||||
constexpr UInt32 minSize() const noexcept{
|
||||
return m_minSize;
|
||||
}
|
||||
|
||||
/// Sets minimal supported buffer size in bytes.
|
||||
void setMinSize(UInt32 minSize) noexcept{
|
||||
m_minSize = minSize;
|
||||
}
|
||||
|
||||
/// Maximal supported buffer size in bytes.
|
||||
constexpr UInt32 maxSize() const noexcept{
|
||||
return m_maxSize;
|
||||
}
|
||||
|
||||
/// Sets maximal supported buffer size in bytes.
|
||||
void setMaxSize(UInt32 maxSize) noexcept{
|
||||
m_maxSize = maxSize;
|
||||
}
|
||||
|
||||
/// Preferred buffer size in bytes.
|
||||
constexpr UInt32 preferredSize() const noexcept{
|
||||
return m_prefSize;
|
||||
}
|
||||
|
||||
/// Sets preferred buffer size in bytes.
|
||||
void setPreferredSize(UInt32 prefSize) noexcept{
|
||||
m_prefSize = prefSize;
|
||||
}
|
||||
|
||||
private:
|
||||
UInt32 m_minSize;
|
||||
UInt32 m_maxSize;
|
||||
UInt32 m_prefSize;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_SETUPMEMXFER_HPP
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_STATUS_HPP
|
||||
#define TWPP_DETAIL_FILE_STATUS_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Additional status information about a performed TWAIN operation.
|
||||
class Status {
|
||||
|
||||
public:
|
||||
/// Creates operation status.
|
||||
/// \param cond Status condition code.
|
||||
/// \param data Additional status data, source-specific.
|
||||
constexpr Status(CC cond = CC::Success, UInt16 data = 0) noexcept :
|
||||
m_cond(cond), m_data(data){}
|
||||
|
||||
/// Status condition code.
|
||||
constexpr CC condition() const noexcept{
|
||||
return m_cond;
|
||||
}
|
||||
|
||||
/// Sets status condition code.
|
||||
void setCondition(CC cc) noexcept{
|
||||
m_cond = cc;
|
||||
}
|
||||
|
||||
/// Aditional status data, source-specific.
|
||||
constexpr UInt16 data() const noexcept{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/// Sets aditional status data, source-specific.
|
||||
void setData(UInt16 data) noexcept{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
constexpr operator CC() const noexcept{
|
||||
return m_cond;
|
||||
}
|
||||
|
||||
constexpr operator bool() const noexcept{
|
||||
return success(m_cond);
|
||||
}
|
||||
|
||||
constexpr bool operator==(CC o) const noexcept{return m_cond == o;}
|
||||
constexpr bool operator!=(CC o) const noexcept{return m_cond != o;}
|
||||
|
||||
constexpr bool operator==(Status o) const noexcept{return m_cond == o.m_cond && m_data == o.m_data;}
|
||||
constexpr bool operator!=(Status o) const noexcept{return m_cond != o.m_cond || m_data != o.m_data;}
|
||||
|
||||
|
||||
private:
|
||||
CC m_cond;
|
||||
UInt16 m_data;
|
||||
|
||||
};
|
||||
|
||||
static inline constexpr bool success(Status stat) noexcept{
|
||||
return stat;
|
||||
}
|
||||
|
||||
/// Structure for translating status to UTF8 text.
|
||||
class StatusUtf8 {
|
||||
|
||||
public:
|
||||
typedef Detail::Lock<const char> ConstString;
|
||||
|
||||
|
||||
/// Creates a status utf8 without string data.
|
||||
StatusUtf8(Status status = Status()) noexcept :
|
||||
m_status(status), m_size(0), m_string(){}
|
||||
|
||||
/// Creates a status utf8 containing copy of string data.
|
||||
/// The string must be null-terminated.
|
||||
/// \tparam inputSize Size of the string including null terminator.
|
||||
/// \param str The string, must be null-terminated.
|
||||
/// \throw std::bad_alloc
|
||||
template<UInt32 inputSize>
|
||||
StatusUtf8(Status status, const char(& str)[inputSize]) :
|
||||
m_status(status), m_size(inputSize), m_string(Detail::alloc(inputSize)){
|
||||
|
||||
std::copy(str, str + inputSize, string().data());
|
||||
}
|
||||
|
||||
/// Creates a new status utf8 containing a copy of the supplied string.
|
||||
/// \param status
|
||||
/// \param str Utf-8 string to copy, must be null-terminated.
|
||||
/// \throw RangeException When string is too long, could not insert null terminator.
|
||||
/// \throw std::bad_alloc
|
||||
StatusUtf8(Status status, const char* str) :
|
||||
m_status(status), m_size(0), m_string(){
|
||||
|
||||
auto len = strlen(str);
|
||||
if (len >= std::numeric_limits<UInt32>::max()){
|
||||
throw RangeException();
|
||||
}
|
||||
|
||||
m_size = static_cast<UInt32>(len) + 1;
|
||||
m_string = Detail::alloc(m_size);
|
||||
std::copy(str, str + len + 1, m_string.lock<char>().data());
|
||||
}
|
||||
|
||||
/// Creates a new status utf8 containing a copy of the supplied string.
|
||||
/// \param status
|
||||
/// \param str Utf-8 string to copy.
|
||||
/// \throw RangeException When string is too long, could not insert null terminator.
|
||||
/// \throw std::bad_alloc
|
||||
StatusUtf8(Status status, const std::string& str) :
|
||||
m_status(status), m_size(0), m_string(){
|
||||
|
||||
auto len = str.length();
|
||||
if (len >= std::numeric_limits<UInt32>::max()){
|
||||
throw RangeException();
|
||||
}
|
||||
|
||||
m_size = static_cast<UInt32>(len) + 1;
|
||||
m_string = Detail::alloc(m_size);
|
||||
|
||||
auto lock = m_string.lock<char>();
|
||||
std::copy(str.cbegin(), str.cend(), lock.data());
|
||||
lock[len] = '\0';
|
||||
}
|
||||
|
||||
/// Creates a new StatusUtf8 containing a copy of the supplied string.
|
||||
/// \param status
|
||||
/// \param str Utf-8 string to copy, null terminator is not required.
|
||||
/// \param strSize {Number of bytes to copy including null terminator.
|
||||
/// Null terminator is inserted automatically.}
|
||||
/// \throw RangeException When string is too short to satisfy the requested size.
|
||||
/// \throw std::bad_alloc
|
||||
StatusUtf8(Status status, const char* str, UInt32 strSize) :
|
||||
m_status(status), m_size(0), m_string(){
|
||||
|
||||
auto len = strlen(str);
|
||||
if (len < strSize){
|
||||
throw RangeException();
|
||||
}
|
||||
|
||||
m_size = static_cast<UInt32>(strSize) + 1;
|
||||
m_string = Detail::alloc(m_size);
|
||||
|
||||
auto lock = m_string.lock<char>();
|
||||
std::copy(str, str + strSize, lock.data());
|
||||
lock[strSize] = '\0';
|
||||
}
|
||||
|
||||
StatusUtf8(const StatusUtf8&) = delete;
|
||||
StatusUtf8& operator=(const StatusUtf8&) = delete;
|
||||
|
||||
StatusUtf8(StatusUtf8&& o) noexcept :
|
||||
m_status(o.m_status), m_size(o.m_size), m_string(std::move(o.m_string)){
|
||||
|
||||
o.m_status = Status();
|
||||
o.m_size = 0;
|
||||
}
|
||||
|
||||
StatusUtf8& operator=(StatusUtf8&& o) noexcept{
|
||||
if (&o != this){
|
||||
m_status = o.m_status;
|
||||
m_size = o.m_size;
|
||||
m_string = std::move(o.m_string);
|
||||
|
||||
o.m_status = Status();
|
||||
o.m_size = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Returns the interpreted status.
|
||||
Status status() const noexcept{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
/// Sets the status to be interpreted.
|
||||
void setStatus(Status status) noexcept{
|
||||
m_status = status;
|
||||
}
|
||||
|
||||
/// Returns the total number of bytes including null byte.
|
||||
UInt32 size() const noexcept{
|
||||
return m_string ? m_size : 0;
|
||||
}
|
||||
|
||||
/// The UTF8 string itself.
|
||||
ConstString string() const noexcept{
|
||||
return m_string.lock<const char>();
|
||||
}
|
||||
|
||||
private:
|
||||
Status m_status;
|
||||
UInt32 m_size;
|
||||
Detail::UniqueHandle m_string;
|
||||
|
||||
};
|
||||
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_STATUS_HPP
|
||||
|
|
@ -1,310 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_STRINGS_HPP
|
||||
#define TWPP_DETAIL_FILE_STRINGS_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
// specialization for twain strings
|
||||
// on mac os, these strings do not contain null terminator
|
||||
// instead, the first byte contains the length
|
||||
template<std::size_t arraySize, std::size_t... i>
|
||||
struct FixedArrayData<char, arraySize, IndexList<i...> > {
|
||||
|
||||
template<std::size_t inputSize>
|
||||
constexpr FixedArrayData(const char(& arr)[inputSize]) noexcept :
|
||||
m_arr{
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
unsignedToSigned<unsigned char>(inputSize - 1),
|
||||
#elif !defined(TWPP_DETAIL_OS_WIN) && !defined(TWPP_DETAIL_OS_LINUX)
|
||||
# error "string data setup for yout platform here"
|
||||
#endif
|
||||
FixedArrayFlat<char, arraySize>(arr)[i]...
|
||||
}{}
|
||||
|
||||
constexpr FixedArrayData() noexcept :
|
||||
m_arr(){}
|
||||
|
||||
char m_arr[arraySize];
|
||||
|
||||
};
|
||||
|
||||
// specialization for twain strings
|
||||
// on mac os, these strings do not contain null terminator
|
||||
// instead, the first byte contains the length
|
||||
// so we provide one less index for the fixed array
|
||||
// on windows, its element is zero-initialized due to it not being specified
|
||||
// on mac os, the first byte contains the length, so the index is not used anyway
|
||||
template<std::size_t arraySize>
|
||||
struct FixedArray<char, arraySize> : public FixedArrayData<char, arraySize, typename Indexes<arraySize - 1>::Result> {
|
||||
|
||||
typedef FixedArrayData<char, arraySize, typename Indexes<arraySize - 1>::Result> ParentType;
|
||||
typedef char Array[arraySize];
|
||||
|
||||
constexpr FixedArray() noexcept :
|
||||
ParentType(){}
|
||||
|
||||
template<std::size_t inputSize>
|
||||
constexpr FixedArray(const char(& arr)[inputSize]) noexcept :
|
||||
ParentType(arr){
|
||||
|
||||
static_assert(inputSize <= arraySize, "string literal is too long");
|
||||
}
|
||||
|
||||
constexpr const Array& array() const noexcept{
|
||||
return ParentType::m_arr;
|
||||
}
|
||||
|
||||
Array& array() noexcept{
|
||||
return ParentType::m_arr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// TWAIN string template.
|
||||
/// \tparam arraySize String capacity, including either null byte, or length byte (Mac OS).
|
||||
template<std::size_t arraySize>
|
||||
class Str : private FixedArray<char, arraySize>{
|
||||
|
||||
typedef FixedArray<char, arraySize> DataType;
|
||||
|
||||
public:
|
||||
typedef const char* const_iterator;
|
||||
typedef char* iterator;
|
||||
|
||||
/// Maximal number of characters this string may hold.
|
||||
/// Excluding null byte (length byte).
|
||||
static constexpr UInt32 maxSize() noexcept{
|
||||
return arraySize - 1;
|
||||
}
|
||||
|
||||
static_assert(maxSize() <= std::numeric_limits<unsigned char>::max(), "string type exceeds allowed sizes");
|
||||
|
||||
|
||||
/// Creates an empty, zero-initialized string.
|
||||
constexpr Str() noexcept{}
|
||||
|
||||
/// Creates a compile-time string from string literal (or char array).
|
||||
/// \tparam inputSize Size of the string literal including null terminator.
|
||||
/// \param str The string literal.
|
||||
template<std::size_t inputSize>
|
||||
constexpr Str(const char(& str)[inputSize]) noexcept :
|
||||
DataType(str){
|
||||
|
||||
static_assert(inputSize <= arraySize, "string literal is too long");
|
||||
}
|
||||
|
||||
/// Alias to length().
|
||||
constexpr UInt32 size() const noexcept{
|
||||
return length();
|
||||
}
|
||||
|
||||
/// Length of the string (number of 8-bit characters).
|
||||
/// O(1) on Mac OS, O(n) anywhere else.
|
||||
constexpr UInt32 length() const noexcept{
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
return static_cast<unsigned const char>(this->array()[0]);
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
return strLen(data());
|
||||
#else
|
||||
# error "String::length for your platform here"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Pointer to constant data.
|
||||
/// On Mac OS, the data is NOT null-terminated,
|
||||
/// and points to the first character after size byte.
|
||||
/// This operation is unsafe, and its use may not be platform-independent.
|
||||
constexpr const char* data() const noexcept{
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
return this->array() + 1;
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
return this->array();
|
||||
#else
|
||||
# error "String::data for your platform here"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Pointer to data.
|
||||
/// On Mac OS, the data is NOT null-terminated,
|
||||
/// and points to the first character after size byte.
|
||||
/// This operation is unsafe, and its use may not be platform-independent.
|
||||
char* data() noexcept{
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
return this->array() + 1;
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
return this->array();
|
||||
#else
|
||||
# error "String::data for your platform here"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Sets string data.
|
||||
/// Copies as much data as possible, discarding the rest.
|
||||
/// The data needn't be null terminated.
|
||||
/// \param str Data to copy.
|
||||
/// \param size Maximal number of bytes to copy.
|
||||
/// \return Number of bytes copied - the new length of this string.
|
||||
UInt32 setData(const char* data, UInt32 size) noexcept{
|
||||
char* arr = this->data();
|
||||
UInt32 i = 0;
|
||||
|
||||
auto maxLen = std::min(maxSize(), size);
|
||||
for ( ; i < maxLen && *data; i++, data++){
|
||||
arr[i] = *data;
|
||||
}
|
||||
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
*reinterpret_cast<unsigned char*>(this->array()) = static_cast<unsigned char>(i);
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
arr[i] = '\0';
|
||||
#else
|
||||
# error "String::setData for your platform here"
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/// Sets string data.
|
||||
/// Copies as much data as possible, discarding the rest.
|
||||
/// The string must be null terminated.
|
||||
/// \param str String to copy.
|
||||
/// \return Number of characters copied - the new length of this string.
|
||||
UInt32 setData(const char* str) noexcept{
|
||||
return setData(str, maxSize());
|
||||
}
|
||||
|
||||
/// Sets string data from container (e.g. std::string).
|
||||
/// Copies as much data as possible, discarding the rest.
|
||||
/// The string needn't be null terminated.
|
||||
/// \tparam Contaier Container type.
|
||||
/// \param cont Container with data to be copied.
|
||||
/// \return Number of characters copied - the new length of this string.
|
||||
template<typename Container, typename = typename std::enable_if<std::is_same<typename Container::value_type, char>::value>::type>
|
||||
UInt32 setData(const Container& cont) noexcept{
|
||||
return setData(cont.data(), static_cast<UInt32>(std::min<typename Container::size_type>(cont.size(), maxSize())));
|
||||
}
|
||||
|
||||
char operator[](UInt32 i) const noexcept{
|
||||
return data()[i];
|
||||
}
|
||||
|
||||
char& operator[](UInt32 i) noexcept{
|
||||
return data()[i];
|
||||
}
|
||||
|
||||
iterator begin() noexcept{
|
||||
return data();
|
||||
}
|
||||
|
||||
constexpr const_iterator begin() const noexcept{
|
||||
return cbegin();
|
||||
}
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept{
|
||||
return data();
|
||||
}
|
||||
|
||||
iterator end() noexcept{
|
||||
return data() + length();
|
||||
}
|
||||
|
||||
constexpr const_iterator end() const noexcept{
|
||||
return cend();
|
||||
}
|
||||
|
||||
constexpr const_iterator cend() const noexcept{
|
||||
return data() + length();
|
||||
}
|
||||
|
||||
std::string string() const{
|
||||
return std::string(cbegin(), cend());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<std::size_t sizeA, std::size_t sizeB>
|
||||
constexpr bool operator==(const Detail::Str<sizeA>& a, const Detail::Str<sizeB>& b) noexcept{
|
||||
// length() is O(1) on mac os, O(n) anywhere else
|
||||
#if defined(TWPP_DETAIL_OS_MAC)
|
||||
return a.length() == b.length() && Detail::strCmp(a.data(), b.data()) == 0;
|
||||
#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
return Detail::strCmp(a.data(), b.data()) == 0;
|
||||
#else
|
||||
# error "String equals operator for your platform here"
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template<std::size_t sizeA, std::size_t sizeB>
|
||||
constexpr bool operator<(const Detail::Str<sizeA>& a, const Detail::Str<sizeB>& b) noexcept{
|
||||
return Detail::strCmp(a.data(), b.data()) < 0;
|
||||
}
|
||||
|
||||
template<std::size_t sizeA, std::size_t sizeB>
|
||||
constexpr bool operator>(const Detail::Str<sizeA>& a, const Detail::Str<sizeB>& b) noexcept{
|
||||
return Detail::strCmp(a.data(), b.data()) > 0;
|
||||
}
|
||||
|
||||
template<std::size_t sizeA, std::size_t sizeB>
|
||||
constexpr bool operator!=(const Detail::Str<sizeA>& a, const Detail::Str<sizeB>& b) noexcept{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
template<std::size_t sizeA, std::size_t sizeB>
|
||||
constexpr bool operator<=(const Detail::Str<sizeA>& a, const Detail::Str<sizeB>& b) noexcept{
|
||||
return !(a > b);
|
||||
}
|
||||
|
||||
template<std::size_t sizeA, std::size_t sizeB>
|
||||
constexpr bool operator>=(const Detail::Str<sizeA>& a, const Detail::Str<sizeB>& b) noexcept{
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
/// TWAIN string that can contain up to 33 characters (bytes).
|
||||
typedef Detail::Str<34> Str32;
|
||||
|
||||
/// TWAIN string that can contain up to 65 characters (bytes).
|
||||
typedef Detail::Str<66> Str64;
|
||||
|
||||
/// TWAIN string that can contain up to 129 characters (bytes).
|
||||
typedef Detail::Str<130> Str128;
|
||||
|
||||
/// TWAIN string that can contain up to 255 characters (bytes).
|
||||
typedef Detail::Str<256> Str255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_STRINGS_HPP
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#ifndef TWGLUE_HPP
|
||||
#define TWGLUE_HPP
|
||||
|
||||
#include <functional>
|
||||
// #include "Device/PublicFunc.h"
|
||||
|
||||
struct TwGlue {
|
||||
|
||||
TwGlue(const std::function<void(const GScanCap&)>& scan, const std::function<void()>& cancel) :
|
||||
m_scan(scan), m_cancel(cancel){}
|
||||
|
||||
std::function<void(const GScanCap&)> m_scan;
|
||||
std::function<void()> m_cancel;
|
||||
|
||||
};
|
||||
|
||||
#endif // TWGLUE_HPP
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_TYPES_HPP
|
||||
#define TWPP_DETAIL_FILE_TYPES_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
typedef std::uintptr_t UIntPtr;
|
||||
typedef std::uint8_t UInt8;
|
||||
typedef std::uint16_t UInt16;
|
||||
typedef std::uint32_t UInt32;
|
||||
typedef std::int8_t Int8;
|
||||
typedef std::int16_t Int16;
|
||||
typedef std::int32_t Int32;
|
||||
|
||||
/// Boolean value.
|
||||
/// Implemented as a class to provide better type safety.
|
||||
class Bool {
|
||||
|
||||
public:
|
||||
constexpr Bool(bool value = false) noexcept :
|
||||
m_value(value){}
|
||||
|
||||
constexpr operator bool() const noexcept{
|
||||
return m_value != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Int16 m_value;
|
||||
|
||||
};
|
||||
|
||||
/// Handle to memory area.
|
||||
/// Implemented as a class to provide better type safety.
|
||||
class Handle {
|
||||
|
||||
public:
|
||||
typedef Detail::RawHandle Raw;
|
||||
|
||||
constexpr explicit Handle(Raw raw = Raw()) noexcept :
|
||||
m_raw(raw){}
|
||||
|
||||
/// Underlying OS-dependent handle.
|
||||
constexpr Raw raw() const noexcept{
|
||||
return m_raw;
|
||||
}
|
||||
|
||||
constexpr operator bool() const noexcept{
|
||||
return m_raw != Raw();
|
||||
}
|
||||
|
||||
private:
|
||||
Raw m_raw;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_TYPES_HPP
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_TYPESOPS_HPP
|
||||
#define TWPP_DETAIL_FILE_TYPESOPS_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
/// Enumeration representing basic types.
|
||||
enum class Type : UInt16 {
|
||||
DontCare = 0xFFFF,
|
||||
Int8 = 0x0000,
|
||||
Int16 = 0x0001,
|
||||
Int32 = 0x0002,
|
||||
UInt8 = 0x0003,
|
||||
UInt16 = 0x0004,
|
||||
UInt32 = 0x0005,
|
||||
Bool = 0x0006,
|
||||
Fix32 = 0x0007,
|
||||
Frame = 0x0008,
|
||||
Str32 = 0x0009,
|
||||
Str64 = 0x000a,
|
||||
Str128 = 0x000b,
|
||||
Str255 = 0x000c,
|
||||
Handle = 0x000f
|
||||
};
|
||||
|
||||
/// Whether the enum value actually is a type, DontCare is not a type.
|
||||
static inline bool isType(Type type){
|
||||
switch (type){
|
||||
case Type::Int8:
|
||||
case Type::UInt8:
|
||||
case Type::Int16:
|
||||
case Type::UInt16:
|
||||
case Type::Int32:
|
||||
case Type::UInt32:
|
||||
case Type::Bool:
|
||||
case Type::Fix32:
|
||||
case Type::Str32:
|
||||
case Type::Str64:
|
||||
case Type::Str128:
|
||||
case Type::Str255:
|
||||
case Type::Frame:
|
||||
case Type::Handle:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Size in bytes of a type represented by enum value.
|
||||
static inline UInt32 typeSize(Type type){
|
||||
switch (type){
|
||||
case Type::Int8: return sizeof(Int8);
|
||||
case Type::UInt8: return sizeof(UInt8);
|
||||
case Type::Int16: return sizeof(Int16);
|
||||
case Type::UInt16: return sizeof(UInt16);
|
||||
case Type::Int32: return sizeof(Int32);
|
||||
case Type::UInt32: return sizeof(UInt32);
|
||||
case Type::Bool: return sizeof(Bool);
|
||||
case Type::Fix32: return sizeof(Fix32);
|
||||
case Type::Str32: return sizeof(Str32);
|
||||
case Type::Str64: return sizeof(Str64);
|
||||
case Type::Str128: return sizeof(Str128);
|
||||
case Type::Str255: return sizeof(Str255);
|
||||
case Type::Frame: return sizeof(Frame);
|
||||
case Type::Handle: return sizeof(Handle);
|
||||
default: throw TypeException();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
|
||||
/// Conversion from Type enum to actual data type.
|
||||
template<Type type> struct Twty {};
|
||||
template<> struct Twty<Type::Int8> {typedef Int8 Type;};
|
||||
template<> struct Twty<Type::Int16> {typedef Int16 Type;};
|
||||
template<> struct Twty<Type::Int32> {typedef Int32 Type;};
|
||||
template<> struct Twty<Type::UInt8> {typedef UInt8 Type;};
|
||||
template<> struct Twty<Type::UInt16> {typedef UInt16 Type;};
|
||||
template<> struct Twty<Type::UInt32> {typedef UInt32 Type;};
|
||||
template<> struct Twty<Type::Bool> {typedef Bool Type;};
|
||||
template<> struct Twty<Type::Fix32> {typedef Fix32 Type;};
|
||||
template<> struct Twty<Type::Frame> {typedef Frame Type;};
|
||||
template<> struct Twty<Type::Str32> {typedef Str32 Type;};
|
||||
template<> struct Twty<Type::Str64> {typedef Str64 Type;};
|
||||
template<> struct Twty<Type::Str128> {typedef Str128 Type;};
|
||||
template<> struct Twty<Type::Str255> {typedef Str255 Type;};
|
||||
template<> struct Twty<Type::Handle> {typedef Handle Type;};
|
||||
|
||||
|
||||
// Conversion from data type to Type enum helpers.
|
||||
template<typename DataType> struct Tytw;
|
||||
|
||||
template<typename DataType, bool isEnum> // true
|
||||
struct TytwHelper : Tytw<typename std::underlying_type<DataType>::type> {};
|
||||
|
||||
template<typename DataType>
|
||||
struct TytwHelper<DataType, false> {};
|
||||
|
||||
/// Conversion from data type to Type enum.
|
||||
template<typename DataType> struct Tytw : TytwHelper<DataType, std::is_enum<DataType>::value> {};
|
||||
template<> struct Tytw<Int8> {static constexpr const Type twty = Type::Int8;};
|
||||
template<> struct Tytw<Int16> {static constexpr const Type twty = Type::Int16;};
|
||||
template<> struct Tytw<Int32> {static constexpr const Type twty = Type::Int32;};
|
||||
template<> struct Tytw<UInt8> {static constexpr const Type twty = Type::UInt8;};
|
||||
template<> struct Tytw<UInt16> {static constexpr const Type twty = Type::UInt16;};
|
||||
template<> struct Tytw<UInt32> {static constexpr const Type twty = Type::UInt32;};
|
||||
template<> struct Tytw<Bool> {static constexpr const Type twty = Type::Bool;};
|
||||
template<> struct Tytw<Fix32> {static constexpr const Type twty = Type::Fix32;};
|
||||
template<> struct Tytw<Frame> {static constexpr const Type twty = Type::Frame;};
|
||||
template<> struct Tytw<Str32> {static constexpr const Type twty = Type::Str32;};
|
||||
template<> struct Tytw<Str64> {static constexpr const Type twty = Type::Str64;};
|
||||
template<> struct Tytw<Str128> {static constexpr const Type twty = Type::Str128;};
|
||||
template<> struct Tytw<Str255> {static constexpr const Type twty = Type::Str255;};
|
||||
template<> struct Tytw<Handle> {static constexpr const Type twty = Type::Handle;};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_TYPESOPS_HPP
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2017 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_USERINTERFACE_HPP
|
||||
#define TWPP_DETAIL_FILE_USERINTERFACE_HPP
|
||||
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
TWPP_DETAIL_PACK_BEGIN
|
||||
/// Structure holding parameters for enabling or disabling data source.
|
||||
class UserInterface {
|
||||
|
||||
public:
|
||||
/// Creates a new UserInterface.
|
||||
/// \param showUi Whether to show internal DS GUI. Disabling DS GUI might not be supported.
|
||||
/// \param modalUi Whether DS GUI should be modal. Not used on Linux. Might not be supported on Windows.
|
||||
/// \param parent Windows-only, others set to null. Handle to parent window. This object does NOT take ownership.
|
||||
#if defined(TWPP_DETAIL_OS_WIN)
|
||||
constexpr UserInterface(Bool showUi, Bool modalUi, Handle parent) noexcept :
|
||||
m_showUi(showUi), m_modalUi(modalUi), m_parent(parent){}
|
||||
#elif defined(TWPP_DETAIL_OS_MAC) || defined(TWPP_DETAIL_OS_LINUX)
|
||||
constexpr UserInterface(Bool showUi, Bool modalUi, Handle parent = Handle()) noexcept :
|
||||
m_showUi(showUi), m_modalUi(modalUi), m_parent(parent){}
|
||||
#else
|
||||
# error "UserInterface constructor for your platform here"
|
||||
#endif
|
||||
|
||||
/// Whether to show internal DS GUI.
|
||||
constexpr Bool showUi() const noexcept{
|
||||
return m_showUi;
|
||||
}
|
||||
|
||||
/// Whether DS GUI should be modal
|
||||
constexpr Bool modalUi() const noexcept{
|
||||
return m_modalUi;
|
||||
}
|
||||
|
||||
/// Handle to parent window.
|
||||
constexpr Handle parent() const noexcept{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
private:
|
||||
Bool m_showUi;
|
||||
Bool m_modalUi;
|
||||
Handle m_parent;
|
||||
|
||||
};
|
||||
TWPP_DETAIL_PACK_END
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_USERINTERFACE_HPP
|
||||
|
|
@ -1,485 +0,0 @@
|
|||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Martin Richter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TWPP_DETAIL_FILE_UTILS_HPP
|
||||
#define TWPP_DETAIL_FILE_UTILS_HPP
|
||||
|
||||
#undef max
|
||||
#undef min
|
||||
#include <limits>
|
||||
#include "../twpp.hpp"
|
||||
|
||||
namespace Twpp {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
/// Creates a template for testing whether a class contains public static method.
|
||||
/// Use this macro anywhere a class may be defined, and pass method name
|
||||
/// as its parameter. Then use `HasStaticMethod_<your-method-name>` template.
|
||||
///
|
||||
/// E. g.:
|
||||
/// TWPP_DETAIL_CREATE_HAS_STATIC_METHOD(myMethod) // <- semicolon not required
|
||||
/// HasStaticMethod_myMethod<MyClass, void(int, char)>::value
|
||||
///
|
||||
/// This test whether `MyClass` has static method `void MyClass::myMethod(int, char)`.
|
||||
/// That is whether you may do this:
|
||||
/// MyClass::myMethod(10, 'a');
|
||||
#define TWPP_DETAIL_CREATE_HAS_STATIC_METHOD(methodName) \
|
||||
template<typename T, typename Fn>\
|
||||
class HasStaticMethod_ ## methodName;\
|
||||
\
|
||||
template<typename T, typename Ret, typename... Args>\
|
||||
class HasStaticMethod_ ## methodName <T, Ret(Args...)> {\
|
||||
\
|
||||
template<typename U>\
|
||||
static constexpr auto test(U*) ->\
|
||||
typename std::is_same<decltype(U::methodName(std::declval<Args>()...)), Ret>::type;\
|
||||
\
|
||||
template<typename>\
|
||||
static constexpr std::false_type test(...);\
|
||||
\
|
||||
public:\
|
||||
typedef decltype(test<T>(0)) type;\
|
||||
static constexpr const bool value = type::value;\
|
||||
\
|
||||
};
|
||||
|
||||
/// Creates a template for testing whether a class contains public method.
|
||||
/// Use this macro anywhere a class may be defined, and pass method name
|
||||
/// as its parameter. Then use `HasMethod_<your-method-name>` template.
|
||||
///
|
||||
/// E. g.:
|
||||
/// TWPP_DETAIL_CREATE_HAS_METHOD(myMethod) // <- semicolon not required
|
||||
/// HasMethod_myMethod<MyClass, void(int, char)>::value
|
||||
///
|
||||
/// This test whether `MyClass` has method (AKA member function) `void MyClass::myMethod(int, char)`.
|
||||
/// That is whether you may do this:
|
||||
/// MyClass o ... ;
|
||||
/// o.myMethod(10, 'a');
|
||||
#define TWPP_DETAIL_CREATE_HAS_METHOD(methodName) \
|
||||
template<typename T, typename Fn>\
|
||||
class HasMethod_ ## methodName;\
|
||||
\
|
||||
template<typename T, typename Ret, typename... Args>\
|
||||
class HasMethod_ ## methodName <T, Ret(Args...)> {\
|
||||
\
|
||||
template<typename U>\
|
||||
static constexpr auto test(U*) ->\
|
||||
typename std::is_same<decltype(std::declval<U>().methodName(std::declval<Args>()...)), Ret>::type;\
|
||||
\
|
||||
template<typename>\
|
||||
static constexpr std::false_type test(...);\
|
||||
\
|
||||
public:\
|
||||
typedef decltype(test<T>(0)) type;\
|
||||
static constexpr const bool value = type::value;\
|
||||
\
|
||||
};
|
||||
|
||||
/// Performs a pointer type cast, suppresses strict aliasing warnings.
|
||||
/// \tparam T Type of the returned pointer. Must be pointer type (e.g. `char*`).
|
||||
/// \param ptr Pointer to be cast.
|
||||
/// \return Cast pointer.
|
||||
template<typename T>
|
||||
static constexpr inline T alias_cast(void* ptr) noexcept{
|
||||
return reinterpret_cast<T>(ptr);
|
||||
}
|
||||
|
||||
/// Performs a constant pointer type cast, suppresses strict aliasing warnings.
|
||||
/// \tparam T Type of the returned pointer. Must be pointer type (e.g. `char*`).
|
||||
/// \param ptr Pointer to be cast.
|
||||
/// \return Cast pointer.
|
||||
template<typename T>
|
||||
static constexpr inline T alias_cast(const void* ptr) noexcept{
|
||||
return reinterpret_cast<T>(ptr);
|
||||
}
|
||||
|
||||
/// Suppresses warnings about unused parameters or arguments.
|
||||
/// \tparam Args List of argument types. No need to specify explicitly.
|
||||
template<typename... Args>
|
||||
static inline void unused(const Args& ...) noexcept{}
|
||||
|
||||
|
||||
|
||||
// CODE FROM http://www.macieira.org/blog/2011/07/initialising-an-array-with-cx0x-using-constexpr-and-variadic-templates/
|
||||
// BEGIN
|
||||
template<std::size_t... Idx> struct IndexList {};
|
||||
|
||||
template<typename IndexList, std::size_t Right> struct Append;
|
||||
template<std::size_t... Left, std::size_t Right>
|
||||
struct Append<IndexList<Left...>, Right>{ typedef IndexList<Left..., Right> Result; };
|
||||
|
||||
template<std::size_t N> struct Indexes {
|
||||
typedef typename Append<typename Indexes<N - 1>::Result, N - 1>::Result Result;
|
||||
};
|
||||
template<> struct Indexes<0> { typedef IndexList<> Result; };
|
||||
// END
|
||||
|
||||
/// Converts an array of arbitary size to array-like recursive structure of fixed size (at compile time).
|
||||
/// Provide template specialization if special handling of elements is required, and you do care
|
||||
/// about their positions - otherwise see FixedArrayData below.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam arraySize Number of elements in the fixed array.
|
||||
template<typename T, std::size_t arraySize>
|
||||
struct FixedArrayFlat : FixedArrayFlat<T, arraySize - 1> {
|
||||
|
||||
/// The index this structure (with this `arraySize`) holds.
|
||||
static constexpr const std::size_t g_index = arraySize - 1;
|
||||
|
||||
/// Performs the conversion from arbiraty-size array to fixed-size structure.
|
||||
/// We use left recursion to initialize values of all inherited structures first.
|
||||
/// Then the value of this one is initialized, either copied from the input array itself,
|
||||
/// or default-initialized in case the array is not large enough.
|
||||
/// \tparam inputSize {Size of the input array. If smaller than the fixed array,
|
||||
/// excessive elements are default-initialized (may be changed in specializations).
|
||||
/// Providing larger array results in undefined behaviour.}
|
||||
/// \param arr The arbitary-size array.
|
||||
template<std::size_t inputSize>
|
||||
constexpr inline FixedArrayFlat(const T(& arr)[inputSize]) noexcept :
|
||||
FixedArrayFlat<T, g_index>(arr), m_val(g_index < inputSize ? arr[g_index] : T()){}
|
||||
|
||||
/// Returns value contained at specific index.
|
||||
/// If the index if smaller than the size of the input array, a value is returned
|
||||
/// as if the operation was performed on that array. Otherwise a default value
|
||||
/// of the type `T` is returned (or anything else a specialization provides).
|
||||
/// Behaviour of this operator is undefined if the index equals to or is greater than
|
||||
/// the size of the fixed array.
|
||||
/// \param i Value index.
|
||||
/// \return Value at index.
|
||||
constexpr inline T operator[](std::size_t i) const noexcept{
|
||||
return i == g_index ? m_val : FixedArrayFlat<T, g_index>::operator [](i);
|
||||
}
|
||||
|
||||
/// Value held by this structure.
|
||||
T m_val;
|
||||
|
||||
};
|
||||
|
||||
/// Converts an array of arbitary size to array-like recursive structure of fixed size (at compile time).
|
||||
/// This template specialization terminates the recursion.
|
||||
/// No need to provide any further specializations.
|
||||
/// \tparam T Element type.
|
||||
template<typename T>
|
||||
struct FixedArrayFlat<T, 0> {
|
||||
|
||||
template<std::size_t inputSize>
|
||||
constexpr inline FixedArrayFlat(const T(&)[inputSize]) noexcept{}
|
||||
|
||||
constexpr inline T operator[](std::size_t) const noexcept{
|
||||
return T();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Converts an array of arbitary size to array of fixed size at compile time.
|
||||
/// The job itself is done in the specialization below.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam arraySize Number of elements in the fixed array.
|
||||
/// \tparam IndexList Type holding indexes of the fixed array.
|
||||
template<typename T, std::size_t arraySize, typename IndexList>
|
||||
struct FixedArrayData {};
|
||||
|
||||
/// Converts an array of arbitary size to array of fixed size at compile time.
|
||||
/// Provide template specialization if special handling of elements is required, and you
|
||||
/// don't care about their positions.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam arraySize Number of elements in the fixed array.
|
||||
/// \tparam i Indexes of the fixed array.
|
||||
template<typename T, std::size_t arraySize, std::size_t... i>
|
||||
struct FixedArrayData<T, arraySize, IndexList<i...> > {
|
||||
|
||||
/// Performs the conversion from arbiraty-size array to fixed-size array.
|
||||
/// Uses FixedArrayFlat to extend the input array to desired size.
|
||||
/// \tparam inputSize Size of the input array.
|
||||
/// \param arr The input array.
|
||||
template<std::size_t inputSize>
|
||||
constexpr FixedArrayData(const T(& arr)[inputSize]) noexcept :
|
||||
m_arr{FixedArrayFlat<T, arraySize>(arr)[i]...}{}
|
||||
|
||||
/// Creates default-initialized array.
|
||||
constexpr FixedArrayData() noexcept :
|
||||
m_arr(){}
|
||||
|
||||
/// The fixed array.
|
||||
T m_arr[arraySize];
|
||||
|
||||
};
|
||||
|
||||
/// Compile-time constructible fixed-size array of type `T` and length `arraySize`.
|
||||
/// The array can be constructed from variable-sized array
|
||||
/// of up to `arraySize` elements at compile time.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam arraySize Number of elements in the array.
|
||||
template<typename T, std::size_t arraySize>
|
||||
struct FixedArray : public FixedArrayData<T, arraySize, typename Indexes<arraySize>::Result> {
|
||||
|
||||
typedef FixedArrayData<T, arraySize, typename Indexes<arraySize>::Result> ParentType;
|
||||
typedef T Array[arraySize];
|
||||
|
||||
/// Creates default-initialized array.
|
||||
constexpr FixedArray() noexcept :
|
||||
ParentType(){}
|
||||
|
||||
/// Creates fixed-size array from variable-size array at compile time.
|
||||
/// If the size of input array exceeds `arraySize`, a compile-time error is emited.
|
||||
/// \tparam inputSize Number of elements of the input array.
|
||||
/// \param arr The input array.
|
||||
template<std::size_t inputSize>
|
||||
constexpr FixedArray(const T(& arr)[inputSize]) noexcept :
|
||||
ParentType(arr){
|
||||
|
||||
static_assert(inputSize <= arraySize, "array literal is too big");
|
||||
}
|
||||
|
||||
/// The contained array.
|
||||
constexpr const Array& array() const noexcept{
|
||||
return ParentType::m_arr;
|
||||
}
|
||||
|
||||
/// The contained array.
|
||||
Array& array() noexcept{
|
||||
return ParentType::m_arr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Joins two arrays at compile time.
|
||||
/// The job itself is done in the specialization below.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam lenA Size of the first array.
|
||||
/// \tparam lenB Size of the second array.
|
||||
/// \tparam IndexList Type holding indexes of the resulting array.
|
||||
template<typename T, std::size_t lenA, std::size_t lenB, typename IndexList>
|
||||
struct ArrayJoinData {};
|
||||
|
||||
/// Joins two arrays at compile time.
|
||||
/// The result of this operation is an array that contains all the elements
|
||||
/// from the first array immediately followed by all the elements from
|
||||
/// the second array.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam lenA Size of the first array.
|
||||
/// \tparam lenB Size of the second array.
|
||||
/// \tparam i Indexes of the resulting array.
|
||||
template<typename T, std::size_t lenA, std::size_t lenB, std::size_t... i>
|
||||
struct ArrayJoinData<T, lenA, lenB, IndexList<i...> > {
|
||||
|
||||
/// Performs the join operation.
|
||||
/// \param a The first array.
|
||||
/// \param b The second array.
|
||||
constexpr ArrayJoinData(const T(& a)[lenA], const T(& b)[lenB]) noexcept :
|
||||
m_arr{(i < lenA ? a[i] : b[i - lenA])...}{}
|
||||
|
||||
/// The resulting array.
|
||||
T m_arr[lenA + lenB];
|
||||
|
||||
};
|
||||
|
||||
/// Compile-time join operation of two arrays of the same type.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam lenA Size of the first array.
|
||||
/// \tparam lenB Size of the second array.
|
||||
template<typename T, std::size_t lenA, std::size_t lenB>
|
||||
struct ArrayJoin : public ArrayJoinData<T, lenA, lenB, typename Indexes<lenA + lenB>::Result> {
|
||||
|
||||
typedef ArrayJoinData<T, lenA, lenB, typename Indexes<lenA + lenB>::Result> ParentType;
|
||||
typedef T Array[lenA + lenB];
|
||||
|
||||
/// Performs the join operation.
|
||||
/// \param a The first array.
|
||||
/// \param b The second array.
|
||||
constexpr ArrayJoin(const T(& a)[lenA], const T(& b)[lenB]) noexcept :
|
||||
ParentType(a, b){}
|
||||
|
||||
/// The joined array.
|
||||
constexpr const Array& array() const noexcept{
|
||||
return ParentType::m_arr;
|
||||
}
|
||||
|
||||
/// The joined array.
|
||||
Array& array() noexcept{
|
||||
return ParentType::m_arr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Performs compile-time array join operation.
|
||||
/// This is a helper function, see ArrayJoin and ArrayJoinData for more info.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam lenA Size of the first array.
|
||||
/// \tparam lenB Size of the second array.
|
||||
/// \param a The first array.
|
||||
/// \param b The second array.
|
||||
/// \return The joined array.
|
||||
template<typename T, std::size_t lenA, std::size_t lenB>
|
||||
static constexpr inline ArrayJoin<T, lenA, lenB> arrayJoin(const T(& a)[lenA], const T(& b)[lenB]) noexcept{
|
||||
return {a, b};
|
||||
}
|
||||
|
||||
|
||||
/// The loop that checks the suffix at compile time, see endsWith below.
|
||||
/// Checks are performed from right to left.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam arrLen The size of the array to be checked for the suffix.
|
||||
/// \tparam subLen The size of the suffix array.
|
||||
/// \param arr The array to be checked for the suffix.
|
||||
/// \param sub The suffix array.
|
||||
/// \param endOff Offset from the last element to be checked in this call.
|
||||
/// \return Whether the suffix is contained.
|
||||
template<typename T, std::size_t arrLen, std::size_t subLen>
|
||||
static constexpr inline bool endsWithLoop(const T(& arr)[arrLen], const T(& sub)[subLen], std::size_t endOff){
|
||||
return endOff >= subLen || (arr[arrLen - 1 - endOff] == sub[subLen - 1 - endOff] && endsWithLoop(arr, sub, endOff + 1));
|
||||
}
|
||||
|
||||
/// Checks whether the input array contains supplied suffix at compile time.
|
||||
/// \tparam T Element type.
|
||||
/// \tparam arrLen The size of the array to be checked for the suffix.
|
||||
/// \tparam subLen The size of the suffix array.
|
||||
/// \param arr The array to be checked for the suffix.
|
||||
/// \param sub The suffix array.
|
||||
/// \return Whether the suffix is contained.
|
||||
template<typename T, std::size_t arrLen, std::size_t subLen>
|
||||
static constexpr inline bool endsWith(const T(& arr)[arrLen], const T(& sub)[subLen]){
|
||||
return arrLen >= subLen && endsWithLoop(arr, sub, 0);
|
||||
}
|
||||
|
||||
/// Implementation of compile-time C string length.
|
||||
/// Uses tail recursion.
|
||||
/// \param str The string, or its remaining part.
|
||||
/// \param len Length of the previous, already processed, part of the string.
|
||||
/// \return Length of the string.
|
||||
static constexpr inline std::size_t strLenImpl(const char* str, std::size_t len = 0) noexcept{
|
||||
return *str == '\0' ? len : strLenImpl(str + 1, len + 1);
|
||||
}
|
||||
|
||||
/// Compile-time C string length.
|
||||
/// \param str The string.
|
||||
/// \return Length of the string.
|
||||
static constexpr inline std::size_t strLen(const char* str) noexcept{
|
||||
return strLenImpl(str);
|
||||
}
|
||||
|
||||
|
||||
/// Unsigned to signed conversion, using static_cast.
|
||||
/// Available only if integers are represented using 2 complement.
|
||||
/// Specialization handles non-2 complement cases.
|
||||
/// \tparam T An integral type.
|
||||
/// \tparam _2complement Whether ints are represented as 2 complement.
|
||||
template<typename T, bool _2complement> // true
|
||||
struct UnsigToSig {
|
||||
typedef typename std::make_signed<T>::type Signed;
|
||||
typedef typename std::make_unsigned<T>::type Unsigned;
|
||||
|
||||
static constexpr Signed convert(Unsigned val) noexcept{
|
||||
return static_cast<Signed>(val);
|
||||
}
|
||||
};
|
||||
|
||||
/// Unsigned to signed conversion.
|
||||
/// This specialization is used when architecture does not use 2 complement.
|
||||
/// \tparam T An integral type.
|
||||
template<typename T>
|
||||
struct UnsigToSig<T, false> {
|
||||
typedef typename std::make_signed<T>::type Signed;
|
||||
typedef typename std::make_unsigned<T>::type Unsigned;
|
||||
|
||||
static constexpr Signed convert(Unsigned val) noexcept{
|
||||
return val <= std::numeric_limits<Signed>::max() ?
|
||||
static_cast<Signed>(val) :
|
||||
static_cast<Signed>(val - std::numeric_limits<Signed>::min()) + std::numeric_limits<Signed>::min();
|
||||
}
|
||||
};
|
||||
|
||||
/// Converts, at compile time, an unsigned integer to its signed counterpart.
|
||||
/// This holds true: unsignedValue == static_cast<unsigned type>(unsignedToSigned(unsignedValue))
|
||||
/// \tparam T Unsigned integral type.
|
||||
/// \param val Unsigned value to be converted to signed.
|
||||
/// \return Signed value that can be converted back to its unsigned type.
|
||||
template<typename T, typename = typename std::enable_if<std::is_unsigned<T>::value>::type>
|
||||
static constexpr inline typename std::make_signed<T>::type unsignedToSigned(T val) noexcept{
|
||||
typedef typename std::make_signed<T>::type Signed;
|
||||
typedef typename std::make_unsigned<T>::type Unsigned;
|
||||
|
||||
return UnsigToSig<T, static_cast<Signed>(-1) == static_cast<Signed>(~Unsigned(0))>::convert(val);
|
||||
}
|
||||
|
||||
/// Compares two C strings at compile time as if strcmp was used.
|
||||
/// \param a First string.
|
||||
/// \param b Second string.
|
||||
/// \return See strcmp.
|
||||
static constexpr inline int strCmp(const char* a, const char* b) noexcept{
|
||||
return *a != *b ? (static_cast<int>(*a) - *b) : (*a == '\0' ? 0 : strCmp(a + 1, b + 1));
|
||||
}
|
||||
|
||||
/// Absolute value.
|
||||
/// Default implementation handles signed values
|
||||
/// of non-integral types.
|
||||
/// \tparam T Data type.
|
||||
/// \tparam integral Whether the type is integral.
|
||||
/// \tparam unsig Whether the data type is unsigned.
|
||||
template<typename T, bool integral, bool unsig> // false, false
|
||||
struct Abs {
|
||||
static constexpr inline T abs(T a) noexcept{
|
||||
return a >= T() ? a : -a;
|
||||
}
|
||||
};
|
||||
|
||||
/// Absolute value.
|
||||
/// This handles signed values of integral types.
|
||||
/// \tparam T Data type.
|
||||
template<typename T>
|
||||
struct Abs<T, true, false> {
|
||||
static constexpr inline T abs(T a) noexcept{
|
||||
return std::abs(a);
|
||||
}
|
||||
};
|
||||
|
||||
/// Absolute value.
|
||||
/// This handles unsigned values.
|
||||
/// \tparam T Data type.
|
||||
template<typename T, bool integral>
|
||||
struct Abs<T, integral, true> {
|
||||
static constexpr inline T abs(T a) noexcept{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
/// Absolute value.
|
||||
/// Handles anything that has `bool operator >=(const T&)` (or equiv.),
|
||||
/// `T operator-()`, and its default value represents `zero`.
|
||||
/// \tparam T Data type.
|
||||
/// \param a Value.
|
||||
template<typename T>
|
||||
static constexpr inline T abs(T a) noexcept{
|
||||
return Abs<T, std::is_integral<T>::value, std::is_unsigned<T>::value>::abs(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWPP_DETAIL_FILE_UTILS_HPP
|
||||
|
Loading…
Reference in New Issue