1 module text.composite_texture; 2 3 import std.conv; 4 import std.range; 5 import std.algorithm; 6 7 import fluid; 8 9 @safe: 10 11 unittest { 12 13 auto content = vscrollable!label( 14 .nullTheme, 15 "One\nTwo\nThree\nFour\nFive\n" 16 ); 17 auto root = testSpace(content); 18 19 root.draw(); 20 21 // One chunk only 22 assert(content.text.texture.chunks.length == 1); 23 24 // This one chunk must have been drawn 25 root.drawAndAssert( 26 content.drawsImage(content.text.texture.chunks[0].image).at(0, 0).ofColor("#fff") 27 ); 28 29 } 30 31 @("Only visible chunks are rendered") 32 unittest { 33 34 enum chunkSize = CompositeTexture.maxChunkSize; 35 36 auto content = vscrollable!label( 37 .nullTheme, 38 "One\nTwo\nThree\nFour\nFive\n" 39 ); 40 auto root = sizeLock!testSpace( 41 .sizeLimit(800, 600), 42 .cropViewport, 43 content 44 ); 45 46 // Add a lot more text 47 content.text = content.text.repeat(30).joiner.text; 48 root.draw(); 49 50 const textSize = content.text.size; 51 52 // Make sure assumptions for this test are sound: 53 assert(textSize.y > chunkSize * 2, "Generated text must span at least three chunks"); 54 assert(root.limit.y < chunkSize, "Window size must be smaller than chunk size"); 55 56 // Three chunks, only the first one is drawn and generated 57 assert(content.text.texture.chunks.length >= 3); 58 assert(content.text.texture.chunks[0].isValid); 59 assert(content.text.texture.chunks[1 .. $].all!((ref a) => !a.isValid)); 60 root.drawAndAssert( 61 content.drawsImage(content.text.texture.chunks[0].image).at(0, 0).ofColor("#fff"), 62 content.doesNotDraw(), 63 ); 64 65 // Scroll just enough so that both chunks should be on screen 66 // This should cause the second chunk to generate too 67 content.scroll = chunkSize - 1; 68 root.draw(); 69 assert(content.text.texture.chunks[0 .. 2].all!((ref a) => a.isValid)); 70 assert(content.text.texture.chunks[2 .. $].all!((ref a) => !a.isValid)); 71 72 root.drawAndAssert( 73 content.drawsImage(content.text.texture.chunks[0].image).at(0, -content.scroll).ofColor("#fff"), 74 content.drawsImage(content.text.texture.chunks[1].image).at(0, -content.scroll + chunkSize).ofColor("#fff"), 75 content.doesNotDraw(), 76 ), 77 78 // Skip to third chunk, force regeneration 79 content.scroll = 2 * chunkSize - 1; 80 root.updateSize(); 81 root.draw(); 82 83 // Because of the resize, the first chunk must have been destroyed 84 assert(content.text.texture.chunks[0 .. 1].all!((ref a) => !a.isValid)); 85 assert(content.text.texture.chunks[1 .. 3].all!((ref a) => a.isValid)); 86 assert(content.text.texture.chunks[3 .. $].all!((ref a) => !a.isValid)); 87 88 root.drawAndAssert( 89 content.drawsImage(content.text.texture.chunks[1].image).at(0, -content.scroll + chunkSize).ofColor("#fff"), 90 content.drawsImage(content.text.texture.chunks[2].image).at(0, -content.scroll + chunkSize*2).ofColor("#fff"), 91 content.doesNotDraw(), 92 ); 93 94 }