private void Draw(Cairo.Context context, bool needClip) { if (needClip) { context.Rectangle(rect.X, rect.Y, rect.Width, rect.Height); context.Clip(); } foreach (var entry in this.entries) { if (entry.horizontalStretchFactor != 0 || entry.verticalStretchFactor != 0) { context.FillRectangle(entry.rect, CairoEx.ColorLightBlue); context.StrokeRectangle(entry.rect, CairoEx.ColorBlack); } else { context.FillRectangle(entry.rect, CairoEx.ColorPink); context.StrokeRectangle(entry.rect, CairoEx.ColorBlack); } var innerGroup = entry as Group; if (innerGroup != null) { innerGroup.Draw(context, needClip); } } if (needClip) { context.ResetClip(); } }
public static Pixbuf CreateColorSwatch(int size, Color color) { using (var surf = CairoExtensions.CreateImageSurface(Cairo.Format.Argb32, size, size)) using (var g = new Cairo.Context(surf)) { g.FillRectangle(new Cairo.Rectangle(0, 0, size, size), color.ToCairoColor()); g.DrawRectangle(new Cairo.Rectangle(0, 0, size, size), new Cairo.Color(0, 0, 0), 1); return(surf.ToPixbuf()); } }
public void Render(List <Layer> layers, Cairo.ImageSurface dst, Point offset) { dst.Flush(); // Our rectangle of interest var r = new Rectangle(offset, dst.GetBounds().Size).ToCairoRectangle(); var doc = PintaCore.Workspace.ActiveDocument; using (var g = new Cairo.Context(dst)) { // Create the transparent checkerboard background g.Translate(-offset.X, -offset.Y); g.FillRectangle(r, tranparent_pattern, new Cairo.PointD(offset.X, offset.Y)); for (var i = 0; i < layers.Count; i++) { var layer = layers[i]; // If we're in LivePreview, substitute current layer with the preview layer if (layer == doc.Layers.CurrentUserLayer && PintaCore.LivePreview.IsEnabled) { layer = CreateLivePreviewLayer(layer); } // If the layer is offset, handle it here if (!layer.Transform.IsIdentity()) { layer = CreateOffsetLayer(layer); } // No need to resize the surface if we're at 100% zoom if (scale_factor.Ratio == 1) { layer.Draw(g, layer.Surface, layer.Opacity, false); } else { using (var scaled = CairoExtensions.CreateImageSurface(Cairo.Format.Argb32, dst.Width, dst.Height)) { g.Save(); // Have to undo the translate set above g.Translate(offset.X, offset.Y); CopyScaled(layer.Surface, scaled, r.ToGdkRectangle()); layer.Draw(g, scaled, layer.Opacity, false); g.Restore(); } } } } // If we are at least 200% and grid is requested, draw it if (enable_pixel_grid && PintaCore.Actions.View.PixelGrid.Value && scale_factor.Ratio <= 0.5d) { RenderPixelGrid(dst, offset); } dst.MarkDirty(); }
private static void Draw(Cairo.Context context, Visual visual) { var node = (Node)visual; var isGroup = node.IsGroup; if (!isGroup) { if (node.RuleSet.HorizontallyStretched || node.RuleSet.VerticallyStretched) { context.FillRectangle(node.Rect, CairoEx.ColorLightBlue); } else if (node.RuleSet.IsFixedWidth || node.RuleSet.IsFixedHeight) { context.FillRectangle(node.Rect, CairoEx.ColorOrange); } else { context.FillRectangle(node.Rect, CairoEx.ColorGreen); } } context.StrokeRectangle(node.Rect, CairoEx.ColorBlack); if (!isGroup) { return; } context.Save(); node.Foreach(v => { Draw(context, v); return(true); }); context.Restore(); }
public void Render (List<Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset) { dst.Flush (); // Our rectangle of interest var r = new Gdk.Rectangle (offset, dst.GetBounds ().Size).ToCairoRectangle (); using (var g = new Cairo.Context (dst)) { // Create the transparent checkerboard background g.Translate (-offset.X, -offset.Y); g.FillRectangle (r, tranparent_pattern, new Cairo.PointD (offset.X, offset.Y)); for (var i = 0; i < layers.Count; i++) { var layer = layers[i]; // If we're in LivePreview, substitute current layer with the preview layer if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled) layer = CreateLivePreviewLayer (layer); // If the layer is offset, handle it here if (!layer.Transform.IsIdentity ()) layer = CreateOffsetLayer (layer); // No need to resize the surface if we're at 100% zoom if (scale_factor.Ratio == 1) layer.Draw (g, layer.Surface, layer.Opacity, false); else { using (var scaled = new Cairo.ImageSurface (Cairo.Format.Argb32, dst.Width, dst.Height)) { g.Save (); // Have to undo the translate set above g.Translate (offset.X, offset.Y); CopyScaled (layer.Surface, scaled, r.ToGdkRectangle ()); layer.Draw (g, scaled, layer.Opacity, false); g.Restore (); } } } } // If we are at least 200% and grid is requested, draw it if (enable_pixel_grid && PintaCore.Actions.View.PixelGrid.Active && scale_factor.Ratio <= 0.5d) RenderPixelGrid (dst, offset); dst.MarkDirty (); }
/// <summary> /// Draws the text. /// </summary> /// <param name="showCursor">Whether or not to show the mouse cursor in the drawing.</param> /// <param name="useTextLayer">Whether or not to use the TextLayer (as opposed to the Userlayer).</param> private void RedrawText(bool showCursor, bool useTextLayer) { Rectangle r = CurrentTextLayout.GetLayoutBounds(); r.Inflate(10 + OutlineWidth, 10 + OutlineWidth); InflateAndInvalidate(r); CurrentTextBounds = r; Rectangle cursorBounds = Rectangle.Zero; Cairo.ImageSurface surf; if (!useTextLayer) { //Draw text on the current UserLayer's surface as finalized text. surf = PintaCore.Workspace.ActiveDocument.Layers.CurrentUserLayer.Surface; } else { //Draw text on the current UserLayer's TextLayer's surface as re-editable text. surf = PintaCore.Workspace.ActiveDocument.Layers.CurrentUserLayer.TextLayer.Layer.Surface; ClearTextLayer(); } using (var g = new Cairo.Context(surf)) { g.Save(); // Show selection if on text layer if (useTextLayer) { // Selected Text Cairo.Color c = new Cairo.Color(0.7, 0.8, 0.9, 0.5); foreach (Rectangle rect in CurrentTextLayout.SelectionRectangles) { g.FillRectangle(rect.ToCairoRectangle(), c); } } if (selection != null) { selection.Clip(g); } g.MoveTo(new Cairo.PointD(CurrentTextEngine.Origin.X, CurrentTextEngine.Origin.Y)); g.SetSourceColor(PintaCore.Palette.PrimaryColor); //Fill in background if (BackgroundFill) { using (var g2 = new Cairo.Context(surf)) { if (selection != null) { selection.Clip(g2); } g2.FillRectangle(CurrentTextLayout.GetLayoutBounds().ToCairoRectangle(), PintaCore.Palette.SecondaryColor); } } // Draw the text if (FillText) { Pango.CairoHelper.ShowLayout(g, CurrentTextLayout.Layout); } if (FillText && StrokeText) { g.SetSourceColor(PintaCore.Palette.SecondaryColor); g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath(g, CurrentTextLayout.Layout); g.Stroke(); } else if (StrokeText) { g.SetSourceColor(PintaCore.Palette.PrimaryColor); g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath(g, CurrentTextLayout.Layout); g.Stroke(); } if (showCursor) { var loc = CurrentTextLayout.GetCursorLocation(); var color = PintaCore.Palette.PrimaryColor; g.Antialias = Cairo.Antialias.None; g.DrawLine(new Cairo.PointD(loc.X, loc.Y), new Cairo.PointD(loc.X, loc.Y + loc.Height), color, 1); cursorBounds = Rectangle.Inflate(loc, 2, 10); } g.Restore(); if (useTextLayer && (is_editing || ctrlKey) && !CurrentTextEngine.IsEmpty()) { //Draw the text edit rectangle. g.Save(); g.Translate(.5, .5); using (Cairo.Path p = g.CreateRectanglePath(CurrentTextBounds.ToCairoRectangle())) { g.AppendPath(p); } g.LineWidth = 1; g.SetSourceColor(new Cairo.Color(1, 1, 1)); g.StrokePreserve(); g.SetDash(new double[] { 2, 4 }, 0); g.SetSourceColor(new Cairo.Color(1, .1, .2)); g.Stroke(); g.Restore(); } } InflateAndInvalidate(PintaCore.Workspace.ActiveDocument.Layers.CurrentUserLayer.previousTextBounds); PintaCore.Workspace.Invalidate(old_cursor_bounds); InflateAndInvalidate(r); PintaCore.Workspace.Invalidate(cursorBounds); old_cursor_bounds = cursorBounds; }
/// <summary> /// Draws the text. /// </summary> /// <param name="showCursor">Whether or not to show the mouse cursor in the drawing.</param> /// <param name="useTextLayer">Whether or not to use the TextLayer (as opposed to the Userlayer).</param> private void RedrawText(bool showCursor, bool useTextLayer) { Rectangle r = CurrentTextEngine.GetLayoutBounds(); r.Inflate(10 + OutlineWidth, 10 + OutlineWidth); CurrentTextBounds = r; Rectangle cursorBounds = Rectangle.Zero; Cairo.ImageSurface surf; if (!useTextLayer) { //Draw text on the current UserLayer's surface as finalized text. surf = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.Surface; } else { //Draw text on the current UserLayer's TextLayer's surface as re-editable text. surf = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.TextLayer.Surface; ClearTextLayer(); } using (var g = new Cairo.Context (surf)) { g.Save (); // Show selection if on text layer if (useTextLayer) { // Selected Text Cairo.Color c = new Cairo.Color (0.7, 0.8, 0.9, 0.5); foreach (Rectangle rect in CurrentTextEngine.SelectionRectangles) g.FillRectangle (rect.ToCairoRectangle (), c); } g.AppendPath (PintaCore.Workspace.ActiveDocument.Selection.SelectionPath); g.FillRule = Cairo.FillRule.EvenOdd; g.Clip (); g.MoveTo (new Cairo.PointD (CurrentTextEngine.Origin.X, CurrentTextEngine.Origin.Y)); g.Color = PintaCore.Palette.PrimaryColor; //Fill in background if (BackgroundFill) { using (var g2 = new Cairo.Context (surf)) { g2.FillRectangle(CurrentTextEngine.GetLayoutBounds().ToCairoRectangle(), PintaCore.Palette.SecondaryColor); } } // Draw the text if (FillText) Pango.CairoHelper.ShowLayout (g, CurrentTextEngine.Layout); if (FillText && StrokeText) { g.Color = PintaCore.Palette.SecondaryColor; g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath (g, CurrentTextEngine.Layout); g.Stroke (); } else if (StrokeText) { g.Color = PintaCore.Palette.PrimaryColor; g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath (g, CurrentTextEngine.Layout); g.Stroke (); } if (showCursor) { var loc = CurrentTextEngine.GetCursorLocation (); g.Antialias = Cairo.Antialias.None; g.DrawLine (new Cairo.PointD (loc.X, loc.Y), new Cairo.PointD (loc.X, loc.Y + loc.Height), new Cairo.Color (0, 0, 0, 1), 1); cursorBounds = Rectangle.Inflate (loc, 2, 10); } g.Restore (); if (useTextLayer && (is_editing || ctrlKey) && !CurrentTextEngine.IsEmpty()) { //Draw the text edit rectangle. g.Save(); g.Translate(.5, .5); using (Cairo.Path p = g.CreateRectanglePath(new Cairo.Rectangle(CurrentTextBounds.Left, CurrentTextBounds.Top, CurrentTextBounds.Width, CurrentTextBounds.Height - FontSize))) { g.AppendPath(p); } g.LineWidth = 1; g.Color = new Cairo.Color(1, 1, 1); g.StrokePreserve(); g.SetDash(new double[] { 2, 4 }, 0); g.Color = new Cairo.Color(1, .1, .2); g.Stroke(); g.Restore(); } } InflateAndInvalidate(PintaCore.Workspace.ActiveDocument.CurrentUserLayer.previousTextBounds); PintaCore.Workspace.Invalidate(old_cursor_bounds); PintaCore.Workspace.Invalidate(r); PintaCore.Workspace.Invalidate(cursorBounds); old_cursor_bounds = cursorBounds; }
private void DrawBackground(Cairo.Context g, Cairo.Rectangle rect, StyleInfo si) { // LinearGradientBrush linGrBrush = null; // SolidBrush sb = null; if (si.BackgroundColor.IsEmpty) { return; } g.Save(); Cairo.Color c = si.BackgroundColor.ToCairoColor(); Cairo.Gradient gradient = null; if (si.BackgroundGradientType != BackgroundGradientTypeEnum.None && !si.BackgroundGradientEndColor.IsEmpty) { Cairo.Color ec = si.BackgroundGradientEndColor.ToCairoColor(); switch (si.BackgroundGradientType) { case BackgroundGradientTypeEnum.LeftRight: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.Horizontal); gradient = new Cairo.LinearGradient(rect.X, rect.Y, rect.X + rect.Width, rect.Y); break; case BackgroundGradientTypeEnum.TopBottom: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.Vertical); gradient = new Cairo.LinearGradient(rect.X, rect.Y, rect.X, rect.Y + rect.Height); break; case BackgroundGradientTypeEnum.Center: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.Horizontal); throw new NotSupportedException(); // break; case BackgroundGradientTypeEnum.DiagonalLeft: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.ForwardDiagonal); gradient = new Cairo.LinearGradient(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height); break; case BackgroundGradientTypeEnum.DiagonalRight: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.BackwardDiagonal); gradient = new Cairo.LinearGradient(rect.X + rect.Width, rect.Y + rect.Height, rect.X, rect.Y); break; case BackgroundGradientTypeEnum.HorizontalCenter: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.Horizontal); throw new NotSupportedException(); // break; case BackgroundGradientTypeEnum.VerticalCenter: // linGrBrush = new LinearGradientBrush(rect, c, ec, LinearGradientMode.Vertical); throw new NotSupportedException(); // break; default: break; } gradient.AddColorStop(0, c); gradient.AddColorStop(1, ec); } if (gradient != null) { //// g.FillRectangle(linGrBrush, rect); g.FillRectangle(rect, gradient); gradient.Destroy(); } else if (!si.BackgroundColor.IsEmpty) { g.FillRectangle(rect, c); // g.DrawRoundedRectangle (rect, 2, c, 1); // g.FillRoundedRectangle (rect, 8, c); } g.Restore(); }
private void RedrawText(bool showCursor, bool useToolLayer) { Cairo.ImageSurface surf; var invalidate_cursor = old_cursor_bounds; if (!useToolLayer) { surf = PintaCore.Workspace.ActiveDocument.CurrentLayer.Surface; } else { surf = PintaCore.Workspace.ActiveDocument.ToolLayer.Surface; surf.Clear(); } using (var g = new Cairo.Context(surf)) { g.Save(); g.AppendPath(PintaCore.Workspace.ActiveDocument.SelectionPath); g.FillRule = Cairo.FillRule.EvenOdd; g.Clip(); g.MoveTo(new Cairo.PointD(engine.Origin.X, engine.Origin.Y)); g.Color = PintaCore.Palette.PrimaryColor; //Fill in background if (BackgroundFill) { using (var g2 = new Cairo.Context(surf)) { g2.FillRectangle(engine.GetLayoutBounds().ToCairoRectangle(), PintaCore.Palette.SecondaryColor); } } // Draw the text if (FillText) { Pango.CairoHelper.ShowLayout(g, engine.Layout); } if (FillText && StrokeText) { g.Color = PintaCore.Palette.SecondaryColor; g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath(g, engine.Layout); g.Stroke(); } else if (StrokeText) { g.Color = PintaCore.Palette.PrimaryColor; g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath(g, engine.Layout); g.Stroke(); } if (showCursor) { var loc = engine.GetCursorLocation(); g.Antialias = Cairo.Antialias.None; g.DrawLine(new Cairo.PointD(loc.X, loc.Y), new Cairo.PointD(loc.X, loc.Y + loc.Height), new Cairo.Color(0, 0, 0, 1), 1); loc.Inflate(2, 10); old_cursor_bounds = loc; } g.Restore(); } Rectangle r = engine.GetLayoutBounds(); r.Inflate(10 + OutlineWidth, 10 + OutlineWidth); PintaCore.Workspace.Invalidate(old_bounds); PintaCore.Workspace.Invalidate(invalidate_cursor); PintaCore.Workspace.Invalidate(r); old_bounds = r; }
private void RedrawText(bool showCursor, bool useToolLayer) { Cairo.ImageSurface surf; var invalidate_cursor = old_cursor_bounds; if (!useToolLayer) surf = PintaCore.Workspace.ActiveDocument.CurrentLayer.Surface; else { surf = PintaCore.Workspace.ActiveDocument.ToolLayer.Surface; surf.Clear (); } using (var g = new Cairo.Context (surf)) { g.Save (); // Show selection if on tool layer if (useToolLayer) { // Selected Text Cairo.Color c = new Cairo.Color (0.7, 0.8, 0.9, 0.5); foreach (Rectangle rect in engine.SelectionRectangles) g.FillRectangle (rect.ToCairoRectangle (), c); } g.AppendPath (PintaCore.Workspace.ActiveDocument.SelectionPath); g.FillRule = Cairo.FillRule.EvenOdd; g.Clip (); g.MoveTo (new Cairo.PointD (engine.Origin.X, engine.Origin.Y)); g.Color = PintaCore.Palette.PrimaryColor; if (BackgroundFill) { using (var g2 = new Cairo.Context (surf)) { g2.FillRectangle (engine.GetLayoutBounds ().ToCairoRectangle (),PintaCore.Palette.SecondaryColor); } } if (FillText) { Pango.CairoHelper.ShowLayout (g, engine.Layout); } if (FillText && StrokeText) { g.Color = PintaCore.Palette.SecondaryColor; g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath (g, engine.Layout); g.Stroke (); } else if (StrokeText) { g.Color = PintaCore.Palette.PrimaryColor; g.LineWidth = OutlineWidth; Pango.CairoHelper.LayoutPath (g, engine.Layout); g.Stroke (); } if (showCursor) { var loc = engine.GetCursorLocation (); g.Antialias = Cairo.Antialias.None; g.DrawLine (new Cairo.PointD (loc.X, loc.Y), new Cairo.PointD (loc.X, loc.Y + loc.Height), new Cairo.Color (0, 0, 0, 1), 1); loc.Inflate (2, 10); old_cursor_bounds = loc; } g.Restore (); } Rectangle r = engine.GetLayoutBounds (); r.Inflate (10 + OutlineWidth, 10 + OutlineWidth); PintaCore.Workspace.Invalidate (old_bounds); PintaCore.Workspace.Invalidate (invalidate_cursor); PintaCore.Workspace.Invalidate (r); old_bounds = r; }
private unsafe void DrawText(Cairo.ImageSurface dst, string textFont, string text, Point pt, Size measuredSize, bool antiAliasing, Cairo.ImageSurface brush8x8) { Point pt2 = pt; Size measuredSize2 = measuredSize; int offset = FontHeight; pt.X -= offset; measuredSize.Width += 2 * offset; Rectangle dstRect = new Rectangle (pt, measuredSize); Rectangle dstRectClipped = Rectangle.Intersect (dstRect, PintaCore.Layers.ToolLayer.Surface.GetBounds ()); PintaCore.Layers.ToolLayer.Clear (); if (dstRectClipped.Width == 0 || dstRectClipped.Height == 0) { return; } // We only use the first 8,8 of brush using (Cairo.Context toolctx = new Cairo.Context (PintaCore.Layers.ToolLayer.Surface)) { //toolctx.FillRectangle (new Cairo.Rectangle(0, 0, 800, 600), new Cairo.Color (0, 0, 0)); toolctx.FillRectangle (dstRect.ToCairoRectangle (), new Cairo.Color (1, 1, 1)); Cairo.ImageSurface surf = PintaCore.Layers.ToolLayer.Surface; //TODO find how create a surface a of a particular area of a bigger surface! //for moment work with the whole surface! if (measuredSize.Width > 0 && measuredSize.Height > 0) { //dstRectClipped using (Cairo.Context ctx = new Cairo.Context (PintaCore.Layers.ToolLayer.Surface)) { Cairo.TextExtents te = TextExtents (ctx, text); //new Cairo.PointD(dstRect.X - dstRectClipped.X + offset, dstRect.Y - dstRectClipped.Y), ctx.DrawText (new Cairo.PointD (dstRect.X + offset - te.XBearing, dstRect.Y - te.YBearing), textFont, FontSlant, FontWeight, FontSize, PintaCore.Palette.PrimaryColor, text); if (underscore_btn.Active) { int lineSize = 1; Cairo.FontExtents fe = FontExtents (ctx, text); ctx.DrawLine (new Cairo.PointD (pt2.X, dstRect.Bottom + fe.Descent), new Cairo.PointD (dstRect.Right - offset, dstRect.Bottom + fe.Descent), PintaCore.Palette.PrimaryColor, lineSize); } } PintaCore.Workspace.Invalidate (dstRectClipped); } // Mask out anything that isn't within the user's clip region (selected region) using (Region clip = Region.Rectangle (PintaCore.Layers.SelectionPath.GetBounds ())) { clip.Xor (Region.Rectangle (dstRectClipped)); // invert clip.Intersect (Region.Rectangle (new Rectangle (pt, measuredSize))); toolctx.FillRegion (clip, new Cairo.Color (1, 1, 1, 1)); } int skipX; if (pt.X < 0) { skipX = -pt.X; } else { skipX = 0; } int xEnd = Math.Min (dst.Width, pt.X + measuredSize.Width); bool blending = false; //AppEnvironment.AlphaBlending; //if (dst.IsColumnVisible(pt.X + skipX)) //{ for (int y = pt.Y; y < pt.Y + measuredSize.Height; ++y) { //if (!dst.IsRowVisible(y)) //{ // continue; //} ColorBgra* dstPtr = dst.GetPointAddressUnchecked (pt.X + skipX, y); ColorBgra* srcPtr = PintaCore.Layers.ToolLayer.Surface.GetPointAddress (pt.X + skipX, y); ColorBgra* brushPtr = brush8x8.GetRowAddressUnchecked (y & 7); for (int x = pt.X + skipX; x < xEnd; ++x) { ColorBgra srcPixel = *srcPtr; ColorBgra dstPixel = *dstPtr; ColorBgra brushPixel = brushPtr[x & 7]; int alpha = ((255 - srcPixel.R) * brushPixel.A) / 255; // we could use srcPixel.R, .G, or .B -- the choice here is arbitrary brushPixel.A = (byte)alpha; // could use R, G, or B -- arbitrary choice if (srcPtr->R == 255) { // do nothing -- leave dst alone } else if (alpha == 255 || !blending) { // copy it straight over *dstPtr = brushPixel; } else { // do expensive blending *dstPtr = UserBlendOps.NormalBlendOp.ApplyStatic (dstPixel, brushPixel); } ++dstPtr; ++srcPtr; } } //} } }
private void DrawText(Cairo.ImageSurface dst, string textFont, string text, Point pt, Size measuredSize, bool antiAliasing, Cairo.Color color) { Rectangle dstRect = new Rectangle (pt, measuredSize); //Rectangle dstRectClipped = Rectangle.Intersect(dstRect, ScratchSurface.Bounds); /* if (dstRectClipped.Width == 0 || dstRectClipped.Height == 0) { return; } */ using (Cairo.ImageSurface surface = new Cairo.ImageSurface (Cairo.Format.Argb32, 8, 8)) { using (Cairo.Context context = new Cairo.Context (surface)) { context.FillRectangle (new Cairo.Rectangle (0, 0, surface.Width, surface.Height), color); } DrawText (dst, textFont, text, pt, measuredSize, antiAliasing, surface); } }
/// <summary> /// Redraws the Text on the screen /// </summary> /// <remarks> /// assumes that the <b>font</b> and the <b>alignment</b> are already set /// </remarks> /// <param name="cursorOn"></param> private void RedrawText(bool cursorOn) { Cairo.ImageSurface surf = PintaCore.Layers.CurrentLayer.Surface; using (Cairo.Context context = new Cairo.Context (surf)) { if (this.ignoreRedraw > 0) { return; } if (saved != null) { saved.Draw (surf); PintaCore.Workspace.Invalidate (saved.Region.Clipbox); saved.Dispose (); saved = null; } // Save the Space behind the lines Rectangle[] rects = new Rectangle[lines.Count + 1]; Point[] localUls = new Point[lines.Count]; // All Lines bool recalcSizes = false; if (this.sizes == null) { recalcSizes = true; this.sizes = new Size[lines.Count + 1]; } if (recalcSizes) { for (int i = 0; i < lines.Count; ++i) { this.MeasureText (i); } } for (int i = 0; i < lines.Count; ++i) { Point upperLeft = GetUpperLeft (sizes[i], i); localUls[i] = upperLeft; Rectangle rect = new Rectangle (upperLeft, sizes[i]); rects[i] = rect; } // The Cursor Line string cursorLine = ((string)lines[linePos]).Substring (0, textPos); Size cursorLineSize; Point cursorUL; Rectangle cursorRect; bool emptyCursorLineFlag; if (cursorLine.Length == 0) { emptyCursorLineFlag = true; Size fullLineSize = sizes[linePos]; cursorLineSize = new Size (2, FontHeight); cursorUL = GetUpperLeft (fullLineSize, linePos); cursorRect = new Rectangle (cursorUL, cursorLineSize); } else if (cursorLine.Length == ((string)lines[linePos]).Length) { emptyCursorLineFlag = false; cursorLineSize = sizes[linePos]; cursorUL = localUls[linePos]; cursorRect = new Rectangle (cursorUL, cursorLineSize); } else { emptyCursorLineFlag = false; cursorLineSize = StringSize (cursorLine); cursorUL = localUls[linePos]; cursorRect = new Rectangle (cursorUL, cursorLineSize); } rects[lines.Count] = cursorRect; // Account for overhang on italic or fancy fonts int offset = FontHeight; for (int i = 0; i < rects.Length; ++i) { rects[i].X -= offset; rects[i].Width += 2 * offset; } // Set the saved region saved = new IrregularSurface (surf, Utility.InflateRectangles (rects, 3)); // Draw the Lines this.uls = localUls; for (int i = 0; i < lines.Count; i++) this.RenderText (surf, i); // Draw the Cursor if (cursorOn) { using (Cairo.Context toolctx = new Cairo.Context (PintaCore.Layers.ToolLayer.Surface)) { if (emptyCursorLineFlag) { toolctx.FillRectangle (cursorRect.ToCairoRectangle (), PintaCore.Palette.PrimaryColor); } else { toolctx.DrawLine (new Cairo.PointD (cursorRect.Right, cursorRect.Top), new Cairo.PointD (cursorRect.Right, cursorRect.Bottom), PintaCore.Palette.PrimaryColor, 1); } } } //PlaceMoveNub(); //UpdateStatusText(); PintaCore.Workspace.Invalidate (saved.Region.Clipbox); //Update(); } }
/// <summary> /// Draw a box model /// </summary> /// <param name="g">the Cairo context</param> /// <param name="rect">the rect (of the border-box) in which to draw this box model </param> /// <param name="content">content of the box mode</param> /// <param name="style">style of the box model</param> internal static void DrawBoxModel(this Cairo.Context g, Rect rect, string text, GUIStyle style) { //Widths of border var bt = style.BorderTop; var br = style.BorderRight; var bb = style.BorderBottom; var bl = style.BorderLeft; //Widths of padding var pt = style.PaddingTop; var pr = style.PaddingRight; var pb = style.PaddingBottom; var pl = style.PaddingLeft; //4 corner of the border-box var btl = new Point(rect.Left, rect.Top); var btr = new Point(rect.Right, rect.Top); var bbr = new Point(rect.Right, rect.Bottom); var bbl = new Point(rect.Left, rect.Bottom); var borderBoxRect = new Rect(btl, bbr); //4 corner of the padding-box var ptl = new Point(btl.X + bl, btl.Y + bt); var ptr = new Point(btr.X - br, btr.Y + bt); var pbr = new Point(bbr.X - br, bbr.Y - bb); var pbl = new Point(bbl.X + bl, bbl.Y - bb); var paddingBoxRect = new Rect(ptl, pbr); //4 corner of the content-box var ctl = new Point(ptl.X + pl, ptl.Y + pt); var ctr = new Point(ptr.X - pr, ptr.Y + pr); var cbr = new Point(pbr.X - pr, pbr.Y - pb); var cbl = new Point(pbl.X + pl, pbl.Y - pb); var contentBoxRect = new Rect(ctl, cbr); /* * Render from inner to outer: Content, Padding, Border, Margin, Outline */ //Content //Content-box background(draw as a filled rectangle now) g.FillRectangle(rect, style.BackgroundColor); //Content-box if (text != null) { g.DrawText(contentBoxRect, text, style.FontSize, style.FontColor); } //Border // Top if (bt != 0) { g.FillPolygon(new[] { ptl, btl, btr, ptr }, style.BorderTopColor); } // Right if (br != 0) { g.FillPolygon(new[] { ptr, btr, bbr, pbr }, style.BorderRightColor); } // Bottom if (bb != 0) { g.FillPolygon(new[] { pbr, bbr, bbl, pbl }, style.BorderBottomColor); } // Left if (bl != 0) { g.FillPolygon(new[] { pbl, bbl, btl, ptl }, style.BorderLeftColor); } //Outline if (style.OutlineWidth != 0) { g.Rectangle(borderBoxRect.TopLeft.ToPointD(), borderBoxRect.Width, borderBoxRect.Height); g.LineWidth = style.OutlineWidth; g.SetSourceColor(style.OutlineColor); g.Stroke(); } #if DrawPaddingBox g.Rectangle(paddingBoxRect.TopLeft.ToPointD(), paddingBoxRect.Width, paddingBoxRect.Height); g.LineWidth = 1; g.SetSourceColor(CairoEx.ColorRgb(0, 100, 100)); g.Stroke(); #endif #if DrawContentBox g.Rectangle(contentBoxRect.TopLeft.ToPointD(), contentBoxRect.Width, contentBoxRect.Height); g.LineWidth = 1; g.SetSourceColor(CairoEx.ColorRgb(100, 0, 100)); g.Stroke(); #endif }