Exemplo n.º 1
0
		/// <summary>
		/// Draws a previously laid-out text at a specified offset.
		/// </summary>
		public void Draw(float xOff, float yOff,
			RenderTextCallback renderCallback, DrawTextHint hint)
		{
			if (GetHLines(_totalLines) == null)
				throw new Exception("Draw invoked on a non-laid-out text.");
			if (GetHLines(_totalLines).Count == 0)
				return;

			bool styled = (_text is StyledText);

			// Original brush and font
			System.Drawing.Brush brushOriginal = hint.Brush;
			Font fontOriginal = hint.Font;

			// We now have the starting line and the number
			// of total lines to layout the text in. Go for it
			int iword = 0;
			for (int i = _startLine; i < _startLine + _totalLines; i++)
			{
				PointList hLine = GetHLines(_totalLines)[i] as PointList;

				for (int j = 0; j < hLine.Count; j += 2)
				{
					PointF pt1 = hLine[j];
					PointF pt2 = hLine[j + 1];
					RectangleF rc = new RectangleF(
						_bounds.X + xOff + pt1.X,
						_bounds.Y + yOff + pt1.Y,
						pt2.X - pt1.X, pt2.Y - pt1.Y);

					bool newLine = false;
					int newword = FitTextInRect(iword, rc, ref newLine);
					if (newword > iword)
					{
						// Calculate the total width of the words
						// which are about to be rendered, but skip
						// the whitespaces at the front and the rear
						int ifront = iword;
						int irear = newword - 1;
						while (ifront < newword && _text.Words[ifront].IsWhitespace)
							ifront++;
						while (irear >= ifront && _text.Words[irear].IsWhitespace)
							irear--;

						int w;
						float total = 0;
						for (w = ifront; w <= irear; w++)
							total += _text.Words[w].Width;

						// Adjust the left side of the destination
						// rectangle according to the specified alignment
						switch (_options.Alignment)
						{

							case StringAlignment.Near:
								// Do nothing
								break;

							case StringAlignment.Center:
								rc.X = rc.X + (rc.Width - total) / 2;
								break;

							case StringAlignment.Far:
								rc.X = rc.Right - total;
								break;

						}

						// Render the words in the range [ifront, irear]
						for (w = ifront; w <= irear; w++)
						{
							Word word = _text.Words[w];

							if (!_fits && hint.AddEllipsis && styled)
							{
								if (i == _startLine + _totalLines - 1)
								{
									if (j == hLine.Count - 2)
									{
										if (w == irear)
										{
											// Append the last word with ellipsis
											StyledText.StyledWord sword =
												word as StyledText.StyledWord;
											StyledText.StyledWord newWord = null;

											int chars = sword.Value.Length;
											float width = sword.Width;
											do
											{
												newWord = new StyledText.StyledWord(
													sword.Value.Substring(0, chars) + "...", sword.Format, sword.Color);
												newWord.UpdateMeasures(hint.Graphics, hint.Font);
												chars--;
											}
											while (chars > 0 && newWord.Width > width);

											word = newWord;
										}
									}
								}
							}

							if (!word.IsLineBreak && !word.IsWhitespace)
							{
								if (styled)
								{
									// In case of styled text formatting,
									// apply fonts and colors
									StyledText.StyledWord sword =
										word as StyledText.StyledWord;

									hint.Font = sword.CreateFont(hint.Font);
									hint.Brush = sword.CreateBrush(hint.Brush);

									rc.Y += sword.YOffset;
								}

								// Add 10 to width and height becaus GDI+ stupid
								// and clips the text
								renderCallback(word.Value, new RectangleF(
									rc.X, rc.Y, word.Width + 10, rc.Height + 10), hint);

								if (styled)
								{
									// Restore font and brush
									StyledText.StyledWord sword = 
										word as StyledText.StyledWord;

									sword.DisposeFont(hint.Font);
									sword.DisposeBrush(hint.Brush);
									hint.Font = fontOriginal;
									hint.Brush = brushOriginal;

									rc.Y -= sword.YOffset;
								}
							}
							rc.X += _text.Words[w].Width;
						}

						iword = newword;
					}

					if (newLine)
						break;
				}
			}
		}
Exemplo n.º 2
0
        /// <summary>
        /// Draws a previously laid-out text at a specified offset.
        /// </summary>
        public void Draw(float xOff, float yOff,
                         RenderTextCallback renderCallback, DrawTextHint hint)
        {
            if (GetHLines(_totalLines) == null)
            {
                throw new Exception("Draw invoked on a non-laid-out text.");
            }
            if (GetHLines(_totalLines).Count == 0)
            {
                return;
            }

            bool styled = (_text is StyledText);

            // Original brush and font
            System.Drawing.Brush brushOriginal = hint.Brush;
            Font fontOriginal = hint.Font;

            // We now have the starting line and the number
            // of total lines to layout the text in. Go for it
            int iword = 0;

            for (int i = _startLine; i < _startLine + _totalLines; i++)
            {
                PointList hLine = GetHLines(_totalLines)[i] as PointList;

                for (int j = 0; j < hLine.Count; j += 2)
                {
                    PointF     pt1 = hLine[j];
                    PointF     pt2 = hLine[j + 1];
                    RectangleF rc  = new RectangleF(
                        _bounds.X + xOff + pt1.X,
                        _bounds.Y + yOff + pt1.Y,
                        pt2.X - pt1.X, pt2.Y - pt1.Y);

                    bool newLine = false;
                    int  newword = FitTextInRect(iword, rc, ref newLine);
                    if (newword > iword)
                    {
                        // Calculate the total width of the words
                        // which are about to be rendered, but skip
                        // the whitespaces at the front and the rear
                        int ifront = iword;
                        int irear  = newword - 1;
                        while (ifront < newword && _text.Words[ifront].IsWhitespace)
                        {
                            ifront++;
                        }
                        while (irear >= ifront && _text.Words[irear].IsWhitespace)
                        {
                            irear--;
                        }

                        int   w;
                        float total = 0;
                        for (w = ifront; w <= irear; w++)
                        {
                            total += _text.Words[w].Width;
                        }

                        // Adjust the left side of the destination
                        // rectangle according to the specified alignment
                        switch (_options.Alignment)
                        {
                        case StringAlignment.Near:
                            // Do nothing
                            break;

                        case StringAlignment.Center:
                            rc.X = rc.X + (rc.Width - total) / 2;
                            break;

                        case StringAlignment.Far:
                            rc.X = rc.Right - total;
                            break;
                        }

                        // Render the words in the range [ifront, irear]
                        for (w = ifront; w <= irear; w++)
                        {
                            Word word = _text.Words[w];

                            if (!_fits && hint.AddEllipsis && styled)
                            {
                                if (i == _startLine + _totalLines - 1)
                                {
                                    if (j == hLine.Count - 2)
                                    {
                                        if (w == irear)
                                        {
                                            // Append the last word with ellipsis
                                            StyledText.StyledWord sword =
                                                word as StyledText.StyledWord;
                                            StyledText.StyledWord newWord = null;

                                            int   chars = sword.Value.Length;
                                            float width = sword.Width;
                                            do
                                            {
                                                newWord = new StyledText.StyledWord(
                                                    sword.Value.Substring(0, chars) + "...", sword.Format, sword.Color);
                                                newWord.UpdateMeasures(hint.Graphics, hint.Font);
                                                chars--;
                                            }while (chars > 0 && newWord.Width > width);

                                            word = newWord;
                                        }
                                    }
                                }
                            }

                            if (!word.IsLineBreak && !word.IsWhitespace)
                            {
                                if (styled)
                                {
                                    // In case of styled text formatting,
                                    // apply fonts and colors
                                    StyledText.StyledWord sword =
                                        word as StyledText.StyledWord;

                                    hint.Font  = sword.CreateFont(hint.Font);
                                    hint.Brush = sword.CreateBrush(hint.Brush);

                                    rc.Y += sword.YOffset;
                                }

                                // Add 10 to width and height becaus GDI+ stupid
                                // and clips the text
                                renderCallback(word.Value, new RectangleF(
                                                   rc.X, rc.Y, word.Width + 10, rc.Height + 10), hint);

                                if (styled)
                                {
                                    // Restore font and brush
                                    StyledText.StyledWord sword =
                                        word as StyledText.StyledWord;

                                    sword.DisposeFont(hint.Font);
                                    sword.DisposeBrush(hint.Brush);
                                    hint.Font  = fontOriginal;
                                    hint.Brush = brushOriginal;

                                    rc.Y -= sword.YOffset;
                                }
                            }
                            rc.X += _text.Words[w].Width;
                        }

                        iword = newword;
                    }

                    if (newLine)
                    {
                        break;
                    }
                }
            }
        }