| |
| |
| #include "stdfx.h" |
| #include "tfxparam.h" |
| #include "ttzpimagefx.h" |
| #include "trop.h" |
| #include "texturefxP.h" |
| |
| |
| |
| class TextureFx final : public TStandardRasterFx { |
| FX_PLUGIN_DECLARATION(TextureFx) |
| |
| TRasterFxPort m_input; |
| TRasterFxPort m_texture; |
| TStringParamP m_string; |
| TIntEnumParamP m_keep; |
| |
| TIntEnumParamP m_mode; |
| TDoubleParamP m_value; |
| |
| public: |
| TextureFx() |
| : m_string(L"1,2,3") |
| , m_keep(new TIntEnumParam(0, "Delete")) |
| |
| , m_mode(new TIntEnumParam(SUBSTITUTE, "Texture")) |
| , m_value(100) { |
| addInputPort("Source", m_input); |
| addInputPort("Texture", m_texture); |
| bindParam(this, "indexes", m_string); |
| bindParam(this, "keep", m_keep); |
| bindParam(this, "mode", m_mode); |
| |
| bindParam(this, "value", m_value); |
| m_value->setValueRange(0, 100); |
| m_keep->addItem(1, "Keep"); |
| |
| |
| m_mode->addItem(PATTERNTYPE, "Pattern"); |
| m_mode->addItem(ADD, "Add"); |
| m_mode->addItem(SUBTRACT, "Subtract"); |
| m_mode->addItem(MULTIPLY, "Multiply"); |
| m_mode->addItem(LIGHTEN, "Lighten"); |
| m_mode->addItem(DARKEN, "Darken"); |
| } |
| |
| ~TextureFx(){}; |
| |
| bool doGetBBox(double frame, TRectD &bBox, |
| const TRenderSettings &info) override { |
| if (m_input.isConnected()) { |
| bool ret = m_input->doGetBBox(frame, bBox, info); |
| return ret; |
| } else { |
| bBox = TRectD(); |
| return false; |
| } |
| } |
| |
| void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override; |
| void doDryCompute(TRectD &rect, double frame, |
| const TRenderSettings &info) override; |
| |
| bool allowUserCacheOnPort(int port) override { return port != 0; } |
| |
| int getMemoryRequirement(const TRectD &rect, double frame, |
| const TRenderSettings &info) override; |
| bool canHandle(const TRenderSettings &info, double frame) override { |
| return true; |
| } |
| }; |
| |
| |
| |
| void TextureFx::doDryCompute(TRectD &rect, double frame, |
| const TRenderSettings &info) { |
| if (!m_input.isConnected()) return; |
| |
| std::vector<std::string> items; |
| std::string indexes = ::to_string(m_string->getValue()); |
| parseIndexes(indexes, items); |
| TRenderSettings ri2(info); |
| PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData; |
| insertIndexes(items, PaletteFilterData); |
| PaletteFilterData->m_keep = (bool)(m_keep->getValue() == 1); |
| |
| ri2.m_data.push_back(PaletteFilterData); |
| ri2.m_userCachable = false; |
| |
| |
| m_input->dryCompute(rect, frame, ri2); |
| |
| if (!m_texture.isConnected()) return; |
| |
| bool isSwatch = ri2.m_isSwatch; |
| if (isSwatch) ri2.m_isSwatch = false; |
| PaletteFilterData->m_keep = !(m_keep->getValue()); |
| |
| |
| m_input->dryCompute(rect, frame, ri2); |
| |
| |
| m_texture->dryCompute(rect, frame, info); |
| } |
| |
| |
| |
| void TextureFx::doCompute(TTile &tile, double frame, |
| const TRenderSettings &ri) { |
| if (!m_input.isConnected()) return; |
| |
| TTile invertMaskTile; |
| |
| |
| std::vector<std::string> items; |
| std::string indexes = ::to_string(m_string->getValue()); |
| parseIndexes(indexes, items); |
| |
| |
| |
| |
| TRenderSettings ri2(ri); |
| PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData; |
| PaletteFilterData->m_keep = !!(m_keep->getValue()); |
| insertIndexes(items, PaletteFilterData); |
| |
| ri2.m_data.push_back(PaletteFilterData); |
| ri2.m_userCachable = false; |
| |
| m_input->allocateAndCompute(invertMaskTile, tile.m_pos, |
| tile.getRaster()->getSize(), tile.getRaster(), |
| frame, ri2); |
| |
| if (!m_texture.isConnected()) { |
| tile.getRaster()->copy(invertMaskTile.getRaster()); |
| return; |
| } |
| |
| |
| |
| |
| bool isSwatch = ri2.m_isSwatch; |
| if (isSwatch) ri2.m_isSwatch = false; |
| PaletteFilterData->m_keep = !(m_keep->getValue()); |
| m_input->compute(tile, frame, ri2); |
| if (isSwatch) ri2.m_isSwatch = true; |
| |
| |
| TRect box; |
| TRop::computeBBox(tile.getRaster(), box); |
| if (box.isEmpty()) { |
| m_input->compute(tile, frame, ri); |
| return; |
| } |
| |
| |
| TTile textureTile; |
| TDimension size = tile.getRaster()->getSize(); |
| TPointD pos = tile.m_pos; |
| m_texture->allocateAndCompute(textureTile, pos, size, tile.getRaster(), frame, |
| ri); |
| |
| |
| |
| |
| |
| |
| |
| |
| double v = m_value->getValue(frame); |
| if (ri.m_bpp == 32) { |
| TRaster32P witheCard; |
| |
| myOver32(tile.getRaster(), invertMaskTile.getRaster(), |
| &makeOpaque<TPixel32>, v); |
| |
| switch (m_mode->getValue()) { |
| case SUBSTITUTE: |
| myOver32(tile.getRaster(), textureTile.getRaster(), &substitute<TPixel32>, |
| v); |
| break; |
| case PATTERNTYPE: |
| witheCard = TRaster32P(textureTile.getRaster()->getSize()); |
| witheCard->fill(TPixel32::White); |
| TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster()); |
| myOver32(tile.getRaster(), textureTile.getRaster(), &pattern32, v); |
| break; |
| case ADD: |
| myOver32(tile.getRaster(), textureTile.getRaster(), &textureAdd<TPixel32>, |
| v / 100.0); |
| break; |
| case SUBTRACT: |
| myOver32(tile.getRaster(), textureTile.getRaster(), &textureSub<TPixel32>, |
| v / 100.0); |
| break; |
| case MULTIPLY: |
| myOver32(tile.getRaster(), textureTile.getRaster(), |
| &textureMult<TPixel32>, v); |
| break; |
| case DARKEN: |
| myOver32(tile.getRaster(), textureTile.getRaster(), |
| &textureDarken<TPixel32>, v); |
| break; |
| case LIGHTEN: |
| myOver32(tile.getRaster(), textureTile.getRaster(), |
| &textureLighten<TPixel32>, v); |
| break; |
| default: |
| assert(0); |
| break; |
| } |
| } else { |
| TRaster64P witheCard; |
| |
| myOver64(tile.getRaster(), invertMaskTile.getRaster(), |
| &makeOpaque<TPixel64>, v); |
| |
| switch (m_mode->getValue()) { |
| case SUBSTITUTE: |
| myOver64(tile.getRaster(), textureTile.getRaster(), &substitute<TPixel64>, |
| v); |
| break; |
| case PATTERNTYPE: |
| witheCard = TRaster64P(textureTile.getRaster()->getSize()); |
| witheCard->fill(TPixel64::White); |
| TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster()); |
| myOver64(tile.getRaster(), textureTile.getRaster(), &pattern64, v); |
| break; |
| case ADD: |
| myOver64(tile.getRaster(), textureTile.getRaster(), &textureAdd<TPixel64>, |
| v / 100.0); |
| break; |
| case SUBTRACT: |
| myOver64(tile.getRaster(), textureTile.getRaster(), &textureSub<TPixel64>, |
| v / 100.0); |
| break; |
| case MULTIPLY: |
| myOver64(tile.getRaster(), textureTile.getRaster(), |
| &textureMult<TPixel64>, v); |
| break; |
| case DARKEN: |
| myOver64(tile.getRaster(), textureTile.getRaster(), |
| &textureDarken<TPixel64>, v); |
| break; |
| case LIGHTEN: |
| myOver64(tile.getRaster(), textureTile.getRaster(), |
| &textureLighten<TPixel64>, v); |
| break; |
| default: |
| assert(0); |
| } |
| } |
| |
| TRop::over(tile.getRaster(), invertMaskTile.getRaster()); |
| } |
| |
| |
| |
| int TextureFx::getMemoryRequirement(const TRectD &rect, double frame, |
| const TRenderSettings &info) { |
| return TRasterFx::memorySize(rect, info.m_bpp); |
| } |
| |
| |
| |
| FX_PLUGIN_IDENTIFIER(TextureFx, "textureFx"); |
| |