public override SpecificLayout GetBestLayout(LayoutQuery query) { if (query.MaxWidth <= 0 || query.MaxHeight <= 0) { double width = 0; double height = 0; if (this.ComputeScore(width, height).CompareTo(query.MinScore) < 0) { return(null); } return(this.MakeLayout(width, height, query)); } LayoutScore score = this.ComputeScore(query.MaxWidth, query.MaxHeight); if (score.CompareTo(query.MinScore) < 0) { return(null); } double ratio = query.MinScore.DividedBy(score); if (query.MinimizesWidth()) { double width = Math.Ceiling(query.MaxWidth * ratio / this.pixelSize) * this.pixelSize; if (this.ComputeScore(width, query.MaxHeight).CompareTo(query.MinScore) < 0) { // the score has some additional components that the division didn't catch, so we have to add another pixel width += this.pixelSize; } if (width > query.MaxWidth) { // We had to round up past the max height, so there is no solution return(null); } return(this.MakeLayout(width, query.MaxHeight, query)); } if (query.MinimizesHeight()) { double height = Math.Ceiling(query.MaxHeight * ratio / this.pixelSize) * this.pixelSize; if (this.ComputeScore(query.MaxWidth, height).CompareTo(query.MinScore) < 0) { // the score has some additional components that the division didn't catch, so we have to add another pixel height += this.pixelSize; } if (height > query.MaxHeight) { // We had to round up past the max height, so there is no solution return(null); } return(this.MakeLayout(query.MaxWidth, height, query)); } return(MakeLayout(query.MaxWidth, query.MaxHeight, query)); }
public override SpecificLayout GetBestLayout(LayoutQuery query) { if (this.font != query.LayoutDefaults.TextBox_Defaults.Font) { // invalidate size cache if the font name or font scale is changing this.font = query.LayoutDefaults.TextBox_Defaults.Font; this.layoutsByWidth = new Dictionary <double, FormattedParagraph>(); } // don't bother doing the layout if the required score is too high if (query.MinScore.CompareTo(this.BestPossibleScore) > 0) { return(null); } TextLayout.NumMeasures++; if (TextLayout.NumMeasures % 80 == 0) { System.Diagnostics.Debug.WriteLine("num text measurements = " + TextLayout.NumMeasures); } DateTime startTime = DateTime.Now; this.TextItem_Text = this.TextItem_Configurer.ModelledText; //ErrorReporter.ReportParadox("avg num computations per query = " + (double)numComputations / (double)numQueries); numQueries++; SpecificLayout result; if (query.MinimizesWidth()) { result = this.Get_MinWidth_Layout(query); } else { if (query.MinimizesHeight()) { result = this.Get_MinHeight_Layout(query); } else { result = this.Get_MaxScoring_Layout(query); } } DateTime endTime = DateTime.Now; TextLayout.TextTime += endTime.Subtract(startTime); return(result); }
public bool SameType(LayoutQuery other) { if (this.MinimizesWidth() != other.MinimizesWidth()) { return(false); } if (this.MinimizesHeight() != other.MinimizesHeight()) { return(false); } if (this.MaximizesScore() != other.MaximizesScore()) { return(false); } return(true); }
public override SpecificLayout GetBestLayout(LayoutQuery query) { // don't bother doing the layout if the required score is too high if (query.MinScore.CompareTo(this.BestPossibleScore) > 0) { return(null); } TextLayout.NumMeasures++; if (TextLayout.NumMeasures % 80 == 0) { System.Diagnostics.Debug.WriteLine("num text measurements = " + TextLayout.NumMeasures); } DateTime startTime = DateTime.Now; this.TextItem_Text = this.TextItem_Configurer.ModelledText; //ErrorReporter.ReportParadox("avg num computations per query = " + (double)numComputations / (double)numQueries); numQueries++; SpecificLayout result; if (query.MinimizesWidth()) { result = this.Get_MinWidth_Layout(query); } else { if (query.MinimizesHeight()) { result = this.Get_MinHeight_Layout(query); } else { result = this.Get_MaxScoring_Layout(query); } } DateTime endTime = DateTime.Now; TextLayout.TextTime += endTime.Subtract(startTime); return(result); }
public override SpecificLayout GetBestLayout(LayoutQuery query) { // The score of a Specific_ScrollLayout is defined in returnLayout: // If the child layout has negative score, the Specific_ScrollLayout refuses to do a layout // If the child layout has nonnegative score, the Specific_ScrollLayout's score equals // (this.resultingScore * (what fraction of the child layout is visible)) if (query.MinScore.CompareTo(this.resultingScore) > 0) { // Demands too high of a score: no solution return(null); } if (query.MaxHeight <= 0) { return(null); } // what fraction of the score of the sublayout will appear onscreen at once double scoreFraction = Math.Max(query.MinScore.DividedBy(this.resultingScore), 0); // what fraction of the child's height we need to include in the size of the ScrollView double requiredHeightFraction = scoreFraction; // the child's height divided by the ScrollView's height double requiredHeightMultiplier; if (requiredHeightFraction != 0) { requiredHeightMultiplier = 1 / requiredHeightFraction; } else { requiredHeightMultiplier = double.PositiveInfinity; } // the maximum child height double maxChildHeight = query.MaxHeight * requiredHeightMultiplier; if (query.MinimizesWidth()) { // For a min-width query, first shrink the width as much as possible before continuing SpecificLayout minWidth_childLayout = this.subLayout.GetBestLayout(new MinWidth_LayoutQuery(query.MaxWidth, maxChildHeight, this.requiredChildScore)); if (minWidth_childLayout == null) { return(null); } query = query.WithDimensions(minWidth_childLayout.Width, minWidth_childLayout.Height); } SpecificLayout childLayout = this.subLayout.GetBestLayout(new MinHeight_LayoutQuery(query.MaxWidth, maxChildHeight, this.requiredChildScore)); if (childLayout == null) { return(null); } if (!query.MinimizesHeight()) { // For a max-score (or min-width) query, use as much height as was allowed Size size = new Size(childLayout.Width, Math.Min(query.MaxHeight, childLayout.Height)); SpecificLayout result = this.makeLayout(size, childLayout); if (query.Accepts(result)) { return(this.prepareLayoutForQuery(result, query)); } return(null); } else { // For a min-height query, use only as much size as is needed double requiredScrollviewHeight = childLayout.Height * requiredHeightFraction; Size size = new Size(childLayout.Width, requiredScrollviewHeight); SpecificLayout result = this.makeLayout(size, childLayout); if (!query.Accepts(result)) { // Check for possible rounding error SpecificLayout larger = this.makeLayout(new Size(size.Width, size.Height + this.pixelSize), childLayout); if (query.Accepts(larger)) { return(this.prepareLayoutForQuery(larger, query)); } return(null); } return(this.prepareLayoutForQuery(result, query)); } }