Improve word wrap measurements

This commit is contained in:
Frank A. Krueger 2018-04-15 21:21:45 -07:00
parent 95b76f3783
commit cfa3078528
No known key found for this signature in database
GPG Key ID: 0471C67474FFE664
3 changed files with 39 additions and 33 deletions

View File

@ -44,7 +44,7 @@ namespace Ooui.Forms.Extensions
return Size.Zero; return Size.Zero;
var fontHeight = fontSize; 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); var isBold = fontAttrs.HasFlag (FontAttributes.Bold);
@ -55,40 +55,40 @@ namespace Ooui.Forms.Extensions
var lines = 1; var lines = 1;
var maxPWidth = 0.0; var maxPWidth = 0.0;
var pwidthConstraint = double.IsPositiveInfinity (widthConstraint) ? double.PositiveInfinity : widthConstraint / fontSize; var pwidthConstraint = double.IsPositiveInfinity (widthConstraint) ? double.PositiveInfinity : widthConstraint / fontSize;
var lastSpaceWidth = -1.0; var firstSpaceX = -1.0;
var lastSpaceIndex = -1;
// Tiny little padding to account for sampling errors var lineStartIndex = 0;
var pwidthHack = 1.0e-6;
var plineHack = 0.333;
var n = text != null ? text.Length : 0; var n = text != null ? text.Length : 0;
for (var i = 0; i < n; i++) { for (var i = 0; i < n; i++) {
var c = (int)text[i]; var c = (int)text[i];
var pw = (c < 128) ? props[c] : avgp; var pw = (c < 128) ? props[c] : avgp;
// Should we wrap? // Should we wrap?
if (px + pw + plineHack > pwidthConstraint) { if (px + pw > pwidthConstraint && lastSpaceIndex > 0) {
lines++; lines++;
if (lastSpaceWidth > 0) { maxPWidth = Math.Max (maxPWidth, firstSpaceX);
maxPWidth = Math.Max (maxPWidth, lastSpaceWidth + pwidthHack); i = lastSpaceIndex;
px = pw - lastSpaceWidth; while (i < n && text[i] == ' ') i++;
lastSpaceWidth = -1; i--;
px = 0;
firstSpaceX = -1;
lastSpaceIndex = -1;
lineStartIndex = i + 1;
} }
else { else {
maxPWidth = Math.Max (maxPWidth, px + pwidthHack);
px = 0;
}
}
if (c == ' ') { if (c == ' ') {
lastSpaceWidth = pw; if (i >= lineStartIndex && text[i-1] != ' ')
firstSpaceX = px;
lastSpaceIndex = i;
} }
px += pw; 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; 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); return new Size (width, height);
} }

View File

@ -392,7 +392,7 @@ namespace Ooui
</head> </head>
<body>"); <body>");
writer.WriteLine (BodyHeaderHtml); 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.WriteLine (initialHtml);
writer.Write (@"</div> writer.Write (@"</div>

View File

@ -24,17 +24,11 @@ namespace Samples
rows.Children.Add (row1); rows.Children.Add (row1);
var row0s = new StackLayout { Orientation = StackOrientation.Horizontal, BackgroundColor = Color.Azure }; 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 = shortText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 200 });
row0s.Children.Add (new Label { Text = mediumText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 100 }); row0s.Children.Add (new Label { Text = mediumText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 200 });
row0s.Children.Add (new Label { Text = longText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 100 }); row0s.Children.Add (new Label { Text = longText, LineBreakMode = LineBreakMode.WordWrap, WidthRequest = 200 });
rows.Children.Add (new ScrollView { Content = row0s }); 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 }; 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 = 8, VerticalOptions = LayoutOptions.Center });
row2.Children.Add (new Entry { Text = shortText, FontSize = 16, 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 }); row6.Children.Add (new TimePicker { VerticalOptions = LayoutOptions.Center });
rows.Children.Add (row6); 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 var page = new ContentPage
{ {
Content = rows Content = rows