//--------------------------------------------------------------------------- extern "C" HRESULT _stdcall _export V2Unlink() { // 吉里吉里側から、プラグインを解放しようとするときに呼ばれる関数。 // もし何らかの条件でプラグインを解放できない場合は // この時点で E_FAIL を返すようにする。 // ここでは、TVPPluginGlobalRefCount が GlobalRefCountAtInit よりも // 大きくなっていれば失敗ということにする。 if(TVPPluginGlobalRefCount > GlobalRefCountAtInit) return E_FAIL; // E_FAIL が帰ると、Plugins.unlink メソッドは偽を返す // TJS のグローバルオブジェクトに登録した関数を削除する // - まず、TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); // - global の DeleteMember メソッドを用い、オブジェクトを削除する if(global) { // TJS 自体が既に解放されていたときなどは // global は NULL になり得るので global が NULL でない // ことをチェックする global->DeleteMember( 0, // フラグ ( 0 でよい ) TJS_W("wmrStart"), // メンバ名 NULL, // ヒント global // コンテキスト ); global->DeleteMember( 0, // フラグ ( 0 でよい ) TJS_W("wmrStop"), // メンバ名 NULL, // ヒント global // コンテキスト ); // 登録した関数が複数ある場合は これを繰り返す } // - global を Release する if(global) global->Release(); // スタブの使用終了(必ず記述する) TVPUninitImportStub(); return S_OK; }
//--------------------------------------------------------------------------- bool eTJSScriptError::AddTrace(const ttstr & data) { tjs_int len = Trace.GetLen(); if(len >= TJS_MAX_TRACE_TEXT_LEN) return false; if(len != 0) Trace += TJS_W(" <-- "); Trace += data; return true; }
ttstr TVPFormatMessage(const tjs_char *msg, const ttstr & p1, const ttstr & p2) { tjs_char *p; tjs_char * buf = new tjs_char[TJS_strlen(msg) + p1.GetLen() + p2.GetLen() + 1]; p = buf; for(;*msg;msg++,p++) { if(*msg == TJS_W('%')) { if(msg[1] == TJS_W('%')) { // %% *p = TJS_W('%'); msg++; continue; } else if(msg[1] == TJS_W('1')) { // %1 TJS_strcpy(p, p1.c_str()); p += p1.GetLen(); p--; msg++; continue; } else if(msg[1] == TJS_W('2')) { // %2 TJS_strcpy(p, p2.c_str()); p += p2.GetLen(); p--; msg++; continue; } } *p = *msg; } *p = 0; ttstr ret(buf); delete [] buf; return ret; }
//--------------------------------------------------------------------------- void GDIFontRasterizer::InitChAntialiasMethod() { if(ChAntialiasMethodInit) return; ChAntialiasMethod = camAPI; // default tTJSVariant val; if( TVPGetCommandLine(TJS_W("-aamethod"), &val) ) { ttstr str(val); #if 0 // まったく意味のないコード? if(str == TJS_W("auto")) ; // nothing to do #endif if(str == TJS_W("res8")) ChAntialiasMethod = camResample8; else if(str == TJS_W("res4")) ChAntialiasMethod = camResample4; else if(str == TJS_W("api")) ChAntialiasMethod = camAPI; else if(str == TJS_W("rgb")) ChAntialiasMethod = camSubpixelRGB; else if(str == TJS_W("bgr")) ChAntialiasMethod = camSubpixelBGR; } ChAntialiasMethodInit = true; }
static tTVInteger LayerPropGet(iTJSDispatch2 *lay, ttstr &prop, tTVInteger defval = 0) { if (!LayerClass) { tTJSVariant var; TVPExecuteExpression(TJS_W("Layer"), &var); LayerClass = var.AsObjectNoAddRef(); } tTJSVariant val; return (TJS_FAILED(LayerClass->PropGet(0, prop.c_str(), prop.GetHint(), &val, lay))) ? defval : val.AsInteger(); }
tjs_error TJS_INTF_METHOD GetName( /*out*/const tjs_char ** name) { if(name) { *name = TJS_W("scroll"); return TJS_S_OK; } else { return TJS_E_FAIL; } }
//--------------------------------------------------------------------------- // tTJSNativeFunction //--------------------------------------------------------------------------- tTJSNativeFunction::tTJSNativeFunction(const tjs_char *name) { if(TJSObjectHashMapEnabled()) { TJSAddObjectHashRecord(this); if(name) TJSObjectHashSetType(this, ttstr(TJS_W("(native function) ")) + name); } }
//--------------------------------------------------------------------------- ttstr TVPGetVersionString() { TVPGetVersion(); tjs_char verstr[100]; TJS_snprintf(verstr, sizeof(verstr)/sizeof(tjs_char), TJS_W("%d.%d.%d.%d"), TVPVersionMajor, TVPVersionMinor, TVPVersionRelease, TVPVersionBuild); return ttstr(verstr); }
/** * 登録処理後 */ static void PostRegistCallback() { // Array.count を取得 { tTJSVariant varScripts; TVPExecuteExpression(TJS_W("Array"), &varScripts); iTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef(); tTJSVariant val; if (TJS_FAILED(dispatch->PropGet(TJS_IGNOREPROP, TJS_W("count"), NULL, &val, dispatch))) { TVPThrowExceptionMessage(L"can't get Array.count"); } ArrayCountProp = val.AsObject(); } }
//--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPDrawDevice::RemoveLayerManager(iTVPLayerManager * manager) { // Managers から manager を削除する。Releaseする。 std::vector<iTVPLayerManager *>::iterator i = std::find(Managers.begin(), Managers.end(), manager); if(i == Managers.end()) TVPThrowExceptionMessage(TJS_W("Internal Error")); (*i)->Release(); Managers.erase(i); }
//--------------------------------------------------------------------------- bool eTJSScriptError::AddTrace(tTJSInterCodeContext *context, tjs_int codepos) { tjs_int len = Trace.GetLen(); if(len >= TJS_MAX_TRACE_TEXT_LEN) return false; if(len != 0) Trace += TJS_W(" <-- "); Trace += context->GetPositionDescriptionString(codepos); return true; }
//--------------------------------------------------------------------------- static void PushConfigFileOptions(TStringList * options) { if(!options) return; for(int j = 0; j < options->Count; j++) { if(options->Strings[j].c_str()[0] != ';') // unless comment TVPProgramArguments.push_back( TVPParseCommandLineOne(TJS_W("-") + ttstr(options->Strings[j]))); } }
//--------------------------------------------------------------------------- bool eTJSScriptError::AddTrace(tTJSScriptBlock *block, tjs_int srcpos) { tjs_int len = Trace.GetLen(); if(len >= TJS_MAX_TRACE_TEXT_LEN) return false; if(len != 0) Trace += TJS_W(" <-- "); Trace += block->GetLineDescriptionString(srcpos); return true; }
//--------------------------------------------------------------------------- void TJSThrowFrom_tjs_error(tjs_error hr, const tjs_char *name) { // raise an exception descripted as tjs_error // name = variable name ( otherwide it can be NULL ) switch(hr) { case TJS_E_MEMBERNOTFOUND: { if(name) { ttstr str(TJSMemberNotFound); str.Replace(TJS_W("%1"), name); TJS_eTJSError(str); } else { TJS_eTJSError(TJSMemberNotFoundNoNameGiven); } } case TJS_E_NOTIMPL: TJS_eTJSError(TJSNotImplemented); case TJS_E_INVALIDPARAM: TJS_eTJSError(TJSInvalidParam); case TJS_E_BADPARAMCOUNT: TJS_eTJSError(TJSBadParamCount); case TJS_E_INVALIDTYPE: TJS_eTJSError(TJSInvalidType); case TJS_E_ACCESSDENYED: TJS_eTJSError(TJSAccessDenyed); case TJS_E_INVALIDOBJECT: TJS_eTJSError(TJSInvalidObject); case TJS_E_NATIVECLASSCRASH: TJS_eTJSError(TJSNativeClassCrash); default: if(TJS_FAILED(hr)) { tjs_char buf[256]; TJS_snprintf(buf, 256, TJS_W("Unknown failure : %08X"), hr); TJS_eTJSError(buf); } } }
/** * サンプル値の取得(新方式) * getVisBuffer(buf, sampleCount, 1, sampleAhead)でサンプルを取得し, * (value/32768)^2の最大値を取得します。(0〜1の実数で返ります) * ※このプロパティを読み出すと暗黙でuseVisBuffer=trueに設定されます */ double getSampleValue() { memset(buf, 0, counts*sizeof(short)); tTJSVariant result; tjs_error r = objthis->FuncCall(0, TJS_W("getVisBuffer"), &hint, &result, 4, params, objthis); if (r != TJS_S_OK) TVPAddLog(ttstr(TJS_W("getVisBuffer failed: "))+ttstr(r)); int cnt = (int)result.AsInteger(); if (cnt > counts || cnt < 0) cnt = counts; // サンプルの二乗中の最大値を返す double max = 0; for (int i=cnt-1;i>=0;i--) { double s = ((double)buf[i]) / +32768.0; s *= s; if (max < s) max = s; } return max; }
//--------------------------------------------------------------------------- // throw helper functions //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- static void TJSReportExceptionSource(const ttstr &msg, tTJSScriptBlock *block, tjs_int srcpos) { if(TJSEnableDebugMode) { tTJS *tjs = block->GetTJS(); tjs->OutputExceptionToConsole((msg + TJS_W(" at ") + block->GetLineDescriptionString(srcpos)).c_str()); } }
//--------------------------------------------------------------------------- ttstr tTJSScriptBlock::GetLineDescriptionString(tjs_int pos) const { // get short description, like "mainwindow.tjs(321)" // pos is in character count from the first of the script tjs_int line =SrcPosToLine(pos)+1; ttstr name; if(Name) { name = Name; } else { tjs_char ptr[128]; TJS_sprintf(ptr, TJS_W("0x%p"), this); name = ttstr(TJS_W("anonymous@")) + ptr; } return name + TJS_W("(") + ttstr(line) + TJS_W(")"); }
//--------------------------------------------------------------------------- static void TJSReportExceptionSource(const ttstr &msg, tTJSInterCodeContext *context, tjs_int codepos) { if(TJSEnableDebugMode) { tTJS *tjs = context->GetBlock()->GetTJS(); tjs->OutputExceptionToConsole((msg + TJS_W(" at ") + context->GetPositionDescriptionString(codepos)).c_str()); } }
// urldecode処理 static tjs_error TJS_INTF_METHOD urldecode(tTJSVariant *result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis) { if (numparams > 0 && result) { bool utf8 = !(numparams> 1 && (int)*param[1] == 0); ttstr str = *param[0]; tjs_int len = str.length(); std::string os; for (int i=0;i<len;i++) { int ch = str[i]; if (ch > 0xff) { return TJS_E_INVALIDPARAM; } if (ch == '%') { if (i + 2 >= len) { return TJS_E_INVALIDPARAM; } char buf[3]; buf[0] = (char)str[i+1]; buf[1] = (char)str[i+2]; buf[2] = '\0'; long n = strtol(buf, NULL, 16); if (errno == ERANGE) { return TJS_E_INVALIDPARAM; } os += (char)n; i+=2; } else { os += (char)ch; } } if (utf8) { const char *s = os.c_str(); tjs_int len = TVPUtf8ToWideCharString(s, NULL); if (len > 0) { tjs_char *dat = new tjs_char[len+1]; try { TVPUtf8ToWideCharString(s, dat); dat[len] = TJS_W('\0'); } catch(...) { delete [] dat; throw; } *result = ttstr(dat); delete [] dat; } } else { *result = ttstr(os.c_str()); } } return TJS_S_OK; }
//--------------------------------------------------------------------------- tjs_error TJS_INTF_METHOD tTJSNativeClass::CreateNew(tjs_uint32 flag, const tjs_char * membername, tjs_uint32 *hint, iTJSDispatch2 **result, tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *objthis) { // CreateNew iTJSDispatch2 *superinst = NULL; if( SuperClass != NULL && membername == NULL ) { tjs_error hr = SuperClass->CreateNew( flag, membername, hint, &superinst, numparams, param, objthis ); if(TJS_FAILED(hr)) { superinst = NULL; } } iTJSDispatch2 *dsp = CreateBaseTJSObject(); tjs_error hr; try { // set object type for debugging if(TJSObjectHashMapEnabled()) TJSObjectHashSetType(dsp, TJS_W("instance of class ") + ClassName); // instance initialization hr = FuncCall(0, NULL, NULL, NULL, 0, NULL, dsp); // add member to dsp if(TJS_FAILED(hr)) return hr; if( superinst != NULL ) { tTJSVariant param(superinst,superinst); dsp->ClassInstanceInfo( TJS_CII_SET_SUPRECLASS, 0, ¶m ); superinst->Release(); superinst = NULL; } hr = FuncCall(0, ClassName.c_str(), ClassName.GetHint(), NULL, numparams, param, dsp); // call the constructor if(hr == TJS_E_MEMBERNOTFOUND) hr = TJS_S_OK; // missing constructor is OK ( is this ugly ? ) } catch(...) { dsp->Release(); if( superinst ) superinst->Release(); throw; } if(TJS_SUCCEEDED(hr)) { *result = dsp; } else if( superinst ) { superinst->Release(); } return hr; }
//--------------------------------------------------------------------------- tjs_error TJS_INTF_METHOD tTJSNativeFunction::IsInstanceOf( tjs_uint32 flag, const tjs_char *membername, tjs_uint32 *hint, const tjs_char *classname, iTJSDispatch2 *objthis) { if(membername == NULL) { if(!TJS_strcmp(classname, TJS_W("Function"))) return TJS_S_TRUE; } return inherited::IsInstanceOf(flag, membername, hint, classname, objthis); }
//--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPGDIDrawDevice::AddLayerManager(iTVPLayerManager * manager) { if(inherited::Managers.size() > 0) { // "GDI" デバイスでは2つ以上のLayer Managerを登録できない TVPThrowExceptionMessage(TJS_W("\"GDI\" device does not support layer manager more than 1")); } inherited::AddLayerManager(manager); manager->SetDesiredLayerType(ltOpaque); // ltOpaque な出力を受け取りたい }
//--------------------------------------------------------------------------- void tTJSNI_VideoOverlay::SetRectangleToVideoOverlay() { // set Rectangle to video overlay if(VideoOverlay && OwnerWindow) { tjs_int ofsx, ofsy; Window->GetVideoOffset(ofsx, ofsy); tjs_int l = Rect.left; tjs_int t = Rect.top; tjs_int r = Rect.right; tjs_int b = Rect.bottom; TVPAddLog(TJS_W("Video zoom: (") + ttstr(l) + TJS_W(",") + ttstr(t) + TJS_W(")-(") + ttstr(r) + TJS_W(",") + ttstr(b) + TJS_W(") ->")); Window->ZoomRectangle(l, t, r, b); TVPAddLog(TJS_W("(") + ttstr(l) + TJS_W(",") + ttstr(t) + TJS_W(")-(") + ttstr(r) + TJS_W(",") + ttstr(b) + TJS_W(")")); RECT rect = {l + ofsx, t + ofsy, r + ofsx, b + ofsy}; VideoOverlay->SetRect(&rect); } }
//--------------------------------------------------------------------------- tTJSBinaryStream * tTVPSusieArchivePlugin::CreateStream(std::wstring localname, unsigned long pos, unsigned long size) { HLOCAL memhandle = NULL; int errorcode = 0xff & GetFile(const_cast<LPSTR>(ttstr(localname).AsNarrowStdString().c_str()), pos, (LPSTR)(void*)&memhandle, 0x0100, (FARPROC)ProgressCallback, 0); if(errorcode || memhandle == NULL) { TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(TJS_W("tTVPSusieArchivePlugin::GetFile failed, errorcode = ")) + ttstr((tjs_int)errorcode)); } tTVPMemoryStream *memstream = new tTVPMemoryStream; void *memblock = NULL; try { memblock = LocalLock(memhandle); if(memblock == NULL) { TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(TJS_W("tTVPSusieArchivePlugin::GetFile failed : invalid memory block."))); } // write to on-memory stream memstream->WriteBuffer(memblock, size); memstream->SetPosition(0); } catch(...) { if(memblock) LocalUnlock(memhandle); LocalFree(memhandle); delete memstream; throw; } if(memblock) LocalUnlock(memhandle); LocalFree(memhandle); return memstream; }
//--------------------------------------------------------------------------- extern "C" HRESULT _stdcall _export V2Unlink() { // 吉里吉里側から、プラグインを解放しようとするときに呼ばれる関数。 // もし何らかの条件でプラグインを解放できない場合は // この時点で E_FAIL を返すようにする。 // ここでは、TVPPluginGlobalRefCount が GlobalRefCountAtInit よりも // 大きくなっていれば失敗ということにする。 TVPAddLog(TVPPluginGlobalRefCount); if(TVPPluginGlobalRefCount > GlobalRefCountAtInit) return E_FAIL; // E_FAIL が帰ると、Plugins.unlink メソッドは偽を返す // TJS のグローバルオブジェクトに登録した drawFFTGraph 関数を削除する // - まず、TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); // - global の DeleteMember メソッドを用い、オブジェクトを削除する if(global) { // TJS 自体が既に解放されていたときなどは // global は NULL になり得るので global が NULL でない // ことをチェックする global->DeleteMember( 0, // フラグ ( 0 でよい ) TJS_W("drawFFTGraph"), // メンバ名 NULL, // ヒント global // コンテキスト ); // 登録した関数が複数ある場合は これを繰り返す } // - global を Release する if(global) global->Release(); // スタブの使用終了(必ず記述する) TVPUninitImportStub(); // その他の処理 if(SampleBuffer) delete [] SampleBuffer, SampleBuffer = NULL; if(FFTData) delete [] FFTData, FFTData = NULL; if(WindowData) delete [] WindowData, WindowData = NULL; if(fft_ip) delete [] fft_ip, fft_ip = NULL; if(fft_w) delete[] fft_w, fft_w = NULL; if(BandData) delete [] BandData, BandData = NULL; if(BandPeakData) delete [] BandPeakData, BandPeakData = NULL; if(BandPeakCount) delete [] BandPeakCount, BandPeakCount = NULL; if(BandStart) delete [] BandStart, BandStart = NULL; if(BandEnd) delete [] BandEnd, BandEnd = NULL; return S_OK; }
std::wstring FontSystem::GetBeingFont(std::wstring fonts) { // retrieve being font in the system. // font candidates are given by "fonts", separated by comma. bool vfont; if(fonts.c_str()[0] == TJS_W('@')) { // for vertical writing fonts = fonts.c_str() + 1; vfont = true; } else { vfont = false; } bool prev_empty_name = false; while(fonts!=TJS_W("")) { std::wstring fontname; int pos = fonts.find_first_of(TJS_W(",")); if( pos != std::string::npos ) { fontname = Trim( fonts.substr( 0, pos) ); fonts = fonts.c_str()+pos+1; } else { fontname = Trim(fonts); fonts=TJS_W(""); } // no existing check if previously specified font candidate is empty // eg. ",Fontname" if(fontname != TJS_W("") && (prev_empty_name || FontExists(fontname) ) ) { if(vfont && fontname.c_str()[0] != TJS_W('@')) { return TJS_W("@") + fontname; } else { return fontname; } } prev_empty_name = (fontname == TJS_W("")); } if(vfont) { return std::wstring(TJS_W("@")) + std::wstring(TVPGetDefaultFontName()); } else { return std::wstring(TVPGetDefaultFontName()); } }
//--------------------------------------------------------------------------- void tTJSDictionaryNI::SaveStructuredData(std::vector<iTJSDispatch2 *> &stack, iTJSTextWriteStream & stream, const ttstr &indentstr) { #ifdef TJS_TEXT_OUT_CRLF stream.Write(TJS_W("(const) %[\r\n")); #else stream.Write(TJS_W("(const) %[\n")); #endif ttstr indentstr2 = indentstr + TJS_W(" "); tSaveStructCallback callback; callback.Stack = &stack; callback.Stream = &stream; callback.IndentStr = &indentstr2; callback.First = true; Owner->EnumMembers(TJS_IGNOREPROP, &tTJSVariantClosure(&callback, NULL), Owner); #ifdef TJS_TEXT_OUT_CRLF if(!callback.First) stream.Write(TJS_W("\r\n")); #else if(!callback.First) stream.Write(TJS_W("\n")); #endif stream.Write(indentstr); stream.Write(TJS_W("]")); }
//--------------------------------------------------------------------------- int tTJSDateParser::Lex(YYSTYPE *yylex) { if(*InputPointer == 0) return -1; while( *InputPointer && TJS_iswspace(*InputPointer)) InputPointer++; if(*InputPointer == 0) return -1; if(TJS_iswdigit(*InputPointer)) { tjs_int32 val = *InputPointer - TJS_W('0'); InputPointer ++; while(TJS_iswdigit(*InputPointer)) { val *= 10; val += *InputPointer - TJS_W('0'); InputPointer++; } yylex->val = val; return DP_NUMBER; } #include "tjsDateWordMap.cc" int n = (int)*(InputPointer++); if(n >= TJS_W('A') && n <= TJS_W('Z')) n += TJS_W('a') - TJS_W('A'); return n; }
tjs_error TJS_INTF_METHOD StartTransition( /*in*/iTVPSimpleOptionProvider *options, // option provider /*in*/iTVPSimpleImageProvider *imagepro, // image provider /*in*/tTVPLayerType layertype, // destination layer type /*in*/tjs_uint src1w, tjs_uint src1h, // source 1 size /*in*/tjs_uint src2w, tjs_uint src2h, // source 2 size /*out*/tTVPTransType *type, // transition type /*out*/tTVPTransUpdateType * updatetype, // update typwe /*out*/iTVPBaseTransHandler ** handler // transition handler ) { if(type) *type = ttExchange; // transition type : exchange if(updatetype) *updatetype = tutDivisible; // update type : divisible if(!handler) return TJS_E_FAIL; if(!options) return TJS_E_FAIL; if(src1w != src2w || src1h != src2h) return TJS_E_FAIL; // src1 と src2 のサイズが一致していないと駄目 // オプションを得る tTJSVariant tmp; tjs_uint64 time; tjs_int maxblocksize = 30; if(TJS_FAILED(options->GetValue(TJS_W("time"), &tmp))) return TJS_E_FAIL; // time 属性が指定されていない if(tmp.Type() == tvtVoid) return TJS_E_FAIL; time = (tjs_int64)tmp; if(time < 2) time = 2; // あまり小さな数値を指定すると問題が起きるので if(TJS_SUCCEEDED(options->GetValue(TJS_W("maxsize"), &tmp))) if(tmp.Type() != tvtVoid) maxblocksize = (tjs_int)tmp; // オブジェクトを作成 *handler = new tTVPMosaicTransHandler(time, src1w, src1h, maxblocksize); return TJS_S_OK; }
tTVPLocalTempStorageHolder::tTVPLocalTempStorageHolder(const ttstr & name) { // name must be normalized !!! FileMustBeDeleted = false; FolderMustBeDeleted = false; LocalName = TVPGetLocallyAccessibleName(name); if(LocalName.IsEmpty()) { // file must be copied to local filesystem // note that the basename is much more important than the directory // which the file is to be in, so we create a temporary folder and // store the file in it. LocalFolder = TVPGetTemporaryName(); LocalName = LocalFolder + TJS_W("/") + TVPExtractStorageName(name); TVPCreateFolders(LocalFolder); // create temporary folder FolderMustBeDeleted = true; FileMustBeDeleted = true; try { // copy to local file tTVPStreamHolder src(name); tTVPStreamHolder dest(LocalName, TJS_BS_WRITE); tjs_uint8 * buffer = new tjs_uint8[TVP_LOCAL_TEMP_COPY_BLOCK_SIZE]; try { tjs_uint read; while(true) { read = src->Read(buffer, TVP_LOCAL_TEMP_COPY_BLOCK_SIZE); if(read == 0) break; dest->WriteBuffer(buffer, read); } } catch(...) { delete [] buffer; throw; } delete [] buffer; } catch(...) { if(FileMustBeDeleted) TVPRemoveFile(LocalName); if(FolderMustBeDeleted) TVPRemoveFolder(LocalFolder); throw; } } }