Пример #1
0
        private unsafe void RenderOneToOne(Cairo.ImageSurface src, Cairo.ImageSurface dst, Gdk.Point offset, bool checker)
        {
            Gdk.Rectangle srcRect = new Gdk.Rectangle (offset, dst.GetBounds ().Size);
            srcRect.Intersect (src.GetBounds ());

            ColorBgra* src_ptr = (ColorBgra*)src.DataPtr;
            ColorBgra* dst_ptr = (ColorBgra*)dst.DataPtr;

            int src_width = src.Width;
            int dst_width = dst.Width;
            int dst_height = dst.Height;

            for (int dstRow = 0; dstRow < srcRect.Height; ++dstRow) {
                ColorBgra* dstRowPtr = dst.GetRowAddressUnchecked (dst_ptr, dst_width, dstRow);
                ColorBgra* srcRowPtr = src.GetPointAddressUnchecked (src_ptr, src_width, offset.X, dstRow + offset.Y);

                int dstCol = offset.X;
                int dstColEnd = offset.X + srcRect.Width;
                int checkerY = dstRow + offset.Y;

                while (dstCol < dstColEnd) {
                    // Blend it over the checkerboard background
                    if (checker) {
                        int b = srcRowPtr->B;
                        int g = srcRowPtr->G;
                        int r = srcRowPtr->R;
                        int a = srcRowPtr->A;

                        int v = (((dstCol ^ checkerY) & 8) << 3) + 191;
                        a = a + (a >> 7);
                        int vmia = v * (256 - a);

                        r = ((r * a) + vmia) >> 8;
                        g = ((g * a) + vmia) >> 8;
                        b = ((b * a) + vmia) >> 8;

                        dstRowPtr->Bgra = (uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)255 << 24);
                    } else {
                        *dstRowPtr = *srcRowPtr;
                    }

                    ++dstRowPtr;
                    ++srcRowPtr;
                    ++dstCol;
                }
            }
        }
Пример #2
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;
                    }
                }
                //}

            }
        }