TWAIN跨平台基础代码

This commit is contained in:
gb 2023-07-10 15:29:23 +08:00
parent 63acafc433
commit 9af89edc32
86 changed files with 312 additions and 35910 deletions

View File

@ -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>

View File

@ -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)
{

View File

@ -10,3 +10,5 @@ EXPORTS
to_default_language
from_default_language
lang_refresh_language
language_option_descriptor

View File

@ -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>

View File

@ -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_);
}

View File

@ -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);
};

View File

@ -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_;
}

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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);
};

View File

@ -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_;
}

View File

@ -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);
};

View File

@ -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_;
}

View File

@ -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);
};

File diff suppressed because it is too large Load Diff

View File

@ -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);
};

View File

@ -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_;
}

View File

@ -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);
};

View File

@ -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 消息处理程序

View File

@ -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);
};

View File

@ -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"

File diff suppressed because it is too large Load Diff

View File

@ -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);
};
};

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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_;
}

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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

View File

@ -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" />

View File

@ -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">

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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

View File

@ -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(&reg_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;
}
};

View File

@ -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);
};

View File

@ -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" />

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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