Exemplo n.º 1
0
        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;
                    }
                }
                //}

            }
        }