/// <summary> /// Prints the specified text with the given render options /// </summary> /// <param name="font">The <see cref="QFont"/> to print the text with</param> /// <param name="text">The text to print</param> /// <param name="position">The position of the text</param> /// <param name="opt">The text render options</param> /// <returns>The size of the printed text</returns> public SizeF Print(QFont font, ProcessedText text, Vector3 position, QFontRenderOptions opt) { var dp = new QFontDrawingPrimitive(font, opt); DrawingPrimitives.Add(dp); return(dp.Print(text, position, opt.ClippingRectangle)); }
/// <summary> /// Prints the specified text /// </summary> /// <param name="font">The <see cref="QFont"/> to print the text with</param> /// <param name="processedText">The processed text to print</param> /// <param name="position">The position of the text</param> /// <param name="colour">The colour of the text</param> /// <returns>The size of the printed text</returns> public SizeF Print(QFont font, ProcessedText processedText, Vector3 position, Color?colour = null) { var dp = new QFontDrawingPrimitive(font); DrawingPrimitives.Add(dp); return(colour.HasValue ? dp.Print(processedText, position, colour.Value) : dp.Print(processedText, position)); }
public SizeF Print(ProcessedText processedText, Vector3 position, Rectangle clippingRectangle = default(Rectangle)) { PrepareVertexCapacityFromLetterCount(processedText.EstimatedLength()); PrintOffset = TransformToViewport(position); return(PrintOrMeasure(processedText, false, clippingRectangle)); }
public void Print(ProcessedText processedText, Vector2 position) { position = TransformPositionToViewport(position); position = LockToPixel(position); GL.PushMatrix(); GL.Translate(position.X, position.Y, 0f); Print(processedText); GL.PopMatrix(); }
public SizeF Print(QFont font, ProcessedText processedText, Vector3 position, Color?colour = null, Rectangle clippingRectangle = default(Rectangle)) { var dp = new QFontDrawingPimitive(font); var size = (colour.HasValue) ? dp.Print(processedText, position, colour.Value) : dp.Print(processedText, position); _glFontDrawingPimitives.Add(dp); return(size); }
public void Print(ProcessedText processedText, Vector2 position, float maxHeight = float.MaxValue) { position = TransformPositionToViewport(position); position = LockToPixel(position); GL.PushMatrix(); GL.Translate(position.X, position.Y, 0f); Print(processedText, maxHeight); GL.PopMatrix(); }
public SizeF Print(QFont font, ProcessedText processedText, Vector3 position, Color?colour = null, Rectangle clippingRectangle = default(Rectangle)) { var dp = new QFontDrawingPimitive(font); DrawingPimitiveses.Add(dp); if (colour.HasValue) { return(dp.Print(processedText, position, colour.Value)); } else { return(dp.Print(processedText, position)); } }
/// <summary> /// Creates node list object associated with the text. /// </summary> /// <param name="text"></param> /// <param name="bounds"></param> /// <returns></returns> public ProcessedText ProcessText(string text, float maxWidth, QFontAlignment alignment) { //TODO: bring justify and alignment calculations in here maxWidth = TransformWidthToViewport(maxWidth); var nodeList = new TextNodeList(text); nodeList.MeasureNodes(fontData, Options); //we "crumble" words that are two long so that that can be split up var nodesToCrumble = new List <TextNode>(); foreach (TextNode node in nodeList) { if (node.Length >= maxWidth && node.Type == TextNodeType.Word) { nodesToCrumble.Add(node); } } foreach (var node in nodesToCrumble) { nodeList.Crumble(node, 1); } //need to measure crumbled words nodeList.MeasureNodes(fontData, Options); var processedText = new ProcessedText(); processedText.textNodeList = nodeList; processedText.maxWidth = maxWidth; processedText.alignment = alignment; return(processedText); }
/// <summary> /// Creates node list object associated with the text. /// </summary> /// <param name="options">The font render options</param> /// <param name="text">The text to process</param> /// <param name="font">The <see cref="QFont"/> to process the text with</param> /// <param name="maxSize">The maximum size of the processed text</param> /// <param name="alignment">The text alignment</param> /// <returns>The processed text</returns> public static ProcessedText ProcessText(QFont font, QFontRenderOptions options, string text, SizeF maxSize, QFontAlignment alignment) { //TODO: bring justify and alignment calculations in here maxSize.Width = TransformWidthToViewport(maxSize.Width, options); var nodeList = new TextNodeList(text); nodeList.MeasureNodes(font.FontData, options); //we "crumble" words that are two long so that that can be split up var nodesToCrumble = new List <TextNode>(); foreach (TextNode node in nodeList) { if ((!options.WordWrap || node.Length >= maxSize.Width) && node.Type == TextNodeType.Word) { nodesToCrumble.Add(node); } } foreach (TextNode node in nodesToCrumble) { nodeList.Crumble(node, 1); } //need to measure crumbled words nodeList.MeasureNodes(font.FontData, options); var processedText = new ProcessedText(); processedText.TextNodeList = nodeList; processedText.MaxSize = maxSize; processedText.Alignment = alignment; return(processedText); }
/// <summary> /// Creates node list object associated with the text. /// </summary> /// <param name="text"></param> /// <param name="bounds"></param> /// <returns></returns> public ProcessedText ProcessText(string text, RectangleF bounds, QFontAlignment alignment) { //TODO: bring justify and alignment calculations in here var nodeList = new TextNodeList(text); nodeList.MeasureNodes(fontData, options); //we "crumble" words that are two long so that that can be split up var nodesToCrumble = new List <TextNode>(); foreach (TextNode node in nodeList) { if (node.Length >= bounds.Width && node.Type == TextNodeType.Word) { nodesToCrumble.Add(node); } } foreach (var node in nodesToCrumble) { nodeList.Crumble(node, 1); } //need to measure crumbled words nodeList.MeasureNodes(fontData, options); var processedText = new ProcessedText(); processedText.textNodeList = nodeList; processedText.bounds = bounds; processedText.alignment = alignment; return(processedText); }
public void Print(ProcessedText processedText, PointF position) { position = LockToPixel(position); renderer.Begin(position); Print(processedText); renderer.End(); }
/// <summary> /// Prints text as previously processed with a boundary and alignment. /// </summary> /// <param name="processedText"></param> public void Print(ProcessedText processedText) { renderer.Begin(PointF.Empty); PrintOrMeasure(processedText, false); renderer.End(); }
public SizeF Print(QFont font, ProcessedText processedText, Vector3 position, Color? colour = null, Rectangle clippingRectangle = default(Rectangle)) { var dp = new QFontDrawingPimitive(font); DrawingPimitiveses.Add(dp); if (colour.HasValue) return dp.Print(processedText, position, colour.Value); else return dp.Print(processedText, position); }
/// <summary> /// Measures the actual width and height of the block of text /// </summary> /// <param name="processedText"></param> /// <returns></returns> public SizeF Measure(ProcessedText processedText) { return PrintOrMeasure(processedText, true); }
/// <summary> /// Measures the actual width and height of the block of text /// </summary> /// <param name="processedText"></param> /// <returns></returns> public SizeF Measure(ProcessedText processedText) { return TransformMeasureFromViewport(PrintOrMeasure(processedText, true)); }
/// <summary> /// Prints text as previously processed with a boundary and alignment. /// </summary> /// <param name="processedText"></param> public void Print(ProcessedText processedText) { PrintOrMeasure(processedText, false); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { var popRequired = false; if (!measureOnly && !ProjectionStack.Begun && Options.TransformToViewport != null) { GL.PushMatrix(); popRequired = true; GL.Scale(1 / fontData.scaleDueToTransformToViewport, 1 / fontData.scaleDueToTransformToViewport, 0); } float maxMeasuredWidth = 0f; if (!measureOnly) { GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); if (Options.UseDefaultBlendFunction) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } } float maxWidth = processedText.maxWidth; var alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) { node.LengthTweak = 0f; //reset tweaks } if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth)); } else if (alignment == QFontAlignment.Justify) { JustifyLine(nodeList.Head, maxWidth); } bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if (!measureOnly) { RenderWord(xOffset + length, yOffset, node); } length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else { newLine = true; if (node.Previous != null) { node = node.Previous; } } } if (newLine) { yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth)); } else if (alignment == QFontAlignment.Justify) { JustifyLine(node.Next, maxWidth); } } } } if (popRequired) { GL.PopMatrix(); } return(new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos)); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { float maxWidth = 0f; if (!measureOnly) { GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } var bounds = processedText.bounds; var alignment = processedText.alignment; float xOffset = bounds.X; float yOffset = bounds.Y; var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) { node.LengthTweak = 0f; //reset tweaks } if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, bounds.Width) - bounds.Width); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, bounds.Width) - bounds.Width * 0.5f); } else if (alignment == QFontAlignment.Justify) { JustifyLine(nodeList.Head, bounds.Width); } bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (SkipTrailingSpace(node, length, bounds.Width) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= bounds.Width || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if (!measureOnly) { RenderWord(xOffset + length, yOffset, node); } length += node.ModifiedLength; maxWidth = Math.Max(length, maxWidth); } else { newLine = true; if (node.Previous != null) { node = node.Previous; } } } if (newLine) { yOffset += LineSpacing; xOffset = bounds.X; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, bounds.Width) - bounds.Width); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, bounds.Width) - bounds.Width * 0.5f); } else if (alignment == QFontAlignment.Justify) { JustifyLine(node.Next, bounds.Width); } } } } return(new SizeF(maxWidth, yOffset + LineSpacing - bounds.Y)); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { float maxMeasuredWidth = 0f; float maxWidth = processedText.maxWidth; var alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) node.LengthTweak = 0f; //reset tweaks if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth) ); else if (alignment == QFontAlignment.Justify) JustifyLine(nodeList.Head, maxWidth); bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if(!measureOnly) RenderWord(xOffset + length, yOffset, node); length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else { newLine = true; if (node.Previous != null) node = node.Previous; } } if (newLine) { yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth) ); else if (alignment == QFontAlignment.Justify) JustifyLine(node.Next, maxWidth); } } } return new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos); }
public SizeF DrawProcessedText(ProcessedText pText, Vector3 position, Color4 colour) { return FontDrawing.Print(DefaultFont.Font, pText, position, (Color)colour); }
/// <summary> /// Prints text as previously processed with a boundary and alignment. /// </summary> /// <param name="processedText"></param> public void Print(ProcessedText processedText, float maxHeight = float.MaxValue) { PrintOrMeasure(processedText, false, maxHeight); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { float maxWidth = 0f; if (!measureOnly) { GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } var bounds = processedText.bounds; var alignment = processedText.alignment; float xOffset = bounds.X; float yOffset = bounds.Y; var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) node.LengthTweak = 0f; //reset tweaks if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, bounds.Width) - bounds.Width); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, bounds.Width) - bounds.Width * 0.5f); else if (alignment == QFontAlignment.Justify) JustifyLine(nodeList.Head, bounds.Width); bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (SkipTrailingSpace(node, length, bounds.Width) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= bounds.Width || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if(!measureOnly) RenderWord(xOffset + length, yOffset, node); length += node.ModifiedLength; maxWidth = Math.Max(length, maxWidth); } else { newLine = true; if (node.Previous != null) node = node.Previous; } } if (newLine) { yOffset += LineSpacing; xOffset = bounds.X; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, bounds.Width) - bounds.Width); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, bounds.Width) - bounds.Width * 0.5f); else if (alignment == QFontAlignment.Justify) JustifyLine(node.Next, bounds.Width); } } } return new SizeF(maxWidth, yOffset + LineSpacing - bounds.Y); }
/// <summary> /// Creates node list object associated with the text. /// </summary> /// <param name="text"></param> /// <param name="bounds"></param> /// <returns></returns> public ProcessedText ProcessText(string text, RectangleF bounds, QFontAlignment alignment) { //TODO: bring justify and alignment calculations in here var nodeList = new TextNodeList(text); nodeList.MeasureNodes(fontData, options); //we "crumble" words that are two long so that that can be split up var nodesToCrumble = new List<TextNode>(); foreach (TextNode node in nodeList) if (node.Length >= bounds.Width && node.Type == TextNodeType.Word) nodesToCrumble.Add(node); foreach (var node in nodesToCrumble) nodeList.Crumble(node, 1); //need to measure crumbled words nodeList.MeasureNodes(fontData, options); var processedText = new ProcessedText(); processedText.textNodeList = nodeList; processedText.bounds = bounds; processedText.alignment = alignment; return processedText; }
/// <summary> /// Measures the actual width and height of the block of text /// </summary> /// <param name="processedText"></param> /// <returns></returns> public SizeF Measure(ProcessedText processedText) { return(PrintOrMeasure(processedText, true)); }
/// <summary> /// Measures the actual width and height of the block of text /// </summary> /// <param name="processedText"></param> /// <returns></returns> public SizeF Measure(ProcessedText processedText, float maxHeight = float.MaxValue) { return(TransformMeasureFromViewport(PrintOrMeasure(processedText, true, maxHeight))); }
/// <summary> /// Measures the specified text. Helper method delegating functionality. /// </summary> /// <param name="processedText">The processed text.</param> /// <returns> /// Measured size. /// </returns> public SizeF Measure(ProcessedText processedText) { var test = new QFontDrawingPimitive(this); return test.Measure(processedText); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { var popRequired = false; if (!measureOnly && !ProjectionStack.Begun && Options.TransformToViewport != null) { GL.PushMatrix(); popRequired = true; GL.Scale(1 / fontData.scaleDueToTransformToViewport, 1 / fontData.scaleDueToTransformToViewport, 0); } float maxMeasuredWidth = 0f; if (!measureOnly) { GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); if (Options.UseDefaultBlendFunction) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } } float maxWidth = processedText.maxWidth; var alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) node.LengthTweak = 0f; //reset tweaks if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth) ); else if (alignment == QFontAlignment.Justify) JustifyLine(nodeList.Head, maxWidth); bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if(!measureOnly) RenderWord(xOffset + length, yOffset, node); length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else { newLine = true; if (node.Previous != null) node = node.Previous; } } if (newLine) { yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth) ); else if (alignment == QFontAlignment.Justify) JustifyLine(node.Next, maxWidth); } } } if (popRequired) GL.PopMatrix(); return new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos); }
public SizeF Print(ProcessedText processedText, Vector3 position, Color colour, Rectangle clippingRectangle = default(Rectangle)) { this.Options.Colour = colour; PrintOffset = TransformToViewport(position); return(PrintOrMeasure(processedText, false, clippingRectangle)); }
public SizeF Print(ProcessedText processedText, Vector3 position, Color colour, Rectangle clippingRectangle = default(Rectangle)) { this.Options.Colour = colour; PrintOffset = TransformToViewport(position); return PrintOrMeasure(processedText, false, clippingRectangle); }
/// <summary> /// Measures the actual width and height of the block of text /// </summary> /// <param name="processedText"></param> /// <returns></returns> public SizeF Measure(ProcessedText processedText) { return(TransformMeasureFromViewport(PrintOrMeasure(processedText, true))); }
public SizeF Print(string text, Vector3 position, SizeF maxSize, QFontAlignment alignment, Color colour, Rectangle clippingRectangle = default(Rectangle)) { ProcessedText processedText = ProcessText(_font, Options, text, maxSize, alignment); return(Print(processedText, TransformToViewport(position), colour, clippingRectangle)); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly, Rectangle clippingRectangle = default(Rectangle)) { // init values we'll return float maxMeasuredWidth = 0f; float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; //make sure fontdata font's options are synced with the actual options ////if (_font.FontData.dropShadowFont != null && _font.FontData.dropShadowFont.Options != this.Options) ////{ //// _font.FontData.dropShadowFont.Options = this.Options; ////} float maxWidth = processedText.maxSize.Width; QFontAlignment alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) TextNodeList nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) node.LengthTweak = 0f; //reset tweaks if (alignment == QFontAlignment.Right) xOffset -= (float) Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float) Math.Ceiling(0.5f*TextNodeLineLength(nodeList.Head, maxWidth)); else if (alignment == QFontAlignment.Justify) JustifyLine(nodeList.Head, maxWidth); bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (this.Options.WordWrap && SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if (!measureOnly) RenderWord(xOffset + length, yOffset, node, ref clippingRectangle); length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else if (this.Options.WordWrap) { newLine = true; if (node.Previous != null) node = node.Previous; } else continue; // continue so we still read line breaks even if reached max width } if (newLine) { if (processedText.maxSize.Height > 0 && yOffset + LineSpacing - yPos >= processedText.maxSize.Height) break; yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) xOffset -= (float) Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float) Math.Ceiling(0.5f*TextNodeLineLength(node.Next, maxWidth)); else if (alignment == QFontAlignment.Justify) JustifyLine(node.Next, maxWidth); } } } LastSize = new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos); return LastSize; }
/// <summary> /// Measures the actual width and height of the block of text. /// </summary> /// <param name="text"></param> /// <param name="bounds"></param> /// <param name="alignment"></param> /// <returns></returns> public SizeF Measure(string text, SizeF maxSize, QFontAlignment alignment) { ProcessedText processedText = ProcessText(_font, Options, text, maxSize, alignment); return(Measure(processedText)); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { // init values we'll return float maxMeasuredWidth = 0f; float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; // determine what capacities we need var caps = new EnableCap[] { }; if (!measureOnly && !UsingVertexBuffers) { GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); caps = new EnableCap[] { EnableCap.Texture2D, EnableCap.Blend }; } Helper.SafeGLEnable(caps, () => { if (!measureOnly && !UsingVertexBuffers && Options.UseDefaultBlendFunction) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } float maxWidth = processedText.maxSize.Width; var alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) { node.LengthTweak = 0f; //reset tweaks } if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth)); } else if (alignment == QFontAlignment.Justify) { JustifyLine(nodeList.Head, maxWidth); } bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (Options.WordWrap && SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if (!measureOnly) { RenderWord(xOffset + length, yOffset, node); } length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else if (Options.WordWrap) { newLine = true; if (node.Previous != null) { node = node.Previous; } } else { continue; // continue so we still read line breaks even if reached max width } } if (newLine) { if (yOffset + LineSpacing - yPos >= processedText.maxSize.Height) { break; } yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth)); } else if (alignment == QFontAlignment.Justify) { JustifyLine(node.Next, maxWidth); } } } } }); return(new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos)); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly, Rectangle clippingRectangle = default(Rectangle)) { // init values we'll return float maxMeasuredWidth = 0f; float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; //make sure fontdata font's options are synced with the actual options ////if (_font.FontData.dropShadowFont != null && _font.FontData.dropShadowFont.Options != this.Options) ////{ //// _font.FontData.dropShadowFont.Options = this.Options; ////} float maxWidth = processedText.maxSize.Width; QFontAlignment alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) TextNodeList nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) { node.LengthTweak = 0f; //reset tweaks } if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth)); } else if (alignment == QFontAlignment.Justify) { JustifyLine(nodeList.Head, maxWidth); } bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (this.Options.WordWrap && SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if (!measureOnly) { RenderWord(xOffset + length, yOffset, node, ref clippingRectangle); } length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else if (this.Options.WordWrap) { newLine = true; if (node.Previous != null) { node = node.Previous; } } else { continue; // continue so we still read line breaks even if reached max width } } if (newLine) { if (processedText.maxSize.Height > 0 && yOffset + LineSpacing - yPos >= processedText.maxSize.Height) { break; } yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) { xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); } else if (alignment == QFontAlignment.Centre) { xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth)); } else if (alignment == QFontAlignment.Justify) { JustifyLine(node.Next, maxWidth); } } } } LastSize = new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos); return(LastSize); }
private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly) { // init values we'll return float maxMeasuredWidth = 0f; float xPos = 0f; float yPos = 0f; float xOffset = xPos; float yOffset = yPos; // determine what capacities we need var caps = new EnableCap[] { }; if (!measureOnly && !UsingVertexBuffers) { GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); caps = new EnableCap[] { EnableCap.Texture2D, EnableCap.Blend }; } Helper.SafeGLEnable(caps, () => { if (!measureOnly && !UsingVertexBuffers && Options.UseDefaultBlendFunction) GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); float maxWidth = processedText.maxSize.Width; var alignment = processedText.alignment; //TODO - use these instead of translate when rendering by position (at some point) var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) node.LengthTweak = 0f; //reset tweaks if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth)); else if (alignment == QFontAlignment.Justify) JustifyLine(nodeList.Head, maxWidth); bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (Options.WordWrap && SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; if (!measureOnly) RenderWord(xOffset + length, yOffset, node); length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else if (Options.WordWrap) { newLine = true; if (node.Previous != null) node = node.Previous; } else continue; // continue so we still read line breaks even if reached max width } if (newLine) { if (yOffset + LineSpacing - yPos >= processedText.maxSize.Height) break; yOffset += LineSpacing; xOffset = xPos; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (alignment == QFontAlignment.Right) xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth); else if (alignment == QFontAlignment.Centre) xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth)); else if (alignment == QFontAlignment.Justify) JustifyLine(node.Next, maxWidth); } } } }); return new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos); }
public void Print(ProcessedText processedText, Vector2 position) { position = TransformPositionToViewport(position); position = LockToPixel(position); GL.PushMatrix(); GL.Translate(position.X,position.Y,0f); Print(processedText); GL.PopMatrix(); }
private ProcessedText SafeProcessText(Rectangle clientRectangle, string text, float maxWidth, QFontAlignment alignment) { //TODO: bring justify and alignment calculations in here maxWidth = TransformWidthToViewport(clientRectangle, maxWidth); var nodeList = new TextNodeList(text); nodeList.MeasureNodes(fontData, Options); //we "crumble" words that are two long so that that can be split up var nodesToCrumble = new List<TextNode>(); foreach (TextNode node in nodeList) if (node.Length >= maxWidth && node.Type == TextNodeType.Word) nodesToCrumble.Add(node); foreach (var node in nodesToCrumble) nodeList.Crumble(node, 1); //need to measure crumbled words nodeList.MeasureNodes(fontData, Options); var processedText = new ProcessedText(); processedText.textNodeList = nodeList; processedText.maxWidth = maxWidth; processedText.alignment = alignment; return processedText; }
/// <summary> /// Creates node list object associated with the text. /// </summary> /// <param name="text"></param> /// <param name="bounds"></param> /// <returns></returns> public ProcessedText ProcessText(string text, SizeF maxSize, QFontAlignment alignment) { //TODO: bring justify and alignment calculations in here maxSize.Width = TransformWidthToViewport(maxSize.Width); var nodeList = new TextNodeList(text); nodeList.MeasureNodes(fontData, Options); //we "crumble" words that are two long so that that can be split up var nodesToCrumble = new List<TextNode>(); foreach (TextNode node in nodeList) if ((!Options.WordWrap || node.Length >= maxSize.Width) && node.Type == TextNodeType.Word) nodesToCrumble.Add(node); foreach (var node in nodesToCrumble) nodeList.Crumble(node, 1); //need to measure crumbled words nodeList.MeasureNodes(fontData, Options); var processedText = new ProcessedText(); processedText.textNodeList = nodeList; processedText.maxSize = maxSize; processedText.alignment = alignment; return processedText; }
public SizeF Print(QFont font, ProcessedText text, Vector3 position, QFontRenderOptions opt) { var dp = new QFontDrawingPimitive(font, opt); DrawingPimitiveses.Add(dp); return dp.Print(text, position, opt.ClippingRectangle); }
/// <summary> /// Measures the specified text. Helper method delegating functionality. /// </summary> /// <param name="processedText">The processed text.</param> /// <returns> /// Measured size. /// </returns> public SizeF Measure(ProcessedText processedText) { var test = new QFontDrawingPimitive(this); return(test.Measure(processedText)); }
/// <summary>Load resources here.</summary> /// <param name="e">Not used.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.Keyboard.KeyDown += KeyDown; drawing = new QFontDrawing(); controlsDrawing = new QFontDrawing(); controlsTextOpts = new QFontRenderOptions() { Colour = Color.FromArgb(new Color4(0.8f, 0.1f, 0.1f, 1.0f).ToArgb()), DropShadowActive = true }; heading2 = new QFont("woodenFont.qfont", new QFontConfiguration(addDropShadow: true), 1.0f); heading2Options = new QFontRenderOptions() { Colour = Color.White, DropShadowActive = true}; var builderConfig = new QFontBuilderConfiguration(addDropShadow: true); builderConfig.ShadowConfig.blurRadius = 2; //reduce blur radius because font is very small builderConfig.ShadowConfig.blurPasses = 1; builderConfig.ShadowConfig.Type = ShadowType.Blurred; builderConfig.TextGenerationRenderHint = TextGenerationRenderHint.ClearTypeGridFit; //best render hint for this font mainText = new QFont("Fonts/times.ttf", 14, builderConfig); mainTextOptions = new QFontRenderOptions() { DropShadowActive = true, Colour = Color.White, WordSpacing = 0.5f}; _benchmarkResults = new QFont("Fonts/times.ttf", 14, builderConfig); heading1 = new QFont("Fonts/HappySans.ttf", 72, new QFontBuilderConfiguration(true)); controlsText = new QFont("Fonts/HappySans.ttf", 32, new QFontBuilderConfiguration(true)); codeText = new QFont("Fonts/Comfortaa-Regular.ttf", 12, new QFontBuilderConfiguration()); heading1Options = new QFontRenderOptions() { Colour = Color.FromArgb(new Color4(0.2f, 0.2f, 0.2f, 1.0f).ToArgb()), DropShadowActive = true}; _processedText = QFontDrawingPimitive.ProcessText(mainText, mainTextOptions, preProcessed, new SizeF(Width - 40, -1), QFontAlignment.Justify); codeTextOptions = new QFontRenderOptions() { Colour = Color.FromArgb(new Color4(0.0f, 0.0f, 0.4f, 1.0f).ToArgb()) }; monoSpaced = new QFont("Fonts/Anonymous.ttf", 10, new QFontBuilderConfiguration()); monoSpacedOptions = new QFontRenderOptions() { Colour = Color.FromArgb(new Color4(0.1f, 0.1f, 0.1f, 1.0f).ToArgb()), DropShadowActive = true}; GL.ClearColor(Color4.CornflowerBlue); }