protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { base.OnPaintSurface(e); var canvas = e.Surface.Canvas; canvas.Clear(); int width = e.Info.Width; int height = e.Info.Height; SKPaint backPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.WhiteSmoke, }; canvas.DrawRect(new SKRect(0, 0, width, height), backPaint); canvas.Save(); canvas.Translate(width / 2, height / 2); canvas.Scale(Math.Min(width / 210f, height / 520f)); SKPoint center = new SKPoint(0, 0); var rect = new SKRect(-100, -100, 100, 100); // Add a buffer for the rectangle rect.Inflate(-10, -10); SKPaint GaugePointPaint = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Fill, Color = ValueColor.ToSKColor() }; SKPaint HighlightRangePaint = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Fill, Color = RangeColor.ToSKColor() }; // Draw the range of values var rangeStartAngle = AmountToAngle(HighlightRangeStartValue); var rangeEndAngle = AmountToAngle(HighlightRangeEndValue); var angleDistance = rangeEndAngle - rangeStartAngle; using (SKPath path = new SKPath()) { path.AddArc(rect, rangeStartAngle, angleDistance); path.LineTo(center); canvas.DrawPath(path, HighlightRangePaint); } // Draw the main gauge line/arc SKPaint GaugeMainLinePaintP1 = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Blue, StrokeWidth = 10 }; var startAngle = 135; var sweepAngle = 67.5f; using (SKPath path = new SKPath()) { path.AddArc(rect, startAngle, sweepAngle); canvas.DrawPath(path, GaugeMainLinePaintP1); } //Sector2 SKPaint GaugeMainLinePaintP2 = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Green, StrokeWidth = 10 }; var startAngleP2 = 202.5f; using (SKPath path = new SKPath()) { path.AddArc(rect, startAngleP2, sweepAngle); canvas.DrawPath(path, GaugeMainLinePaintP2); } //Sector3 SKPaint GaugeMainLinePaintP3 = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Orange, StrokeWidth = 10 }; var startAngleP3 = 270f; using (SKPath path = new SKPath()) { path.AddArc(rect, startAngleP3, sweepAngle); canvas.DrawPath(path, GaugeMainLinePaintP3); } //Sector 4 SKPaint GaugeMainLinePaintP4 = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Red, StrokeWidth = 10 }; var startAngleP4 = 337.5f; using (SKPath path = new SKPath()) { path.AddArc(rect, startAngleP4, sweepAngle); canvas.DrawPath(path, GaugeMainLinePaintP4); } //Draw Needle DrawNeedle(canvas, Value); //Draw Screw SKPaint NeedleScrewPaint = new SKPaint() { IsAntialias = true, Shader = SKShader.CreateRadialGradient(center, width / 60, new SKColor[] { new SKColor(171, 171, 171), SKColors.White }, new float[] { 0.05f, 0.9f }, SKShaderTileMode.Mirror) }; canvas.DrawCircle(center, width / 60, NeedleScrewPaint); SKPaint paint = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = new SKColor(81, 84, 89).WithAlpha(100), StrokeWidth = 1f }; canvas.DrawCircle(center, width / 60, paint); // Draw the Units of Measurement Text on the display SKPaint textPaint = new SKPaint { IsAntialias = true, Color = SKColors.Black }; float textWidth = textPaint.MeasureText(UnitsText); textPaint.TextSize = 12f; SKRect textBounds = SKRect.Empty; textPaint.MeasureText(UnitsText, ref textBounds); float xText = -1 * textBounds.MidX; float yText = 95 - textBounds.Height; // And draw the text canvas.DrawText(UnitsText, xText, yText, textPaint); // Draw the Value on the display var valueText = Value.ToString("F0"); //You can set F1 or F2 if you need float values float valueTextWidth = textPaint.MeasureText(valueText); textPaint.TextSize = ValueFontSize; textPaint.MeasureText(valueText, ref textBounds); xText = -1 * textBounds.MidX; yText = 85 - textBounds.Height; // And draw the text canvas.DrawText(valueText, xText, yText, textPaint); canvas.Restore(); }
/// <summary> /// Paint this font run /// </summary> /// <param name="ctx"></param> internal void Paint(PaintTextContext ctx) { // Paint selection? if (ctx.PaintSelectionBackground != null && RunKind != FontRunKind.Ellipsis) { float selStartXCoord; if (ctx.SelectionStart < Start) { selStartXCoord = Direction == TextDirection.LTR ? 0 : Width; } else if (ctx.SelectionStart >= End) { selStartXCoord = Direction == TextDirection.LTR ? Width : 0; } else { selStartXCoord = RelativeCodePointXCoords[ctx.SelectionStart - this.Start]; } float selEndXCoord; if (ctx.SelectionEnd < Start) { selEndXCoord = Direction == TextDirection.LTR ? 0 : Width; } else if (ctx.SelectionEnd >= End) { selEndXCoord = Direction == TextDirection.LTR ? Width : 0; } else { selEndXCoord = RelativeCodePointXCoords[ctx.SelectionEnd - this.Start]; } if (selStartXCoord != selEndXCoord) { var tl = new SKPoint(selStartXCoord + this.XCoord, Line.YCoord); var br = new SKPoint(selEndXCoord + this.XCoord, Line.YCoord + Line.Height); // Align coords to pixel boundaries // Not needed - disabled antialias on SKPaint instead /* * if (ctx.Canvas.TotalMatrix.TryInvert(out var inverse)) * { * tl = ctx.Canvas.TotalMatrix.MapPoint(tl); * br = ctx.Canvas.TotalMatrix.MapPoint(br); * tl = new SKPoint((float)Math.Round(tl.X), (float)Math.Round(tl.Y)); * br = new SKPoint((float)Math.Round(br.X), (float)Math.Round(br.Y)); * tl = inverse.MapPoint(tl); * br = inverse.MapPoint(br); * } */ var rect = new SKRect(tl.X, tl.Y, br.X, br.Y); ctx.Canvas.DrawRect(rect, ctx.PaintSelectionBackground); } } // Don't paint trailing whitespace runs if (RunKind == FontRunKind.TrailingWhitespace) { return; } // Text using (var paint = new SKPaint()) { // Work out font variant adjustments float glyphScale = 1; float glyphVOffset = 0; if (Style.FontVariant == FontVariant.SuperScript) { glyphScale = 0.65f; glyphVOffset = -Style.FontSize * 0.35f; } if (Style.FontVariant == FontVariant.SubScript) { glyphScale = 0.65f; glyphVOffset = Style.FontSize * 0.1f; } // Setup SKPaint paint.Color = Style.TextColor; paint.IsAntialias = ctx.Options.IsAntialias; paint.LcdRenderText = ctx.Options.LcdRenderText; unsafe { fixed(ushort *pGlyphs = Glyphs.Underlying) { // Get glyph positions var glyphPositions = GlyphPositions.ToArray(); // Create the font if (_font == null) { _font = new SKFont(this.Typeface, this.Style.FontSize * glyphScale); _font.Subpixel = true; } // Create the SKTextBlob (if necessary) if (_textBlob == null) { _textBlob = SKTextBlob.CreatePositioned( (IntPtr)(pGlyphs + Glyphs.Start), Glyphs.Length * sizeof(ushort), SKTextEncoding.GlyphId, _font, GlyphPositions.AsSpan()); } // Paint underline if (Style.Underline != UnderlineStyle.None && RunKind == FontRunKind.Normal) { // Work out underline metrics float underlineYPos = Line.YCoord + Line.BaseLine + (_font.Metrics.UnderlinePosition ?? 0); paint.StrokeWidth = _font.Metrics.UnderlineThickness ?? 1; if (Style.Underline == UnderlineStyle.Gapped) { // Get intercept positions var interceptPositions = _textBlob.GetIntercepts(underlineYPos - paint.StrokeWidth / 2, underlineYPos + paint.StrokeWidth); // Paint gapped underlinline float x = XCoord; for (int i = 0; i < interceptPositions.Length; i += 2) { float b = interceptPositions[i] - paint.StrokeWidth; if (x < b) { ctx.Canvas.DrawLine(new SKPoint(x, underlineYPos), new SKPoint(b, underlineYPos), paint); } x = interceptPositions[i + 1] + paint.StrokeWidth; } if (x < XCoord + Width) { ctx.Canvas.DrawLine(new SKPoint(x, underlineYPos), new SKPoint(XCoord + Width, underlineYPos), paint); } } else { switch (Style.Underline) { case UnderlineStyle.ImeInput: paint.PathEffect = SKPathEffect.CreateDash(new float[] { paint.StrokeWidth, paint.StrokeWidth }, paint.StrokeWidth); break; case UnderlineStyle.ImeConverted: paint.PathEffect = SKPathEffect.CreateDash(new float[] { paint.StrokeWidth, paint.StrokeWidth }, paint.StrokeWidth); break; case UnderlineStyle.ImeTargetConverted: paint.StrokeWidth *= 2; break; case UnderlineStyle.ImeTargetNonConverted: break; } // Paint solid underline ctx.Canvas.DrawLine(new SKPoint(XCoord, underlineYPos), new SKPoint(XCoord + Width, underlineYPos), paint); paint.PathEffect = null; } } ctx.Canvas.DrawText(_textBlob, 0, 0, paint); } } // Paint strikethrough if (Style.StrikeThrough != StrikeThroughStyle.None && RunKind == FontRunKind.Normal) { paint.StrokeWidth = _font.Metrics.StrikeoutThickness ?? 0; float strikeYPos = Line.YCoord + Line.BaseLine + (_font.Metrics.StrikeoutPosition ?? 0) + glyphVOffset; ctx.Canvas.DrawLine(new SKPoint(XCoord, strikeYPos), new SKPoint(XCoord + Width, strikeYPos), paint); } } }
public static void DrawBitmap(this SKCanvas canvas, SKBitmap bitmap, SKRect source, SKRect dest, BitmapStretch stretch, BitmapAlignment horizontal = BitmapAlignment.Center, BitmapAlignment vertical = BitmapAlignment.Center, SKPaint paint = null) { if (stretch == BitmapStretch.Fill) { canvas.DrawBitmap(bitmap, source, dest, paint); } else { float scale = 1; switch (stretch) { case BitmapStretch.None: break; case BitmapStretch.Uniform: scale = Math.Min(dest.Width / source.Width, dest.Height / source.Height); break; case BitmapStretch.UniformToFill: scale = Math.Max(dest.Width / source.Width, dest.Height / source.Height); break; } SKRect display = CalculateDisplayRect(dest, scale * source.Width, scale * source.Height, horizontal, vertical); canvas.DrawBitmap(bitmap, source, display, paint); } }
public static void drawClock(SKCanvas canvas, Context context, SKRect targetFrame, ResizingBehavior resizing, SKColor numbersColor, SKColor darkHandsColor, SKColor lightHandColor, SKColor rimColor, SKColor tickColor, SKColor faceColor, float hours, float minutes, float seconds) { // General Declarations // Stack<Matrix> currentTransformation = new Stack<Matrix>(); // skipping - we do not support Matrix yet // currentTransformation.push(new Matrix()); // skipping - we do not support Matrix yet SKPaint paint = CacheForClock.paint; // Local Variables String expression = hours > 12f ? "PM" : "AM"; float secondsAngle = -seconds / 60f * 360f; float minuteAngle = -(minutes / 60f * 360f - secondsAngle / 60f); float hourAngle = -hours / 12f * 360f + minuteAngle / 12f; // Resize to Target Frame canvas.Save(); var resizedFrame = Helpers.ResizingBehaviorApply(resizing, CacheForClock.originalFrame, targetFrame); canvas.Translate(resizedFrame.Left, resizedFrame.Top); canvas.Scale(resizedFrame.Width / 260f, resizedFrame.Height / 260f); // Oval 2 canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet var oval2Rect = new SKRect(-116f, -116f, 116f, 116f); SKPath oval2Path = CacheForClock.oval2Path; oval2Path.Reset(); oval2Path.AddOval(oval2Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)rimColor; canvas.DrawPath(oval2Path, paint); canvas.Restore(); // Oval canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet var ovalRect = new SKRect(-110f, -110f, 110f, 110f); SKPath ovalPath = CacheForClock.ovalPath; ovalPath.Reset(); ovalPath.AddOval(ovalRect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)faceColor; canvas.DrawPath(ovalPath, paint); canvas.Restore(); // Text var textRect = new SKRect(118.48f, 34.85f, 142.5f, 53f); SKPath textPath = CacheForClock.textPath; textPath.Reset(); textPath.MoveTo(123.73f, 38.95f); textPath.LineTo(120.23f, 41.82f); textPath.LineTo(118.48f, 39.75f); textPath.LineTo(124f, 35.3f); textPath.LineTo(126.73f, 35.3f); textPath.LineTo(126.73f, 53f); textPath.LineTo(123.73f, 53f); textPath.LineTo(123.73f, 38.95f); textPath.Close(); textPath.MoveTo(130.73f, 50.25f); textPath.LineTo(137.55f, 43.55f); textPath.CubicTo(138.1f, 43.02f, 138.54f, 42.48f, 138.86f, 41.94f); textPath.CubicTo(139.19f, 41.4f, 139.35f, 40.78f, 139.35f, 40.07f); textPath.CubicTo(139.35f, 39.24f, 139.08f, 38.58f, 138.54f, 38.09f); textPath.CubicTo(138f, 37.6f, 137.33f, 37.35f, 136.53f, 37.35f); textPath.CubicTo(135.67f, 37.35f, 134.99f, 37.64f, 134.48f, 38.21f); textPath.CubicTo(133.96f, 38.79f, 133.64f, 39.51f, 133.53f, 40.38f); textPath.LineTo(130.6f, 39.92f); textPath.CubicTo(130.68f, 39.19f, 130.89f, 38.52f, 131.23f, 37.9f); textPath.CubicTo(131.56f, 37.28f, 131.98f, 36.75f, 132.5f, 36.3f); textPath.CubicTo(133.02f, 35.85f, 133.62f, 35.5f, 134.31f, 35.24f); textPath.CubicTo(135f, 34.98f, 135.76f, 34.85f, 136.57f, 34.85f); textPath.CubicTo(137.34f, 34.85f, 138.08f, 34.96f, 138.79f, 35.17f); textPath.CubicTo(139.5f, 35.39f, 140.12f, 35.72f, 140.68f, 36.16f); textPath.CubicTo(141.23f, 36.6f, 141.66f, 37.15f, 141.99f, 37.79f); textPath.CubicTo(142.31f, 38.43f, 142.48f, 39.17f, 142.48f, 40.03f); textPath.CubicTo(142.48f, 40.59f, 142.4f, 41.12f, 142.25f, 41.61f); textPath.CubicTo(142.1f, 42.1f, 141.9f, 42.57f, 141.64f, 43f); textPath.CubicTo(141.38f, 43.43f, 141.08f, 43.85f, 140.74f, 44.24f); textPath.CubicTo(140.4f, 44.63f, 140.03f, 45.01f, 139.63f, 45.38f); textPath.LineTo(134.53f, 50.25f); textPath.LineTo(142.5f, 50.25f); textPath.LineTo(142.5f, 53f); textPath.LineTo(130.73f, 53f); textPath.LineTo(130.73f, 50.25f); textPath.Close(); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)numbersColor; canvas.DrawPath(textPath, paint); // Bezier canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-(minuteAngle + 90f)); // currentTransformation.peek().postRotate(-(minuteAngle + 90f)); // skipping - we do not support Matrix yet var bezierRect = new SKRect(-10f, -10f, 95f, 10f); SKPath bezierPath = CacheForClock.bezierPath; bezierPath.Reset(); bezierPath.MoveTo(7.07f, -7.07f); bezierPath.CubicTo(8.25f, -5.89f, 9.07f, -4.49f, 9.54f, -3f); bezierPath.LineTo(95f, -3f); bezierPath.LineTo(95f, 3f); bezierPath.LineTo(9.54f, 3f); bezierPath.CubicTo(9.07f, 4.49f, 8.25f, 5.89f, 7.07f, 7.07f); bezierPath.CubicTo(3.17f, 10.98f, -3.17f, 10.98f, -7.07f, 7.07f); bezierPath.CubicTo(-10.98f, 3.17f, -10.98f, -3.17f, -7.07f, -7.07f); bezierPath.CubicTo(-3.17f, -10.98f, 3.17f, -10.98f, 7.07f, -7.07f); bezierPath.Close(); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)darkHandsColor; canvas.DrawPath(bezierPath, paint); canvas.Restore(); // Bezier 2 canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-(hourAngle + 90f)); // currentTransformation.peek().postRotate(-(hourAngle + 90f)); // skipping - we do not support Matrix yet var bezier2Rect = new SKRect(-10f, -10f, 56f, 10f); SKPath bezier2Path = CacheForClock.bezier2Path; bezier2Path.Reset(); bezier2Path.MoveTo(7.07f, -7.07f); bezier2Path.CubicTo(7.7f, -6.44f, 8.24f, -5.74f, 8.66f, -5f); bezier2Path.LineTo(56f, -5f); bezier2Path.LineTo(56f, 5f); bezier2Path.LineTo(8.66f, 5f); bezier2Path.CubicTo(8.24f, 5.74f, 7.7f, 6.44f, 7.07f, 7.07f); bezier2Path.CubicTo(3.17f, 10.98f, -3.17f, 10.98f, -7.07f, 7.07f); bezier2Path.CubicTo(-10.98f, 3.17f, -10.98f, -3.17f, -7.07f, -7.07f); bezier2Path.CubicTo(-3.17f, -10.98f, 3.17f, -10.98f, 7.07f, -7.07f); bezier2Path.Close(); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)darkHandsColor; canvas.DrawPath(bezier2Path, paint); canvas.Restore(); // Bezier 3 canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-(secondsAngle + 90f)); // currentTransformation.peek().postRotate(-(secondsAngle + 90f)); // skipping - we do not support Matrix yet var bezier3Rect = new SKRect(-6f, -6f, 99f, 6f); SKPath bezier3Path = CacheForClock.bezier3Path; bezier3Path.Reset(); bezier3Path.MoveTo(4.24f, -4.24f); bezier3Path.CubicTo(5.16f, -3.33f, 5.72f, -2.19f, 5.92f, -1f); bezier3Path.LineTo(99f, -1f); bezier3Path.LineTo(99f, 1f); bezier3Path.LineTo(5.92f, 1f); bezier3Path.CubicTo(5.72f, 2.19f, 5.16f, 3.33f, 4.24f, 4.24f); bezier3Path.CubicTo(1.9f, 6.59f, -1.9f, 6.59f, -4.24f, 4.24f); bezier3Path.CubicTo(-6.59f, 1.9f, -6.59f, -1.9f, -4.24f, -4.24f); bezier3Path.CubicTo(-1.9f, -6.59f, 1.9f, -6.59f, 4.24f, -4.24f); bezier3Path.Close(); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)lightHandColor; canvas.DrawPath(bezier3Path, paint); canvas.Restore(); // Group { // Rectangle var rectangleRect = new SKRect(127f, 20f, 133f, 28f); SKPath rectanglePath = CacheForClock.rectanglePath; rectanglePath.Reset(); rectanglePath.AddRect(rectangleRect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectanglePath, paint); // Rectangle 2 var rectangle2Rect = new SKRect(127f, 232f, 133f, 240f); SKPath rectangle2Path = CacheForClock.rectangle2Path; rectangle2Path.Reset(); rectangle2Path.AddRect(rectangle2Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle2Path, paint); } // Group 2 { canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(90f); // currentTransformation.peek().postRotate(90f); // skipping - we do not support Matrix yet // Rectangle 3 var rectangle3Rect = new SKRect(-3f, -110f, 3f, -102f); SKPath rectangle3Path = CacheForClock.rectangle3Path; rectangle3Path.Reset(); rectangle3Path.AddRect(rectangle3Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle3Path, paint); // Rectangle 4 var rectangle4Rect = new SKRect(-3f, 102f, 3f, 110f); SKPath rectangle4Path = CacheForClock.rectangle4Path; rectangle4Path.Reset(); rectangle4Path.AddRect(rectangle4Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle4Path, paint); canvas.Restore(); } // Group 3 { canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-30f); // currentTransformation.peek().postRotate(-30f); // skipping - we do not support Matrix yet // Rectangle 5 var rectangle5Rect = new SKRect(-3f, -110f, 3f, -102f); SKPath rectangle5Path = CacheForClock.rectangle5Path; rectangle5Path.Reset(); rectangle5Path.AddRect(rectangle5Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle5Path, paint); // Rectangle 6 var rectangle6Rect = new SKRect(-3f, 102f, 3f, 110f); SKPath rectangle6Path = CacheForClock.rectangle6Path; rectangle6Path.Reset(); rectangle6Path.AddRect(rectangle6Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle6Path, paint); canvas.Restore(); } // Group 4 { canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-60f); // currentTransformation.peek().postRotate(-60f); // skipping - we do not support Matrix yet // Rectangle 7 var rectangle7Rect = new SKRect(-3f, -110f, 3f, -102f); SKPath rectangle7Path = CacheForClock.rectangle7Path; rectangle7Path.Reset(); rectangle7Path.AddRect(rectangle7Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle7Path, paint); // Rectangle 8 var rectangle8Rect = new SKRect(-3f, 102f, 3f, 110f); SKPath rectangle8Path = CacheForClock.rectangle8Path; rectangle8Path.Reset(); rectangle8Path.AddRect(rectangle8Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle8Path, paint); canvas.Restore(); } // Group 5 { canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-120f); // currentTransformation.peek().postRotate(-120f); // skipping - we do not support Matrix yet // Rectangle 9 var rectangle9Rect = new SKRect(-3f, -110f, 3f, -102f); SKPath rectangle9Path = CacheForClock.rectangle9Path; rectangle9Path.Reset(); rectangle9Path.AddRect(rectangle9Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle9Path, paint); // Rectangle 10 var rectangle10Rect = new SKRect(-3f, 102f, 3f, 110f); SKPath rectangle10Path = CacheForClock.rectangle10Path; rectangle10Path.Reset(); rectangle10Path.AddRect(rectangle10Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle10Path, paint); canvas.Restore(); } // Group 6 { canvas.Save(); canvas.Translate(130f, 130f); // currentTransformation.peek().postTranslate(130f, 130f); // skipping - we do not support Matrix yet canvas.RotateDegrees(-150f); // currentTransformation.peek().postRotate(-150f); // skipping - we do not support Matrix yet // Rectangle 11 var rectangle11Rect = new SKRect(-3f, -110f, 3f, -102f); SKPath rectangle11Path = CacheForClock.rectangle11Path; rectangle11Path.Reset(); rectangle11Path.AddRect(rectangle11Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle11Path, paint); // Rectangle 12 var rectangle12Rect = new SKRect(-3f, 102f, 3f, 110f); SKPath rectangle12Path = CacheForClock.rectangle12Path; rectangle12Path.Reset(); rectangle12Path.AddRect(rectangle12Rect, SKPathDirection.Clockwise); paint.Reset(); paint.IsAntialias = true; paint.Style = SKPaintStyle.Fill; paint.Color = (SKColor)tickColor; canvas.DrawPath(rectangle12Path, paint); canvas.Restore(); } // Text 2 var text2Rect = new SKRect(111f, 198f, 149f, 238f); var text2TextPaint = CacheForClock.text2TextPaint; text2TextPaint.Reset(); text2TextPaint.IsAntialias = true; text2TextPaint.Color = (SKColor)numbersColor; text2TextPaint.Typeface = TypefaceManager.GetTypeface("Avenir Next.ttc"); text2TextPaint.TextSize = 25f; StaticLayout text2StaticLayout = CacheForClock.text2StaticLayout.get((int)text2Rect.Width, SKTextAlign.Center, "6", text2TextPaint); canvas.Save(); canvas.ClipRect(text2Rect); canvas.Translate(text2Rect.Left, text2Rect.Top + (text2Rect.Height - text2StaticLayout.getHeight()) / 2f); text2StaticLayout.draw(canvas); canvas.Restore(); // Text 3 var text3Rect = new SKRect(201f, 110f, 239f, 150f); var text3TextPaint = CacheForClock.text3TextPaint; text3TextPaint.Reset(); text3TextPaint.IsAntialias = true; text3TextPaint.Color = (SKColor)numbersColor; text3TextPaint.Typeface = TypefaceManager.GetTypeface("Avenir Next.ttc"); text3TextPaint.TextSize = 25f; StaticLayout text3StaticLayout = CacheForClock.text3StaticLayout.get((int)text3Rect.Width, SKTextAlign.Center, "3", text3TextPaint); canvas.Save(); canvas.ClipRect(text3Rect); canvas.Translate(text3Rect.Left, text3Rect.Top + (text3Rect.Height - text3StaticLayout.getHeight()) / 2f); text3StaticLayout.draw(canvas); canvas.Restore(); // Text 4 var text4Rect = new SKRect(22f, 110f, 60f, 150f); var text4TextPaint = CacheForClock.text4TextPaint; text4TextPaint.Reset(); text4TextPaint.IsAntialias = true; text4TextPaint.Color = (SKColor)numbersColor; text4TextPaint.Typeface = TypefaceManager.GetTypeface("Avenir Next.ttc"); text4TextPaint.TextSize = 25f; StaticLayout text4StaticLayout = CacheForClock.text4StaticLayout.get((int)text4Rect.Width, SKTextAlign.Center, "9", text4TextPaint); canvas.Save(); canvas.ClipRect(text4Rect); canvas.Translate(text4Rect.Left, text4Rect.Top + (text4Rect.Height - text4StaticLayout.getHeight()) / 2f); text4StaticLayout.draw(canvas); canvas.Restore(); // Text 13 var text13Rect = new SKRect(99f, 144f, 161f, 178f); var text13TextPaint = CacheForClock.text13TextPaint; text13TextPaint.Reset(); text13TextPaint.IsAntialias = true; text13TextPaint.Color = (SKColor)numbersColor; text13TextPaint.Typeface = TypefaceManager.GetTypeface("Avenir Next.ttc"); text13TextPaint.TextSize = 20f; StaticLayout text13StaticLayout = CacheForClock.text13StaticLayout.get((int)text13Rect.Width, SKTextAlign.Center, expression, text13TextPaint); canvas.Save(); canvas.ClipRect(text13Rect); canvas.Translate(text13Rect.Left, text13Rect.Top + (text13Rect.Height - text13StaticLayout.getHeight()) / 2f); text13StaticLayout.draw(canvas); canvas.Restore(); canvas.Restore(); }
private void Build(Document document) { // Add a page to the document! Page page = new Page(document); // Instantiates the page inside the document context. document.Pages.Add(page); // Puts the page in the pages collection. SKSize pageSize = page.Size; // Create a content composer for the content stream! /* * NOTE: There are several ways to add contents to a content stream: * - adding content objects directly to the Contents collection; * - adding content objects through a ContentScanner instance; * - invoking basic drawing functions through a PrimitiveComposer instance; * - invoking advanced static-positioning functions through a BlockComposer instance; * - invoking advanced dynamic-positioning functions through a FlowComposer instance (currently not implemented yet). */ PrimitiveComposer composer = new PrimitiveComposer(page); // Wrap the content composer within a block filter! /* * NOTE: The block filter is a basic typesetter. It exposes higher-level graphical * functionalities (horizontal/vertical alignment, indentation, paragraph composition etc.) * leveraging the content composer primitives. * It's important to note that this is just an intermediate abstraction layer of the typesetting * stack: further abstract levels could sit upon it, allowing the convenient treatment of * typographic entities like titles, paragraphs, columns, tables, headers, footers etc. * When such further abstract levels are available, the final user (developer of consuming * applications) won't care any more of the details you can see here in the following code lines * (such as bothering to select the first-letter font...). */ BlockComposer blockComposer = new BlockComposer(composer); composer.BeginLocalState(); // Define the block frame that will constrain our contents on the page canvas! SKRect frame = SKRect.Create( Margin_X, Margin_Y, (float)pageSize.Width - Margin_X * 2, (float)pageSize.Height - Margin_Y * 2 ); // Begin the title block! blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Top); fonts::Font decorativeFont = fonts::Font.Get( document, GetResourcePath("fonts" + Path.DirectorySeparatorChar + "Ruritania-Outline.ttf") ); composer.SetFont(decorativeFont, 56); blockComposer.ShowText("Chapter 1"); blockComposer.ShowBreak(); composer.SetFont(decorativeFont, 32); blockComposer.ShowText("Down the Rabbit-Hole"); // End the title block! blockComposer.End(); // Update the block frame in order to begin after the title! frame = SKRect.Create( (float)blockComposer.BoundBox.Left, (float)blockComposer.BoundBox.Top + blockComposer.BoundBox.Height, (float)blockComposer.BoundBox.Width, (float)pageSize.Height - Margin_Y - (blockComposer.BoundBox.Top + blockComposer.BoundBox.Height) ); // Begin the body block! blockComposer.Begin(frame, XAlignmentEnum.Justify, YAlignmentEnum.Bottom); fonts::Font bodyFont = fonts::Font.Get( document, GetResourcePath("fonts" + Path.DirectorySeparatorChar + "TravelingTypewriter.otf") ); composer.SetFont(bodyFont, 14); composer.BeginLocalState(); composer.SetFont(decorativeFont, 28); blockComposer.ShowText("A"); composer.End(); blockComposer.ShowText("lice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice 'without pictures or conversation?'"); // Define new-paragraph first-line offset! SKSize breakSize = new SKSize(24, 8); // Indentation (24pt) and top margin (8pt). // Begin a new paragraph! blockComposer.ShowBreak(breakSize); blockComposer.ShowText("So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her."); // Begin a new paragraph! blockComposer.ShowBreak(breakSize); blockComposer.ShowText("There was nothing so VERY remarkable in that; nor did Alice think it so VERY much out of the way to hear the Rabbit say to itself, 'Oh dear! Oh dear! I shall be late!' (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT- POCKET, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge."); // End the body block! blockComposer.End(); composer.End(); composer.BeginLocalState(); composer.Rotate( 90, new SKPoint( pageSize.Width - 50, pageSize.Height - 25 ) ); blockComposer = new BlockComposer(composer); blockComposer.Begin( SKRect.Create(0, 0, 300, 50), XAlignmentEnum.Left, YAlignmentEnum.Middle ); composer.SetFont(bodyFont, 8); blockComposer.ShowText("Generated by PDF Clown on " + System.DateTime.Now); blockComposer.ShowBreak(); blockComposer.ShowText("For more info, visit http://www.pdfclown.org"); blockComposer.End(); composer.End(); // Flush the contents into the page! composer.Flush(); }
public void SetUp() { _rect1 = new SKRect(0.1f, 0.2f, 0.3f, 0.4f); _rect2 = _rect1.Scale(new SKSize(500f, 600f)); }
public static SKPath ToSKPath(this IEnumerable <IBaseShape> shapes) { var path = new SKPath { FillType = SKPathFillType.Winding }; var previous = default(IPointShape); foreach (var shape in shapes) { switch (shape) { case ILineShape lineShape: { if (previous == null || previous != lineShape.Start) { path.MoveTo( (float)(lineShape.Start.X), (float)(lineShape.Start.Y)); } path.LineTo( (float)(lineShape.End.X), (float)(lineShape.End.Y)); previous = lineShape.End; } break; case IRectangleShape rectangleShape: { path.AddRect( SkiaSharpDrawUtil.CreateRect(rectangleShape.TopLeft, rectangleShape.BottomRight), SKPathDirection.Clockwise); } break; case IEllipseShape ellipseShape: { path.AddOval( SkiaSharpDrawUtil.CreateRect(ellipseShape.TopLeft, ellipseShape.BottomRight), SKPathDirection.Clockwise); } break; case IArcShape arcShape: { var a = new GdiArc( Point2.FromXY(arcShape.Point1.X, arcShape.Point1.Y), Point2.FromXY(arcShape.Point2.X, arcShape.Point2.Y), Point2.FromXY(arcShape.Point3.X, arcShape.Point3.Y), Point2.FromXY(arcShape.Point4.X, arcShape.Point4.Y)); var rect = new SKRect( (float)(a.X), (float)(a.Y), (float)(a.X + a.Width), (float)(a.Y + a.Height)); path.AddArc(rect, (float)a.StartAngle, (float)a.SweepAngle); } break; case ICubicBezierShape cubicBezierShape: { if (previous == null || previous != cubicBezierShape.Point1) { path.MoveTo( (float)(cubicBezierShape.Point1.X), (float)(cubicBezierShape.Point1.Y)); } path.CubicTo( (float)(cubicBezierShape.Point2.X), (float)(cubicBezierShape.Point2.Y), (float)(cubicBezierShape.Point3.X), (float)(cubicBezierShape.Point3.Y), (float)(cubicBezierShape.Point4.X), (float)(cubicBezierShape.Point4.Y)); previous = cubicBezierShape.Point4; } break; case IQuadraticBezierShape quadraticBezierShape: { if (previous == null || previous != quadraticBezierShape.Point1) { path.MoveTo( (float)(quadraticBezierShape.Point1.X), (float)(quadraticBezierShape.Point1.Y)); } path.QuadTo( (float)(quadraticBezierShape.Point2.X), (float)(quadraticBezierShape.Point2.Y), (float)(quadraticBezierShape.Point3.X), (float)(quadraticBezierShape.Point3.Y)); previous = quadraticBezierShape.Point3; } break; case ITextShape textShape: { var resultPath = ToSKPath(textShape); if (resultPath != null && !resultPath.IsEmpty) { path.AddPath(resultPath, SKPathAddMode.Append); } } break; case IPathShape pathShape: { var resultPath = ToSKPath(pathShape); if (resultPath != null && !resultPath.IsEmpty) { path.AddPath(resultPath, SKPathAddMode.Append); } } break; case IGroupShape groupShape: { var resultPath = ToSKPath(groupShape.Shapes); if (resultPath != null && !resultPath.IsEmpty) { path.AddPath(resultPath, SKPathAddMode.Append); } } break; } } return(path); }
public ImageDrawable(SvgImage svgImage, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None) : base(svgImage, root, parent) { IgnoreAttributes = ignoreAttributes; IsDrawable = CanDraw(svgImage, IgnoreAttributes) && HasFeatures(svgImage, IgnoreAttributes); if (!IsDrawable) { return; } float width = svgImage.Width.ToDeviceValue(UnitRenderingType.Horizontal, svgImage, skOwnerBounds); float height = svgImage.Height.ToDeviceValue(UnitRenderingType.Vertical, svgImage, skOwnerBounds); float x = svgImage.Location.X.ToDeviceValue(UnitRenderingType.Horizontal, svgImage, skOwnerBounds); float y = svgImage.Location.Y.ToDeviceValue(UnitRenderingType.Vertical, svgImage, skOwnerBounds); var location = new SKPoint(x, y); if (width <= 0f || height <= 0f || svgImage.Href == null) { IsDrawable = false; return; } // TODO: Check for image recursive references. //if (SkiaUtil.HasRecursiveReference(svgImage, (e) => e.Href)) //{ // _canDraw = false; // return; //} var image = SvgImageExtensions.GetImage(svgImage.Href, svgImage.OwnerDocument); var skImage = image as SKImage; var svgFragment = image as SvgFragment; if (skImage == null && svgFragment == null) { IsDrawable = false; return; } if (skImage != null) { _disposable.Add(skImage); } SrcRect = default; if (skImage != null) { SrcRect = SKRect.Create(0f, 0f, skImage.Width, skImage.Height); } if (svgFragment != null) { var skSize = SvgExtensions.GetDimensions(svgFragment); SrcRect = SKRect.Create(0f, 0f, skSize.Width, skSize.Height); } var destClip = SKRect.Create(location.X, location.Y, width, height); var aspectRatio = svgImage.AspectRatio; if (aspectRatio.Align != SvgPreserveAspectRatio.none) { var fScaleX = destClip.Width / SrcRect.Width; var fScaleY = destClip.Height / SrcRect.Height; var xOffset = 0f; var yOffset = 0f; if (aspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } switch (aspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: xOffset = (destClip.Width - SrcRect.Width * fScaleX) / 2; break; case SvgPreserveAspectRatio.xMaxYMin: xOffset = (destClip.Width - SrcRect.Width * fScaleX); break; case SvgPreserveAspectRatio.xMinYMid: yOffset = (destClip.Height - SrcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMidYMid: xOffset = (destClip.Width - SrcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - SrcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMaxYMid: xOffset = (destClip.Width - SrcRect.Width * fScaleX); yOffset = (destClip.Height - SrcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMinYMax: yOffset = (destClip.Height - SrcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMidYMax: xOffset = (destClip.Width - SrcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - SrcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMaxYMax: xOffset = (destClip.Width - SrcRect.Width * fScaleX); yOffset = (destClip.Height - SrcRect.Height * fScaleY); break; } DestRect = SKRect.Create( destClip.Left + xOffset, destClip.Top + yOffset, SrcRect.Width * fScaleX, SrcRect.Height * fScaleY); } else { DestRect = destClip; } Clip = destClip; var skClipRect = SvgClippingExtensions.GetClipRect(svgImage, destClip); if (skClipRect != null) { Clip = skClipRect; } if (skImage != null) { Image = skImage; } if (svgFragment != null) { FragmentDrawable = new FragmentDrawable(svgFragment, skOwnerBounds, root, this, ignoreAttributes); _disposable.Add(FragmentDrawable); } IsAntialias = SvgPaintingExtensions.IsAntialias(svgImage); if (Image != null) { TransformedBounds = DestRect; } if (FragmentDrawable != null) { //_skBounds = _fragmentDrawable._skBounds; TransformedBounds = DestRect; } Transform = SvgTransformsExtensions.ToSKMatrix(svgImage.Transforms); FragmentTransform = SKMatrix.MakeIdentity(); if (FragmentDrawable != null) { float dx = DestRect.Left; float dy = DestRect.Top; float sx = DestRect.Width / SrcRect.Width; float sy = DestRect.Height / SrcRect.Height; var skTranslationMatrix = SKMatrix.MakeTranslation(dx, dy); var skScaleMatrix = SKMatrix.MakeScale(sx, sy); FragmentTransform = FragmentTransform.PreConcat(skTranslationMatrix); FragmentTransform = FragmentTransform.PreConcat(skScaleMatrix); } Fill = null; Stroke = null; // TODO: Transform _skBounds using _skMatrix. TransformedBounds = Transform.MapRect(TransformedBounds); }
protected Shape(Page page, SKRect box, string text, PdfName subtype) : base(page, subtype, box, text) { }
private void Populate(Document document) { Page page = new Page(document); document.Pages.Add(page); PrimitiveComposer composer = new PrimitiveComposer(page); fonts::PdfType1Font font = fonts::PdfType1Font.Load(document, fonts::PdfType1Font.FamilyEnum.Courier, true, false); composer.SetFont(font, 12); // Sticky note. composer.ShowText("Sticky note annotation:", new SKPoint(35, 35)); new StickyNote(page, new SKPoint(50, 50), "Text of the Sticky note annotation") { ImageName = ImageNameEnum.Note, Color = DeviceRGBColor.Get(SKColors.Yellow), Popup = new Popup( page, SKRect.Create(200, 25, 200, 75), "Text of the Popup annotation (this text won't be visible as associating popups to markup annotations overrides the former's properties with the latter's)" ), Author = "Stefano", Subject = "Sticky note", IsOpen = true }; new StickyNote(page, new SKPoint(80, 50), "Text of the Help sticky note annotation") { ImageName = ImageNameEnum.Help, Color = DeviceRGBColor.Get(SKColors.Pink), Author = "Stefano", Subject = "Sticky note", Popup = new Popup( page, SKRect.Create(400, 25, 200, 75), "Text of the Popup annotation (this text won't be visible as associating popups to markup annotations overrides the former's properties with the latter's)" ) }; new StickyNote(page, new SKPoint(110, 50), "Text of the Comment sticky note annotation") { ImageName = ImageNameEnum.Comment, Color = DeviceRGBColor.Get(SKColors.Green), Author = "Stefano", Subject = "Sticky note" }; new StickyNote(page, new SKPoint(140, 50), "Text of the Key sticky note annotation") { ImageName = ImageNameEnum.Key, Color = DeviceRGBColor.Get(SKColors.Blue), Author = "Stefano", Subject = "Sticky note" }; // Callout. composer.ShowText("Callout note annotation:", new SKPoint(35, 85)); new FreeText(page, SKRect.Create(250, 90, 150, 70), "Text of the Callout note annotation") { Line = new FreeText.CalloutLine( page, new SKPoint(100, 100), new SKPoint(150, 125), new SKPoint(250, 125) ), Intent = MarkupIntent.FreeTextCallout, LineEndStyle = LineEndStyleEnum.OpenArrow, Border = new Border(1), Color = DeviceRGBColor.Get(SKColors.Yellow) }; // File attachment. composer.ShowText("File attachment annotation:", new SKPoint(35, 135)); new FileAttachment( page, SKRect.Create(50, 150, 15, 20), "Text of the File attachment annotation", FileSpecification.Get( EmbeddedFile.Get(document, GetResourcePath("images" + Path.DirectorySeparatorChar + "gnu.jpg")), "happyGNU.jpg") ) { AttachmentName = FileAttachmentImageType.PaperClip, Author = "Stefano", Subject = "File attachment" }; composer.ShowText("Line annotation:", new SKPoint(35, 185)); { composer.BeginLocalState(); composer.SetFont(font, 10); // Arrow line. composer.ShowText("Arrow:", new SKPoint(50, 200)); new Line( page, new SKPoint(50, 260), new SKPoint(200, 210), "Text of the Arrow line annotation", DeviceRGBColor.Get(SKColors.Black)) { StartStyle = LineEndStyleEnum.Circle, EndStyle = LineEndStyleEnum.ClosedArrow, CaptionVisible = true, InteriorColor = DeviceRGBColor.Get(SKColors.Green), Author = "Stefano", Subject = "Arrow line" }; // Dimension line. composer.ShowText("Dimension:", new SKPoint(300, 200)); new Line( page, new SKPoint(300, 220), new SKPoint(500, 220), "Text of the Dimension line annotation", DeviceRGBColor.Get(SKColors.Blue) ) { LeaderLineLength = -20, LeaderLineExtension = 10, StartStyle = LineEndStyleEnum.OpenArrow, EndStyle = LineEndStyleEnum.OpenArrow, Border = new Border(1), CaptionVisible = true, Author = "Stefano", Subject = "Dimension line" }; composer.End(); } var path = new SKPath(); path.MoveTo(new SKPoint(50, 320)); path.LineTo(new SKPoint(70, 305)); path.LineTo(new SKPoint(110, 335)); path.LineTo(new SKPoint(130, 320)); path.LineTo(new SKPoint(110, 305)); path.LineTo(new SKPoint(70, 335)); path.LineTo(new SKPoint(50, 320)); // Scribble. composer.ShowText("Scribble annotation:", new SKPoint(35, 285)); new Scribble( page, new List <SKPath> { path }, "Text of the Scribble annotation", DeviceRGBColor.Get(SKColors.Orange)) { Border = new Border(1, new LineDash(new float[] { 5, 2, 2, 2 })), Author = "Stefano", Subject = "Scribble" }; // Rectangle. composer.ShowText("Rectangle annotation:", new SKPoint(35, 350)); new PdfClown.Documents.Interaction.Annotations.Rectangle( page, SKRect.Create(50, 370, 100, 30), "Text of the Rectangle annotation") { Color = DeviceRGBColor.Get(SKColors.Red), Border = new Border(1, new LineDash(new float[] { 5 })), Author = "Stefano", Subject = "Rectangle", Popup = new Popup( page, SKRect.Create(200, 325, 200, 75), "Text of the Popup annotation (this text won't be visible as associating popups to markup annotations overrides the former's properties with the latter's)" ) }; // Ellipse. composer.ShowText("Ellipse annotation:", new SKPoint(35, 415)); new Ellipse( page, SKRect.Create(50, 440, 100, 30), "Text of the Ellipse annotation") { BorderEffect = new BorderEffect(BorderEffectType.Cloudy, 1), InteriorColor = DeviceRGBColor.Get(SKColors.Cyan), Color = DeviceRGBColor.Get(SKColors.Black), Author = "Stefano", Subject = "Ellipse" }; // Rubber stamp. composer.ShowText("Rubber stamp annotations:", new SKPoint(35, 505)); { fonts::Font stampFont = fonts::PdfType0Font.Load(document, GetResourcePath("fonts" + Path.DirectorySeparatorChar + "TravelingTypewriter.otf")); new Stamp( page, new SKPoint(75, 570), "This is a round custom stamp", new StampAppearanceBuilder(document, StampAppearanceBuilder.TypeEnum.Round, "Done", 50, stampFont) .Build() ) { Rotation = -10, Author = "Stefano", Subject = "Custom stamp" }; new Stamp( page, new SKPoint(210, 570), "This is a squared (and round-cornered) custom stamp", new StampAppearanceBuilder(document, StampAppearanceBuilder.TypeEnum.Squared, "Classified", 150, stampFont) { Color = DeviceRGBColor.Get(SKColors.Orange) }.Build() ) { Rotation = 15, Author = "Stefano", Subject = "Custom stamp" }; fonts::Font stampFont2 = fonts::PdfType0Font.Load(document, GetResourcePath("fonts" + Path.DirectorySeparatorChar + "MgOpenCanonicaRegular.ttf")); new Stamp( page, new SKPoint(350, 570), "This is a striped custom stamp", new StampAppearanceBuilder(document, StampAppearanceBuilder.TypeEnum.Striped, "Out of stock", 100, stampFont2) { Color = DeviceRGBColor.Get(SKColors.Gray) }.Build() ) { Rotation = 90, Author = "Stefano", Subject = "Custom stamp" }; // Define the standard stamps template path! /* * NOTE: The PDF specification defines several stamps (aka "standard stamps") whose rendering * depends on the support of viewer applications. As such support isn't guaranteed, PDF Clown * offers smooth, ready-to-use embedding of these stamps through the StampPath property of the * document configuration: you can decide to point to the stamps directory of your Acrobat * installation (e.g., in my GNU/Linux system it's located in * "/opt/Adobe/Reader9/Reader/intellinux/plug_ins/Annotations/Stamps/ENU") or to the * collection included in this distribution (std-stamps.pdf). */ document.Configuration.StampPath = GetResourcePath("../../pkg/templates/std-stamps.pdf"); // Add a standard stamp, rotating it 15 degrees counterclockwise! new Stamp( page, new SKPoint(485, 515), null, // Default size is natural size. "This is 'Confidential', a standard stamp", StandardStampEnum.Confidential) { Rotation = 15, Author = "Stefano", Subject = "Standard stamp" }; // Add a standard stamp, without rotation! new Stamp( page, new SKPoint(485, 580), null, // Default size is natural size. "This is 'SBApproved', a standard stamp", StandardStampEnum.BusinessApproved) { Author = "Stefano", Subject = "Standard stamp" }; // Add a standard stamp, rotating it 10 degrees clockwise! new Stamp( page, new SKPoint(485, 635), new SKSize(0, 40), // This scales the width proportionally to the 40-unit height (you can obviously do also the opposite, defining only the width). "This is 'SHSignHere', a standard stamp", StandardStampEnum.SignHere) { Rotation = -10, Author = "Stefano", Subject = "Standard stamp" }; } composer.ShowText("Text markup annotations:", new SKPoint(35, 650)); { composer.BeginLocalState(); composer.SetFont(font, 8); var matrix = page.RotateMatrix; new TextMarkup(page, composer.ShowText("Highlight annotation", new SKPoint(35, 680)).Transform(ref matrix), "Text of the Highlight annotation", TextMarkupType.Highlight) { Author = "Stefano", Subject = "An highlight text markup!" }; new TextMarkup(page, composer.ShowText("Highlight annotation 2", new SKPoint(35, 695)).Inflate(0, 1).Transform(ref matrix), "Text of the Highlight annotation 2", TextMarkupType.Highlight) { Color = DeviceRGBColor.Get(SKColors.Magenta) }; new TextMarkup(page, composer.ShowText("Highlight annotation 3", new SKPoint(35, 710)).Inflate(0, 2).Transform(ref matrix), "Text of the Highlight annotation 3", TextMarkupType.Highlight) { Color = DeviceRGBColor.Get(SKColors.Red) }; new TextMarkup(page, composer.ShowText("Squiggly annotation", new SKPoint(180, 680)).Transform(ref matrix), "Text of the Squiggly annotation", TextMarkupType.Squiggly); new TextMarkup(page, composer.ShowText("Squiggly annotation 2", new SKPoint(180, 695)).Inflate(0, 2.5f).Transform(ref matrix), "Text of the Squiggly annotation 2", TextMarkupType.Squiggly) { Color = DeviceRGBColor.Get(SKColors.Orange) }; new TextMarkup(page, composer.ShowText("Squiggly annotation 3", new SKPoint(180, 710)).Inflate(0, 3).Transform(ref matrix), "Text of the Squiggly annotation 3", TextMarkupType.Squiggly) { Color = DeviceRGBColor.Get(SKColors.Pink) }; new TextMarkup(page, composer.ShowText("Underline annotation", new SKPoint(320, 680)).Transform(ref matrix), "Text of the Underline annotation", TextMarkupType.Underline); new TextMarkup(page, composer.ShowText("Underline annotation 2", new SKPoint(320, 695)).Inflate(0, 2.5f).Transform(ref matrix), "Text of the Underline annotation 2", TextMarkupType.Underline) { Color = DeviceRGBColor.Get(SKColors.Orange) }; new TextMarkup(page, composer.ShowText("Underline annotation 3", new SKPoint(320, 710)).Inflate(0, 3).Transform(ref matrix), "Text of the Underline annotation 3", TextMarkupType.Underline) { Color = DeviceRGBColor.Get(SKColors.Green) }; new TextMarkup(page, composer.ShowText("StrikeOut annotation", new SKPoint(455, 680)).Transform(ref matrix), "Text of the StrikeOut annotation", TextMarkupType.StrikeOut); new TextMarkup(page, composer.ShowText("StrikeOut annotation 2", new SKPoint(455, 695)).Inflate(0, 2.5f).Transform(ref matrix), "Text of the StrikeOut annotation 2", TextMarkupType.StrikeOut) { Color = DeviceRGBColor.Get(SKColors.Orange) }; new TextMarkup(page, composer.ShowText("StrikeOut annotation 3", new SKPoint(455, 710)).Inflate(0, 3).Transform(ref matrix), "Text of the StrikeOut annotation 3", TextMarkupType.StrikeOut) { Color = DeviceRGBColor.Get(SKColors.Green) }; composer.End(); } composer.Flush(); }
/// <summary> /// Draws the rating view /// </summary> /// <param name="canvas"></param> /// <param name="width"></param> /// <param name="height"></param> public void Draw(SKCanvas canvas, int width, int height) { canvas.Clear(this.CanvasBackgroundColor); var path = SKPath.ParseSvgPathData(this.Path); var itemWidth = ((width - (this.Count - 1) * this.Spacing)) / this.Count; var scaleX = (itemWidth / (path.Bounds.Width)); scaleX = (itemWidth - scaleX * this.StrokeWidth) / path.Bounds.Width; this.ItemHeight = height; var scaleY = this.ItemHeight / (path.Bounds.Height); scaleY = (this.ItemHeight - scaleY * this.StrokeWidth) / (path.Bounds.Height); this.CanvasScale = Math.Min(scaleX, scaleY); this.ItemWidth = path.Bounds.Width * this.CanvasScale; canvas.Scale(this.CanvasScale); canvas.Translate(this.StrokeWidth / 2, this.StrokeWidth / 2); canvas.Translate(-path.Bounds.Left, 0); canvas.Translate(0, -path.Bounds.Top); using (var strokePaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = this.SKOutlineOnColor, StrokeWidth = this.StrokeWidth, StrokeJoin = SKStrokeJoin.Round, IsAntialias = true, }) using (var fillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = this.SKColorOn, IsAntialias = true, }) { for (int i = 0; i < this.Count; i++) { if (i <= this.Value - 1) // Full { canvas.DrawPath(path, fillPaint); canvas.DrawPath(path, strokePaint); } else if (i < this.Value) //Partial { float filledPercentage = (float)(this.Value - Math.Truncate(this.Value)); strokePaint.Color = this.SKOutlineOffColor; canvas.DrawPath(path, strokePaint); using (var rectPath = new SKPath()) { var rect = SKRect.Create(path.Bounds.Left + path.Bounds.Width * filledPercentage, path.Bounds.Top, path.Bounds.Width * (1 - filledPercentage), this.ItemHeight); rectPath.AddRect(rect); canvas.ClipPath(rectPath, SKClipOperation.Difference); canvas.DrawPath(path, fillPaint); } } else //Empty { strokePaint.Color = this.SKOutlineOffColor; canvas.DrawPath(path, strokePaint); } canvas.Translate((this.ItemWidth + this.Spacing) / this.CanvasScale, 0); } } }
public static async Task <HLinkMediaModel> CreateClippedMediaModel(HLinkLoadImageModel argHLinkLoadImageModel) { if (argHLinkLoadImageModel is null) { throw new ArgumentNullException(nameof(argHLinkLoadImageModel)); } if (!argHLinkLoadImageModel.DeRef.Valid) { throw new ArgumentException("CreateClippedMediaModel argument is invalid", nameof(argHLinkLoadImageModel)); } IMediaModel returnMediaModel = await MainThread.InvokeOnMainThreadAsync <IMediaModel>(() => { // TODO cleanup code. Multiple copies of things in use IMediaModel theMediaModel = argHLinkLoadImageModel.DeRef; SKBitmap resourceBitmap = new SKBitmap(); IMediaModel newMediaModel = new MediaModel(); string newHLinkKey = argHLinkLoadImageModel.HLinkKey + "-" + argHLinkLoadImageModel.GCorner1X + argHLinkLoadImageModel.GCorner1Y + argHLinkLoadImageModel.GCorner2X + argHLinkLoadImageModel.GCorner2Y; string outFileName = Path.Combine("Cropped", newHLinkKey + ".png"); string outFilePath = Path.Combine(DataStore.AD.CurrentDataFolder.FullName, outFileName); Debug.WriteLine(argHLinkLoadImageModel.DeRef.MediaStorageFilePath); // Check if already exists IMediaModel fileExists = DV.MediaDV.GetModelFromHLinkString(newHLinkKey); if (!fileExists.Valid) { // Needs clipping using (StreamReader stream = new StreamReader(theMediaModel.MediaStorageFilePath)) { resourceBitmap = SKBitmap.Decode(stream.BaseStream); } // Check for too large a bitmap Debug.WriteLine("Image ResourceBitmap size: " + resourceBitmap.ByteCount); if (resourceBitmap.ByteCount > int.MaxValue - 1000) { // TODO Handle this better. Perhaps resize? Delete for now resourceBitmap = new SKBitmap(); } float crleft = (float)(argHLinkLoadImageModel.GCorner1X / 100d * theMediaModel.MetaDataWidth); float crright = (float)(argHLinkLoadImageModel.GCorner2X / 100d * theMediaModel.MetaDataWidth); float crtop = (float)(argHLinkLoadImageModel.GCorner1Y / 100d * theMediaModel.MetaDataHeight); float crbottom = (float)(argHLinkLoadImageModel.GCorner2Y / 100d * theMediaModel.MetaDataHeight); SKRect cropRect = new SKRect(crleft, crtop, crright, crbottom); SKBitmap croppedBitmap = new SKBitmap( (int)cropRect.Width, (int)cropRect.Height ); SKRect dest = new SKRect( 0, 0, cropRect.Width, cropRect.Height ); SKRect source = new SKRect( cropRect.Left, cropRect.Top, cropRect.Right, cropRect.Bottom); using (SKCanvas canvas = new SKCanvas(croppedBitmap)) { canvas.DrawBitmap(resourceBitmap, source, dest); } // create an image COPY SKImage image = SKImage.FromBitmap(croppedBitmap); // encode the image (defaults to PNG) SKData encoded = image.Encode(); // get a stream over the encoded data using (Stream stream = File.Open(outFilePath, FileMode.OpenOrCreate, System.IO.FileAccess.Write, FileShare.ReadWrite)) { encoded.SaveTo(stream); } croppedBitmap.Dispose(); // ------------ Save new MediaObject newMediaModel = theMediaModel.Copy(); newMediaModel.HLinkKey = newHLinkKey; newMediaModel.OriginalFilePath = outFileName; newMediaModel.MediaStorageFile = StoreFolder.FolderGetFile(DataStore.AD.CurrentDataFolder, outFileName);; newMediaModel.IsClippedFile = true; newMediaModel.MetaDataHeight = cropRect.Height; newMediaModel.MetaDataWidth = cropRect.Width; newMediaModel = SetHomeImage(newMediaModel); DataStore.DS.MediaData.Add((MediaModel)newMediaModel); } resourceBitmap.Dispose(); return(newMediaModel); }); return(returnMediaModel.HLink); }
public void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IWidget widget, float layerOpacity) { var scaleBar = (ScaleBarWidget)widget; if (!scaleBar.CanTransform()) { return; } // If this is the first time, we call this renderer, ... if (_paintScaleBar == null) { // ... than create the paints _paintScaleBar = CreateScaleBarPaint(scaleBar.TextColor.ToSkia(layerOpacity), StrokeInternal, SKPaintStyle.Fill, scaleBar.Scale); _paintScaleBarStroke = CreateScaleBarPaint(scaleBar.Halo.ToSkia(layerOpacity), StrokeExternal, SKPaintStyle.Stroke, scaleBar.Scale); _paintScaleText = CreateTextPaint(scaleBar.TextColor.ToSkia(layerOpacity), 2, SKPaintStyle.Fill, scaleBar.Scale); _paintScaleTextStroke = CreateTextPaint(scaleBar.Halo.ToSkia(layerOpacity), 2, SKPaintStyle.Stroke, scaleBar.Scale); } else { // Update paints with new values _paintScaleBar.Color = scaleBar.TextColor.ToSkia(layerOpacity); _paintScaleBar.StrokeWidth = StrokeInternal * scaleBar.Scale; _paintScaleBarStroke.Color = scaleBar.Halo.ToSkia(layerOpacity); _paintScaleBarStroke.StrokeWidth = StrokeExternal * scaleBar.Scale; _paintScaleText.Color = scaleBar.TextColor.ToSkia(layerOpacity); _paintScaleText.StrokeWidth = StrokeInternal * scaleBar.Scale; _paintScaleText.Typeface = SKTypeface.FromFamilyName(scaleBar.Font.FontFamily, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); _paintScaleText.TextSize = (float)scaleBar.Font.Size * scaleBar.Scale; _paintScaleTextStroke.Color = scaleBar.Halo.ToSkia(layerOpacity); _paintScaleTextStroke.StrokeWidth = StrokeInternal * scaleBar.Scale; _paintScaleTextStroke.Typeface = SKTypeface.FromFamilyName(scaleBar.Font.FontFamily, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); _paintScaleTextStroke.TextSize = (float)scaleBar.Font.Size * scaleBar.Scale; } float scaleBarLength1; string scaleBarText1; float scaleBarLength2; string scaleBarText2; (scaleBarLength1, scaleBarText1, scaleBarLength2, scaleBarText2) = scaleBar.GetScaleBarLengthAndText(viewport); // Calc height of scale bar SKRect textSize = SKRect.Empty; // Do this, because height of text changes sometimes (e.g. from 2 m to 1 m) _paintScaleTextStroke.MeasureText("9999 m", ref textSize); var scaleBarHeight = textSize.Height + (scaleBar.TickLength + StrokeExternal * 0.5f + scaleBar.TextMargin) * scaleBar.Scale; if (scaleBar.ScaleBarMode == ScaleBarMode.Both && scaleBar.SecondaryUnitConverter != null) { scaleBarHeight *= 2; } else { scaleBarHeight += StrokeExternal * 0.5f * scaleBar.Scale; } scaleBar.Height = scaleBarHeight; // Draw lines // Get lines for scale bar var points = scaleBar.GetScaleBarLinePositions(viewport, scaleBarLength1, scaleBarLength2, StrokeExternal); // BoundingBox for scale bar BoundingBox envelop = new BoundingBox(); if (points != null) { // Draw outline of scale bar for (int i = 0; i < points.Length; i += 2) { canvas.DrawLine((float)points[i].X, (float)points[i].Y, (float)points[i + 1].X, (float)points[i + 1].Y, _paintScaleBarStroke); } // Draw scale bar for (int i = 0; i < points.Length; i += 2) { canvas.DrawLine((float)points[i].X, (float)points[i].Y, (float)points[i + 1].X, (float)points[i + 1].Y, _paintScaleBar); } envelop = points[0].BoundingBox; for (int i = 1; i < points.Length; i++) { envelop = envelop.Join(points[i].BoundingBox); } envelop = envelop.Grow(StrokeExternal * 0.5f * scaleBar.Scale); } // Draw text // Calc text height SKRect textSize1 = SKRect.Empty; SKRect textSize2 = SKRect.Empty; scaleBarText1 = scaleBarText1 ?? string.Empty; scaleBarText2 = scaleBarText2 ?? string.Empty; _paintScaleTextStroke.MeasureText(scaleBarText1, ref textSize1); _paintScaleTextStroke.MeasureText(scaleBarText2, ref textSize2); var(posX1, posY1, posX2, posY2) = scaleBar.GetScaleBarTextPositions(viewport, textSize.ToMapsui(), textSize1.ToMapsui(), textSize2.ToMapsui(), StrokeExternal); // Now draw text canvas.DrawText(scaleBarText1, posX1, posY1 - textSize1.Top, _paintScaleTextStroke); canvas.DrawText(scaleBarText1, posX1, posY1 - textSize1.Top, _paintScaleText); envelop = envelop.Join(new BoundingBox(posX1, posY1, posX1 + textSize1.Width, posY1 + textSize1.Height)); if (scaleBar.ScaleBarMode == ScaleBarMode.Both && scaleBar.SecondaryUnitConverter != null) { // Now draw second text canvas.DrawText(scaleBarText2, posX2, posY2 - textSize2.Top, _paintScaleTextStroke); canvas.DrawText(scaleBarText2, posX2, posY2 - textSize2.Top, _paintScaleText); envelop = envelop.Join(new BoundingBox(posX2, posY2, posX2 + textSize2.Width, posY2 + textSize2.Height)); } scaleBar.Envelope = envelop; if (scaleBar.ShowEnvelop) { // Draw a rect around the scale bar for testing var tempPaint = _paintScaleTextStroke; canvas.DrawRect(new SKRect((float)envelop.MinX, (float)envelop.MinY, (float)envelop.MaxX, (float)envelop.MaxY), tempPaint); } }
public RectArea(SKRect rect) { Rect = rect; }
public override void PostProcess(SKCanvas canvas, SKRect renderBounds, SKPaint paint) { }
/// <inheritdoc /> public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint) { lock (_lock) context.Canvas.DrawBitmap(_bitmap, sourceRect, destRect, paint); }
public Polyline(Page page, SKRect box, string text) : base(page, box, text, PdfName.PolyLine) { }
private void PaintRainbow(object sender, SKPaintSurfaceEventArgs args) { var info = args.Info; var size = info.Size; var surface = args.Surface; var canvas = args.Surface.Canvas; var canvasCenter = new SKPoint(size.Width / 2.0f, size.Height / 2.0f); // Clear the canvas and move the canvas center point to the viewport center canvas.Clear(); canvas.Translate(canvasCenter); // Draw background as a disc backgroundPaint.Color = BackgroundColor.ToSKColor(); if (HasShadow) { backgroundPaint.ImageFilter = SKImageFilter.CreateDropShadow( size.Width * 0.05f, size.Height * 0.05f, size.Width * 0.1f, size.Height * 0.1f, ShadowColor.ToSKColor(), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground); canvas.Scale(0.73f, 0.73f); } var radius = size.Width * 0.5f; // the term backgroundDiscRadiusScale is there just to ensure the shadow will be visible canvas.DrawCircle(0, 0, radius, backgroundPaint); // Rotate the canvas canvas.RotateDegrees((float)(_rotation * 360.0f)); // Draw the progress arc var progressArcBoundingRect = new SKRect( -size.Width * _progressArcDiameterProportion * 0.5f, -size.Height * _progressArcDiameterProportion * 0.5f, size.Width * _progressArcDiameterProportion * 0.5f, size.Height * _progressArcDiameterProportion * 0.5f); progressPaint.StrokeWidth = size.Width * 0.08f; progressPaint.Color = _currentColor; using (var arcPath = new SKPath()) { float startAngle = 0.0f; float sweepAngle = 0.0f; if (_progress <= 0.5f) { sweepAngle = (float)(2 * _progress * 360.0f); startAngle = -90.0f; } if (_progress > 0.5d) { startAngle = ((float)_progress - 0.5f) // shift the range to (0, 0.5] * 2 // map the range to (0, 1.0] * 360.0f // map the range to (0, 360] - 90.0f; // shift the range to (-90.0, 270] sweepAngle = 270.0f - startAngle; } arcPath.AddArc(progressArcBoundingRect, startAngle, sweepAngle); canvas.DrawPath(arcPath, progressPaint); } }
///<inheritdoc/> public override void Draw(ZplElementBase element, DrawerOptions options) { if (element is ZplTextField textField) { float x = textField.PositionX; float y = textField.PositionY; var font = textField.Font; float fontSize = font.FontHeight > 0 ? font.FontHeight : font.FontWidth; var scaleX = 1.0f; if (font.FontWidth != 0 && font.FontWidth != fontSize) { scaleX = (float)font.FontWidth / fontSize; } fontSize *= 0.95f; var typeface = options.FontLoader(font.FontName); using var skPaint = new SKPaint(); skPaint.Color = SKColors.Black; skPaint.Typeface = typeface; skPaint.TextSize = fontSize; skPaint.TextScaleX = scaleX; var textBounds = new SKRect(); var textBoundBaseline = new SKRect(); string DisplayText = textField.Text.ReplaceSpecialChars(); skPaint.MeasureText(new string('A', DisplayText.Length), ref textBoundBaseline); skPaint.MeasureText(DisplayText, ref textBounds); if (textField.FieldTypeset != null) { y -= textBounds.Height; } using (new SKAutoCanvasRestore(this._skCanvas)) { SKMatrix matrix = SKMatrix.Empty; if (textField.FieldOrigin != null) { switch (textField.Font.FieldOrientation) { case Label.FieldOrientation.Rotated90: matrix = SKMatrix.CreateRotationDegrees(90, x, y); y -= font.FontHeight - textBoundBaseline.Height; break; case Label.FieldOrientation.Rotated180: matrix = SKMatrix.CreateRotationDegrees(180, x, y); x -= textBounds.Width; y -= font.FontHeight - textBoundBaseline.Height; break; case Label.FieldOrientation.Rotated270: matrix = SKMatrix.CreateRotationDegrees(270, x, y); x -= textBounds.Width; y += textBoundBaseline.Height; break; case Label.FieldOrientation.Normal: y += textBoundBaseline.Height; break; } } else { switch (textField.Font.FieldOrientation) { case Label.FieldOrientation.Rotated90: matrix = SKMatrix.CreateRotationDegrees(90, x, y); x += textBoundBaseline.Height; break; case Label.FieldOrientation.Rotated180: matrix = SKMatrix.CreateRotationDegrees(180, x, y); y -= textBoundBaseline.Height; break; case Label.FieldOrientation.Rotated270: matrix = SKMatrix.CreateRotationDegrees(270, x, y); x -= textBoundBaseline.Height; break; case Label.FieldOrientation.Normal: y += textBoundBaseline.Height; break; } } if (matrix != SKMatrix.Empty) { this._skCanvas.SetMatrix(matrix); } this._skCanvas.DrawText(DisplayText, x, y, new SKFont(typeface, fontSize, scaleX, 0), skPaint); } } }
protected override void OnDrawSample(SKCanvas canvas, int width, int height) { canvas.DrawColor(SKColors.White); using (var paint = new SKPaint()) { paint.TextSize = 64.0f; paint.IsAntialias = true; paint.Color = (SKColor)0xFF4281A4; paint.TextEncoding = SKTextEncoding.Utf32; canvas.DrawText("Skia (UTF-32)", 0, 64.0f, paint); var bounds = new SKRect(); paint.MeasureText("Skia (UTF-32)", ref bounds); bounds.Top += 64.0f; bounds.Bottom += 64.0f; paint.IsStroke = true; paint.Color = SKColors.Red; canvas.DrawRect(bounds, paint); } using (var paint = new SKPaint()) { paint.TextSize = 64.0f; paint.IsAntialias = true; paint.Color = (SKColor)0xFF9CAFB7; paint.TextEncoding = SKTextEncoding.Utf16; canvas.DrawText("Skia (UTF-16)", 0, 144.0f, paint); var bounds = new SKRect(); paint.MeasureText("Skia (UTF-16)", ref bounds); bounds.Top += 144.0f; bounds.Bottom += 144.0f; paint.IsStroke = true; paint.Color = SKColors.Red; canvas.DrawRect(bounds, paint); } using (var paint = new SKPaint()) { paint.TextSize = 64.0f; paint.IsAntialias = true; paint.Color = (SKColor)0xFFE6B89C; paint.TextEncoding = SKTextEncoding.Utf8; canvas.DrawText("Skia (UTF-8)", 0, 224.0f, paint); var bounds = new SKRect(); paint.MeasureText("Skia (UTF-8)", ref bounds); bounds.Top += 224.0f; bounds.Bottom += 224.0f; paint.IsStroke = true; paint.Color = SKColors.Red; canvas.DrawRect(bounds, paint); } }
public void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); using (SKPaint fillPaint = new SKPaint()) using (SKPaint outlinePaint = new SKPaint()) { SKPath path = new SKPath(); float y = yGap * info.Height; double ratio = (Value - Minimum) / (Maximum - Minimum); float radius = info.Height / 2f; SKRect rect1 = new SKRect(0, y, info.Height - 2 * y, info.Height - y); SKRect rect2 = new SKRect(info.Width - info.Height + 2 * y, y, info.Width, info.Height - y); if (!NativeFeel) { path.ArcTo(rect1, 90f, 180f, false); path.LineTo(Math.Max((float)Math.Min(info.Width * ratio, info.Width - radius), radius), y); path.LineTo(Math.Max((float)Math.Min(info.Width * ratio, info.Width - radius), radius), info.Height - y); path.Close(); } else { path.MoveTo(0, radius); path.LineTo((float)(info.Width * ratio), radius); } outlinePaint.Style = SKPaintStyle.Stroke; if (!NativeFeel) { outlinePaint.StrokeWidth = 2; outlinePaint.Color = new SKColor(255, 255, 255, 100); } else { outlinePaint.StrokeWidth = 5; outlinePaint.Color = Color.Red.ToSKColor(); } outlinePaint.IsAntialias = true; fillPaint.Style = SKPaintStyle.Fill; fillPaint.Color = ActiveBarColor.ToSKColor(); fillPaint.IsAntialias = true; if (!NativeFeel) { canvas.DrawPath(path, fillPaint); } canvas.DrawPath(path, outlinePaint); SKPath path1 = new SKPath(); if (!NativeFeel) { path1.ArcTo(rect2, 90f, -180f, false); path1.LineTo(Math.Min((float)Math.Max(info.Width * ratio, radius), info.Width - radius), y); path1.LineTo(Math.Min((float)Math.Max(info.Width * ratio, radius), info.Width - radius), info.Height - y); path1.Close(); } else { path1.MoveTo((float)(info.Width * ratio), radius); path1.LineTo(info.Width, radius); } fillPaint.Color = InactiveBarColor.ToSKColor(); if (!NativeFeel) { canvas.DrawPath(path1, fillPaint); } else { outlinePaint.Color = Color.Gray.ToSKColor(); } canvas.DrawPath(path1, outlinePaint); fillPaint.Color = !NativeFeel?ControlBarColor.ToSKColor() : SKColors.White; SKPoint centerpt = new SKPoint((float)(info.Width * ratio), info.Height / 2f); if (centerpt.X - radius < 0) { centerpt.X = radius; } if (centerpt.X + radius > info.Width) { centerpt.X = info.Width - radius; } canvas.DrawCircle(centerpt.X, centerpt.Y, radius, fillPaint); if (!NativeFeel) { canvas.DrawCircle(centerpt.X, centerpt.Y, radius, outlinePaint); } if (IsBusy) { //CircularProgressControl.DrawProgressCircle(args, centerpt.X - radius, centerpt.Y - radius, 0, _busyIndicatorProgress, Color.Red, ControlBarColor, 1); } } }
protected abstract void Draw(SKCanvas canvas, SKRect canvasBounds);
private static void Draw(SKSurface bitmapCanvas, CompositionLayer compositionLayer, SKRect bounds, float scale, byte alpha, Matrix3X3 matrix, double width, double height) { bitmapCanvas.Canvas.Clear(SKColors.Transparent); LottieLog.BeginSection("Drawable.Draw"); if (compositionLayer == null) { return; } var localScale = scale; float extraScale = 1f; float maxScale = GetMaxScale(bitmapCanvas.Canvas, bounds); if (localScale > maxScale) { localScale = maxScale; extraScale = scale / localScale; } if (extraScale > 1) { // This is a bit tricky... // We can't draw on a canvas larger than ViewConfiguration.get(context).getScaledMaximumDrawingCacheSize() // which works out to be roughly the size of the screen because Android can't generate a // bitmap large enough to render to. // As a result, we cap the scale such that it will never be wider/taller than the screen // and then only render in the top left corner of the canvas. We then use extraScale // to scale up the rest of the scale. However, since we rendered the animation to the top // left corner, we need to scale up and translate the canvas to zoom in on the top left // corner. bitmapCanvas.Canvas.Save(); float halfWidth = (float)bounds.Width / 2f; float halfHeight = (float)bounds.Height / 2f; float scaledHalfWidth = halfWidth * localScale; float scaledHalfHeight = halfHeight * localScale; bitmapCanvas.Canvas.Translate( scale * halfWidth - scaledHalfWidth, scale * halfHeight - scaledHalfHeight); bitmapCanvas.Canvas.Scale(extraScale, extraScale, scaledHalfWidth, scaledHalfHeight); } matrix.Reset(); matrix = MatrixExt.PreScale(matrix, localScale, localScale); compositionLayer.Draw(bitmapCanvas.Canvas, matrix, alpha); LottieLog.EndSection("Drawable.Draw"); if (extraScale > 1) { bitmapCanvas.Canvas.Restore(); } }
static SKShader CreateRadialGradient(RadialGradientBrush radialGradientBrush, SKRect pathBounds) { var center = new SKPoint((float)radialGradientBrush.Center.X * pathBounds.Width + pathBounds.Left, (float)radialGradientBrush.Center.Y * pathBounds.Height + pathBounds.Top); var radius = (float)radialGradientBrush.Radius * Math.Max(pathBounds.Height, pathBounds.Width); var orderedGradientStops = radialGradientBrush.GradientStops.OrderBy(x => x.Offset).ToList(); var gradientColors = orderedGradientStops.Select(x => x.Color.ToPlatform().ToSKColor()).ToArray(); var gradientColorPos = orderedGradientStops.Select(x => x.Offset).ToArray(); return(SKShader.CreateRadialGradient(center, radius, gradientColors, gradientColorPos, SKShaderTileMode.Clamp)); }
public DisplayCharacterRanges(SKCanvas canvas, SKPaint font, IDrawTextFormat format, string text) { if (String.IsNullOrEmpty(text)) { _rectF = new CanvasRectangleF[0]; return; } _rectF = new CanvasRectangleF[text.Length]; var rect = new SKRect(); font.MeasureText("_", ref rect); float spaceWidth = rect.Width; float xOffset = 0, height = 0;; for (int i = 0, to = text.Length; i < to; i++) { font.MeasureText($"{ text[i] }_", ref rect); _rectF[i].Left = rect.Left + xOffset; _rectF[i].Top = rect.Top; if (text[i] == ' ') { _rectF[i].Width = rect.Width; } else { _rectF[i].Width = rect.Width - spaceWidth * 0.9f; } height = Math.Max(rect.Height, height); xOffset += rect.Width; } //var far = font.FontMetrics != null ? -font.FontMetrics.Bottom : 0f; //var near = font.FontMetrics != null ? -font.FontMetrics.Top : 0f; //var center = (far + near) * .5f; var empiricValue = 1f; switch (format.LineAlignment) { case StringAlignment.Near: case StringAlignment.Far: empiricValue = 1.5f; // to generate more vartical line offset break; } for (int i = 0; i < _rectF.Length; i++) { //switch (format.LineAlignment) //{ // case StringAlignment.Near: // _rectF[i].Top += near; // break; // case StringAlignment.Far: // _rectF[i].Top += far; // break; // default: // _rectF[i].Top += center; // break; //} _rectF[i].Height = height * empiricValue; } }
static SKShader CreateLinearGradient(LinearGradientBrush linearGradientBrush, SKRect pathBounds) { var startPoint = new SKPoint(pathBounds.Left + (float)linearGradientBrush.StartPoint.X * pathBounds.Width, pathBounds.Top + (float)linearGradientBrush.StartPoint.Y * pathBounds.Height); var endPoint = new SKPoint(pathBounds.Left + (float)linearGradientBrush.EndPoint.X * pathBounds.Width, pathBounds.Top + (float)linearGradientBrush.EndPoint.Y * pathBounds.Height); var orderedGradientStops = linearGradientBrush.GradientStops.OrderBy(x => x.Offset).ToList(); var gradientColors = orderedGradientStops.Select(x => x.Color.ToPlatform().ToSKColor()).ToArray(); var gradientColorPos = orderedGradientStops.Select(x => x.Offset).ToArray(); return(SKShader.CreateLinearGradient(startPoint, endPoint, gradientColors, gradientColorPos, SKShaderTileMode.Clamp)); }
public void DrawGaugeAsync() { int uPadding = 150; int side = 500; int radialGaugeWidth = 25; int lineSize1 = 220; int lineSize2 = 70; int lineSize3 = 80; int lineHeight1 = 100; int lineHeight2 = 200; int lineHeight3 = 300; float startAngle = -220; float sweepAngle = 260; try { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; progressHelpers.SetDevice(info.Height, info.Width); canvas.Clear(); float upperPading = progressHelpers.GetFactoredHeight(uPadding); int Xc = info.Width / 2; float Yc = progressHelpers.GetFactoredHeight(side); int X1 = (int)(Xc - Yc); int Y1 = (int)(Yc - Yc + upperPading); int X2 = (int)(Xc + Yc); int Y2 = (int)(Yc + Yc + upperPading); SKPaint paint1 = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.FromHex("#fc0b03").ToSKColor(), StrokeWidth = progressHelpers.GetFactoredWidth(radialGaugeWidth), StrokeCap = SKStrokeCap.Round }; SKPaint paint2 = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.FromHex("#05c782").ToSKColor(), StrokeWidth = progressHelpers.GetFactoredWidth(radialGaugeWidth), StrokeCap = SKStrokeCap.Round }; SKRect rect = new SKRect(X1, Y1, X2, Y2); SKPath path1 = new SKPath(); path1.AddArc(rect, startAngle, sweepAngle); canvas.DrawPath(path1, paint1); SKPath path2 = new SKPath(); path2.AddArc(rect, startAngle, (float)sweepAngleSlider.Value); canvas.DrawPath(path2, paint2); using (SKPaint sKPaint = new SKPaint()) { sKPaint.Style = SKPaintStyle.Fill; sKPaint.IsAntialias = true; sKPaint.Color = SKColor.Parse("#0000"); sKPaint.TextAlign = SKTextAlign.Center; sKPaint.TextSize = progressHelpers.GetFactoredHeight(lineSize3); canvas.DrawText("Limite Disponível", Xc, Yc + progressHelpers.GetFactoredHeight(lineHeight1), sKPaint); } using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#171717"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressHelpers.GetFactoredHeight(lineHeight2); skPaint.TextSize = progressHelpers.GetFactoredHeight(lineSize1); skPaint.Typeface = SKTypeface.FromFamilyName( "Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); canvas.DrawText($"R${LIMITE_DISPONIVEL} ", Xc, Yc + progressHelpers.GetFactoredHeight(lineHeight1), skPaint); } using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#676a69"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressHelpers.GetFactoredHeight(lineSize2); canvas.DrawText("Limite", Xc, Yc + progressHelpers.GetFactoredHeight(lineHeight2), skPaint); } using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#e2797a"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressHelpers.GetFactoredHeight(lineSize3); if (sw_listToggle.IsToggled) { canvas.DrawText($"Total R$ {LIMITE_TOTAL} ", Xc, Yc + progressHelpers.GetFactoredHeight(lineHeight3), skPaint); } else { canvas.DrawText($"Utilizado R$ {(LIMITE_TOTAL - LIMITE_DISPONIVEL)}", Xc, Yc + progressHelpers.GetFactoredHeight(lineHeight3), skPaint); } } } catch (Exception e) { Debug.WriteLine(e.StackTrace); } }
public override void PreProcess(SKCanvas canvas, SKRect renderBounds, SKPaint paint) { paint.ColorF = paint.ColorF.WithAlpha(_alpha); }
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation?orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { if (string.IsNullOrWhiteSpace(inputPath)) { throw new ArgumentNullException(nameof(inputPath)); } if (string.IsNullOrWhiteSpace(inputPath)) { throw new ArgumentNullException(nameof(outputPath)); } var skiaOutputFormat = GetImageFormat(selectedOutputFormat); var hasBackgroundColor = !string.IsNullOrWhiteSpace(options.BackgroundColor); var hasForegroundColor = !string.IsNullOrWhiteSpace(options.ForegroundLayer); var blur = options.Blur ?? 0; var hasIndicator = options.AddPlayedIndicator || options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0); using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace, autoOrient, orientation)) { if (bitmap == null) { throw new ArgumentOutOfRangeException(string.Format("Skia unable to read image {0}", inputPath)); } var originalImageSize = new ImageDimensions(bitmap.Width, bitmap.Height); if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize) && !autoOrient) { // Just spit out the original file if all the options are default return(inputPath); } var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize); var width = newImageSize.Width; var height = newImageSize.Height; using (var resizedBitmap = new SKBitmap(width, height, bitmap.ColorType, bitmap.AlphaType)) { // scale image bitmap.ScalePixels(resizedBitmap, SKFilterQuality.High); // If all we're doing is resizing then we can stop now if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator) { Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var outputStream = new SKFileWStream(outputPath)) using (var pixmap = new SKPixmap(new SKImageInfo(width, height), resizedBitmap.GetPixels())) { pixmap.Encode(outputStream, skiaOutputFormat, quality); return(outputPath); } } // create bitmap to use for canvas drawing used to draw into bitmap using (var saveBitmap = new SKBitmap(width, height)) //, bitmap.ColorType, bitmap.AlphaType)) using (var canvas = new SKCanvas(saveBitmap)) { // set background color if present if (hasBackgroundColor) { canvas.Clear(SKColor.Parse(options.BackgroundColor)); } // Add blur if option is present if (blur > 0) { // create image from resized bitmap to apply blur using (var paint = new SKPaint()) using (var filter = SKImageFilter.CreateBlur(blur, blur)) { paint.ImageFilter = filter; canvas.DrawBitmap(resizedBitmap, SKRect.Create(width, height), paint); } } else { // draw resized bitmap onto canvas canvas.DrawBitmap(resizedBitmap, SKRect.Create(width, height)); } // If foreground layer present then draw if (hasForegroundColor) { if (!double.TryParse(options.ForegroundLayer, out double opacity)) { opacity = .4; } canvas.DrawColor(new SKColor(0, 0, 0, (byte)((1 - opacity) * 0xFF)), SKBlendMode.SrcOver); } if (hasIndicator) { DrawIndicator(canvas, width, height, options); } Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var outputStream = new SKFileWStream(outputPath)) { using (var pixmap = new SKPixmap(new SKImageInfo(width, height), saveBitmap.GetPixels())) { pixmap.Encode(outputStream, skiaOutputFormat, quality); } } } } } return(outputPath); }
public SKRoundedRect(SKRect rect, float rx, float ry) { Rect = rect; RadiusX = rx; RadiusY = ry; }