Improve word wrap measurements
This commit is contained in:
		
							parent
							
								
									95b76f3783
								
							
						
					
					
						commit
						cfa3078528
					
				| 
						 | 
				
			
			@ -44,7 +44,7 @@ namespace Ooui.Forms.Extensions
 | 
			
		|||
                return Size.Zero;
 | 
			
		||||
 | 
			
		||||
            var fontHeight = fontSize;
 | 
			
		||||
            var lineHeight = fontHeight * 1.4;
 | 
			
		||||
            var lineHeight = (int)(fontSize * 1.42857143); // Floor is intentional -- browsers round down
 | 
			
		||||
 | 
			
		||||
            var isBold = fontAttrs.HasFlag (FontAttributes.Bold);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,40 +55,40 @@ namespace Ooui.Forms.Extensions
 | 
			
		|||
            var lines = 1;
 | 
			
		||||
            var maxPWidth = 0.0;
 | 
			
		||||
            var pwidthConstraint = double.IsPositiveInfinity (widthConstraint) ? double.PositiveInfinity : widthConstraint / fontSize;
 | 
			
		||||
            var lastSpaceWidth = -1.0;
 | 
			
		||||
 | 
			
		||||
            // Tiny little padding to account for sampling errors
 | 
			
		||||
            var pwidthHack = 1.0e-6;
 | 
			
		||||
            var plineHack = 0.333;
 | 
			
		||||
            var firstSpaceX = -1.0;
 | 
			
		||||
            var lastSpaceIndex = -1;
 | 
			
		||||
            var lineStartIndex = 0;
 | 
			
		||||
 | 
			
		||||
            var n = text != null ? text.Length : 0;
 | 
			
		||||
 | 
			
		||||
            for (var i = 0; i < n; i++) {
 | 
			
		||||
                var c = (int)text[i];
 | 
			
		||||
                var pw = (c < 128) ? props[c] : avgp;
 | 
			
		||||
                // Should we wrap?
 | 
			
		||||
                if (px + pw + plineHack > pwidthConstraint) {
 | 
			
		||||
                if (px + pw > pwidthConstraint && lastSpaceIndex > 0) {
 | 
			
		||||
                    lines++;
 | 
			
		||||
                    if (lastSpaceWidth > 0) {
 | 
			
		||||
                        maxPWidth = Math.Max (maxPWidth, lastSpaceWidth + pwidthHack);
 | 
			
		||||
                        px = pw - lastSpaceWidth;
 | 
			
		||||
                        lastSpaceWidth = -1;
 | 
			
		||||
                    maxPWidth = Math.Max (maxPWidth, firstSpaceX);
 | 
			
		||||
                    i = lastSpaceIndex;
 | 
			
		||||
                    while (i < n && text[i] == ' ') i++;
 | 
			
		||||
                    i--;
 | 
			
		||||
                    px = 0;
 | 
			
		||||
                    firstSpaceX = -1;
 | 
			
		||||
                    lastSpaceIndex = -1;
 | 
			
		||||
                    lineStartIndex = i + 1;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                        maxPWidth = Math.Max (maxPWidth, px + pwidthHack);
 | 
			
		||||
                        px = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                    if (c == ' ') {
 | 
			
		||||
                    lastSpaceWidth = pw;
 | 
			
		||||
                        if (i >= lineStartIndex && text[i-1] != ' ')
 | 
			
		||||
                            firstSpaceX = px;
 | 
			
		||||
                        lastSpaceIndex = i;
 | 
			
		||||
                    }
 | 
			
		||||
                    px += pw;
 | 
			
		||||
                }
 | 
			
		||||
            maxPWidth = Math.Max (maxPWidth, px + pwidthHack);
 | 
			
		||||
            var width = fontSize * maxPWidth;
 | 
			
		||||
            }
 | 
			
		||||
            maxPWidth = Math.Max (maxPWidth, px);
 | 
			
		||||
            var width = (int)Math.Ceiling (fontSize * maxPWidth);
 | 
			
		||||
            var height = lines * lineHeight;
 | 
			
		||||
 | 
			
		||||
            // Console.WriteLine ($"MEASURE TEXT SIZE {widthConstraint}x{heightConstraint} \"{text}\" == {width}x{height}");
 | 
			
		||||
            //Console.WriteLine ($"MEASURE TEXT SIZE {widthConstraint}x{heightConstraint} ==> {width}x{height} \"{text}\"");
 | 
			
		||||
 | 
			
		||||
            return new Size (width, height);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -392,7 +392,7 @@ namespace Ooui
 | 
			
		|||
</head>
 | 
			
		||||
<body>");
 | 
			
		||||
            writer.WriteLine (BodyHeaderHtml);
 | 
			
		||||
            writer.WriteLine (@"<div id=""ooui-body"" class=""container-fluid"">");
 | 
			
		||||
            writer.WriteLine (@"<div id=""ooui-body"" class=""container-fluid"" style=""padding:0;margin:0"">");
 | 
			
		||||
            writer.WriteLine (initialHtml);
 | 
			
		||||
            writer.Write (@"</div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,17 +24,11 @@ namespace Samples
 | 
			
		|||
            rows.Children.Add (row1);
 | 
			
		||||
 | 
			
		||||
            var row0s = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = Color.Azure };
 | 
			
		||||
            row0s.Children.Add (new Label { Text = shortText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 100 });
 | 
			
		||||
            row0s.Children.Add (new Label { Text = mediumText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 100 });
 | 
			
		||||
            row0s.Children.Add (new Label { Text = longText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 100 });
 | 
			
		||||
            row0s.Children.Add (new Label { Text = shortText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 200 });
 | 
			
		||||
            row0s.Children.Add (new Label { Text = mediumText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 200 });
 | 
			
		||||
            row0s.Children.Add (new Label { Text = longText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 200 });
 | 
			
		||||
            rows.Children.Add (new ScrollView { Content = row0s });
 | 
			
		||||
 | 
			
		||||
            var row1s = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = Color.GhostWhite };
 | 
			
		||||
            row1s.Children.Add (new Label { Text = shortText, FontAttributes = FontAttributes.Bold, WidthRequest = 100, HorizontalOptions = LayoutOptions.Start });
 | 
			
		||||
            row1s.Children.Add (new Label { Text = mediumText, FontAttributes = FontAttributes.Bold, WidthRequest = 100, HorizontalOptions = LayoutOptions.FillAndExpand });
 | 
			
		||||
            row1s.Children.Add (new Label { Text = longText, FontAttributes = FontAttributes.Bold, WidthRequest = 100, HorizontalOptions = LayoutOptions.End });
 | 
			
		||||
            rows.Children.Add (new ScrollView { Content = row1s });
 | 
			
		||||
 | 
			
		||||
            var row2 = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = Color.Azure };
 | 
			
		||||
            row2.Children.Add (new Entry { Text = shortText, FontSize = 8, VerticalOptions = LayoutOptions.Center });
 | 
			
		||||
            row2.Children.Add (new Entry { Text = shortText, FontSize = 16, VerticalOptions = LayoutOptions.Center });
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +60,18 @@ namespace Samples
 | 
			
		|||
            row6.Children.Add (new TimePicker { VerticalOptions = LayoutOptions.Center });
 | 
			
		||||
            rows.Children.Add (row6);
 | 
			
		||||
 | 
			
		||||
            var row7 = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = Color.Azure };
 | 
			
		||||
            row7.Children.Add (new Label { Text = shortText, FontSize = 32, LineBreakMode = LineBreakMode.WordWrap });
 | 
			
		||||
            row7.Children.Add (new Label { Text = mediumText, FontSize = 16, LineBreakMode = LineBreakMode.WordWrap });
 | 
			
		||||
            row7.Children.Add (new Label { Text = longText, FontSize = 8, LineBreakMode = LineBreakMode.WordWrap });
 | 
			
		||||
            rows.Children.Add (row7);
 | 
			
		||||
 | 
			
		||||
            var row8 = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = Color.GhostWhite };
 | 
			
		||||
            row8.Children.Add (new Label { Text = shortText, FontSize = 32, FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Start });
 | 
			
		||||
            row8.Children.Add (new Label { Text = mediumText, FontSize = 16, FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.FillAndExpand });
 | 
			
		||||
            row8.Children.Add (new Label { Text = longText, FontSize = 8, FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.End });
 | 
			
		||||
            rows.Children.Add (row8);
 | 
			
		||||
 | 
			
		||||
            var page = new ContentPage
 | 
			
		||||
            {
 | 
			
		||||
                Content = rows
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue