/** * レイヤ情報の取得 * @param no レイヤ番号 * @return レイヤ情報が格納された辞書 */ tTJSVariant getLayerInfo(int no) { checkLayerNo(no); psd_layer_record *lay = context->layer_records + no; tTJSVariant result; ncbDictionaryAccessor dict; if (dict.IsValid()) { #define SETPROP(dict, obj, prop) dict.SetValue(L ## #prop, obj->prop) SETPROP(dict, lay, layer_type); SETPROP(dict, lay, top); SETPROP(dict, lay, left); SETPROP(dict, lay, bottom); SETPROP(dict, lay, right); SETPROP(dict, lay, width); SETPROP(dict, lay, height); SETPROP(dict, lay, blend_mode); SETPROP(dict, lay, opacity); SETPROP(dict, lay, visible); dict.SetValue(L"name", layname(lay)); dict.SetValue(L"type", convBlendMode(lay->blend_mode)); // additional information SETPROP(dict, lay, clipping); SETPROP(dict, lay, transparency_protected); SETPROP(dict, lay, obsolete); SETPROP(dict, lay, pixel_data_irrelevant); // ...struct: layer_mask_info // ...struct: layer_blending_ranges // ...struct: vector_mask // ...array: layer_info_type/data (layer_info_count) SETPROP(dict, lay, adjustment_valid); // 調整レイヤーかどうか? SETPROP(dict, lay, fill_opacity); SETPROP(dict, lay, layer_name_id); SETPROP(dict, lay, layer_id); SETPROP(dict, lay, layer_version); SETPROP(dict, lay, blend_clipped); SETPROP(dict, lay, blend_interior); SETPROP(dict, lay, knockout); SETPROP(dict, lay, transparency); SETPROP(dict, lay, composite); SETPROP(dict, lay, position_respectively); SETPROP(dict, lay, sheet_color); SETPROP(dict, lay, reference_point_x); // 塗りつぶしレイヤ(パターン)のオフセット SETPROP(dict, lay, reference_point_y); // 塗りつぶしレイヤ(パターン)のオフセット SETPROP(dict, lay, transparency_shapes_layer); SETPROP(dict, lay, layer_mask_hides_effects); SETPROP(dict, lay, vector_mask_hides_effects); SETPROP(dict, lay, divider_type); SETPROP(dict, lay, divider_blend_mode); // group layer はスクリプト側では layer_id 参照で引くようにする if (lay->group_layer != NULL) dict.SetValue(L"group_layer_id", lay->group_layer->layer_id); result = dict; } return result; }
/** * レイヤデータの読み出し * @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; } }
/** * レイヤデータの読み出し(内部処理) * @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); } }
/** * レイヤ情報の取得 * @param no レイヤ番号 * @return レイヤ情報が格納された辞書 */ tTJSVariant PSD::getLayerInfo(int no) { checkLayerNo(no); psd::LayerInfo &lay = layerList[no]; tTJSVariant result; ncbDictionaryAccessor dict; if (dict.IsValid()) { #define SETPROP(dict, obj, prop) dict.SetValue(L ## #prop, obj.prop) SETPROP(dict, lay, top); SETPROP(dict, lay, left); SETPROP(dict, lay, bottom); SETPROP(dict, lay, right); SETPROP(dict, lay, width); SETPROP(dict, lay, height); SETPROP(dict, lay, opacity); bool mask = false; for (std::vector<psd::ChannelInfo>::iterator i = lay.channels.begin(); i != lay.channels.end(); i++) { if (i->isMaskChannel()) { mask = true; break; } } dict.SetValue(L"mask", mask); dict.SetValue(L"type", convBlendMode(lay.blendMode)); dict.SetValue(L"layer_type", lay.layerType); dict.SetValue(L"blend_mode", lay.blendMode); dict.SetValue(L"visible", lay.isVisible()); dict.SetValue(L"name", layname(lay)); // additional information SETPROP(dict, lay, clipping); dict.SetValue(L"layer_id", lay.layerId); dict.SetValue(L"obsolete", lay.isObsolete()); dict.SetValue(L"transparency_protected", lay.isTransparencyProtected()); dict.SetValue(L"pixel_data_irrelevant", lay.isPixelDataIrrelevant()); // レイヤーカンプ if (lay.layerComps.size() > 0) { ncbDictionaryAccessor compDict; if (compDict.IsValid()) { for (std::map<int, psd::LayerCompInfo>::iterator it = lay.layerComps.begin(); it != lay.layerComps.end(); it++) { ncbDictionaryAccessor tmp; if (tmp.IsValid()) { psd::LayerCompInfo &comp = it->second; tmp.SetValue(L"id", comp.id); tmp.SetValue(L"offset_x", comp.offsetX); tmp.SetValue(L"offset_y", comp.offsetY); tmp.SetValue(L"enable", comp.isEnabled); compDict.SetValue((tjs_int32)comp.id, tmp.GetDispatch()); } } dict.SetValue(L"layer_comp", compDict.GetDispatch()); } } // SETPROP(dict, lay, adjustment_valid); // 調整レイヤーかどうか?レイヤタイプで判別可能 // SETPROP(dict, lay, fill_opacity); // SETPROP(dict, lay, layer_name_id); // SETPROP(dict, lay, layer_version); // SETPROP(dict, lay, blend_clipped); // SETPROP(dict, lay, blend_interior); // SETPROP(dict, lay, knockout); // SETPROP(dict, lay, transparency); // lspf(protection)のもの // SETPROP(dict, lay, composite); // SETPROP(dict, lay, position_respectively); // SETPROP(dict, lay, sheet_color); // SETPROP(dict, lay, reference_point_x); // 塗りつぶしレイヤ(パターン)のオフセット // SETPROP(dict, lay, reference_point_y); // 塗りつぶしレイヤ(パターン)のオフセット // SETPROP(dict, lay, transparency_shapes_layer); // SETPROP(dict, lay, layer_mask_hides_effects); // SETPROP(dict, lay, vector_mask_hides_effects); // SETPROP(dict, lay, divider_type); // SETPROP(dict, lay, divider_blend_mode); // group layer はスクリプト側では layer_id 参照で引くようにする if (lay.parent != NULL) dict.SetValue(L"group_layer_id", lay.parent->layerId); result = dict; } return result; }
/** * レイヤ名称の取得 * @param no レイヤ番号 * @return レイヤ種別 */ ttstr PSD::getLayerName(int no) { checkLayerNo(no); return layname(layerList[no]); }
/** * レイヤ種別の取得 * @param no レイヤ番号 * @return レイヤ種別 */ int PSD::getLayerType(int no) { checkLayerNo(no); return (int)layerList[no].layerType; }
/** * レイヤ名称の取得 * @param no レイヤ番号 * @return レイヤ種別 */ ttstr getLayerName(int no) { checkLayerNo(no); psd_layer_record *lay = context->layer_records + no; return layname(lay); }
/** * レイヤ種別の取得 * @param no レイヤ番号 * @return レイヤ種別 */ int getLayerType(int no) { checkLayerNo(no); psd_layer_record *lay = context->layer_records + no; return lay->layer_type; }