File indexing completed on 2024-12-22 04:10:19
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_layer_style_projection_plane_test.h" 0008 0009 #include <simpletest.h> 0010 0011 #include <testutil.h> 0012 #include <testimage.h> 0013 0014 #include <KoColor.h> 0015 #include <KoColorSpace.h> 0016 #include <KoColorSpaceRegistry.h> 0017 #include <resources/KoPattern.h> 0018 0019 #include "kis_transparency_mask.h" 0020 #include "kis_paint_layer.h" 0021 #include "kis_image.h" 0022 #include "kis_painter.h" 0023 0024 #include "kis_selection.h" 0025 #include "kis_pixel_selection.h" 0026 0027 #include "layerstyles/kis_layer_style_projection_plane.h" 0028 #include "kis_psd_layer_style.h" 0029 #include "kis_paint_device_debug_utils.h" 0030 #include <KisGlobalResourcesInterface.h> 0031 #include <KisLocalStrokeResources.h> 0032 0033 0034 void KisLayerStyleProjectionPlaneTest::test(KisPSDLayerStyleSP style, const QString testName) 0035 { 0036 const QRect imageRect(0, 0, 200, 200); 0037 const QRect rFillRect(10, 10, 100, 100); 0038 const QRect tMaskRect(50, 50, 20, 20); 0039 const QRect partialSelectionRect(90, 50, 20, 20); 0040 0041 const QRect updateRect1(10, 10, 50, 100); 0042 const QRect updateRect2(60, 10, 50, 100); 0043 0044 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); 0045 KisImageSP image = new KisImage(0, imageRect.width(), imageRect.height(), cs, "styles test"); 0046 0047 KisPaintLayerSP layer = new KisPaintLayer(image, "test", OPACITY_OPAQUE_U8); 0048 image->addNode(layer); 0049 0050 KisLayerStyleProjectionPlane plane(layer.data(), style); 0051 0052 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "00L_initial", testName); 0053 0054 //layer->paintDevice()->fill(rFillRect, KoColor(Qt::red, cs)); 0055 { 0056 KisPainter gc(layer->paintDevice()); 0057 gc.setPaintColor(KoColor(Qt::red, cs)); 0058 gc.setFillStyle(KisPainter::FillStyleForegroundColor); 0059 gc.paintEllipse(rFillRect); 0060 } 0061 0062 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "01L_fill", testName); 0063 0064 KisPaintDeviceSP projection = new KisPaintDevice(cs); 0065 0066 { 0067 projection->clear(); 0068 const QRect changeRect = plane.changeRect(rFillRect, KisLayer::N_FILTHY); 0069 dbgKrita << ppVar(rFillRect) << ppVar(changeRect); 0070 0071 plane.recalculate(changeRect, layer); 0072 0073 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "02L_recalculate_fill", testName); 0074 0075 KisPainter painter(projection); 0076 plane.apply(&painter, changeRect); 0077 0078 KIS_DUMP_DEVICE_2(projection, imageRect, "03P_apply_on_fill", testName); 0079 } 0080 0081 { 0082 KisNodeSP clonedNode = layer->clone(); 0083 KisLayerSP clonedLayer = dynamic_cast<KisLayer*>(layer.data()); 0084 0085 KisLayerStyleProjectionPlaneSP clonedPlane = 0086 toQShared(new KisLayerStyleProjectionPlane(plane, 0087 clonedLayer.data(), 0088 style)); 0089 0090 const QRect changeRect = clonedPlane->changeRect(rFillRect, KisLayer::N_FILTHY); 0091 dbgKrita << ppVar(rFillRect) << ppVar(changeRect); 0092 0093 KIS_DUMP_DEVICE_2(clonedLayer->projection(), imageRect, "04L_clone_state_after_copy", testName); 0094 0095 { 0096 projection->clear(); 0097 KisPainter painter(projection); 0098 clonedPlane->apply(&painter, changeRect); 0099 0100 KIS_DUMP_DEVICE_2(projection, imageRect, "05P_apply_clone_after_copy", testName); 0101 } 0102 0103 clonedPlane->recalculate(changeRect, clonedLayer); 0104 0105 KIS_DUMP_DEVICE_2(clonedLayer->projection(), imageRect, "06L_recalculate_clone", testName); 0106 0107 { 0108 projection->clear(); 0109 KisPainter painter(projection); 0110 clonedPlane->apply(&painter, changeRect); 0111 0112 KIS_DUMP_DEVICE_2(projection, imageRect, "07P_apply_recalculated_clone", testName); 0113 } 0114 } 0115 0116 //return; 0117 0118 KisTransparencyMaskSP transparencyMask = new KisTransparencyMask(image, "tmask"); 0119 0120 KisSelectionSP selection = new KisSelection(); 0121 selection->pixelSelection()->select(tMaskRect, OPACITY_OPAQUE_U8); 0122 transparencyMask->setSelection(selection); 0123 image->addNode(transparencyMask, layer); 0124 0125 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "08L_mask_added", testName); 0126 0127 plane.recalculate(imageRect, layer); 0128 0129 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "09_mask_added_recalculated", testName); 0130 0131 { 0132 projection->clear(); 0133 0134 KisPainter painter(projection); 0135 plane.apply(&painter, imageRect); 0136 0137 KIS_DUMP_DEVICE_2(projection, imageRect, "10P_apply_on_mask", testName); 0138 } 0139 0140 selection->pixelSelection()->select(partialSelectionRect, OPACITY_OPAQUE_U8); 0141 0142 { 0143 const QRect changeRect = plane.changeRect(partialSelectionRect, KisLayer::N_FILTHY); 0144 projection->clear(changeRect); 0145 0146 dbgKrita << ppVar(partialSelectionRect) << ppVar(changeRect); 0147 0148 plane.recalculate(changeRect, layer); 0149 0150 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "11L_recalculate_partial", testName); 0151 0152 KisPainter painter(projection); 0153 plane.apply(&painter, changeRect); 0154 0155 KIS_DUMP_DEVICE_2(projection, imageRect, "12P_apply_partial", testName); 0156 } 0157 0158 // half updates 0159 transparencyMask->setVisible(false); 0160 0161 { 0162 const QRect changeRect = plane.changeRect(updateRect1, KisLayer::N_FILTHY); 0163 projection->clear(changeRect); 0164 0165 dbgKrita << ppVar(updateRect1) << ppVar(changeRect); 0166 0167 plane.recalculate(changeRect, layer); 0168 0169 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "13recalculate_half1", testName); 0170 0171 KisPainter painter(projection); 0172 plane.apply(&painter, changeRect); 0173 0174 KIS_DUMP_DEVICE_2(projection, imageRect, "14P_apply_half1", testName); 0175 } 0176 0177 { 0178 const QRect changeRect = plane.changeRect(updateRect2, KisLayer::N_FILTHY); 0179 projection->clear(changeRect); 0180 0181 dbgKrita << ppVar(updateRect2) << ppVar(changeRect); 0182 0183 plane.recalculate(changeRect, layer); 0184 0185 KIS_DUMP_DEVICE_2(layer->projection(), imageRect, "15L_recalculate_half1", testName); 0186 0187 KisPainter painter(projection); 0188 plane.apply(&painter, changeRect); 0189 0190 KIS_DUMP_DEVICE_2(projection, imageRect, "16P_apply_half2", testName); 0191 } 0192 } 0193 0194 0195 void KisLayerStyleProjectionPlaneTest::testShadow() 0196 { 0197 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0198 style->dropShadow()->setSize(15); 0199 style->dropShadow()->setDistance(15); 0200 style->dropShadow()->setOpacity(70); 0201 style->dropShadow()->setNoise(30); 0202 style->dropShadow()->setEffectEnabled(true); 0203 0204 style->innerShadow()->setSize(10); 0205 style->innerShadow()->setSpread(10); 0206 style->innerShadow()->setDistance(5); 0207 style->innerShadow()->setOpacity(70); 0208 style->innerShadow()->setNoise(30); 0209 style->innerShadow()->setEffectEnabled(true); 0210 0211 test(style, "shadow"); 0212 } 0213 0214 void KisLayerStyleProjectionPlaneTest::testGlow() 0215 { 0216 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0217 style->outerGlow()->setSize(15); 0218 style->outerGlow()->setSpread(10); 0219 style->outerGlow()->setOpacity(70); 0220 style->outerGlow()->setNoise(30); 0221 style->outerGlow()->setEffectEnabled(true); 0222 style->outerGlow()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='1.0' b='0.0'/></color>")); 0223 0224 test(style, "glow_outer"); 0225 } 0226 0227 #include <resources/KoStopGradient.h> 0228 0229 void KisLayerStyleProjectionPlaneTest::testGlowGradient() 0230 { 0231 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0232 style->outerGlow()->setSize(15); 0233 style->outerGlow()->setSpread(10); 0234 style->outerGlow()->setOpacity(70); 0235 style->outerGlow()->setNoise(10); 0236 style->outerGlow()->setEffectEnabled(true); 0237 style->outerGlow()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='1.0' b='0.0'/></color>")); 0238 0239 QLinearGradient testGradient; 0240 testGradient.setColorAt(0.0, Qt::white); 0241 testGradient.setColorAt(0.5, Qt::green); 0242 testGradient.setColorAt(1.0, Qt::black); 0243 testGradient.setSpread(QGradient::ReflectSpread); 0244 QSharedPointer<KoStopGradient> gradient( 0245 KoStopGradient::fromQGradient(&testGradient)); 0246 0247 style->outerGlow()->setGradient(gradient); 0248 style->outerGlow()->setFillType(psd_fill_gradient); 0249 0250 test(style, "glow_outer_grad"); 0251 } 0252 0253 void KisLayerStyleProjectionPlaneTest::testGlowGradientJitter() 0254 { 0255 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0256 style->outerGlow()->setSize(15); 0257 style->outerGlow()->setSpread(10); 0258 style->outerGlow()->setOpacity(70); 0259 style->outerGlow()->setNoise(0); 0260 style->outerGlow()->setEffectEnabled(true); 0261 style->outerGlow()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='1.0' b='0.0'/></color>")); 0262 0263 QLinearGradient testGradient; 0264 testGradient.setColorAt(0.0, Qt::white); 0265 testGradient.setColorAt(0.5, Qt::green); 0266 testGradient.setColorAt(1.0, Qt::black); 0267 testGradient.setSpread(QGradient::ReflectSpread); 0268 QSharedPointer<KoStopGradient> gradient( 0269 KoStopGradient::fromQGradient(&testGradient)); 0270 0271 style->outerGlow()->setGradient(gradient); 0272 style->outerGlow()->setFillType(psd_fill_gradient); 0273 style->outerGlow()->setJitter(20); 0274 0275 0276 0277 test(style, "glow_outer_grad_jit"); 0278 } 0279 0280 void KisLayerStyleProjectionPlaneTest::testGlowInnerGradient() 0281 { 0282 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0283 style->innerGlow()->setSize(15); 0284 style->innerGlow()->setSpread(10); 0285 style->innerGlow()->setOpacity(80); 0286 style->innerGlow()->setNoise(10); 0287 style->innerGlow()->setEffectEnabled(true); 0288 style->innerGlow()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")); 0289 0290 QLinearGradient testGradient; 0291 testGradient.setColorAt(0.0, Qt::white); 0292 testGradient.setColorAt(0.5, Qt::green); 0293 testGradient.setColorAt(1.0, Qt::black); 0294 testGradient.setSpread(QGradient::ReflectSpread); 0295 QSharedPointer<KoStopGradient> gradient( 0296 KoStopGradient::fromQGradient(&testGradient)); 0297 0298 style->innerGlow()->setGradient(gradient); 0299 style->innerGlow()->setFillType(psd_fill_gradient); 0300 0301 test(style, "glow_inner_grad"); 0302 0303 style->innerGlow()->setFillType(psd_fill_solid_color); 0304 style->innerGlow()->setSource(psd_glow_center); 0305 test(style, "glow_inner_grad_center"); 0306 } 0307 0308 #include <KoCompositeOpRegistry.h> 0309 0310 0311 void KisLayerStyleProjectionPlaneTest::testSatin() 0312 { 0313 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0314 style->satin()->setSize(15); 0315 style->satin()->setOpacity(80); 0316 style->satin()->setAngle(180); 0317 style->satin()->setEffectEnabled(true); 0318 style->satin()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")); 0319 style->satin()->setBlendMode(COMPOSITE_LINEAR_DODGE); 0320 0321 test(style, "satin"); 0322 } 0323 0324 void KisLayerStyleProjectionPlaneTest::testColorOverlay() 0325 { 0326 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0327 style->colorOverlay()->setOpacity(80); 0328 style->colorOverlay()->setEffectEnabled(true); 0329 style->colorOverlay()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")); 0330 style->colorOverlay()->setBlendMode(COMPOSITE_LINEAR_DODGE); 0331 0332 test(style, "color_overlay"); 0333 } 0334 0335 void KisLayerStyleProjectionPlaneTest::testGradientOverlay() 0336 { 0337 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0338 style->gradientOverlay()->setAngle(90); 0339 style->gradientOverlay()->setOpacity(80); 0340 style->gradientOverlay()->setEffectEnabled(true); 0341 style->gradientOverlay()->setBlendMode(COMPOSITE_LINEAR_DODGE); 0342 style->gradientOverlay()->setAlignWithLayer(true); 0343 style->gradientOverlay()->setScale(100); 0344 style->gradientOverlay()->setStyle(psd_gradient_style_diamond); 0345 0346 QLinearGradient testGradient; 0347 testGradient.setColorAt(0.0, Qt::white); 0348 testGradient.setColorAt(0.5, Qt::green); 0349 testGradient.setColorAt(1.0, Qt::black); 0350 testGradient.setSpread(QGradient::ReflectSpread); 0351 QSharedPointer<KoStopGradient> gradient( 0352 KoStopGradient::fromQGradient(&testGradient)); 0353 0354 style->gradientOverlay()->setGradient(gradient); 0355 0356 test(style, "grad_overlay"); 0357 } 0358 0359 void KisLayerStyleProjectionPlaneTest::testPatternOverlay() 0360 { 0361 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0362 style->patternOverlay()->setOpacity(80); 0363 style->patternOverlay()->setEffectEnabled(true); 0364 style->patternOverlay()->setBlendMode(COMPOSITE_LINEAR_DODGE); 0365 style->patternOverlay()->setScale(100); 0366 0367 style->patternOverlay()->setAlignWithLayer(false); 0368 0369 QString fileName(TestUtil::fetchDataFileLazy("pattern.pat")); 0370 0371 KoPatternSP pattern(new KoPattern(fileName)); 0372 0373 QVERIFY(pattern->load(KisGlobalResourcesInterface::instance())); 0374 0375 0376 QSharedPointer<KisLocalStrokeResources> resourcesInterface(new KisLocalStrokeResources()); 0377 resourcesInterface->addResource(pattern); 0378 style->setResourcesInterface(resourcesInterface); 0379 0380 style->patternOverlay()->setPattern(pattern); 0381 0382 test(style, "pat_overlay"); 0383 } 0384 0385 void KisLayerStyleProjectionPlaneTest::testStroke() 0386 { 0387 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0388 style->stroke()->setColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='0.0' b='1.0'/></color>")); 0389 style->stroke()->setOpacity(80); 0390 style->stroke()->setEffectEnabled(true); 0391 style->stroke()->setBlendMode(COMPOSITE_OVER); 0392 0393 style->stroke()->setSize(3); 0394 style->stroke()->setPosition(psd_stroke_center); 0395 0396 test(style, "stroke_col_ctr"); 0397 0398 style->stroke()->setPosition(psd_stroke_outside); 0399 0400 test(style, "stroke_col_out"); 0401 0402 style->stroke()->setPosition(psd_stroke_inside); 0403 0404 test(style, "stroke_col_in"); 0405 0406 0407 QString fileName(TestUtil::fetchDataFileLazy("pattern.pat")); 0408 KoPatternSP pattern(new KoPattern(fileName)); 0409 QVERIFY(pattern->load(KisGlobalResourcesInterface::instance())); 0410 0411 QSharedPointer<KisLocalStrokeResources> resourcesInterface(new KisLocalStrokeResources()); 0412 resourcesInterface->addResource(pattern); 0413 style->setResourcesInterface(resourcesInterface); 0414 0415 style->stroke()->setPattern(pattern); 0416 style->stroke()->setFillType(psd_fill_pattern); 0417 0418 test(style, "stroke_pat"); 0419 0420 0421 QLinearGradient testGradient; 0422 testGradient.setColorAt(0.0, Qt::white); 0423 testGradient.setColorAt(0.5, Qt::green); 0424 testGradient.setColorAt(1.0, Qt::black); 0425 testGradient.setSpread(QGradient::ReflectSpread); 0426 QSharedPointer<KoStopGradient> gradient( 0427 KoStopGradient::fromQGradient(&testGradient)); 0428 0429 style->stroke()->setGradient(gradient); 0430 style->stroke()->setFillType(psd_fill_gradient); 0431 0432 test(style, "stroke_grad"); 0433 0434 } 0435 0436 #include "layerstyles/gimp_bump_map.h" 0437 0438 void KisLayerStyleProjectionPlaneTest::testBumpmap() 0439 { 0440 KisPixelSelectionSP device = new KisPixelSelection(); 0441 0442 const int numCycles = 30; 0443 const int step = 5; 0444 0445 QRect applyRect(200, 100, 100, 100); 0446 QRect fillRect(210, 110, 80, 80); 0447 quint8 selectedness = 256 - numCycles * step; 0448 0449 0450 for (int i = 0; i < numCycles; i++) { 0451 device->select(fillRect, selectedness); 0452 0453 fillRect = kisGrowRect(fillRect, -1); 0454 selectedness += step; 0455 } 0456 0457 KIS_DUMP_DEVICE_2(device, applyRect, "00_initial", "bumpmap"); 0458 0459 0460 bumpmap_vals_t bmvals; 0461 0462 bmvals.azimuth = 240; 0463 bmvals.elevation = 30; 0464 bmvals.depth = 50; 0465 bmvals.ambient = 128; 0466 bmvals.compensate = false; 0467 bmvals.invert = false; 0468 bmvals.type = 0; 0469 0470 bumpmap(device, applyRect, bmvals); 0471 0472 KIS_DUMP_DEVICE_2(device, applyRect, "01_bumpmapped", "bumpmap"); 0473 0474 } 0475 0476 void KisLayerStyleProjectionPlaneTest::testBevel() 0477 { 0478 KisPSDLayerStyleSP style(new KisPSDLayerStyle()); 0479 style->bevelAndEmboss()->setEffectEnabled(true); 0480 0481 style->bevelAndEmboss()->setAngle(135); 0482 style->bevelAndEmboss()->setAltitude(45); 0483 style->bevelAndEmboss()->setDepth(100); 0484 0485 style->bevelAndEmboss()->setHighlightColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='1.0' g='1.0' b='1.0'/></color>")); 0486 style->bevelAndEmboss()->setHighlightBlendMode(COMPOSITE_OVER); 0487 style->bevelAndEmboss()->setHighlightOpacity(100); 0488 0489 style->bevelAndEmboss()->setShadowColor(KoColor::fromXML("<color channeldepth='U8'><sRGB r='0.0' g='0.0' b='0.0'/></color>")); 0490 style->bevelAndEmboss()->setShadowBlendMode(COMPOSITE_OVER); 0491 style->bevelAndEmboss()->setShadowOpacity(100); 0492 0493 QString fileName(TestUtil::fetchDataFileLazy("pattern.pat")); 0494 KoPatternSP pattern(new KoPattern(fileName)); 0495 QVERIFY(pattern->load(KisGlobalResourcesInterface::instance())); 0496 Q_ASSERT(!pattern->md5Sum().isEmpty()); 0497 QSharedPointer<KisLocalStrokeResources> resourcesInterface(new KisLocalStrokeResources()); 0498 resourcesInterface->addResource(pattern); 0499 0500 style->setResourcesInterface(resourcesInterface); 0501 style->bevelAndEmboss()->setTexturePattern(pattern); 0502 0503 style->bevelAndEmboss()->setTextureEnabled(true); 0504 style->bevelAndEmboss()->setTextureDepth(-10); 0505 style->bevelAndEmboss()->setTextureInvert(false); 0506 0507 style->bevelAndEmboss()->setStyle(psd_bevel_outer_bevel); 0508 style->bevelAndEmboss()->setDirection(psd_direction_up); 0509 style->bevelAndEmboss()->setSoften(0); 0510 test(style, "bevel_outer_up"); 0511 0512 style->bevelAndEmboss()->setTextureInvert(true); 0513 style->bevelAndEmboss()->setStyle(psd_bevel_outer_bevel); 0514 style->bevelAndEmboss()->setDirection(psd_direction_up); 0515 style->bevelAndEmboss()->setSoften(0); 0516 test(style, "bevel_outer_up_invert_texture"); 0517 style->bevelAndEmboss()->setTextureInvert(false); 0518 0519 style->bevelAndEmboss()->setStyle(psd_bevel_outer_bevel); 0520 style->bevelAndEmboss()->setDirection(psd_direction_down); 0521 style->bevelAndEmboss()->setSoften(0); 0522 test(style, "bevel_outer_down"); 0523 0524 style->bevelAndEmboss()->setStyle(psd_bevel_emboss); 0525 style->bevelAndEmboss()->setDirection(psd_direction_up); 0526 style->bevelAndEmboss()->setSoften(0); 0527 test(style, "bevel_emboss_up"); 0528 0529 style->bevelAndEmboss()->setStyle(psd_bevel_pillow_emboss); 0530 style->bevelAndEmboss()->setDirection(psd_direction_up); 0531 style->bevelAndEmboss()->setSoften(0); 0532 test(style, "bevel_pillow_up"); 0533 0534 style->bevelAndEmboss()->setStyle(psd_bevel_pillow_emboss); 0535 style->bevelAndEmboss()->setDirection(psd_direction_down); 0536 style->bevelAndEmboss()->setSoften(0); 0537 test(style, "bevel_pillow_down"); 0538 0539 style->bevelAndEmboss()->setStyle(psd_bevel_pillow_emboss); 0540 style->bevelAndEmboss()->setDirection(psd_direction_up); 0541 style->bevelAndEmboss()->setSoften(3); 0542 test(style, "bevel_pillow_up_soft"); 0543 } 0544 0545 #include "kis_ls_utils.h" 0546 0547 void KisLayerStyleProjectionPlaneTest::testBlending() 0548 { 0549 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); 0550 KisPaintDeviceSP layer = new KisPaintDevice(cs); 0551 KisPaintDeviceSP overlay = new KisPaintDevice(cs); 0552 KisPaintDeviceSP bg = new KisPaintDevice(cs); 0553 KisPaintDeviceSP result = new KisPaintDevice(cs); 0554 0555 const int width = 20; 0556 0557 QVector<QColor> layerColors; 0558 QVector<QColor> overlayColors; 0559 QVector<QColor> bgColors; 0560 0561 layerColors << QColor(0, 255, 0); 0562 layerColors << QColor(128, 255, 64); 0563 0564 overlayColors << QColor(255, 0, 0); 0565 overlayColors << QColor(255, 128, 64); 0566 0567 bgColors << QColor(0, 0, 0, 0); 0568 bgColors << QColor(0, 0, 0, 255); 0569 bgColors << QColor(255, 255, 255, 255); 0570 bgColors << QColor(64, 128, 255, 255); 0571 0572 bgColors << QColor(0, 0, 0, 128); 0573 bgColors << QColor(255, 255, 255, 128); 0574 bgColors << QColor(64, 128, 255, 128); 0575 0576 const int overlayOpacity = 255; 0577 const int layerOpacity = 255; 0578 int y = 1; 0579 Q_FOREACH(const QColor &layerColor, layerColors) { 0580 Q_FOREACH(const QColor &overlayColor, overlayColors) { 0581 Q_FOREACH(const QColor &bgColor, bgColors) { 0582 bg->setPixel(0, y, layerColor); 0583 bg->setPixel(1, y, overlayColor); 0584 bg->setPixel(2, y, bgColor); 0585 bg->setPixel(3, y, QColor(layerOpacity, layerOpacity, layerOpacity, 255)); 0586 bg->setPixel(4, y, QColor(overlayOpacity, overlayOpacity, overlayOpacity, 255)); 0587 0588 for (int i = 5; i < width; i++) { 0589 bg->setPixel(i, y, bgColor); 0590 } 0591 0592 for (int i = 0; i <= 10; i++) { 0593 const quint8 alpha = i == 0 ? 71 : qRound(255 * qreal(i) / 10); 0594 0595 { 0596 QColor c(layerColor); 0597 c.setAlpha(alpha); 0598 layer->setPixel(7 + i, y, c); 0599 } 0600 0601 { 0602 QColor c(overlayColor); 0603 c.setAlpha(alpha); 0604 overlay->setPixel(7 + i, y, c); 0605 } 0606 } 0607 0608 y++; 0609 } 0610 } 0611 } 0612 0613 const QRect rc = bg->exactBounds() | layer->exactBounds(); 0614 0615 0616 KIS_DUMP_DEVICE_2(layer, rc, "00_layer", "dd"); 0617 KIS_DUMP_DEVICE_2(overlay, rc, "01_overlay", "dd"); 0618 KIS_DUMP_DEVICE_2(bg, rc, "02_bg", "dd"); 0619 0620 KisPaintDeviceSP originalBg = new KisPaintDevice(*bg); 0621 0622 KisSelectionSP selection = new KisSelection(); 0623 KisLsUtils::selectionFromAlphaChannel(layer, selection, rc); 0624 0625 { 0626 KisSequentialIterator it(layer, rc); 0627 while (it.nextPixel()) { 0628 cs->setOpacity(it.rawData(), quint8(255), 1); 0629 } 0630 } 0631 0632 { 0633 KisSequentialIterator it(overlay, rc); 0634 while (it.nextPixel()) { 0635 cs->setOpacity(it.rawData(), quint8(255), 1); 0636 } 0637 } 0638 0639 KisPainter painter(bg); 0640 0641 painter.setOpacity(layerOpacity); 0642 painter.setCompositeOpId(COMPOSITE_OVER); 0643 0644 painter.bitBlt(rc.topLeft(), layer, rc); 0645 0646 painter.setOpacity(overlayOpacity); 0647 painter.setCompositeOpId(COMPOSITE_ADD); 0648 0649 painter.bitBlt(rc.topLeft(), overlay, rc); 0650 0651 KIS_DUMP_DEVICE_2(bg, rc, "03_result", "dd"); 0652 0653 KisPainter bgPainter(originalBg); 0654 bgPainter.setCompositeOpId(COMPOSITE_COPY); 0655 bgPainter.setSelection(selection); 0656 bgPainter.bitBlt(rc.topLeft(), bg, rc); 0657 0658 KIS_DUMP_DEVICE_2(originalBg, rc, "04_knockout", "dd"); 0659 } 0660 0661 KISTEST_MAIN(KisLayerStyleProjectionPlaneTest)