// 実行 bool exec(iTJSDispatch2 *obj, tTVPWindowMessage *message) { switch (receiver.Type()) { case tvtObject: { tTJSVariant result; tTJSVariant wparam = (tjs_int)message->WParam; tTJSVariant lparam = (tjs_int)message->LParam; tTJSVariant *p[] = {&userData, &wparam, &lparam}; receiver.AsObjectClosureNoAddRef().FuncCall(0, NULL, NULL, &result, 3, p, NULL); return (int)result != 0; } break; case tvtString: { tTJSVariant result; tTJSVariant wparam = (tjs_int)message->WParam; tTJSVariant lparam = (tjs_int)message->LParam; tTJSVariant *p[] = {&userData, &wparam, &lparam}; obj->FuncCall(0, receiver.GetString(), NULL, &result, 3, p, obj); return (int)result != 0; } break; case tvtInteger: { NativeReceiver receiverNative = (NativeReceiver)(tjs_int)receiver; return receiverNative(obj, (void*)(tjs_int)userData, message); } break; } return false; }
/** * XMLのノードから tTJSVariantを取得する * @param var 結果格納先 * @param node ノード */ static void getVariantFromNode(tTJSVariant &var, xml_node *node) { if (node && node->type() == rapidxml::node_element) { if (_wcsicmp(node->name(), L"undefined") == 0) { var.Clear(); } else if (_wcsicmp(node->name(), L"null") == 0) { var = tTJSVariant((iTJSDispatch2*)NULL); } else if (_wcsicmp(node->name(), L"array") == 0) { iTJSDispatch2 *array = TJSCreateArrayObject(); for (xml_node *propNode = node->first_node(); propNode; propNode = propNode->next_sibling()) { if (_wcsicmp(propNode->name(), L"property") == 0) { xml_attribute *attr_id = propNode->first_attribute(L"id"); if (attr_id) { tjs_int id = wcstol(attr_id->value(), NULL, 10); xml_node *valueNode = propNode->first_node(); if (valueNode) { tTJSVariant value; getVariantFromNode(value, valueNode); array->PropSetByNum(0, id, &value, array); } } } } var = tTJSVariant(array, array); array->Release(); } else if (_wcsicmp(node->name(), L"object") == 0) { iTJSDispatch2 *dict = TJSCreateDictionaryObject(); for (xml_node *propNode = node->first_node(); propNode; propNode = propNode->next_sibling()) { if (_wcsicmp(propNode->name(), L"property") == 0) { xml_attribute *attr_id = propNode->first_attribute(L"id"); if (attr_id) { ttstr id = attr_id->value(); if (id.length() > 0) { xml_node *valueNode = propNode->first_node(); if (valueNode) { tTJSVariant value; getVariantFromNode(value, valueNode); dict->PropSet(0, id.c_str(), 0, &value, dict); } } } } } var = tTJSVariant(dict, dict); dict->Release(); } else if (_wcsicmp(node->name(), L"string") == 0) { var = node->value(); } else if (_wcsicmp(node->name(), L"number") == 0) { var = wcstod(node->value(), NULL); } } else { var.Clear(); } }
/** * Date クラスの時刻をファイル時刻に変換 * @param restore 参照先(Dateクラスインスタンス) * @param filetime ファイル時刻結果格納先 * @return 取得できたかどうか */ static bool restoreDate(tTJSVariant &restore, FILETIME &filetime) { if (restore.Type() != tvtObject) return false; iTJSDispatch2 *date = restore.AsObjectNoAddRef(); if (!date) return false; tTJSVariant result; if (dateGetTime->FuncCall(0, NULL, NULL, &result, 0, NULL, date) != TJS_S_OK) return false; tjs_uint64 ft = result.AsInteger(); ft *= 10000; ft += 0x19DB1DED53E8000; filetime.dwLowDateTime = (DWORD)( ft & 0xFFFFFFFF); filetime.dwHighDateTime = (DWORD)((ft >> 32) & 0xFFFFFFFF); return true; }
//---------------------------------------------------------------------- // 構造体比較関数 tTJSVariant ScriptsAdd::clone(tTJSVariant obj) { // タイプがオブジェクトなら細かく判定 if (obj.Type() == tvtObject) { tTJSVariantClosure &o1 = obj.AsObjectClosureNoAddRef(); // Arrayの複製 if (o1.IsInstanceOf(0, NULL, NULL, L"Array", NULL)== TJS_S_TRUE) { iTJSDispatch2 *array = TJSCreateArrayObject(); tTJSVariant o1Count; (void)o1.PropGet(0, L"count", &countHint, &o1Count, NULL); tjs_int count = o1Count; tTJSVariant val; tTJSVariant *args[] = {&val}; for (tjs_int i = 0; i < count; i++) { (void)o1.PropGetByNum(TJS_IGNOREPROP, i, &val, NULL); val = ScriptsAdd::clone(val); static tjs_uint addHint = 0; (void)array->FuncCall(0, TJS_W("add"), &addHint, 0, 1, args, array); } tTJSVariant result(array, array); array->Release(); return result; } // Dictionaryの複製 if (o1.IsInstanceOf(0, NULL, NULL, L"Dictionary", NULL)== TJS_S_TRUE) { iTJSDispatch2 *dict = TJSCreateDictionaryObject(); DictMemberCloneCaller *caller = new DictMemberCloneCaller(dict); tTJSVariantClosure closure(caller); o1.EnumMembers(TJS_IGNOREPROP, &closure, NULL); caller->Release(); tTJSVariant result(dict, dict); dict->Release(); return result; } // cloneメソッドの呼び出しに成功すればそれを返す tTJSVariant result; static tjs_uint cloneHint = 0; if (o1.FuncCall(0, L"clone", &cloneHint, &result, 0, NULL, NULL)== TJS_S_TRUE) { return result; } } return obj; }
//---------------------------------------------------------------------- // 構造体比較関数 bool ScriptsAdd::equalStruct(tTJSVariant v1, tTJSVariant v2) { // タイプがオブジェクトなら特殊判定 if (v1.Type() == tvtObject && v2.Type() == tvtObject) { if (v1.AsObjectNoAddRef() == v2.AsObjectNoAddRef()) return true; tTJSVariantClosure &o1 = v1.AsObjectClosureNoAddRef(); tTJSVariantClosure &o2 = v2.AsObjectClosureNoAddRef(); // 関数どうしなら特別扱いで関数比較 if (o1.IsInstanceOf(0, NULL, NULL, L"Function", NULL)== TJS_S_TRUE && o2.IsInstanceOf(0, NULL, NULL, L"Function", NULL)== TJS_S_TRUE) return v1.DiscernCompare(v2); // Arrayどうしなら全項目を比較 if (o1.IsInstanceOf(0, NULL, NULL, L"Array", NULL)== TJS_S_TRUE && o2.IsInstanceOf(0, NULL, NULL, L"Array", NULL)== TJS_S_TRUE) { // 長さが一致していなければ比較失敗 tTJSVariant o1Count, o2Count; (void)o1.PropGet(0, L"count", &countHint, &o1Count, NULL); (void)o2.PropGet(0, L"count", &countHint, &o2Count, NULL); if (! o1Count.DiscernCompare(o2Count)) return false; // 全項目を順番に比較 tjs_int count = o1Count; tTJSVariant o1Val, o2Val; for (tjs_int i = 0; i < count; i++) { (void)o1.PropGetByNum(TJS_IGNOREPROP, i, &o1Val, NULL); (void)o2.PropGetByNum(TJS_IGNOREPROP, i, &o2Val, NULL); if (! equalStruct(o1Val, o2Val)) return false; } return true; } // Dictionaryどうしなら全項目を比較 if (o1.IsInstanceOf(0, NULL, NULL, L"Dictionary", NULL)== TJS_S_TRUE && o2.IsInstanceOf(0, NULL, NULL, L"Dictionary", NULL)== TJS_S_TRUE) { // 項目数が一致していなければ比較失敗 tjs_int o1Count, o2Count; (void)o1.GetCount(&o1Count, NULL, NULL, NULL); (void)o2.GetCount(&o2Count, NULL, NULL, NULL); if (o1Count != o2Count) return false; // 全項目を順番に比較 DictMemberCompareCaller *caller = new DictMemberCompareCaller(o2); tTJSVariantClosure closure(caller); tTJSVariant(o1.EnumMembers(TJS_IGNOREPROP, &closure, NULL)); bool result = caller->match; caller->Release(); return result; } } return v1.DiscernCompare(v2); }
/** * 合成結果の取得。取得領域は画像全体サイズ内におさまってる必要があります * @param layer 格納先レイヤ(width,heightサイズに調整される) * @param left 合成結果取得領域の左上座標 * @param top 合成結果取得領域の左上座標 * @param width 取得サイズ横幅 * @param height 取得サイズ縦幅 * @return 取得に成功したら true */ bool getBlend(tTJSVariant layer, int left, int top, int width, int height) { if (!layer.AsObjectNoAddRef()->IsInstanceOf(0, 0, 0, L"Layer", NULL)) { TVPThrowExceptionMessage(L"not layer"); } // 合成結果を生成 if (psd_image_blend(context, left, top, width, height) == psd_status_done) { // 格納先を調整 ncbPropAccessor obj(layer); obj.SetValue(L"width", width); obj.SetValue(L"height", height); obj.SetValue(L"imageLeft", 0); obj.SetValue(L"imageTop", 0); obj.SetValue(L"imageWidth", width); obj.SetValue(L"imageHeight", height); // 合成結果画像データのコピー psd_argb_color *src = context->blending_image_data + top * context->width + left; int len = width * 4; unsigned char *buffer = (unsigned char*)obj.GetValue(L"mainImageBufferForWrite", ncbTypedefs::Tag<tjs_int>()); int pitch = obj.GetValue(L"mainImageBufferPitch", ncbTypedefs::Tag<tjs_int>()); for (int y=0;y<height;y++) { memcpy(buffer, (unsigned char*)src, len); src += context->width; buffer += pitch; } // 合成結果情報の破棄 psd_image_blend_free(context); return true; } return false; }
/** * コンストラクタ */ TJSObject::TJSObject(HSQUIRRELVM v, int idx, tTJSVariant &instance) : instance(instance) { initSelf(v, idx); iTJSDispatch2 *objthis = instance.AsObjectNoAddRef(); // TJSインスタンスにネイティブインスタンスとして登録しておく iTJSNativeInstance *ninstance = this; objthis->NativeInstanceSupport(TJS_NIS_REGISTER, classId, &ninstance); // callSQ メソッド登録 tCallSQFunction *callSQ = new tCallSQFunction(); if (callSQ) { tTJSVariant val(callSQ, objthis); objthis->PropSet(TJS_MEMBERENSURE, TJS_W("callSQ"), NULL, &val, objthis); callSQ->Release(); } // missing メソッド登録 tMissingFunction *missing = new tMissingFunction(); if (missing) { tTJSVariant val(missing, objthis); const tjs_char *missingName = TJS_W("missing"); objthis->PropSet(TJS_MEMBERENSURE, missingName, NULL, &val, objthis); missing->Release(); // missing 有効化 tTJSVariant name(missingName); objthis->ClassInstanceInfo(TJS_CII_SET_MISSING, 0, &name); } }
/** * 合成結果の取得。取得領域は画像全体サイズ内におさまってる必要があります * 注意:PSDファイル自体に合成済み画像が存在しない場合は取得に失敗します * * @param layer 格納先レイヤ(width,heightサイズに調整される) * @return 取得に成功したら true */ bool PSD::getBlend(tTJSVariant layer) { if (!layer.AsObjectNoAddRef()->IsInstanceOf(0, 0, 0, L"Layer", NULL)) { TVPThrowExceptionMessage(L"not layer"); } // 合成結果を生成 if (imageData) { // 格納先を調整 ncbPropAccessor obj(layer); obj.SetValue(L"width", get_width()); obj.SetValue(L"height", get_height()); obj.SetValue(L"imageLeft", 0); obj.SetValue(L"imageTop", 0); obj.SetValue(L"imageWidth", get_width()); obj.SetValue(L"imageHeight", get_height()); // 画像データのコピー unsigned char *buffer = (unsigned char*)obj.GetValue(L"mainImageBufferForWrite", ncbTypedefs::Tag<tjs_int>()); int pitch = obj.GetValue(L"mainImageBufferPitch", ncbTypedefs::Tag<tjs_int>()); getMergedImage(buffer, psd::BGRA_LE, pitch); return true; } return false; }
/** * コンストラクタ */ TJSInstance::TJSInstance(Isolate *isolate, Local<Object> &obj, const tTJSVariant &variant) : isolate(isolate), TJSBase(variant) { HandleScope handle_scope(isolate); // Javascript オブジェクトに格納 wrap(isolate, obj); self.Reset(isolate, obj); self.SetWeak(this, release); iTJSDispatch2 *objthis = variant.AsObjectNoAddRef(); // TJSインスタンスにネイティブインスタンスとして登録しておく iTJSNativeInstance *ninstance = this; objthis->NativeInstanceSupport(TJS_NIS_REGISTER, classId, &ninstance); // callJS メソッド登録 tCallJSFunction *callJS = new tCallJSFunction(); if (callJS) { tTJSVariant val(callJS, objthis); objthis->PropSet(TJS_MEMBERENSURE, TJS_W("callJS"), NULL, &val, objthis); callJS->Release(); } // missing メソッド登録 tMissingFunction *missing = new tMissingFunction(); if (missing) { tTJSVariant val(missing, objthis); const tjs_char *missingName = TJS_W("missing"); objthis->PropSet(TJS_MEMBERENSURE, missingName, NULL, &val, objthis); missing->Release(); // missing 有効化 tTJSVariant name(missingName); objthis->ClassInstanceInfo(TJS_CII_SET_MISSING, 0, &name); } }
static void getVariantString(tTJSVariant &var, IWriter *writer) { switch(var.Type()) { case tvtVoid: writer->write(L"void"); break; case tvtObject: { iTJSDispatch2 *obj = var.AsObjectNoAddRef(); if (obj == NULL) { writer->write(L"null"); } else if (obj->IsInstanceOf(TJS_IGNOREPROP,NULL,NULL,L"Array",obj) == TJS_S_TRUE) { getArrayString(obj, writer); } else { getDictString(obj, writer); } } break; case tvtString: quoteString(var.GetString(), writer); break; case tvtOctet: quoteOctet(var.AsOctetNoAddRef(), writer); break; case tvtInteger: writer->write(L"int "); writer->write((tTVInteger)var); break; case tvtReal: writer->write(L"real "); writer->write((tTVReal)var); break; default: writer->write(L"void"); break; }; }
/** * バイアント値を格納する */ void tTJSBinarySerializer::PutVariant( tTJSBinaryStream* stream, tTJSVariant& v ) { tTJSVariantType type = v.Type(); switch( type ) { case tvtVoid: { tjs_uint8 tmp[1]; tmp[0] = TYPE_VOID; stream->Write( tmp, sizeof(tmp) ); break; } case tvtObject: break; /* { iTJSDispatch2* obj = v.AsObjectNoAddRef(); iTJSDispatch2* objthis = v.AsObjectThisNoAddRef(); if( obj == NULL && objthis == NULL ) { Put( TYPE_NIL ); } else { SaveStructured } break; } */ case tvtString: PutString( stream, v.AsStringNoAddRef() ); break; case tvtOctet: PutOctet( stream, v.AsOctetNoAddRef() ); break; case tvtInteger: PutInteger( stream, v.AsInteger() ); break; case tvtReal: PutDouble( stream, v.AsReal() ); break; default: break; } }
/** * 吉里吉里オブジェクトを squirrel に登録。squirrel 側で生成されたオブジェクトの場合は元のオブジェクト情報をそのまま返す * @return 登録成功 */ bool TJSObject::pushVariant(HSQUIRRELVM v, tTJSVariant &variant) { // 登録済みインスタンスかどうかの判定 iTJSNativeInstance *ninstance; if (TJS_SUCCEEDED(variant.AsObjectNoAddRef()->NativeInstanceSupport(TJS_NIS_GETINSTANCE, classId, &ninstance))) { // 元々 squirrel 側から登録されたオブジェクトの場合は元の squirrel オブジェクト情報をそのまま返す TJSObject *self = (TJSObject*)ninstance; self->self.push(v); return true; } return false; }
virtual tjs_error TJS_INTF_METHOD FuncCall( // function invocation tjs_uint32 flag, // calling flag const tjs_char * membername,// member name ( NULL for a default member ) tjs_uint32 *hint, // hint for the member name (in/out) tTJSVariant *result, // result tjs_int numparams, // number of parameters tTJSVariant **param, // parameters iTJSDispatch2 *objthis // object as "this" ) { breakResult.Clear(); if (numparams > 1) { if ((int)*param[1] != TJS_HIDDENMEMBER) { paramList[0] = param[0]; paramList[1] = param[2]; (void)func->FuncCall(0, NULL, NULL, &breakResult, paramCount, paramList, functhis); } } if (result) { *result = breakResult.Type() == tvtVoid; } return TJS_S_OK; }
/** * 吉里吉里オブジェクトを javascriptオブジェクトに変換 * @return 登録成功 */ bool TJSInstance::getJSObject(Local<Object> &result, const tTJSVariant &variant) { iTJSDispatch2 *dispatch = variant.AsObjectNoAddRef(); iTJSNativeInstance *ninstance; if (TJS_SUCCEEDED(dispatch->NativeInstanceSupport(TJS_NIS_GETINSTANCE, classId, &ninstance))) { // Javascript側から登録されたオブジェクトの場合は元の Javascriptオブジェクト情報をそのまま返す TJSInstance *self = (TJSInstance*)ninstance; result = self->getObject(); return true; } return false; }
void copy(tTJSVariant v) { if (!buffer) TVPThrowExceptionMessage(TJS_W("LongExposure.copy: not initialized")); size_t curw = 0, curh = 0; if (!GetLayerSize(self, curw, curh)) TVPThrowExceptionMessage(TJS_W("LongExposure.copy: invalid layer image")); if (curw != width || curh != height) TVPThrowExceptionMessage(TJS_W("LongExposure.copy: invalid layer size")); BYTE *ptr = 0; long pitch = 0; if (!GetLayerImageForWrite(self, ptr, pitch)) TVPThrowExceptionMessage(TJS_W("LongExposure.copy: invalid layer image")); MinMaxRGBA m; switch (v.Type()) { case tvtVoid: if (!_stat(m)) TVPThrowExceptionMessage(TJS_W("LongExposure.copy: stat failed")); break; case tvtObject: { ncbPropAccessor rdic(v); if (rdic.IsValid()) { m._min.r = rdic.getIntValue(TJS_W("min_r")); m._min.g = rdic.getIntValue(TJS_W("min_g")); m._min.b = rdic.getIntValue(TJS_W("min_b")); m._min.a = rdic.getIntValue(TJS_W("min_a")); m._max.r = rdic.getIntValue(TJS_W("max_r")); m._max.g = rdic.getIntValue(TJS_W("max_g")); m._max.b = rdic.getIntValue(TJS_W("max_b")); m._max.a = rdic.getIntValue(TJS_W("max_a")); } } break; } for (size_t y = 0; y < height; y++) { const DWORD* r = buffer + width*4 * y; BYTE* w = ptr + pitch * y; for (size_t x = 0; x < width; x++) { *w++ = m.getNormalizeB(*r++); *w++ = m.getNormalizeG(*r++); *w++ = m.getNormalizeR(*r++); *w++ = m.getNormalizeA(*r++); } } }
/** * レイヤデータの読み出し * @param layer 読み出し先レイヤ * @param no レイヤ番号 */ void getLayerData(tTJSVariant layer, int no) { if (!layer.AsObjectNoAddRef()->IsInstanceOf(0, 0, 0, L"Layer", NULL)) { TVPThrowExceptionMessage(L"not layer"); } checkLayerNo(no); psd_layer_record *lay = context->layer_records + no; if (lay->layer_type != psd_layer_type_normal) { TVPThrowExceptionMessage(L"invalid layer type"); } int width = lay->width; int height = lay->height; if (width <= 0 || height <= 0) { // サイズ0のレイヤはロードできない return; } ncbPropAccessor obj(layer); SETPROP(obj, lay, left); SETPROP(obj, lay, top); obj.SetValue(L"width", width); obj.SetValue(L"height", height); obj.SetValue(L"type", convBlendMode(lay->blend_mode)); SETPROP(obj, lay, opacity); SETPROP(obj, lay, visible); obj.SetValue(L"imageLeft", 0); obj.SetValue(L"imageTop", 0); obj.SetValue(L"imageWidth", width); obj.SetValue(L"imageHeight", height); obj.SetValue(L"name", layname(lay)); // 画像データのコピー psd_argb_color *src = lay->image_data; int srclen = width * 4; unsigned char *buffer = (unsigned char*)obj.GetValue(L"mainImageBufferForWrite", ncbTypedefs::Tag<tjs_int>()); int pitch = obj.GetValue(L"mainImageBufferPitch", ncbTypedefs::Tag<tjs_int>()); for (int y=0;y<height;y++) { memcpy(buffer, (unsigned char*)src, srclen); src += width; buffer += pitch; } }
/** * VARIANT を tTJSVariant に格納する * @param result 変換先 * @param variant 変換元 */ void IDispatchWrapper::storeVariant(tTJSVariant &result, VARIANT &variant) { result.Clear(); switch (variant.vt) { case VT_NULL: result = (iTJSDispatch2*)NULL; break; case VT_I8: result = variant.llVal; break; case VT_I4: result = (tjs_int32)variant.lVal; break; case VT_UI1: result = (tjs_int32)variant.bVal; break; case VT_I2: result = (tjs_int32)variant.iVal; break; case VT_R4: result = (double)variant.fltVal; break; case VT_R8: result = variant.dblVal; break; case VT_BOOL: result = (variant.boolVal == VARIANT_TRUE); break; case VT_BSTR: result = variant.bstrVal; break; case VT_ARRAY | VT_UI1: { SAFEARRAY *psa = variant.parray; unsigned char *p; if (SUCCEEDED(SafeArrayAccessData(psa, (LPVOID*)&p))) { // p; //psa->rgsabound->cElements; // XXX variant にどう入れよう? SafeArrayUnaccessData(psa); } } break; case VT_UNKNOWN: case VT_DISPATCH: if (variant.punkVal) { iTJSDispatch2 *obj = NULL; if (variant.punkVal->QueryInterface(IID_iTJSDispatch2, (void**)&obj) == S_OK) { result = obj; obj->Release(); } else { IDispatch *dispatch = NULL; if (variant.punkVal->QueryInterface(IID_IDispatch, (void**)&dispatch) == S_OK) { iTJSDispatch2 *obj = new iTJSDispatch2Wrapper(dispatch); result = obj; obj->Release(); dispatch->Release(); } } } else { result = (iTJSDispatch2*)NULL; } break; case VT_BYREF | VT_I8: result = *variant.pllVal; break; case VT_BYREF | VT_I4: result = (tjs_int32)*variant.plVal; break; case VT_BYREF | VT_UI1: result = (tjs_int32)*variant.pbVal; break; case VT_BYREF | VT_I2: result = (tjs_int32)*variant.piVal; break; case VT_BYREF | VT_R4: result = *variant.pfltVal; break; case VT_BYREF | VT_R8: result = *variant.pdblVal; break; case VT_BYREF | VT_BOOL: result = (*variant.pboolVal == VARIANT_TRUE); break; case VT_BYREF | VT_BSTR: result = *variant.pbstrVal; break; case VT_BYREF | VT_ARRAY | VT_UI1: { SAFEARRAY *psa = *(variant.pparray); const tjs_uint8 *p; if (SUCCEEDED(SafeArrayAccessData(psa, (LPVOID*)&p))) { result = tTJSVariant(p, psa->rgsabound->cElements); SafeArrayUnaccessData(psa); } } break; case VT_BYREF | VT_UNKNOWN: case VT_BYREF | VT_DISPATCH: if (*(variant.ppunkVal)) { iTJSDispatch2 *obj = NULL; if ((*(variant.ppunkVal))->QueryInterface(IID_iTJSDispatch2, (void**)&obj) == S_OK) { result = obj; obj->Release(); } else { IDispatch *dispatch = NULL; if ((*(variant.ppunkVal))->QueryInterface(IID_IDispatch, (void**)&dispatch) == S_OK) { iTJSDispatch2 *obj = new iTJSDispatch2Wrapper(dispatch); result = obj; obj->Release(); dispatch->Release(); } } } else { result = (iTJSDispatch2*)NULL; } break; case (VT_BYREF | VT_VARIANT): storeVariant(result, *variant.pvarVal); default: ;//log(L"unkown result type"); } }
//--------------------------------------------------------------------------- tTJSString::tTJSString(const tTJSVariant & val) { Ptr = val.AsString(); }
/** * tTJSVariant を VARIANT に格納する * @param result 格納先 * @param variant 格納元 */ void IDispatchWrapper::storeVariant(VARIANT &result, tTJSVariant &variant) { VariantClear(&result); switch (variant.Type()) { case tvtVoid: //log(L"void"); break; case tvtObject: // オブジェクト //log(L"object"); { switch (variant.Type()) { case tvtObject: V_VT(&result) = VT_DISPATCH; V_DISPATCH(&result) = new IDispatchWrapper(variant.AsObjectNoAddRef()); break; default: V_VT(&result) = VT_NULL; break; } } break; case tvtString: //log(L"string"); // 文字列 V_VT(&result) = VT_BSTR; V_BSTR(&result) = SysAllocString(variant.GetString()); break; case tvtOctet: //log(L"octet"); // オクテット列 { tTJSVariantOctet *octet = variant.AsOctetNoAddRef(); if (octet) { SAFEARRAY *psa; SAFEARRAYBOUND sabound; sabound.lLbound = 0; sabound.cElements = octet->GetLength(); if ((psa = SafeArrayCreate(VT_UI1, 1, &sabound))) { // データをコピーする unsigned char *p; if (SUCCEEDED(SafeArrayAccessData(psa, (LPVOID*)&p))) { memcpy(p, octet->GetData(), octet->GetLength()); SafeArrayUnaccessData(psa); V_VT(&result) = VT_ARRAY | VT_UI1; V_ARRAY(&result) = psa; } else { SafeArrayDestroy(psa); } } else { // メモリ不足例外 } } } break; case tvtInteger: // COM は 64bit をサポートしていない!! // ということで COM に渡す引数で整数値は 32bit を超えないように注意すること(涙) //log(L"integer"); V_VT(&result) = VT_I4; V_I4(&result) = (int)(variant); break; case tvtReal: //log(L"real"); V_VT(&result) = VT_R8; V_R8(&result) = (double)(variant); break; } }
/** * レイヤデータの読み出し(内部処理) * @param layer 読み出し先レイヤ * @param no レイヤ番号 * @param imageMode イメージモード */ void PSD::_getLayerData(tTJSVariant layer, int no, psd::ImageMode imageMode) { if (!layer.AsObjectNoAddRef()->IsInstanceOf(0, 0, 0, L"Layer", NULL)) { TVPThrowExceptionMessage(L"not layer"); } checkLayerNo(no); psd::LayerInfo &lay = layerList[no]; psd::LayerMask &mask = lay.extraData.layerMask; if (lay.layerType != psd::LAYER_TYPE_NORMAL && ! (lay.layerType == psd::LAYER_TYPE_FOLDER && imageMode == psd::IMAGE_MODE_MASK)) { TVPThrowExceptionMessage(L"invalid layer type"); } int left, top, width, height, opacity, type; bool dummyMask = false; if (imageMode == psd::IMAGE_MODE_MASK) { left = mask.left; top = mask.top; width = mask.width; height = mask.height; opacity = 255; type = ltPsNormal; if (width == 0 || height == 0) { left = top = 0; width = height = 1; dummyMask = true; } } else { left = lay.left; top = lay.top; width = lay.width; height = lay.height; opacity = lay.opacity; type = convBlendMode(lay.blendMode); } if (width <= 0 || height <= 0) { // サイズ0のレイヤはロードできない return; } ncbPropAccessor obj(layer); obj.SetValue(L"left", left); obj.SetValue(L"top", top); obj.SetValue(L"opacity", opacity); obj.SetValue(L"width", width); obj.SetValue(L"height", height); obj.SetValue(L"type", type); obj.SetValue(L"visible", lay.isVisible()); obj.SetValue(L"imageLeft", 0); obj.SetValue(L"imageTop", 0); obj.SetValue(L"imageWidth", width); obj.SetValue(L"imageHeight", height); obj.SetValue(L"name", layname(lay)); if (imageMode == psd::IMAGE_MODE_MASK) obj.SetValue(L"defaultMaskColor", mask.defaultColor); // 画像データのコピー unsigned char *buffer = (unsigned char*)obj.GetValue(L"mainImageBufferForWrite", ncbTypedefs::Tag<tjs_int>()); int pitch = obj.GetValue(L"mainImageBufferPitch", ncbTypedefs::Tag<tjs_int>()); if (dummyMask) { buffer[0] = buffer[1] = buffer[2] = mask.defaultColor; buffer[3] = 255; } else { getLayerImage(lay, buffer, psd::BGRA_LE, pitch, imageMode); } }
//--------------------------------------------------------------------------- tTJSString TJSVariantToReadableString(const tTJSVariant &val, tjs_int maxlen) { // convert given variant to human-readable string // ( eg. "(string)\"this is a\\nstring\"" ) tTJSVariantType type = val.Type(); switch(type) { case tvtVoid: { tTJSString str(TJS_W("(void)")); TJSTrimStringLength(str, maxlen); return str; } case tvtInteger: { tTJSString str(TJS_W("(int)")); str += (tTJSString)val; TJSTrimStringLength(str, maxlen); return str; } case tvtReal: { tTJSString str(TJS_W("(real)")); str += (tTJSString)val; TJSTrimStringLength(str, maxlen); return str; } case tvtString: { tTJSString str(TJS_W("(string)\"")); str += ttstr(val).EscapeC(); str += TJS_W("\""); TJSTrimStringLength(str, maxlen); return str; } case tvtOctet: { // TODO: octet conversion tTJSString str(TJS_W("(octet)<% ")); tTJSVariantString * s = TJSOctetToListString(val.AsOctetNoAddRef()); try { str += s; } catch(...) { if(s) s->Release(); throw; } if(s) s->Release(); str += TJS_W(" %>"); TJSTrimStringLength(str, maxlen); return str; } case tvtObject: { tTJSString str(TJS_W("(object)")); try { str += ttstr(val); } catch(...) { } TJSTrimStringLength(str, maxlen); return str; } } return TJS_W(""); }
//--------------------------------------------------------------------------- tTJSString TJSVariantToExpressionString(const tTJSVariant &val) { // convert given variant to string which can be interpret as an expression. // this function does not convert objects ( returns empty string ) tTJSVariantType type = val.Type(); switch(type) { case tvtVoid: { return TJS_W("void"); } case tvtInteger: { return ttstr(val); } case tvtReal: { tTJSString str; tTJSVariantString *s = TJSRealToHexString(val.AsReal()); try { str = s; } catch(...) { if(s) s->Release(); throw; } if(s) s->Release(); return str + TJS_W(" /" "* ") + ttstr(val) + TJS_W(" *" "/"); } case tvtString: { tTJSString str(TJS_W("\"")); str += ttstr(val).EscapeC(); str += TJS_W("\""); return str; } case tvtOctet: { tTJSString str(TJS_W("<% ")); tTJSVariantString * s = TJSOctetToListString(val.AsOctetNoAddRef()); try { str += s; } catch(...) { if(s) s->Release(); throw; } if(s) s->Release(); str += TJS_W(" %>"); return str; } case tvtObject: { return TJS_W(""); } } return TJS_W(""); }
/** * コンテキストの取得 */ tTJSVariant ScriptsAdd::getObjectContext(tTJSVariant obj) { iTJSDispatch2 *objthis = obj.AsObjectClosureNoAddRef().ObjThis; return tTJSVariant(objthis, objthis); }
/** * コンテキストが null かどうか判定 */ bool ScriptsAdd::isNullContext(tTJSVariant obj) { return obj.AsObjectClosureNoAddRef().ObjThis == NULL; }