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; } } //} } }