/// <summary> /// Draw a text primitive and merge the result to the text mesh. /// </summary> /// <param name="primitive"></param> /// <param name="fontFamily">font file path</param> /// <param name="fontSize">font pixel size</param> /// <param name="fontColor">font color</param> /// <param name="fontStyle">italic or normal. Oblique will not be supported for now.</param> /// <param name="fontWeight">bold or normal.</param> /// TODO apply text alignment public void DrawText(TextPrimitive primitive, Rect rect, string fontFamily, double fontSize, Color fontColor, FontStyle fontStyle, FontWeight fontWeight) { primitive.Offset = (Vector)rect.TopLeft; //check if we need to rebuild the glyph data of this text primitive var needRebuild = this.CheckTextPrimitive(primitive, fontFamily, fontSize, fontStyle, fontWeight); //build text mesh if (needRebuild) { primitive.FontFamily = fontFamily; // primitive.FontSize = fontSize; primitive.FontStyle = fontStyle; //No effect in current Typography. primitive.FontWeight = fontWeight; //No effect in current Typography. var textContext = new OSImplentation.TypographyTextContext(primitive.Text, fontFamily, (float)fontSize, FontStretch.Normal, fontStyle, fontWeight, (int)rect.Size.Width, (int)rect.Size.Height, TextAlignment.Leading); textContext.Build((Point)primitive.Offset); primitive.Offsets.AddRange(textContext.GlyphOffsets); foreach (var character in primitive.Text) { if (char.IsWhiteSpace(character)) { continue; } Typography.OpenFont.Glyph glyph = OSImplentation.TypographyTextContext.LookUpGlyph(fontFamily, character); Typography.OpenFont.GlyphLoader.Read(glyph, out var polygons, out var bezierSegments); var glyphData = GlyphCache.Default.GetGlyph(character, fontFamily, fontStyle, fontWeight); if (glyphData == null) { glyphData = GlyphCache.Default.AddGlyph(character, fontFamily, fontStyle, fontWeight, polygons, bezierSegments); } Debug.Assert(glyphData != null); primitive.Glyphs.Add(glyphData); } } //FIXME Should each text segment consume a draw call? NO! //add a new draw command DrawCommand cmd = new DrawCommand(); cmd.ClipRect = Rect.Big; cmd.TextureData = null; this.TextMesh.Commands.Add(cmd); var oldIndexBufferCount = this.TextMesh.IndexBuffer.Count; var scale = OSImplentation.TypographyTextContext.GetScale(fontFamily, fontSize); int index = -1; // get glyph data from typeface foreach (var character in primitive.Text) { if (char.IsWhiteSpace(character)) { continue; } index++; var glyphData = primitive.Glyphs[index]; Vector glyphOffset = primitive.Offsets[index]; this.TextMesh.Append(primitive.Offset, glyphData, glyphOffset, scale, fontColor, false); } var newIndexBufferCount = this.TextMesh.IndexBuffer.Count; // Update command var command = this.TextMesh.Commands[this.TextMesh.Commands.Count - 1]; command.ElemCount += newIndexBufferCount - oldIndexBufferCount; this.TextMesh.Commands[this.TextMesh.Commands.Count - 1] = command; }
/// <summary> /// Draw a text primitive and merge the result to the text mesh. /// </summary> /// <param name="primitive"></param> /// <param name="rect"></param> /// <param name="style"></param> public void DrawText(TextPrimitive primitive, Rect rect, StyleRuleSet style) { //check if we need to rebuild the glyph data of this text primitive var needRebuild = this.CheckTextPrimitive(primitive, style); var fontFamily = style.FontFamily; var fontSize = style.FontSize; var fontColor = style.FontColor; //build text mesh if (needRebuild) { primitive.Glyphs.Clear(); primitive.Offsets.Clear(); primitive.FontSize = fontSize; primitive.FontFamily = fontFamily; primitive.FontStyle = style.FontStyle; primitive.FontWeight = style.FontWeight; var fontStretch = FontStretch.Normal; var fontStyle = style.FontStyle; var fontWeight = style.FontWeight; var textAlignment = (TextAlignment)style.Get <int>(GUIStyleName.TextAlignment);//TODO apply text alignment var textContext = new OSImplentation.TypographyTextContext(primitive.Text, fontFamily, fontSize, fontStretch, fontStyle, fontWeight, (int)rect.Size.Width, (int)rect.Size.Height, textAlignment); textContext.Build(rect.Location); primitive.Offsets.AddRange(textContext.GlyphOffsets); foreach (var character in primitive.Text) { Typography.OpenFont.Glyph glyph = OSImplentation.TypographyTextContext.LookUpGlyph(fontFamily, character); Typography.OpenFont.GlyphLoader.Read(glyph, out var polygons, out var bezierSegments); var glyphData = GlyphCache.Default.GetGlyph(character, fontFamily, fontStyle, fontWeight); if (glyphData == null) { glyphData = GlyphCache.Default.AddGlyph(character, fontFamily, fontStyle, fontWeight, polygons, bezierSegments); } Debug.Assert(glyphData != null); primitive.Glyphs.Add(glyphData); } } //FIXME Should each text segment consume a draw call? NO! //add a new draw command DrawCommand cmd = new DrawCommand(); cmd.ClipRect = Rect.Big; cmd.TextureData = null; this.TextMesh.Commands.Add(cmd); var oldIndexBufferCount = this.TextMesh.IndexBuffer.Count; var scale = OSImplentation.TypographyTextContext.GetScale(fontFamily, fontSize); int index = -1; // get glyph data from typeface foreach (var character in primitive.Text) { index++; var glyphData = primitive.Glyphs[index]; Vector glyphOffset = primitive.Offsets[index]; this.TextMesh.Append((Vector)rect.Location + primitive.Offset, glyphData, glyphOffset, scale, fontColor, false); } var newIndexBufferCount = this.TextMesh.IndexBuffer.Count; // Update command var command = this.TextMesh.Commands[this.TextMesh.Commands.Count - 1]; command.ElemCount += newIndexBufferCount - oldIndexBufferCount; this.TextMesh.Commands[this.TextMesh.Commands.Count - 1] = command; }