public Text(DefineTextTag tag, ISystemServices services, FlashDocument document) { ID = tag.CharacterID; Matrix = tag.Matrix; Bounds = tag.Bounds; var path = new VGPath(); var parts = new List<VGPreparedPath>(); var scale = Vector2.One; var leftTop = new Vector2(tag.Bounds.Left, tag.Bounds.Top); Font font = null; ushort? lastFont = null; VGColor? lastColor = null; foreach (var rec in tag.TextRecords) { if ((rec.HasFont && lastFont != rec.FontId) || (rec.HasColor && lastColor != rec.Color)) { if (!path.IsEmpty && lastFont.HasValue && lastColor.HasValue) { var pp = services.VectorDevice.PreparePath(path, VGPaintMode.Fill); pp.Tag = services.VectorDevice.CreateColorPaint(lastColor.Value); parts.Add(pp); } path = new VGPath(); } if (rec.HasColor) lastColor = rec.Color; if (rec.HasFont) { font = document[rec.FontId] as Font; scale = scale = new Vector2(rec.FontSize, rec.FontSize); if (font != null) lastFont = rec.FontId; } if (font == null || !lastColor.HasValue || rec.Glyphs.Length == 0) continue; var offset = new Vector2(rec.HasXOffset ? rec.XOffset : 0, rec.HasYOffset ? rec.YOffset : 0); var refPt = Vector2.Zero; if (rec.Glyphs[0].GlyphIndex < font.GlyphFont.Length) refPt = font.GlyphFont[rec.Glyphs[0].GlyphIndex].ReferencePoint * scale; var xoff = Vector2.Zero; foreach (var g in rec.Glyphs) { if (g.GlyphIndex >= font.GlyphFont.Length) continue; var fg = font.GlyphFont[g.GlyphIndex]; if (fg.GlyphPath == null) continue; var rpt = fg.ReferencePoint.X * scale.X; var p = fg.GlyphPath.Clone(); p.Scale(scale); p.Offset(offset + xoff); path.Append(p); xoff.X += g.GlyphAdvance; } } if (!path.IsEmpty && lastFont.HasValue && lastColor.HasValue) { var pp = services.VectorDevice.PreparePath(path, VGPaintMode.Fill); pp.Tag = services.VectorDevice.CreateColorPaint(lastColor.Value); parts.Add(pp); } TextParts = parts.ToArray(); }
public VGPath Flatten() { if (_flattened) return this; VGPath p = new VGPath(); p._extents = _extents; p._last = _last; p._start = _start; p._startTarget = _startTarget; p._flattened = true; Action<Vector2, Vector2, bool> callback = (pt, n, join) => { n.Normalize(); p._segments.AddLast(new Segment(SegmentType._Tesselated, pt, join, n)); p._counts[(int)SegmentType._Tesselated]++; }; Vector2 last = new Vector2(); for (var s = _segments.First; s != null; s = s.Next) { if (s.Value.Type == SegmentType.CurveTo) { QuadraticFlattener.Flatten( last.X, last.Y, s.Value.Target.X, s.Value.Target.Y, s.Value.Controls[0].X, s.Value.Controls[0].Y, s.Value.MakeJoin, callback); } else { p._segments.AddLast(s.Value); p._counts[(int)s.Value.Type]++; } last = s.Value.Target; } return p; }
public void SetGlyph(char glyph, VGPath path, float escapeX, float escapeY) { if (IsStatic) throw new InvalidOperationException(_invalidOpError); ClearGlyph(glyph); _glyphs[glyph] = new PathGlyph(Device.PreparePath(path, VGPaintMode.Fill), new Vector2(escapeX, escapeY)); Vector4 extents = _glyphs[glyph].Extents; VectorMath.ExpandExtents(ref _maxGlyphExtents, ref extents); }
public void Append(VGPath path) { if (_extents == Vector4.Zero) _extents = path._extents; else { UpdateExtents(path._extents.X, path._extents.Y); UpdateExtents(path._extents.Z, path._extents.W); } foreach (var s in path._segments) _segments.AddLast(new Segment(s)); _last = path._last; _flattened &= path._flattened; _smooth = path._smooth; _smoothIsQuadratic = path._smoothIsQuadratic; for (int i = 0; i < _counts.Length; i++) _counts[i] += path._counts[i]; }