public void CopyFrom(Specific_TextLayout original)
 {
     this.width    = original.width;
     this.height   = original.height;
     this.fontSize = original.fontSize;
     this.textItem = original.textItem;
 }
Exemple #2
0
        // compute the best dimensions fitting within the given size
        private Specific_TextLayout ComputeDimensions(Size availableSize, bool debug)
        {
            DateTime start = DateTime.Now;

            numComputations++;

            FormattedParagraph formattedText = this.formatText(availableSize.Width, debug, this.FontSize);
            Size desiredSize = formattedText.Size;

            if (desiredSize.Width < 0 || desiredSize.Height < 0)
            {
                ErrorReporter.ReportParadox("Illegal size " + desiredSize + " returned by textFormatter.FormatText");
            }
            bool   cropped = false;
            double width, height;

            // assign the width, height, and score
            if (desiredSize.Width <= availableSize.Width && desiredSize.Height <= availableSize.Height)
            {
                // no cropping is necessary
                width  = desiredSize.Width;
                height = desiredSize.Height;
            }
            else
            {
                // cropping
                cropped = true;
                if (this.ScoreIfCropped)
                {
                    width  = Math.Min(desiredSize.Width, availableSize.Width);
                    height = Math.Min(desiredSize.Height, availableSize.Height);
                }
                else
                {
                    width = height = 0;
                }
            }
            Specific_TextLayout specificLayout = new Specific_TextLayout(this.TextItem_Configurer, width, height, this.FontSize,
                                                                         this.ComputeScore(desiredSize, availableSize, this.TextToFit, formattedText.Text),
                                                                         formattedText.Text, desiredSize);

            specificLayout.Cropped = cropped;

            // diagnostics
            if (this.LoggingEnabled)
            {
                DateTime end      = DateTime.Now;
                TimeSpan duration = end.Subtract(start);
                System.Diagnostics.Debug.WriteLine("spent " + duration + " to measure '" + this.Summarize(this.TextToFit) + "' in " + availableSize +
                                                   "; desired " + desiredSize + " (formatted = " + this.Summarize(formattedText.Text) + "); requesting " + specificLayout.Size);
            }

            return(specificLayout);
        }
Exemple #3
0
        private void considerAnnouncingChanges()
        {
            if (this.LoggingEnabled)
            {
                System.Diagnostics.Debug.WriteLine("considerAnnouncingChanges textItem_text = " + this.textItem_text + " Text = " + this.Text);
            }
            if (this.Get_ChangedSinceLastRender())
            {
                return;
            }
            bool mustRedraw = false;

            if (!this.ScoreIfEmpty && (this.Text == "" || this.Text == null || this.textItem_text == "" || this.textItem_text == null))
            {
                mustRedraw = true;
            }
            else
            {
                View view        = this.TextItem_Configurer.View;
                Size currentSize = new Size(view.Width, view.Height);
                Specific_TextLayout layoutForCurrentText = this.ComputeDimensions(currentSize, false);
                this.TextItem_Text  = this.Text;
                this.layoutsByWidth = new Dictionary <double, FormattedParagraph>();
                Specific_TextLayout layoutForNewText = this.ComputeDimensions(currentSize, false);
                LayoutScore         oldScore         = layoutForCurrentText.Score;
                LayoutScore         newScore         = layoutForNewText.Score;
                if (!oldScore.Equals(newScore))
                {
                    // Something about the score would change if we keep the same size and use the new text
                    // Maybe we suddenly need more space and should ask for it
                    // Maybe we suddenly have enough space and we might become an interesting layout that permits a different font size
                    // In either of these cases, we want to recalculate the layout size
                    mustRedraw = true;
                }
                else
                {
                    // The score didn't change with the new text and the old layout size
                    // So, the user probably isn't interested in having us recompute the layout dimensions
                    mustRedraw = false;
                    this.TextItem_Configurer.DisplayText = layoutForNewText.DisplayText;
                }

                if (this.LoggingEnabled)
                {
                    System.Diagnostics.Debug.WriteLine("TextLayout calculating: Have size: " + currentSize + ". Old text: " + layoutForCurrentText.DisplayText +
                                                       ". Old target: " + layoutForCurrentText.DesiredSizeForDebugging + ". New text: " + layoutForNewText.DisplayText + ". New target: " + layoutForNewText.DesiredSizeForDebugging);
                }
            }

            this.AnnounceChange(mustRedraw);
        }
Exemple #4
0
        // computes the size of the highest-scoring layout satisfying the given criteria
        private SpecificLayout Get_MaxScoring_Layout(LayoutQuery query)
        {
            if (query.MaxWidth < 0 || query.MaxHeight < 0)
            {
                return(null);
            }
            Specific_TextLayout specificLayout = this.ComputeDimensions(new Size(query.MaxWidth, query.MaxHeight), query.Debug);

            if (query.Accepts(specificLayout))
            {
                return(this.prepareLayoutForQuery(specificLayout, query));
            }
            return(null);
        }
Exemple #5
0
        // computes the size of the layout with smallest height satisfying the given criteria
        private SpecificLayout Get_MinHeight_Layout(LayoutQuery query)
        {
            if (query.MaxWidth < 0 || query.MaxHeight < 0)
            {
                return(null);
            }
            // first check whether this query will accept a cropped layout
            Specific_TextLayout specificLayout = this.ComputeDimensions(new Size(0, 0), query.Debug);

            if (query.Accepts(specificLayout))
            {
                return(this.prepareLayoutForQuery(specificLayout, query));
            }
            specificLayout = this.ComputeDimensions(new Size(query.MaxWidth, query.MaxHeight), query.Debug);
            if (query.Accepts(specificLayout))
            {
                return(this.prepareLayoutForQuery(specificLayout.GetBestLayout(query), query));
            }
            return(null);
        }
Exemple #6
0
        // computes the size of the layout with smallest width satisfying the given criteria
        private SpecificLayout Get_MinWidth_Layout(LayoutQuery query)
        {
            if (query.MaxWidth < 0 || query.MaxHeight < 0)
            {
                return(null);
            }
            // first check whether this query will accept a cropped layout
            Specific_TextLayout specificLayout = this.ComputeDimensions(new Size(0, 0), query.Debug);

            if (query.Accepts(specificLayout))
            {
                return(this.prepareLayoutForQuery(specificLayout, query));
            }
            // not satisfied with cropping so we need to try harder to do a nice-looking layout
            Specific_TextLayout nonCropping_layout = this.Get_NonCropping_MinWidthLayout(query);

            if (nonCropping_layout != null)
            {
                return(this.prepareLayoutForQuery(nonCropping_layout, query));
            }
            return(null);
        }
Exemple #7
0
        // computes the layout dimensions of the layout of minimum width such that there is no cropping
        private Specific_TextLayout Get_NonCropping_MinWidthLayout(LayoutQuery query)
        {
            Specific_TextLayout bestAllowedDimensions = this.ComputeDimensions(new Size(double.PositiveInfinity, double.PositiveInfinity), query.Debug);
            double pixelSize        = 1;
            double maxRejectedWidth = 0;
            int    numIterations    = 0;
            bool   firstIteration   = true;
            double maxWidth         = query.MaxWidth;

            while (maxRejectedWidth < bestAllowedDimensions.Width - pixelSize / 2)
            {
                numIterations++;
                // given the current width, compute the required height
                Specific_TextLayout newDimensions = this.ComputeDimensions(new Size(maxWidth, double.PositiveInfinity), query.Debug);
                if (newDimensions.Height <= query.MaxHeight && query.MinScore.CompareTo(newDimensions.Score) <= 0)
                {
                    // this layout fits in the required dimensions
                    if (newDimensions.Width <= bestAllowedDimensions.Width && newDimensions.Width <= query.MaxWidth)
                    {
                        // this layout is at least as good as the best layout we found so far
                        bestAllowedDimensions = newDimensions;
                        maxWidth = newDimensions.Width;
                    }
                    else
                    {
                        // we've found a layout having sufficiently small width and height, but it isn't any better than what we'd previously found
                        // So, we're not making progress with this process and should quit
                        break;
                    }
                }
                else
                {
                    // this layout does not fit in the required dimensions
                    if (maxWidth > maxRejectedWidth)
                    {
                        maxRejectedWidth = maxWidth;
                    }
                    // if the first layout we found was too tall, then there will need to be some cropping
                    if (double.IsPositiveInfinity(bestAllowedDimensions.Width))
                    {
                        return(null);
                    }
                }
                // calculate a new size, by guessing based on required area
                double desiredArea = newDimensions.Height * Math.Max(maxWidth, newDimensions.Width);
                maxWidth = desiredArea / query.MaxHeight;
                // Make sure that the next value we check is inside the range that we haven't checked yet, to make sure we're making progress
                // If our area-based is outside the unexplored range, then from now on just split the remaining range in half on each iteration
                if (maxWidth < (maxRejectedWidth + pixelSize / 2))
                {
                    if (firstIteration)
                    {
                        // The first time that we find we have enough area to make the width very tiny, we calculate the true minimum amount of width required
                        Size desiredSize = this.formatText(maxWidth, query.Debug, this.FontSize).Size;
                        if (desiredSize.Width > maxWidth)
                        {
                            maxRejectedWidth = desiredSize.Width - pixelSize / 2;
                        }
                        maxWidth = desiredSize.Width;
                    }
                    else
                    {
                        // The second time we find that we have enough area to make the width very tiny, we don't recalculate the true min width required because we already did
                        // Instead we just do a binary search
                        maxWidth = (maxRejectedWidth + bestAllowedDimensions.Width) / 2;
                    }
                }
                else
                {
                    if (maxWidth > (bestAllowedDimensions.Width - pixelSize / 2))
                    {
                        maxWidth = (maxRejectedWidth + bestAllowedDimensions.Width) / 2;
                    }
                }
                firstIteration = false;
            }
            if (this.LoggingEnabled)
            {
                System.Diagnostics.Debug.WriteLine("Spent " + numIterations + " iterations in Get_NonCropping_MinWidthLayout with query = " + query + " and text length = " + this.TextLength);
            }
            if (!query.Accepts(bestAllowedDimensions))
            {
                return(null);
            }
            return(bestAllowedDimensions);
        }
        public override SpecificLayout Clone()
        {
            Specific_TextLayout clone = new Specific_TextLayout(this.textItem, this.width, this.height, this.fontSize, this.score, this.DisplayText, this.DesiredSizeForDebugging);

            return(clone);
        }