From 31083e058e7bf79504d01de9d5486d7ca478a1f6 Mon Sep 17 00:00:00 2001 From: Lluis Sanchez Date: Mon, 2 Dec 2013 10:16:17 +0100 Subject: [PATCH] Fixed rendering of 9-patch images in retina resolution --- Testing/GtkTestRunner.csproj | 12 ++ Testing/MacTestRunner.csproj | 12 ++ Testing/Tests/DrawingTestsBase.cs | 4 +- Testing/Tests/NinePatchTests.cs | 161 +++++++++++++++++++++++ Testing/Tests/ReferenceImageManager.cs | 21 +-- Testing/Tests/ninep-ss.9@2x.png | Bin 0 -> 2239 bytes Testing/Tests/ninep-st.9@2x.png | Bin 0 -> 2243 bytes Testing/Tests/ninep-ts.9@2x.png | Bin 0 -> 2242 bytes Testing/Tests/ninep-tt.9@2x.png | Bin 0 -> 2247 bytes Xwt.Gtk/Xwt.GtkBackend/ImageHandler.cs | 3 +- Xwt.Mac/Xwt.Mac/ContextBackendHandler.cs | 4 +- Xwt.Mac/Xwt.Mac/ImageHandler.cs | 14 +- Xwt/Xwt.Drawing/Image.cs | 4 +- Xwt/Xwt.Drawing/NinePatchImage.cs | 30 ++--- 14 files changed, 229 insertions(+), 36 deletions(-) create mode 100644 Testing/Tests/ninep-ss.9@2x.png create mode 100644 Testing/Tests/ninep-st.9@2x.png create mode 100644 Testing/Tests/ninep-ts.9@2x.png create mode 100644 Testing/Tests/ninep-tt.9@2x.png diff --git a/Testing/GtkTestRunner.csproj b/Testing/GtkTestRunner.csproj index dfaf3fea..864fac51 100644 --- a/Testing/GtkTestRunner.csproj +++ b/Testing/GtkTestRunner.csproj @@ -143,5 +143,17 @@ ninep-tt.9.png + + ninep-ss.9@2x.png + + + ninep-st.9@2x.png + + + ninep-ts.9@2x.png + + + ninep-tt.9@2x.png + \ No newline at end of file diff --git a/Testing/MacTestRunner.csproj b/Testing/MacTestRunner.csproj index 587d5812..1039b3da 100644 --- a/Testing/MacTestRunner.csproj +++ b/Testing/MacTestRunner.csproj @@ -270,5 +270,17 @@ ninep-tt.9.png + + ninep-ss.9@2x.png + + + ninep-st.9@2x.png + + + ninep-ts.9@2x.png + + + ninep-tt.9@2x.png + \ No newline at end of file diff --git a/Testing/Tests/DrawingTestsBase.cs b/Testing/Tests/DrawingTestsBase.cs index 959014d0..98bf0fcb 100644 --- a/Testing/Tests/DrawingTestsBase.cs +++ b/Testing/Tests/DrawingTestsBase.cs @@ -52,11 +52,11 @@ namespace Xwt context.SetLineWidth (1); } - protected void CheckImage (string refImageName) + protected void CheckImage (string refImageName, double scaleFactor = 1) { if (builder == null) return; - var img = builder.ToBitmap (); + var img = builder.ToBitmap (scaleFactor); builder.Dispose (); builder = null; diff --git a/Testing/Tests/NinePatchTests.cs b/Testing/Tests/NinePatchTests.cs index d3d17122..5f20a6d8 100644 --- a/Testing/Tests/NinePatchTests.cs +++ b/Testing/Tests/NinePatchTests.cs @@ -189,6 +189,167 @@ namespace Xwt context.DrawImage (np, 0, 0); CheckImage ("NinePatchTileTileHigher.png"); } + + // 2x scale factor + + [Test] + public void NinePatchStretchStretchDefaultSize2x () + { + var np = Image.FromResource ("ninep-ss.9.png"); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchStretchDefaultSize2x.png", 2); + } + + [Test] + public void NinePatchStretchStretchWiderHigher2x () + { + var np = Image.FromResource ("ninep-ss.9.png"); + np = np.WithSize (np.Width * 3, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchStretchWiderHigher2x.png", 2); + } + + [Test] + public void NinePatchStretchStretchWider2x () + { + var np = Image.FromResource ("ninep-ss.9.png"); + np = np.WithSize (np.Width * 3, np.Height); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchStretchWider2x.png", 2); + } + + [Test] + public void NinePatchStretchStretchHigher2x () + { + var np = Image.FromResource ("ninep-ss.9.png"); + np = np.WithSize (np.Width, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchStretchHigher2x.png", 2); + } + + + [Test] + public void NinePatchStretchTileDefaultSize2x () + { + var np = Image.FromResource ("ninep-st.9.png"); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchTileDefaultSize2x.png", 2); + } + + [Test] + public void NinePatchStretchTileWiderHigher2x () + { + var np = Image.FromResource ("ninep-st.9.png"); + np = np.WithSize (np.Width * 3, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchTileWiderHigher2x.png", 2); + } + + [Test] + public void NinePatchStretchTileWider2x () + { + var np = Image.FromResource ("ninep-st.9.png"); + np = np.WithSize (np.Width * 3, np.Height); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchTileWider2x.png", 2); + } + + [Test] + public void NinePatchStretchTileHigher2x () + { + var np = Image.FromResource ("ninep-st.9.png"); + np = np.WithSize (np.Width, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchStretchTileHigher2x.png", 2); + } + + + [Test] + public void NinePatchTileStretchDefaultSize2x () + { + var np = Image.FromResource ("ninep-ts.9.png"); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileStretchDefaultSize2x.png", 2); + } + + [Test] + public void NinePatchTileStretchWiderHigher2x () + { + var np = Image.FromResource ("ninep-ts.9.png"); + np = np.WithSize (np.Width * 3, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileStretchWiderHigher2x.png", 2); + } + + [Test] + public void NinePatchTileStretchWider2x () + { + var np = Image.FromResource ("ninep-ts.9.png"); + np = np.WithSize (np.Width * 3, np.Height); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileStretchWider2x.png", 2); + } + + [Test] + public void NinePatchTileStretchHigher2x () + { + var np = Image.FromResource ("ninep-ts.9.png"); + np = np.WithSize (np.Width, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileStretchHigher2x.png", 2); + } + + + [Test] + public void NinePatchTileTileDefaultSize2x () + { + var np = Image.FromResource ("ninep-tt.9.png"); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileTileDefaultSize2x.png", 2); + } + + [Test] + public void NinePatchTileTileWiderHigher2x () + { + var np = Image.FromResource ("ninep-tt.9.png"); + np = np.WithSize (np.Width * 3, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileTileWiderHigher2x.png", 2); + } + + [Test] + public void NinePatchTileTileWider2x () + { + var np = Image.FromResource ("ninep-tt.9.png"); + np = np.WithSize (np.Width * 3, np.Height); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileTileWider2x.png", 2); + } + + [Test] + public void NinePatchTileTileHigher2x () + { + var np = Image.FromResource ("ninep-tt.9.png"); + np = np.WithSize (np.Width, np.Height * 3); + InitBlank ((int)np.Width, (int)np.Height); + context.DrawImage (np, 0, 0); + CheckImage ("NinePatchTileTileHigher2x.png", 2); + } } } diff --git a/Testing/Tests/ReferenceImageManager.cs b/Testing/Tests/ReferenceImageManager.cs index 548880d4..d17c05db 100644 --- a/Testing/Tests/ReferenceImageManager.cs +++ b/Testing/Tests/ReferenceImageManager.cs @@ -99,8 +99,9 @@ namespace Xwt return null; } - public static void CheckImage (string refImageName, Image img) + public static void CheckImage (string refImageName, Image im) { + BitmapImage img = im as BitmapImage ?? im.ToBitmap (); Image coreRefImage = LoadReferenceImage (refImageName); Image refImage = !RecheckAll ? LoadCustomReferenceImage (refImageName) : null; @@ -109,8 +110,8 @@ namespace Xwt if (refImage == null) { ImageFailures.Add (new FailedImageInfo () { - TestImage = img, - ReferenceImage = img, + TestImage = img.WithSize (img.PixelWidth, img.PixelHeight), + ReferenceImage = img.WithSize (img.PixelWidth, img.PixelHeight), Name = refImageName, TargetDir = ProjectReferenceImageDir }); @@ -135,8 +136,8 @@ namespace Xwt if (!knownFailure) { ImageFailures.Add (new FailedImageInfo () { - TestImage = img, - ReferenceImage = refImage, + TestImage = img.WithSize (img.PixelWidth, img.PixelHeight), + ReferenceImage = refImage.WithSize (img.PixelWidth, img.PixelHeight), DiffImage = diff, Name = refImageName, TargetDir = ProjectCustomReferenceImageDir @@ -149,13 +150,13 @@ namespace Xwt public static Image DiffImages (Image img1, Image img2) { bool foundDifference = false; - var bmp1 = img1.ToBitmap (); - var bmp2 = img2.ToBitmap (); - var res = new ImageBuilder ((int)Math.Min (bmp1.Size.Width, bmp2.Size.Width), (int) Math.Min (bmp1.Size.Height, bmp2.Size.Height)); + var bmp1 = (img1 as BitmapImage) ?? img1.ToBitmap (); + var bmp2 = (img2 as BitmapImage) ?? img2.ToBitmap (); + var res = new ImageBuilder ((int)Math.Min (bmp1.PixelWidth, bmp2.PixelWidth), (int) Math.Min (bmp1.PixelHeight, bmp2.PixelHeight)); var bmpr = res.ToBitmap (); res.Dispose (); - for (int y=0; yKLZ*U+@Om_!p#rO2g^M0T2_xn8WlYz|VRo{2h z7R-8~s+989_{5}@xj~v|SVK2!s&?S#%H<(|s_(lza_;?13gFuImGA%atf|SshSU>4 zvliI1kU9psYx^n$;})>zXy}KKc^2qW;}esR$pT&VC@uh9Q&Bt)bg9uwKV)3Mv>VkL zWafdMsYJe>h$9aGbd{thm1A3#Qr;@7=CtF=gx$wn|Iah)wwCoa0c(Sqkwd^%NF8ga zfl3^IVpoeJz>AQ&?1%XZuo+T+v}VR~z&1!fHLVVeMfmiqCmN$~0_z}MbHc&VIDf*M z8a^D=rq9eY4^?8!WjpAf1fGZV&4wHtiu`EQWT6Q3fVQd88i@I|gTdTLahc~tqklN! z(bPNDgJqx_wD(oBayas=osn*-67g#n{jeN+&=x&+cqrl&rVNTB%lWV|IuO;0-Ju$d zYsKWWb6_yW&--q9DDo!Gs#awz#$2tcVkzPge@kyH=F~UTs)a+q4$${=BvnPyWD1Fm z$9*g+l*nV@qi8aXgG&jCheY9|o@54R6KaTg@e5cCQ`T^W13>U$ckMe zEB1;Zu}|y~eOTf(@w(VA3L-1|#NKvoIiYV+=XRUtU0O&iDjXqyy1TWtqjyrh?bugN z-Fcw8`G{w^>?b(^0%qFC?aBTx&40I{!*N}ld+XZTOY};n7Us9#EY2PIq^1>?^14$oGct4Rf-m zlg<8;{WE(#`)T%U_V9}@3pVBZ?qq=wDZ~p?Fa3m_NDf1;;mNSkM`S> zOLQyoR-CoOHS^|1^98eDK4-pU4t4m<^=7X*U~VxB=EnBBCH0cMI85NSr@FFMgd4-d z;V2SCKou8{;}7kBTrD<q>F#F8d82|_GL@vxqnSVL6k7-t-v_wAv+VzNoMWwIo3d`=F& z@8J94`+j*|--qCG#c{PFSNcL#RXvGB;saThKLN1BIiDkh%o9QsTtjirb10eEcN_9IQx{&WOreSO_KGc&U( zNzw)(Bme-4qF{D*7LiBuNPBOQ`Ztkuh&Dj+l6VGXfzr)Iy!=`>!P|&Y}?*G zK0e;s+1cs-Z$O%+-H~PadqT*&01%Bv5s$|a30Bog_FQo0lhg^*6CAfxL}0DyQr4!26Iopb&`RaMUrP$H4IM+i|A zMY-`l$BBZ$AQVLbAw)?e68DCHBuQEoX3*^t3xd zK!Sl_LI)?@c>wTwy{-o&7zidZ04@xn(^Glp?G;D!KY!zENAsUNdCxH*!GKa4e91{q zbdJ-WAeaDhq)R=jJMAIgy!gW5FL*wwpve}S0J?cSh%m-pAj5&V9)9D+ki+ z^@LGu0|?TADLMpzZnx|DiV+M16FT_+;}8H$({w!`!9Xw(fPM%5xe9T+1Ovf@0)TDX zPXP=s)7&hIP%f9Ban5yJ*U@gbT??n(ZbR2~aL)B|x%_MhD4)+;gplt5pi-&0 z7SPDrABzOY&=-tJUfjW2|5p28zWZ7-M4(hcSj?u?WL3z!)o3tJSRwj~cmL z&NK|;KIiSo4H2i-5*!7&fy*=oA9BuD0W1+h<_A&WYa0U|M1T)pYYZ4y9}s_Cdgc269sraX95T>ThkyV8 N002ovPDHLkV1hXKH;MoN literal 0 HcmV?d00001 diff --git a/Testing/Tests/ninep-st.9@2x.png b/Testing/Tests/ninep-st.9@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..aacb21a67e84c5d058ebfe8382823b7fb8b741e0 GIT binary patch literal 2243 zcmV;!2t4KLZ*U+@Om_!p#rO2g^M0T2_xn8WlYz|VRo{2h z7R-8~s+989_{5}@xj~v|SVK2!s&?S#%H<(|s_(lza_;?13gFuImGA%atf|SshSU>4 zvliI1kU9psYx^n$;})>zXy}KKc^2qW;}esR$pT&VC@uh9Q&Bt)bg9uwKV)3Mv>VkL zWafdMsYJe>h$9aGbd{thm1A3#Qr;@7=CtF=gx$wn|Iah)wwCoa0c(Sqkwd^%NF8ga zfl3^IVpoeJz>AQ&?1%XZuo+T+v}VR~z&1!fHLVVeMfmiqCmN$~0_z}MbHc&VIDf*M z8a^D=rq9eY4^?8!WjpAf1fGZV&4wHtiu`EQWT6Q3fVQd88i@I|gTdTLahc~tqklN! z(bPNDgJqx_wD(oBayas=osn*-67g#n{jeN+&=x&+cqrl&rVNTB%lWV|IuO;0-Ju$d zYsKWWb6_yW&--q9DDo!Gs#awz#$2tcVkzPge@kyH=F~UTs)a+q4$${=BvnPyWD1Fm z$9*g+l*nV@qi8aXgG&jCheY9|o@54R6KaTg@e5cCQ`T^W13>U$ckMe zEB1;Zu}|y~eOTf(@w(VA3L-1|#NKvoIiYV+=XRUtU0O&iDjXqyy1TWtqjyrh?bugN z-Fcw8`G{w^>?b(^0%qFC?aBTx&40I{!*N}ld+XZTOY};n7Us9#EY2PIq^1>?^14$oGct4Rf-m zlg<8;{WE(#`)T%U_V9}@3pVBZ?qq=wDZ~p?Fa3m_NDf1;;mNSkM`S> zOLQyoR-CoOHS^|1^98eDK4-pU4t4m<^=7X*U~VxB=EnBBCH0cMI85NSr@FFMgd4-d z;V2SCKou8{;}7kBTrD<q>F#F8dypoX|f76SGljZjmhSV{@)9$QGehq-K__yIswRZLG$BODIH=kvkq^LsZwX zZQEN%M@O66+uNQ04M^AZJF+bQNC2zgyj5PePva;d}hr_>6N*98`AX2Fm zWLd_jN|GeZ&CQ`!tHCtQ+p;WwI6puC{odYQPmH0%6Qa@R2BkEmC<>CvBq*gAbx}%@ zOeUcy3Mi$iXf(QU;(PI7eSLj~Qo05Ji9}*#x7AtlcsxiX5(3!T`uh5euu=m+e!u@A zA>>vh5*fLM{3Z&8LWo2nAcWlV`~443RFI}=9?tm#0Eoq6aI3`HIp+^FP4f%@#pCgN zgb-C#)f?|~oG1_oKvh)`LezLXes2IslB8u}2Hh^fKro>IKnQtT>_fLpFc3@xpjiO$ z`FySiBp3)Lw12{#1pu$t>v}+ffnXv7;KC3(J(aiKU2-)4%eTIDH2=wy4;%v$3@D|6 zSDf@%XE^OKf-xXRy3nJ#(;o8Oi?1C1g6HE38gH>Npqtl&2xH8klm@!pt|Kqx+=o2B zav=iDe3i_Zptve~Rf2>Ag3 zN~Mx(0S&GFu}FXne9-an@i(0FR<&AnWiP7N>!?<%;GDNwt=6MgjAA;St}w>70H9DP zz_KjYz_Ba~g+f92pRM8R=Mzr4TrO`i#&Yd;8~J=5jIoi2!x%$8pGUjh24gH&E|)jY zJ!)h!8MEDP-{+j~HyRD(a=DSNB+Igp%jM8$G{6}9%eL*$Gnve=86?u_Njp0`&84NK zUn!-_rfJ@;R4SO9oP?q%BiD0wcXweJhJf>_uIn#OkNeL6l_W_&QA$(5I6!r##u2=6 zh|^h!^RzTg^DHhde#|*v2CzT~ne9h`uWbyt9|1nN)EF?XI3RwBdhPmO4gj-S9Wt6} RUnBqk002ovPDHLkV1h2*LYe>o literal 0 HcmV?d00001 diff --git a/Testing/Tests/ninep-ts.9@2x.png b/Testing/Tests/ninep-ts.9@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a27a4dc0f310cdba4aae905802ab2184c23556c0 GIT binary patch literal 2242 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 V9y_pQOECZd002ovPDHLkV1iiII#2)r literal 0 HcmV?d00001 diff --git a/Xwt.Gtk/Xwt.GtkBackend/ImageHandler.cs b/Xwt.Gtk/Xwt.GtkBackend/ImageHandler.cs index 1847da6f..26c4e869 100644 --- a/Xwt.Gtk/Xwt.GtkBackend/ImageHandler.cs +++ b/Xwt.Gtk/Xwt.GtkBackend/ImageHandler.cs @@ -344,8 +344,9 @@ namespace Xwt.GtkBackend using (var ctx = new Cairo.Context (sf)) { ImageDescription idesc = new ImageDescription () { Alpha = 1, - Size = new Size (width * scaleFactor, height * scaleFactor) + Size = new Size (width, height) }; + ctx.Scale (scaleFactor, scaleFactor); Draw (actx, ctx, scaleFactor, 0, 0, idesc); var f = new ImageFrame (ImageBuilderBackend.CreatePixbuf (sf), Math.Max((int)width,1), Math.Max((int)height,1), true); AddFrame (f); diff --git a/Xwt.Mac/Xwt.Mac/ContextBackendHandler.cs b/Xwt.Mac/Xwt.Mac/ContextBackendHandler.cs index 850801e1..5e3991c1 100644 --- a/Xwt.Mac/Xwt.Mac/ContextBackendHandler.cs +++ b/Xwt.Mac/Xwt.Mac/ContextBackendHandler.cs @@ -43,6 +43,7 @@ namespace Xwt.Mac public CGAffineTransform? InverseViewTransform; public Stack StatusStack = new Stack (); public ContextStatus CurrentStatus = new ContextStatus (); + public double ScaleFactor = 1; } class ContextStatus @@ -56,7 +57,8 @@ namespace Xwt.Mac public override double GetScaleFactor (object backend) { - return 1; + var ct = (CGContextBackend) backend; + return ct.ScaleFactor; } public override void Save (object backend) diff --git a/Xwt.Mac/Xwt.Mac/ImageHandler.cs b/Xwt.Mac/Xwt.Mac/ImageHandler.cs index a9498ab7..6673ac4b 100644 --- a/Xwt.Mac/Xwt.Mac/ImageHandler.cs +++ b/Xwt.Mac/Xwt.Mac/ImageHandler.cs @@ -129,12 +129,13 @@ namespace Xwt.Mac var bmp = new CGBitmapContext (IntPtr.Zero, pixelWidth, pixelHeight, 8, bytesPerRow, Util.DeviceRGBColorSpace, flags); bmp.TranslateCTM (0, pixelHeight); - bmp.ScaleCTM (1, -1); + bmp.ScaleCTM ((float)scaleFactor, (float)-scaleFactor); var ctx = new CGContextBackend { Context = bmp, - Size = new SizeF (pixelWidth, pixelHeight), - InverseViewTransform = bmp.GetCTM ().Invert () + Size = new SizeF ((float)width, (float)height), + InverseViewTransform = bmp.GetCTM ().Invert (), + ScaleFactor = scaleFactor }; var ci = (CustomImage)handle; @@ -146,6 +147,7 @@ namespace Xwt.Mac var im = new NSImage (); im.AddRepresentation (imageRep); im.Size = new SizeF ((float)width, (float)height); + bmp.Dispose (); return im; } else { @@ -192,7 +194,11 @@ namespace Xwt.Mac public override Size GetSize (object handle) { NSImage img = (NSImage)handle; - return new Size ((int)img.Size.Width, (int)img.Size.Height); + NSBitmapImageRep bitmap = img.Representations ().OfType ().FirstOrDefault (); + if (bitmap != null) + return new Size (bitmap.PixelsWide, bitmap.PixelsHigh); + else + return new Size ((int)img.Size.Width, (int)img.Size.Height); } public override object CopyBitmap (object handle) diff --git a/Xwt/Xwt.Drawing/Image.cs b/Xwt/Xwt.Drawing/Image.cs index f9177c26..240aa497 100644 --- a/Xwt/Xwt.Drawing/Image.cs +++ b/Xwt/Xwt.Drawing/Image.cs @@ -252,8 +252,8 @@ namespace Xwt.Drawing if (i == -1) scaleFactor = 1; else { - int j = fi.Item1.IndexOf ('.', ++i); - if (!double.TryParse (fi.Item1.Substring (i + 1, j - i), out scaleFactor)) { + int j = fi.Item1.IndexOf ('x', ++i); + if (!double.TryParse (fi.Item1.Substring (i, j - i), out scaleFactor)) { toolkit.ImageBackendHandler.Dispose (fi.Item2); continue; } diff --git a/Xwt/Xwt.Drawing/NinePatchImage.cs b/Xwt/Xwt.Drawing/NinePatchImage.cs index 5d5914f7..7f15a264 100644 --- a/Xwt/Xwt.Drawing/NinePatchImage.cs +++ b/Xwt/Xwt.Drawing/NinePatchImage.cs @@ -138,8 +138,8 @@ namespace Xwt.Drawing var frame = GetFrame (ctx.ScaleFactor); var fixedWidth = frame.Bitmap.Width - 2 - frame.StretchableWidth; var fixedHeight = frame.Bitmap.Height - 2 - frame.StretchableHeight; - double totalVariableWidth = bounds.Width - fixedWidth; - double totalVariableHeight = bounds.Height - fixedHeight; + double totalVariableWidth = bounds.Width - fixedWidth / frame.ScaleFactor; + double totalVariableHeight = bounds.Height - fixedHeight / frame.ScaleFactor; double remainingVariableHeight = totalVariableHeight; double y = bounds.Y, yb = 1; @@ -173,34 +173,30 @@ namespace Xwt.Drawing var t = GetTile (frame, tileIndex, sourceRegion); ctx.DrawImage (t, targetRegion); } else { - double scaleX = 1; - double scaleY = 1; + double pw = hs.Size / frame.ScaleFactor; + double ph = vs.Size / frame.ScaleFactor; if (hs.Mode == RenderMode.Stretch) { - scaleX = sw / hs.Size; - targetRegion.Width = hs.Size; + pw = targetRegion.Width; } if (vs.Mode == RenderMode.Stretch) { - scaleY = sh / vs.Size; - targetRegion.Height = vs.Size; + ph = targetRegion.Height; } ctx.Save (); ctx.Translate (targetRegion.Location); - if (scaleX != 1 || scaleY != 1) - ctx.Scale (scaleX, scaleY); targetRegion.Location = Point.Zero; - ctx.Pattern = new ImagePattern (GetTile (frame, tileIndex, sourceRegion)); + ctx.Pattern = new ImagePattern (GetTile (frame, tileIndex, sourceRegion).WithSize (pw, ph)); ctx.NewPath (); ctx.Rectangle (targetRegion); ctx.Fill (); ctx.Restore (); } - x += sw / frame.ScaleFactor; + x += sw; xb += hs.Size; tileIndex++; } yb += vs.Size; - y += sh / frame.ScaleFactor; + y += sh; } ctx.Restore (); } @@ -215,7 +211,7 @@ namespace Xwt.Drawing return sw; } else { - return sec.Size; + return sec.Size / frame.ScaleFactor; } } @@ -234,8 +230,10 @@ namespace Xwt.Drawing protected sealed override Size GetDefaultSize () { - var frame = frames [0]; - return new Size (frame.Bitmap.Width - 2, frame.Bitmap.Height - 2); + var frame = GetFrame (1); + if (frame == null) + frame = frames [0]; + return new Size ((frame.Bitmap.Width - 2) / frame.ScaleFactor, (frame.Bitmap.Height - 2) / frame.ScaleFactor); } public WidgetSpacing Padding { get; private set; }