From 429a98964859b83016f2eb47a47a08ab8dc3c57e Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 22 Jun 2019 15:03:54 +0100 Subject: Add support for 9-sliced backgrounds (#8600) 9-slice textures are commonly used in GUIs to allow scaling them to match any resolution without distortion. https://en.wikipedia.org/wiki/9-slice_scaling --- src/client/guiscalingfilter.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ src/client/guiscalingfilter.h | 6 +++++ 2 files changed, 65 insertions(+) (limited to 'src/client') diff --git a/src/client/guiscalingfilter.cpp b/src/client/guiscalingfilter.cpp index 312f93939..3490c47e8 100644 --- a/src/client/guiscalingfilter.cpp +++ b/src/client/guiscalingfilter.cpp @@ -167,3 +167,62 @@ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, driver->draw2DImage(scaled, destrect, mysrcrect, cliprect, colors, usealpha); } + +void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture, + const core::rect &rect, const core::rect &middle) +{ + const video::SColor color(255,255,255,255); + const video::SColor colors[] = {color,color,color,color}; + + auto originalSize = texture->getOriginalSize(); + core::vector2di lowerRightOffset = core::vector2di(originalSize.Width, originalSize.Height) - middle.LowerRightCorner; + + for (int y = 0; y < 3; ++y) { + for (int x = 0; x < 3; ++x) { + core::rect src({0, 0}, originalSize); + core::rect dest = rect; + + switch (x) { + case 0: + dest.LowerRightCorner.X = rect.UpperLeftCorner.X + middle.UpperLeftCorner.X; + src.LowerRightCorner.X = middle.UpperLeftCorner.X; + break; + + case 1: + dest.UpperLeftCorner.X += middle.UpperLeftCorner.X; + dest.LowerRightCorner.X -= lowerRightOffset.X; + src.UpperLeftCorner.X = middle.UpperLeftCorner.X; + src.LowerRightCorner.X = middle.LowerRightCorner.X; + break; + + case 2: + dest.UpperLeftCorner.X = rect.LowerRightCorner.X - lowerRightOffset.X; + src.UpperLeftCorner.X = middle.LowerRightCorner.X; + break; + } + + switch (y) { + case 0: + dest.LowerRightCorner.Y = rect.UpperLeftCorner.Y + middle.UpperLeftCorner.Y; + src.LowerRightCorner.Y = middle.UpperLeftCorner.Y; + break; + + case 1: + dest.UpperLeftCorner.Y += middle.UpperLeftCorner.Y; + dest.LowerRightCorner.Y -= lowerRightOffset.Y; + src.UpperLeftCorner.Y = middle.UpperLeftCorner.Y; + src.LowerRightCorner.Y = middle.LowerRightCorner.Y; + break; + + case 2: + dest.UpperLeftCorner.Y = rect.LowerRightCorner.Y - lowerRightOffset.Y; + src.UpperLeftCorner.Y = middle.LowerRightCorner.Y; + break; + } + + draw2DImageFilterScaled(driver, texture, dest, + src, + NULL/*&AbsoluteClippingRect*/, colors, true); + } + } +} diff --git a/src/client/guiscalingfilter.h b/src/client/guiscalingfilter.h index a5cd78511..181009551 100644 --- a/src/client/guiscalingfilter.h +++ b/src/client/guiscalingfilter.h @@ -48,3 +48,9 @@ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, const core::rect &destrect, const core::rect &srcrect, const core::rect *cliprect = 0, const video::SColor *const colors = 0, bool usealpha = false); + +/* + * 9-slice / segment drawing + */ +void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture, + const core::rect &rect, const core::rect &middle); -- cgit v1.2.3