This commit is contained in:
恍兮惚兮 2024-07-14 15:09:37 +08:00
parent a5473ad1a1
commit 856c901f63
21 changed files with 244 additions and 468 deletions

View File

@ -1,5 +1,6 @@
import winsharedutils import winsharedutils
import os import os, functools, csv, gobject
from ctypes import CFUNCTYPE, c_char_p
from hiraparse.basehira import basehira from hiraparse.basehira import basehira
@ -23,11 +24,36 @@ from hiraparse.basehira import basehira
# 'aModType lid lemma_id'.split(' ')) # 'aModType lid lemma_id'.split(' '))
class mecabwrap:
def __init__(self, mecabpath) -> None:
self.kks = winsharedutils.mecab_init(
mecabpath.encode("utf8"), gobject.GetDllpath("libmecab.dll")
)
def __del__(self):
winsharedutils.mecab_end(self.kks)
def parse(self, text: str, codec: str):
res = []
def cb(surface: bytes, feature: bytes):
fields = list(csv.reader([feature.decode(codec)]))[0]
res.append((surface.decode(codec), fields))
succ = winsharedutils.mecab_parse(
self.kks, text.encode(codec), CFUNCTYPE(None, c_char_p, c_char_p)(cb)
)
if not succ:
raise Exception # failed
return res
class mecab(basehira): class mecab(basehira):
def init(self) -> None: def init(self) -> None:
mecabpath = self.config["path"] mecabpath = self.config["path"]
if os.path.exists(mecabpath): if os.path.exists(mecabpath):
self.kks = winsharedutils.mecabwrap( self.kks = mecabwrap(
mecabpath mecabpath
) # fugashi.Tagger('-r nul -d "{}" -Owakati'.format(mecabpath)) ) # fugashi.Tagger('-r nul -d "{}" -Owakati'.format(mecabpath))

View File

@ -1,6 +1,6 @@
import gobject, os, uuid, json import gobject, os, uuid
from ocrengines.baseocrclass import baseocr from ocrengines.baseocrclass import baseocr
from ctypes import CDLL, c_void_p, c_wchar_p, c_char_p, cast from ctypes import CDLL, c_void_p, c_wchar_p, c_char_p, CFUNCTYPE, c_bool, c_int
class OCR(baseocr): class OCR(baseocr):
@ -41,20 +41,24 @@ class OCR(baseocr):
ff.write(imagebinary) ff.write(imagebinary)
imgfile = os.path.abspath(fname) imgfile = os.path.abspath(fname)
wcocr_ocr = self.wcocr.wcocr_ocr wcocr_ocr = self.wcocr.wcocr_ocr
wcocr_ocr.argtypes = c_void_p, c_char_p wcocr_ocr.argtypes = c_void_p, c_char_p, c_void_p
wcocr_ocr.restype = c_void_p wcocr_ocr.restype = c_bool
wcocr_free_str = self.wcocr.wcocr_free_str ret = []
wcocr_free_str.argtypes = (c_void_p,)
pstring = wcocr_ocr(self.pobj, imgfile.encode("utf8"))
if not pstring:
return
string = cast(pstring, c_char_p).value.decode("utf8")
wcocr_free_str(pstring)
def cb(x1, y1, x2, y2, text: bytes):
ret.append((x1, y1, x2, y2, text.decode("utf8")))
succ = wcocr_ocr(
self.pobj,
imgfile.encode("utf8"),
CFUNCTYPE(None, c_int, c_int, c_int, c_int, c_char_p)(cb),
)
if not succ:
return
os.remove(imgfile) os.remove(imgfile)
boxs = [] boxs = []
texts = [] texts = []
for line in json.loads(string): for line in ret:
x1, y1, x2, y2, text = line x1, y1, x2, y2, text = line
boxs.append((x1, y1, x2, y2)) boxs.append((x1, y1, x2, y2))
texts.append(text) texts.append(text)

View File

@ -1,6 +1,4 @@
import time, os
import winsharedutils import winsharedutils
from tts.basettsclass import TTSbase from tts.basettsclass import TTSbase
@ -35,8 +33,6 @@ class TTS(TTSbase):
else: else:
version = 7 version = 7
voice_idx = self._7m[voice] voice_idx = self._7m[voice]
data=winsharedutils.SAPI_Speak( data = winsharedutils.SAPI_Speak(content, version, voice_idx, rate, 100)
content, version, voice_idx, rate, 100
)
return data return data

View File

@ -1,12 +1,10 @@
from ctypes import ( from ctypes import (
c_uint, c_uint,
c_bool, c_bool,
POINTER,
c_wchar_p, c_wchar_p,
pointer,
CDLL, CDLL,
c_size_t, c_size_t,
Structure, CFUNCTYPE,
c_void_p, c_void_p,
) )
import platform, gobject import platform, gobject
@ -21,49 +19,35 @@ except:
if winrtutilsdll: if winrtutilsdll:
class ocrres(Structure):
_fields_ = [
("lines", POINTER(c_wchar_p)),
("xs", POINTER(c_uint)),
("ys", POINTER(c_uint)),
("xs2", POINTER(c_uint)),
("ys2", POINTER(c_uint)),
]
_OCR_f = winrtutilsdll.OCR _OCR_f = winrtutilsdll.OCR
_OCR_f.argtypes = c_void_p, c_size_t, c_wchar_p, c_wchar_p, POINTER(c_uint) _OCR_f.argtypes = c_void_p, c_size_t, c_wchar_p, c_wchar_p, c_void_p
_OCR_f.restype = ocrres
_freeocrres = winrtutilsdll.freeocrres
_freeocrres.argtypes = ocrres, c_uint
_freewstringlist = winrtutilsdll.freewstringlist
_freewstringlist.argtypes = POINTER(c_wchar_p), c_uint
_check_language_valid = winrtutilsdll.check_language_valid _check_language_valid = winrtutilsdll.check_language_valid
_check_language_valid.argtypes = (c_wchar_p,) _check_language_valid.argtypes = (c_wchar_p,)
_check_language_valid.restype = c_bool _check_language_valid.restype = c_bool
_getlanguagelist = winrtutilsdll.getlanguagelist _getlanguagelist = winrtutilsdll.getlanguagelist
_getlanguagelist.argtypes = (POINTER(c_uint),) _getlanguagelist.argtypes = (c_void_p,)
_getlanguagelist.restype = POINTER(c_wchar_p)
def getlanguagelist(): def getlanguagelist():
num = c_uint() ret = []
ret = _getlanguagelist(pointer(num)) _getlanguagelist(CFUNCTYPE(None, c_wchar_p)(ret.append))
_allsupport = [] return ret
for i in range(num.value):
_allsupport.append(ret[i])
_freewstringlist(ret, num.value)
return _allsupport
def OCR_f(data, lang, space): def OCR_f(data, lang, space):
num = c_uint() ret = []
ret = _OCR_f(data, len(data), lang, space, pointer(num))
res = []
for i in range(num.value):
res.append((ret.lines[i], ret.xs[i], ret.ys[i], ret.xs2[i], ret.ys2[i]))
_freeocrres(ret, num.value) def cb(x1, y1, x2, y2, text):
return res ret.append((text, x1, y1, x2, y2))
_OCR_f(
data,
len(data),
lang,
space,
CFUNCTYPE(None, c_uint, c_uint, c_uint, c_uint, c_wchar_p)(cb),
)
return ret
_winrt_capture_window = winrtutilsdll.winrt_capture_window _winrt_capture_window = winrtutilsdll.winrt_capture_window
_winrt_capture_window.argtypes = c_wchar_p, c_void_p _winrt_capture_window.argtypes = c_wchar_p, c_void_p

View File

@ -3,7 +3,6 @@ from ctypes import (
c_bool, c_bool,
POINTER, POINTER,
c_char_p, c_char_p,
c_uint64,
c_wchar_p, c_wchar_p,
pointer, pointer,
CDLL, CDLL,
@ -22,18 +21,12 @@ from ctypes import (
CFUNCTYPE, CFUNCTYPE,
c_long, c_long,
) )
from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT, BYTE from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT
from windows import WINDOWPLACEMENT from windows import WINDOWPLACEMENT
import gobject, csv import gobject
utilsdll = CDLL(gobject.GetDllpath(("winsharedutils32.dll", "winsharedutils64.dll"))) utilsdll = CDLL(gobject.GetDllpath(("winsharedutils32.dll", "winsharedutils64.dll")))
_freewstringlist = utilsdll.freewstringlist
_freewstringlist.argtypes = POINTER(c_wchar_p), c_uint
_free_all = utilsdll.free_all
_free_all.argtypes = (c_void_p,)
_freestringlist = utilsdll.freestringlist
_freestringlist.argtypes = POINTER(c_char_p), c_uint
_SetProcessMute = utilsdll.SetProcessMute _SetProcessMute = utilsdll.SetProcessMute
_SetProcessMute.argtypes = c_uint, c_bool _SetProcessMute.argtypes = c_uint, c_bool
@ -42,23 +35,10 @@ _GetProcessMute = utilsdll.GetProcessMute
_GetProcessMute.restype = c_bool _GetProcessMute.restype = c_bool
_SAPI_List = utilsdll.SAPI_List _SAPI_List = utilsdll.SAPI_List
_SAPI_List.argtypes = ( _SAPI_List.argtypes = (c_uint, c_void_p)
c_uint,
POINTER(c_uint64),
)
_SAPI_List.restype = POINTER(c_wchar_p)
_SAPI_Speak = utilsdll.SAPI_Speak _SAPI_Speak = utilsdll.SAPI_Speak
_SAPI_Speak.argtypes = ( _SAPI_Speak.argtypes = (c_wchar_p, c_uint, c_uint, c_uint, c_uint, c_void_p)
c_wchar_p,
c_uint,
c_uint,
c_uint,
c_uint,
POINTER(c_int),
POINTER(c_void_p),
)
_SAPI_Speak.restype = c_bool _SAPI_Speak.restype = c_bool
@ -69,27 +49,20 @@ levenshtein_ratio = utilsdll.levenshtein_ratio
levenshtein_ratio.argtypes = c_uint, c_wchar_p, c_uint, c_wchar_p levenshtein_ratio.argtypes = c_uint, c_wchar_p, c_uint, c_wchar_p
levenshtein_ratio.restype = c_double levenshtein_ratio.restype = c_double
_mecab_init = utilsdll.mecab_init mecab_init = utilsdll.mecab_init
_mecab_init.argtypes = c_char_p, c_wchar_p mecab_init.argtypes = c_char_p, c_wchar_p
_mecab_init.restype = c_void_p mecab_init.restype = c_void_p
_mecab_parse = utilsdll.mecab_parse mecab_parse = utilsdll.mecab_parse
_mecab_parse.argtypes = ( mecab_parse.argtypes = (c_void_p, c_char_p, c_void_p)
c_void_p, mecab_parse.restype = c_bool
c_char_p,
POINTER(POINTER(c_char_p)),
POINTER(POINTER(c_char_p)),
POINTER(c_uint),
)
_mecab_parse.restype = c_bool
_mecab_end = utilsdll.mecab_end mecab_end = utilsdll.mecab_end
_mecab_end.argtypes = (c_void_p,) mecab_end.argtypes = (c_void_p,)
_clipboard_get = utilsdll.clipboard_get _clipboard_get = utilsdll.clipboard_get
_clipboard_get.restype = ( _clipboard_get.argtypes = (c_void_p,)
c_void_p # 实际上是c_wchar_p但是写c_wchar_p 傻逼python自动转成str没法拿到指针 _clipboard_get.restype = c_bool
)
_clipboard_set = utilsdll.clipboard_set _clipboard_set = utilsdll.clipboard_set
_clipboard_set.argtypes = ( _clipboard_set.argtypes = (
c_void_p, c_void_p,
@ -106,26 +79,28 @@ def GetProcessMute(pid):
def SAPI_List(v): def SAPI_List(v):
num = c_uint64()
_list = _SAPI_List(v, pointer(num))
ret = [] ret = []
for i in range(num.value): _SAPI_List(v, CFUNCTYPE(None, c_wchar_p)(ret.append))
ret.append(_list[i])
_freewstringlist(_list, num.value)
return ret return ret
def SAPI_Speak(content, v, voiceid, rate, volume): def SAPI_Speak(content, v, voiceid, rate, volume):
length = c_int() ret = []
buff = c_void_p()
def _cb(ptr, size):
ret.append(cast(ptr, POINTER(c_char))[:size])
succ = _SAPI_Speak( succ = _SAPI_Speak(
content, v, voiceid, int(rate), int(volume), pointer(length), pointer(buff) content,
v,
voiceid,
int(rate),
int(volume),
CFUNCTYPE(None, c_void_p, c_size_t)(_cb),
) )
if not succ: if not succ:
return None return None
data = cast(buff, POINTER(c_char))[: length.value] return ret[0]
c_free(buff)
return data
def distance( def distance(
@ -138,38 +113,6 @@ def distance_ratio(s1, s2):
return levenshtein_ratio(len(s1), s1, len(s2), s2) return levenshtein_ratio(len(s1), s1, len(s2), s2)
class mecabwrap:
def __init__(self, mecabpath) -> None:
self.kks = _mecab_init(
mecabpath.encode("utf8"), gobject.GetDllpath("libmecab.dll")
)
def __del__(self):
_mecab_end(self.kks)
def parse(self, text, codec):
surface = POINTER(c_char_p)()
feature = POINTER(c_char_p)()
num = c_uint()
succ = _mecab_parse(
self.kks,
text.encode(codec),
pointer(surface),
pointer(feature),
pointer(num),
)
if not succ:
raise Exception # failed
res = []
for i in range(num.value):
f = feature[i]
fields = list(csv.reader([f.decode(codec)]))[0]
res.append((surface[i].decode(codec), fields))
_freestringlist(feature, num.value)
_freestringlist(surface, num.value)
return res
clphwnd = windll.user32.CreateWindowExW(0, "STATIC", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) clphwnd = windll.user32.CreateWindowExW(0, "STATIC", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
@ -180,13 +123,10 @@ def clipboard_set(text):
def clipboard_get(): def clipboard_get():
p = _clipboard_get() ret = []
if p: if not _clipboard_get(CFUNCTYPE(None, c_wchar_p)(ret.append)):
v = cast(p, c_wchar_p).value
_free_all(p)
return v
else:
return "" return ""
return ret[0]
html_version = utilsdll.html_version html_version = utilsdll.html_version
@ -267,24 +207,20 @@ def otsu_binary(image, thresh):
_extracticon2data = utilsdll.extracticon2data _extracticon2data = utilsdll.extracticon2data
_extracticon2data.argtypes = c_wchar_p, POINTER(c_size_t) _extracticon2data.argtypes = c_wchar_p, c_void_p
_extracticon2data.restype = c_void_p _extracticon2data.restype = c_bool
def extracticon2data(fname): def extracticon2data(fname):
length = c_size_t() ret = []
datap = _extracticon2data(fname, pointer(length))
if datap: def cb(ptr, size):
save = create_string_buffer(length.value) ret.append(cast(ptr, POINTER(c_char))[:size])
memmove(save, datap, length.value)
_free_all(datap) succ = _extracticon2data(fname, CFUNCTYPE(None, c_void_p, c_size_t)(cb))
return save if not succ:
else:
return None return None
return ret[0]
c_free = utilsdll.c_free
c_free.argtypes = (c_void_p,)
_queryversion = utilsdll.queryversion _queryversion = utilsdll.queryversion
@ -380,23 +316,25 @@ PlayAudioInMem_Stop = utilsdll.PlayAudioInMem_Stop
PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p
_gdi_screenshot = utilsdll.gdi_screenshot _gdi_screenshot = utilsdll.gdi_screenshot
_gdi_screenshot.argtypes = HWND, RECT, POINTER(c_size_t) _gdi_screenshot.argtypes = HWND, RECT, c_void_p
_gdi_screenshot.restype = POINTER(BYTE) _gdi_screenshot.restype = c_bool
def gdi_screenshot(x1, y1, x2, y2, hwnd=None): def gdi_screenshot(x1, y1, x2, y2, hwnd=None):
sz = c_size_t()
rect = RECT() rect = RECT()
rect.left = x1 rect.left = x1
rect.top = y1 rect.top = y1
rect.right = x2 rect.right = x2
rect.bottom = y2 rect.bottom = y2
bf = _gdi_screenshot(hwnd, rect, pointer(sz)) ret = []
if not (sz.value and bf):
def cb(ptr, size):
ret.append(cast(ptr, POINTER(c_char))[:size])
bf = _gdi_screenshot(hwnd, rect, CFUNCTYPE(None, c_void_p, c_size_t)(cb))
if not bf:
return None return None
data = cast(bf, POINTER(c_char))[: sz.value] return ret[0]
c_free(bf)
return data
maximum_window = utilsdll.maximum_window maximum_window = utilsdll.maximum_window

View File

@ -1,16 +1,16 @@
bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume, int *length, char **buffer) std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume)
{ {
ISpVoice *pVoice = NULL; ISpVoice *pVoice = NULL;
if (FAILED(::CoInitialize(NULL))) if (FAILED(::CoInitialize(NULL)))
return false; return {};
bool ret = true; std::optional<std::vector<byte>> ret = {};
do do
{ {
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if (FAILED(hr) || (NULL == pVoice)) if (FAILED(hr) || (NULL == pVoice))
{ {
ret = false; ret = {};
break; break;
} }
IEnumSpObjectTokens *pSpEnumTokens = NULL; IEnumSpObjectTokens *pSpEnumTokens = NULL;
@ -32,7 +32,7 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate,
hr = pVoice->GetOutputStream(&cpOldStream); hr = pVoice->GetOutputStream(&cpOldStream);
if (FAILED(hr) || (NULL == cpOldStream)) if (FAILED(hr) || (NULL == cpOldStream))
{ {
ret = false; ret = {};
break; break;
} }
originalFmt.AssignFormat(cpOldStream); originalFmt.AssignFormat(cpOldStream);
@ -52,7 +52,7 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate,
hr = cpWavStream->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, originalFmt.WaveFormatExPtr()); hr = cpWavStream->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, originalFmt.WaveFormatExPtr());
if (FAILED(hr)) if (FAILED(hr))
{ {
ret = false; ret = {};
break; break;
} }
} }
@ -84,8 +84,10 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate,
ULONG sSize = stats.cbSize.QuadPart; // size of the data to be read ULONG sSize = stats.cbSize.QuadPart; // size of the data to be read
auto wavfmt = *originalFmt.WaveFormatExPtr(); auto wavfmt = *originalFmt.WaveFormatExPtr();
ULONG bytesRead; // this will tell the number of bytes that have been read ULONG bytesRead; // this will tell the number of bytes that have been read
char *pBuffer = new char[sSize + 0x3ea]; // buffer to read the data std::vector<byte> datas;
datas.resize(sSize + 0x3ea);
auto pBuffer = datas.data(); // buffer to read the data
// memcpy(pBuffer,&wavHeader,sizeof(WAV_HEADER)); // memcpy(pBuffer,&wavHeader,sizeof(WAV_HEADER));
int fsize = sSize + 0x3ea; int fsize = sSize + 0x3ea;
int ptr = 0; int ptr = 0;
@ -128,8 +130,7 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate,
cout << pBuffer[i] << " "; cout << pBuffer[i] << " ";
cout << endl; cout << endl;
*/ */
*buffer = pBuffer; ret = std::move(datas);
*length = fsize;
pIstream->Release(); pIstream->Release();
} }

View File

@ -1,4 +1,4 @@
bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume, int *length, char **buffer); std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume);
std::vector<std::wstring> _List(const wchar_t *token); std::vector<std::wstring> _List(const wchar_t *token);
int neospeechlist(int argc, wchar_t *argv[]) int neospeechlist(int argc, wchar_t *argv[])
@ -54,11 +54,18 @@ int neospeech(int argc, wchar_t *argv[])
break; break;
std::wstring content = text; std::wstring content = text;
int fsize; int fsize;
char *buff; auto data = std::move(_Speak(content, hkey, idx, speed, 100));
_Speak(content, hkey, idx, speed, 100, &fsize, &buff); if (data)
memcpy(mapview, buff, fsize); {
delete buff; memcpy(mapview, data.value().data(), data.value().size());
WriteFile(hPipe, &fsize, 4, &_, NULL); fsize = data.value().size();
WriteFile(hPipe, &fsize, 4, &_, NULL);
}
else
{
fsize = 0;
WriteFile(hPipe, &fsize, 4, &_, NULL);
}
} }
return 0; return 0;
} }

View File

@ -1,6 +1,5 @@
#include <stdafx.h> #include <stdafx.h>
#include <wechatocr.h> #include <wechatocr.h>
#include <nlohmann/json.hpp>
#define DECLARE extern "C" __declspec(dllexport) #define DECLARE extern "C" __declspec(dllexport)
DECLARE void *wcocr_init(const wchar_t *wexe, const wchar_t *wwcdir) DECLARE void *wcocr_init(const wchar_t *wexe, const wchar_t *wwcdir)
@ -24,28 +23,19 @@ DECLARE void wcocr_destroy(void *pobj)
auto obj = reinterpret_cast<CWeChatOCR *>(pobj); auto obj = reinterpret_cast<CWeChatOCR *>(pobj);
delete obj; delete obj;
} }
DECLARE void wcocr_free_str(char *ptr) DECLARE bool wcocr_ocr(void *pobj, const char *u8path, void (*cb)(int, int, int, int, LPCSTR))
{
delete[] ptr;
}
DECLARE char *wcocr_ocr(void *pobj, const char *u8path)
{ {
if (!pobj) if (!pobj)
return 0; return false;
auto obj = reinterpret_cast<CWeChatOCR *>(pobj); auto obj = reinterpret_cast<CWeChatOCR *>(pobj);
CWeChatOCR::result_t res; CWeChatOCR::result_t res;
std::string imgpath = u8path; if (!obj->doOCR(u8path, &res))
if (!obj->doOCR(imgpath, &res)) return false;
return 0;
std::vector<std::wstring> rets; std::vector<std::wstring> rets;
std::vector<int> xs, ys, xs2, ys2; std::vector<int> xs, ys, xs2, ys2;
nlohmann::json js = std::vector<nlohmann::json>{};
for (auto &blk : res.ocr_response) for (auto &blk : res.ocr_response)
{ {
js.push_back({blk.left, blk.top, blk.right, blk.bottom, blk.text}); cb(blk.left, blk.top, blk.right, blk.bottom, blk.text.c_str());
} }
std::string _s = js.dump(); return true;
auto s = new char[_s.size() + 1];
strcpy(s, _s.c_str());
return s;
} }

View File

@ -10,7 +10,7 @@ generate_product_version(
VERSION_PATCH ${VERSION_PATCH} VERSION_PATCH ${VERSION_PATCH}
) )
add_library(winrtutils MODULE winrtsnapshot.cpp cinterface.cpp dllmain.cpp winrtocr.cpp ${versioninfo}) add_library(winrtutils MODULE winrtsnapshot.cpp dllmain.cpp winrtocr.cpp ${versioninfo})
target_precompile_headers(winrtutils REUSE_FROM pch) target_precompile_headers(winrtutils REUSE_FROM pch)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)

View File

@ -1,67 +0,0 @@
#include "define.h"
void free_all(void *str)
{
delete str;
}
void freewstringlist(wchar_t **strlist, int num)
{
for (int i = 0; i < num; i++)
{
delete strlist[i];
}
delete strlist;
}
void freestringlist(char **strlist, int num)
{
for (int i = 0; i < num; i++)
{
delete strlist[i];
}
delete strlist;
}
void freeocrres(ocrres res, int num)
{
freewstringlist(res.lines, num);
delete res.xs;
delete res.ys;
delete res.xs2;
delete res.ys2;
}
int *vecint2c(std::vector<int> &vs)
{
int *argv = new int[vs.size() + 1];
for (size_t i = 0; i < vs.size(); i++)
{
argv[i] = vs[i];
}
return argv;
}
char **vecstr2c(std::vector<std::string> &vs)
{
char **argv = new char *[vs.size() + 1];
for (size_t i = 0; i < vs.size(); i++)
{
argv[i] = new char[vs[i].size() + 1];
strcpy_s(argv[i], vs[i].size() + 1, vs[i].c_str());
argv[i][vs[i].size()] = 0;
}
return argv;
}
wchar_t **vecwstr2c(std::vector<std::wstring> &vs)
{
wchar_t **argv = new wchar_t *[vs.size() + 1];
for (size_t i = 0; i < vs.size(); i++)
{
argv[i] = new wchar_t[vs[i].size() + 1];
wcscpy_s(argv[i], vs[i].size() + 1, vs[i].c_str());
argv[i][vs[i].size()] = 0;
}
return argv;
}

View File

@ -1,23 +1,10 @@
#pragma once #pragma once
struct ocrres
{
wchar_t **lines;
int *xs;
int *ys;
int *xs2;
int *ys2;
};
extern "C" extern "C"
{ {
__declspec(dllexport) void winrt_capture_window(wchar_t *savepath, HWND hwnd); __declspec(dllexport) void winrt_capture_window(wchar_t *savepath, HWND hwnd);
__declspec(dllexport) bool check_language_valid(wchar_t *); __declspec(dllexport) bool check_language_valid(wchar_t *);
__declspec(dllexport) wchar_t **getlanguagelist(int *); __declspec(dllexport) void getlanguagelist(void (*cb)(LPCWSTR));
__declspec(dllexport) ocrres OCR(void* ptr, size_t size, wchar_t *lang, wchar_t *, int *); __declspec(dllexport) void OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *, void (*)(int, int, int, int, LPCWSTR));
__declspec(dllexport) void freewstringlist(wchar_t **, int); }
__declspec(dllexport) void freeocrres(ocrres, int);
}
char **vecstr2c(std::vector<std::string> &vs);
int *vecint2c(std::vector<int> &vs);
wchar_t **vecwstr2c(std::vector<std::wstring> &vs);

View File

@ -40,24 +40,18 @@ bool check_language_valid(wchar_t *language)
return false; return false;
} }
} }
wchar_t **getlanguagelist(int *num) void getlanguagelist(void(*cb)(LPCWSTR))
{ {
OcrEngine ocrEngine = OcrEngine::TryCreateFromUserProfileLanguages(); OcrEngine ocrEngine = OcrEngine::TryCreateFromUserProfileLanguages();
auto languages = ocrEngine.AvailableRecognizerLanguages(); auto languages = ocrEngine.AvailableRecognizerLanguages();
auto ret = new wchar_t *[languages.Size()];
int i = 0;
for (auto &&language : languages) for (auto &&language : languages)
{ {
auto lang = language.LanguageTag(); auto lang = language.LanguageTag();
size_t len = lang.size() + 1; cb(lang.c_str());
ret[i] = new wchar_t[len];
wcscpy_s(ret[i], len, lang.c_str());
i += 1;
} }
*num = languages.Size();
return ret;
} }
ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num) void OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, void (*cb)(int, int, int, int, LPCWSTR))
{ {
IBuffer buffer = CryptographicBuffer::CreateFromByteArray( IBuffer buffer = CryptographicBuffer::CreateFromByteArray(
winrt::array_view<uint8_t>(static_cast<uint8_t *>(ptr), size)); winrt::array_view<uint8_t>(static_cast<uint8_t *>(ptr), size));
@ -71,13 +65,8 @@ ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num)
OcrEngine ocrEngine = OcrEngine::TryCreateFromLanguage(language); OcrEngine ocrEngine = OcrEngine::TryCreateFromLanguage(language);
OcrResult ocrResult = ocrEngine.RecognizeAsync(softwareBitmap).get(); OcrResult ocrResult = ocrEngine.RecognizeAsync(softwareBitmap).get();
auto res = ocrResult.Lines(); auto res = ocrResult.Lines();
std::vector<std::wstring> rets;
std::vector<int> xs, ys, xs2, ys2;
int i = 0;
std::wstring sspace = space;
for (auto line : res) for (auto line : res)
{ {
std::wstring xx = L""; std::wstring xx = L"";
bool start = true; bool start = true;
unsigned int x1 = -1, x2 = 0, y1 = -1, y2 = 0; unsigned int x1 = -1, x2 = 0, y1 = -1, y2 = 0;
@ -85,7 +74,7 @@ ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num)
for (auto word : line.Words()) for (auto word : line.Words())
{ {
if (!start) if (!start)
xx += sspace; xx += space;
start = false; start = false;
xx += word.Text(); xx += word.Text();
auto &rect = word.BoundingRect(); auto &rect = word.BoundingRect();
@ -94,13 +83,7 @@ ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num)
y1 = std::min((unsigned int)rect.Y, y1); y1 = std::min((unsigned int)rect.Y, y1);
y2 = std::max(y2, (unsigned int)(rect.Y + rect.Height)); y2 = std::max(y2, (unsigned int)(rect.Y + rect.Height));
} }
ys.push_back(y1); cb(x1,y2,x2,y2,xx.c_str());
xs.push_back(x1);
xs2.push_back(x2);
ys2.push_back(y2);
rets.emplace_back(xx);
i += 1;
} }
*num = res.Size();
return ocrres{vecwstr2c(rets), vecint2c(xs), vecint2c(ys), vecint2c(xs2), vecint2c(ys2)};
} }

View File

@ -11,7 +11,7 @@ generate_product_version(
VERSION_PATCH ${VERSION_PATCH} VERSION_PATCH ${VERSION_PATCH}
) )
add_library(winsharedutils MODULE webview2_extra.cpp AreoAcrylic.cpp screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo}) add_library(winsharedutils MODULE webview2_extra.cpp AreoAcrylic.cpp screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo})
target_precompile_headers(winsharedutils REUSE_FROM pch) target_precompile_headers(winsharedutils REUSE_FROM pch)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64") set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64")

View File

@ -1,64 +0,0 @@
#include "define.h"
void free_all(void *str)
{
delete str;
}
void freewstringlist(wchar_t **strlist, int num)
{
for (int i = 0; i < num; i++)
{
delete strlist[i];
}
delete strlist;
}
void freestringlist(char **strlist, int num)
{
for (int i = 0; i < num; i++)
{
delete strlist[i];
}
delete strlist;
}
int *vecint2c(std::vector<int> &vs)
{
int *argv = new int[vs.size() + 1];
for (size_t i = 0; i < vs.size(); i++)
{
argv[i] = vs[i];
}
return argv;
}
char **vecstr2c(std::vector<std::string> &vs)
{
char **argv = new char *[vs.size() + 1];
for (size_t i = 0; i < vs.size(); i++)
{
argv[i] = new char[vs[i].size() + 1];
strcpy_s(argv[i], vs[i].size() + 1, vs[i].c_str());
argv[i][vs[i].size()] = 0;
}
return argv;
}
wchar_t **vecwstr2c(std::vector<std::wstring> &vs)
{
wchar_t **argv = new wchar_t *[vs.size() + 1];
for (size_t i = 0; i < vs.size(); i++)
{
argv[i] = new wchar_t[vs[i].size() + 1];
wcscpy_s(argv[i], vs[i].size() + 1, vs[i].c_str());
argv[i][vs[i].size()] = 0;
}
return argv;
}
void c_free(void *ptr)
{
free(ptr);
}

View File

@ -1,3 +0,0 @@
char **vecstr2c(std::vector<std::string> &vs);
int *vecint2c(std::vector<int> &vs);
wchar_t **vecwstr2c(std::vector<std::wstring> &vs);

View File

@ -17,11 +17,12 @@ bool tryopenclipboard(HWND hwnd = 0)
} }
return success; return success;
} }
wchar_t *clipboard_get()
std::optional<std::wstring> clipboard_get_internal()
{ {
wchar_t *data = 0; std::optional<std::wstring> data = {};
if (tryopenclipboard() == false) if (tryopenclipboard() == false)
return 0; return {};
do do
{ {
HANDLE hData = GetClipboardData(CF_UNICODETEXT); HANDLE hData = GetClipboardData(CF_UNICODETEXT);
@ -31,14 +32,22 @@ wchar_t *clipboard_get()
if (pszText == 0) if (pszText == 0)
break; break;
int sz = GlobalSize(hData); int sz = GlobalSize(hData);
data = new wchar_t[sz + 1]; data = std::move(std::wstring(pszText, sz));
wcscpy_s(data, sz, pszText);
data[sz] = 0;
GlobalUnlock(hData); GlobalUnlock(hData);
} while (false); } while (false);
CloseClipboard(); CloseClipboard();
return data; return data;
} }
bool clipboard_get(void (*cb)(const wchar_t *))
{
auto data = std::move(clipboard_get_internal());
if (!data)
return false;
cb(data.value().c_str());
return true;
}
bool clipboard_set(HWND hwnd, wchar_t *text) bool clipboard_set(HWND hwnd, wchar_t *text)
{ {
bool success = false; bool success = false;
@ -66,7 +75,7 @@ bool clipboard_set(HWND hwnd, wchar_t *text)
return success; return success;
} }
static void clipboard_callback_1(void (*callback)(wchar_t *, bool), HANDLE hsema, HWND *hwnd) static void clipboard_callback_1(void (*callback)(const wchar_t *, bool), HANDLE hsema, HWND *hwnd)
{ {
const wchar_t CLASS_NAME[] = L"LunaClipboardListener"; const wchar_t CLASS_NAME[] = L"LunaClipboardListener";
@ -75,15 +84,14 @@ static void clipboard_callback_1(void (*callback)(wchar_t *, bool), HANDLE hsema
{ {
if (WM_CLIPBOARDUPDATE == message) if (WM_CLIPBOARDUPDATE == message)
{ {
auto data = clipboard_get(); auto data = clipboard_get_internal();
auto callback_ = reinterpret_cast<decltype(callback)>(GetWindowLongPtrW(hWnd, GWLP_USERDATA)); auto callback_ = reinterpret_cast<decltype(callback)>(GetWindowLongPtrW(hWnd, GWLP_USERDATA));
if (data && callback_) if (data && callback_)
{ {
auto ohwnd = GetClipboardOwner(); auto ohwnd = GetClipboardOwner();
DWORD pid; DWORD pid;
GetWindowThreadProcessId(ohwnd, &pid); GetWindowThreadProcessId(ohwnd, &pid);
callback_(data, pid == GetCurrentProcessId()); callback_(data.value().c_str(), pid == GetCurrentProcessId());
delete data;
} }
} }
return DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam);
@ -109,7 +117,7 @@ static void clipboard_callback_1(void (*callback)(wchar_t *, bool), HANDLE hsema
} }
} }
DECLARE HWND clipboard_callback(void (*callback)(wchar_t *, bool)) DECLARE HWND clipboard_callback(void (*callback)(const wchar_t *, bool))
{ {
HANDLE hsema = CreateSemaphoreW(0, 0, 10, 0); HANDLE hsema = CreateSemaphoreW(0, 0, 10, 0);
HWND hwnd; HWND hwnd;

View File

@ -6,7 +6,7 @@ extern "C"
__declspec(dllexport) HANDLE startdarklistener(); __declspec(dllexport) HANDLE startdarklistener();
__declspec(dllexport) bool queryversion(const wchar_t *exe, WORD *_1, WORD *_2, WORD *_3, WORD *_4); __declspec(dllexport) bool queryversion(const wchar_t *exe, WORD *_1, WORD *_2, WORD *_3, WORD *_4);
__declspec(dllexport) wchar_t **SAPI_List(int version, size_t *); __declspec(dllexport) void SAPI_List(int version, void (*cb)(const wchar_t *));
__declspec(dllexport) BOOL SetProcessMute(DWORD Pid, bool mute); __declspec(dllexport) BOOL SetProcessMute(DWORD Pid, bool mute);
__declspec(dllexport) bool GetProcessMute(DWORD Pid); __declspec(dllexport) bool GetProcessMute(DWORD Pid);
@ -15,20 +15,14 @@ extern "C"
__declspec(dllexport) double levenshtein_ratio(size_t len1, const wchar_t *string1, __declspec(dllexport) double levenshtein_ratio(size_t len1, const wchar_t *string1,
size_t len2, const wchar_t *string2); size_t len2, const wchar_t *string2);
__declspec(dllexport) void freewstringlist(wchar_t **, int);
__declspec(dllexport) void free_all(void *str);
__declspec(dllexport) void freestringlist(char **, int);
__declspec(dllexport) void *mecab_init(char *utf8path, wchar_t *); __declspec(dllexport) void *mecab_init(char *utf8path, wchar_t *);
__declspec(dllexport) bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***features, int *num); __declspec(dllexport) bool mecab_parse(void *trigger, char *utf8string, void (*callback)(const char *, const char *));
__declspec(dllexport) void mecab_end(void *trigger); __declspec(dllexport) void mecab_end(void *trigger);
__declspec(dllexport) wchar_t *clipboard_get(); __declspec(dllexport) bool clipboard_get(void (*)(const wchar_t *));
__declspec(dllexport) bool clipboard_set(HWND hwnd, wchar_t *text); __declspec(dllexport) bool clipboard_set(HWND hwnd, wchar_t *text);
__declspec(dllexport) void GetLnkTargetPath(wchar_t *lnkFilePath, wchar_t *path, wchar_t *tgtpath, wchar_t *iconpath, wchar_t *dirpath); __declspec(dllexport) void GetLnkTargetPath(wchar_t *lnkFilePath, wchar_t *path, wchar_t *tgtpath, wchar_t *iconpath, wchar_t *dirpath);
__declspec(dllexport) bool otsu_binary(const void *image, int thresh); __declspec(dllexport) bool otsu_binary(const void *image, int thresh);
__declspec(dllexport) void *extracticon2data(const wchar_t *name, size_t *l); __declspec(dllexport) bool extracticon2data(const wchar_t *name, void (*)(const char *, size_t));
__declspec(dllexport) void c_free(void *);
} }

View File

@ -1,13 +1,13 @@
#include "define.h" #include "define.h"
#include "BMP.h" #include "BMP.h"
void *extracticon2data(const wchar_t *name, size_t *l) bool extracticon2data(const wchar_t *name, void (*cb)(const char *, size_t))
{ {
HICON h1, h2; HICON h1, h2;
ExtractIconExW(name, 0, &h1, &h2, 1); ExtractIconExW(name, 0, &h1, &h2, 1);
if (h1 == 0) if (h1 == 0)
return 0; return false;
HDC hdc = GetDC(NULL); HDC hdc = GetDC(NULL);
HDC memDC = CreateCompatibleDC(hdc); HDC memDC = CreateCompatibleDC(hdc);
ICONINFO iconInfo; ICONINFO iconInfo;
@ -63,8 +63,6 @@ void *extracticon2data(const wchar_t *name, size_t *l)
} }
std::string data; std::string data;
bmpp.write_tomem(data); bmpp.write_tomem(data);
auto sdata = new char[data.size()]; cb(data.c_str(),data.size());
memcpy(sdata, data.data(), data.size()); return true;
*l = data.size();
return sdata;
} }

View File

@ -1,58 +1,61 @@
 
#include "define.h" #include "define.h"
#include "cinterface.h" std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume);
bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume, int *length, char **buffer);
std::vector<std::wstring> _List(const wchar_t *token); std::vector<std::wstring> _List(const wchar_t *token);
namespace SAPI namespace SAPI
{ {
bool Speak(std::wstring &Content, int version, int voiceid, int rate, int volume, int *length, char **buffer);
std::vector<std::wstring> List(int version);
constexpr wchar_t SPCAT_VOICES_7[] = L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices"; constexpr wchar_t SPCAT_VOICES_7[] = L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices";
constexpr wchar_t SPCAT_VOICES_10[] = L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices"; constexpr wchar_t SPCAT_VOICES_10[] = L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices";
std::vector<std::wstring> List(int version)
{
if (version == 7)
{
return _List(SPCAT_VOICES_7);
}
else if (version == 10)
{
return _List(SPCAT_VOICES_10);
}
else
{
return {};
}
}
std::optional<std::vector<byte>> Speak(std::wstring &Content, int version, int voiceid, int rate, int volume)
{
const wchar_t *_;
switch (version)
{
case 7:
_ = SPCAT_VOICES_7;
break;
case 10:
_ = SPCAT_VOICES_10;
break;
return {};
}
return _Speak(Content, _, voiceid, rate, volume);
}
}; };
bool SAPI::Speak(std::wstring &Content, int version, int voiceid, int rate, int volume, int *length, char **buffer) DECLARE bool SAPI_Speak(const wchar_t *Content, int version, int voiceid, int rate, int volume, void (*cb)(byte *, size_t))
{
if (version == 7)
{
return _Speak(Content, SPCAT_VOICES_7, voiceid, rate, volume, length, buffer);
}
else if (version == 10)
{
return _Speak(Content, SPCAT_VOICES_10, voiceid, rate, volume, length, buffer);
}
else
{
return false;
}
}
std::vector<std::wstring> SAPI::List(int version)
{
if (version == 7)
{
return _List(SPCAT_VOICES_7);
}
else if (version == 10)
{
return _List(SPCAT_VOICES_10);
}
else
{
return {};
}
}
DECLARE bool SAPI_Speak(const wchar_t *Content, int version, int voiceid, int rate, int volume, int *length, char **buffer)
{ {
auto _c = std::wstring(Content); auto _c = std::wstring(Content);
return SAPI::Speak(_c, version, voiceid, rate, volume, length, buffer); if (auto _ = std::move(SAPI::Speak(_c, version, voiceid, rate, volume)))
{
cb(_.value().data(), _.value().size());
return true;
}
return false;
} }
wchar_t **SAPI_List(int version, size_t *num) void SAPI_List(int version, void (*cb)(const wchar_t *))
{ {
auto _list = SAPI::List(version); auto _list = SAPI::List(version);
*num = _list.size(); for (auto _ : _list)
return vecwstr2c(_list); cb(_.c_str());
} }

View File

@ -97,7 +97,7 @@ int SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName)
return TRUE; return TRUE;
} }
BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size) std::vector<byte> SaveBitmapToBuffer(HBITMAP hBitmap)
{ {
WORD wBitCount; // 位图中每个像素所占字节数 WORD wBitCount; // 位图中每个像素所占字节数
// 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数 // 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
@ -131,7 +131,9 @@ BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size)
bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0; bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
auto buffer = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize]; std::vector<byte> data;
data.resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize);
auto buffer = data.data();
// 写入位图文件头 // 写入位图文件头
// WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图信息头 // 写入位图信息头
@ -150,28 +152,28 @@ BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size)
// 写位图数据 // 写位图数据
// WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL); // WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);
*size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
// 清除 // 清除
delete[] lpmem; delete[] lpmem;
return buffer; return data;
} }
DECLARE BYTE *gdi_screenshot(HWND hwnd, RECT rect, size_t *size) DECLARE bool gdi_screenshot(HWND hwnd, RECT rect, void (*cb)(byte *, size_t))
{ {
*size = 0;
if (rect.bottom == rect.top || rect.left == rect.right) if (rect.bottom == rect.top || rect.left == rect.right)
return nullptr; return false;
if (!hwnd) if (!hwnd)
hwnd = GetDesktopWindow(); hwnd = GetDesktopWindow();
auto hdc = GetDC(hwnd); auto hdc = GetDC(hwnd);
if (!hdc) if (!hdc)
return nullptr; return false;
auto bm = GetBitmap(rect, hdc); auto bm = GetBitmap(rect, hdc);
// SaveBitmapToFile(bm, LR"(.\2.bmp)"); // SaveBitmapToFile(bm, LR"(.\2.bmp)");
auto bf = SaveBitmapToBuffer(bm, size); size_t size;
auto bf = std::move(SaveBitmapToBuffer(bm));
cb(bf.data(), bf.size());
DeleteObject(bm); DeleteObject(bm);
ReleaseDC(hwnd, hdc); ReleaseDC(hwnd, hdc);
return bf; return true;
} }
DECLARE void maximum_window(HWND hwnd) DECLARE void maximum_window(HWND hwnd)

View File

@ -1,7 +1,5 @@
#pragma execution_character_set("utf-8")
#include "define.h" #include "define.h"
#include "cinterface.h"
struct mecab_node_t struct mecab_node_t
{ {
struct mecab_node_t *prev; struct mecab_node_t *prev;
@ -41,11 +39,8 @@ void *mecab_init(char *utf8path, wchar_t *mepath)
auto _mecab_new = (mecab_new)GetProcAddress(mecablib, "mecab_new"); auto _mecab_new = (mecab_new)GetProcAddress(mecablib, "mecab_new");
if (_mecab_new == 0) if (_mecab_new == 0)
return 0; return 0;
std::vector<std::string> vargv = {"fugashi", "-C", "-r", "nul", "-d", utf8path, "-Owakati"}; char *argv[] = {"fugashi", "-C", "-r", "nul", "-d", utf8path, "-Owakati"};
auto trigger = _mecab_new(ARRAYSIZE(argv), argv);
auto argv = vecstr2c(vargv);
auto trigger = _mecab_new(vargv.size(), argv);
freestringlist(argv, vargv.size());
return trigger; return trigger;
} }
void mecab_end(void *trigger) void mecab_end(void *trigger)
@ -59,7 +54,8 @@ void mecab_end(void *trigger)
return; return;
mecab_destroy((mecab_t *)trigger); mecab_destroy((mecab_t *)trigger);
} }
bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***features, int *num)
bool mecab_parse(void *trigger, char *utf8string, void (*callback)(const char *, const char *))
{ {
if (trigger == 0) if (trigger == 0)
return false; return false;
@ -72,8 +68,6 @@ bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***featu
std::string cstr = utf8string; std::string cstr = utf8string;
auto node = _mecab_sparse_tonode((mecab_t *)trigger, cstr.c_str()); auto node = _mecab_sparse_tonode((mecab_t *)trigger, cstr.c_str());
std::vector<std::string> surfs;
std::vector<std::string> featuresv;
while (node->next) while (node->next)
{ {
node = node->next; node = node->next;
@ -81,13 +75,8 @@ bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***featu
{ {
break; break;
} }
std::string surf = node->surface; std::string surf = std::string(node->surface, node->length);
surf = surf.substr(0, node->length); callback(surf.c_str(), node->feature);
surfs.emplace_back(surf);
featuresv.emplace_back(node->feature);
} }
*surface = vecstr2c(surfs);
*features = vecstr2c(featuresv);
*num = surfs.size();
return true; return true;
} }