public void Paint(float x, float y, IPathCanvas canvas) { if (_svg == null) return; _xScale = _xGlyphScale; _yScale = _yGlyphScale; var startX = x; var startY = y; _currentX = startX; _currentY = startY; canvas.BeginPath(); for (int i = 0, j = _svg.Commands.Count; i < j; i++) { ParseCommand(startX, startY, canvas, _svg.Commands[i]); } canvas.Fill(); }
public void Paint(float x, float y, IPathCanvas canvas) { if (_svg == null) { return; } _xScale = _xGlyphScale; _yScale = _yGlyphScale; var startX = x; var startY = y; _currentX = startX; _currentY = startY; canvas.BeginPath(); for (int i = 0, j = _svg.Commands.Count; i < j; i++) { ParseCommand(startX, startY, canvas, _svg.Commands[i]); } canvas.Fill(); }
private void ParseCommand(float cx, float cy, IPathCanvas canvas, SvgCommand cmd) { bool canContinue; // reusable flag for shorthand curves int i; switch (cmd.Cmd) { // // Moving // case "M": // absolute moveto _currentX = (cx + cmd.Numbers[0] * _xScale); _currentY = (cy + cmd.Numbers[1] * _yScale); canvas.MoveTo(_currentX, _currentY); break; case "m": // relative moveto _currentX += (cmd.Numbers[0] * _xScale); _currentY += (cmd.Numbers[1] * _yScale); canvas.MoveTo(_currentX, _currentY); break; // // Closing // case "Z": case "z": canvas.ClosePath(); break; // // Lines // case "L": // absolute lineTo i = 0; while (i < cmd.Numbers.Count) { _currentX = (cx + cmd.Numbers[i++] * _xScale); _currentY = (cy + cmd.Numbers[i++] * _yScale); canvas.LineTo(_currentX, _currentY); } break; case "l": // relative lineTo i = 0; while (i < cmd.Numbers.Count) { _currentX += (cmd.Numbers[i++] * _xScale); _currentY += (cmd.Numbers[i++] * _yScale); canvas.LineTo(_currentX, _currentY); } break; case "V": // absolute verticalTo i = 0; while (i < cmd.Numbers.Count) { _currentY = (cy + cmd.Numbers[i++] * _yScale); canvas.LineTo(_currentX, _currentY); } break; case "v": // relative verticalTo i = 0; while (i < cmd.Numbers.Count) { _currentY += (cmd.Numbers[i++] * _yScale); canvas.LineTo(_currentX, _currentY); } break; case "H": // absolute horizontalTo i = 0; while (i < cmd.Numbers.Count) { _currentX = (cx + cmd.Numbers[i++] * _xScale); canvas.LineTo(_currentX, _currentY); } break; case "h": // relative horizontalTo i = 0; while (i < cmd.Numbers.Count) { _currentX += (cmd.Numbers[i++] * _xScale); canvas.LineTo(_currentX, _currentY); } break; // // cubic bezier curves // case "C": // absolute cubicTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (cx + cmd.Numbers[i++] * _xScale); float y1 = (cy + cmd.Numbers[i++] * _yScale); float x2 = (cx + cmd.Numbers[i++] * _xScale); float y2 = (cy + cmd.Numbers[i++] * _yScale); float x3 = (cx + cmd.Numbers[i++] * _xScale); float y3 = (cy + cmd.Numbers[i++] * _yScale); _lastControlX = x2; _lastControlY = y2; _currentX = x3; _currentY = y3; canvas.BezierCurveTo(x1, y1, x2, y2, x3, y3); } break; case "c": // relative cubicTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (_currentX + cmd.Numbers[i++] * _xScale); float y1 = (_currentY + cmd.Numbers[i++] * _yScale); float x2 = (_currentX + cmd.Numbers[i++] * _xScale); float y2 = (_currentY + cmd.Numbers[i++] * _yScale); float x3 = (_currentX + cmd.Numbers[i++] * _xScale); float y3 = (_currentY + cmd.Numbers[i++] * _yScale); _lastControlX = x2; _lastControlY = y2; _currentX = x3; _currentY = y3; canvas.BezierCurveTo(x1, y1, x2, y2, x3, y3); } break; case "S": // absolute shorthand cubicTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (cx + cmd.Numbers[i++] * _xScale); float y1 = (cy + cmd.Numbers[i++] * _yScale); canContinue = _lastCmd == "c" || _lastCmd == "C" || _lastCmd == "S" || _lastCmd == "s"; float x2 = canContinue ? _currentX + (_currentX - _lastControlX) : _currentX; float y2 = canContinue ? _currentY + (_currentY - _lastControlY) : _currentY; float x3 = (cx + cmd.Numbers[i++] * _xScale); float y3 = (cy + cmd.Numbers[i++] * _yScale); _lastControlX = x2; _lastControlY = y2; _currentX = x3; _currentY = y3; canvas.BezierCurveTo(x1, y1, x2, y2, x3, y3); } break; case "s": // relative shorthand cubicTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (_currentX + cmd.Numbers[i++] * _xScale); float y1 = (_currentY + cmd.Numbers[i++] * _yScale); canContinue = _lastCmd == "c" || _lastCmd == "C" || _lastCmd == "S" || _lastCmd == "s"; float x2 = canContinue ? _currentX + (_currentX - _lastControlX) : _currentX; float y2 = canContinue ? _currentY + (_currentY - _lastControlY) : _currentY; float x3 = (_currentX + cmd.Numbers[i++] * _xScale); float y3 = (_currentY + cmd.Numbers[i++] * _yScale); _lastControlX = x2; _lastControlY = y2; _currentX = x3; _currentY = y3; canvas.BezierCurveTo(x1, y1, x2, y2, x3, y3); } break; // // quadratic bezier curves // case "Q": // absolute quadraticTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (cx + cmd.Numbers[i++] * _xScale); float y1 = (cy + cmd.Numbers[i++] * _yScale); float x2 = (cx + cmd.Numbers[i++] * _xScale); float y2 = (cy + cmd.Numbers[i++] * _yScale); _lastControlX = x1; _lastControlY = y1; _currentX = x2; _currentY = y2; canvas.QuadraticCurveTo(x1, y1, x2, y2); } break; case "q": // relative quadraticTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (_currentX + cmd.Numbers[i++] * _xScale); float y1 = (_currentY + cmd.Numbers[i++] * _yScale); float x2 = (_currentX + cmd.Numbers[i++] * _xScale); float y2 = (_currentY + cmd.Numbers[i++] * _yScale); _lastControlX = x1; _lastControlY = y1; _currentX = x2; _currentY = y2; canvas.QuadraticCurveTo(x1, y1, x2, y2); } break; case "T": // absolute shorthand quadraticTo i = 0; while (i < cmd.Numbers.Count) { float x1 = (cx + cmd.Numbers[i++] * _xScale); float y1 = (cy + cmd.Numbers[i++] * _yScale); canContinue = _lastCmd == "q" || _lastCmd == "Q" || _lastCmd == "t" || _lastCmd == "T"; float cpx = canContinue ? _currentX + (_currentX - _lastControlX) : _currentX; float cpy = canContinue ? _currentY + (_currentY - _lastControlY) : _currentY; _currentX = x1; _currentY = y1; _lastControlX = cpx; _lastControlY = cpy; canvas.QuadraticCurveTo(cpx, cpy, x1, y1); } break; case "t": // relative shorthand quadraticTo i = 0; while (i < cmd.Numbers.Count) { // TODO: buggy/incomplete float x1 = (_currentX + cmd.Numbers[i++] * _xScale); float y1 = (_currentY + cmd.Numbers[i++] * _yScale); canContinue = _lastCmd == "q" || _lastCmd == "Q" || _lastCmd == "t" || _lastCmd == "T"; float cpx = canContinue ? _currentX + (_currentX - _lastControlX) : _currentX; float cpy = canContinue ? _currentY + (_currentY - _lastControlY) : _currentY; _lastControlX = cpx; _lastControlY = cpy; canvas.QuadraticCurveTo(cpx, cpy, x1, y1); } break; } _lastCmd = cmd.Cmd; }