Пример #1
0
        public IEnumerable <NoForms.Common.Rectangle> HitTextRange(int start, int length, NoForms.Common.Point offset, UText text)
        {
            // Grab a ref to the sdgtextinfo
            var ti = glyphRunner.GetTextInfo(text);

            return(glyphRunner.HitTextRange(ti, start, length, offset));
        }
Пример #2
0
        // FIXME another example of type switching.  Cant put d2d code on other side of bridge in eg UGeometryBase abstraction
        //       and also, using a factory to create the UGeometryBase will make d2d specific versions.
        // IDEA  This is possible:  Use factory (DI?) and check the Uxxx instances when passed to this type of class, and recreate
        //       a portion of the Uxxx if it doesnt match D2D?  Factory could be configured for d2d/ogl etc.  This links in with cacheing
        //       code too? Not sure if this will static compile :/ thats kinda the point...  we'd need the Uxxx.ICreateStuff to be a specific
        //       D2D interface...could subclass... would check if(ICreateStuff is D2DCreator) as d2dcreator else Icreatestuff=new d2dcreator...
        void AppendGeometry(ref GraphicsPath path, UGeometryBase geo, NoForms.Common.Point start) // ref GraphicsPath will allow us to recreate it if we want with new.
        {
            if (geo is UArcBase)
            {
                System.Drawing.PointF[] pts;
                if (geo is UArc)
                {
                    UArc arc = geo as UArc;
                    pts = (geo.Retreive <SDGDraw>(() =>
                    {
                        var elInput = new GeometryLib.Ellipse_Input(start.X, start.Y, arc.endPoint.X, arc.endPoint.Y, arc.arcSize.width, arc.arcSize.height, arc.rotation);
                        var elSolution = new List <GeometryLib.Ellipse_Output>(GeometryLib.Ellipse.Get_X0Y0(elInput)).ToArray();
                        GeometryLib.Ellipse.SampleArc(elInput, elSolution, arc.reflex, arc.sweepClockwise, arc.resolution, out pts);
                        return(new disParr(pts));
                    }) as disParr).pts;
                }
                //else if (geo is UEasyArc)
                //{
                //    var arc = geo as UEasyArc;
                //    pts = (geo.Retreive<SDGDraw>(() =>
                //    {
                //        return new disParr(new List<System.Drawing.PointF>(EllipseLib.EasyEllipse.Generate(new EllipseLib.EasyEllipse.EasyEllipseInput()
                //        {
                //            rotation = arc.rotation,
                //            start_x = start.X,
                //            start_y = start.Y,
                //            rx = arc.arcSize.width,
                //            ry = arc.arcSize.height,
                //            t1 = arc.startAngle,
                //            t2 = arc.endAngle,
                //            resolution = arc.resolution
                //        })).ToArray());
                //    }) as disParr).pts;
                //}
                else
                {
                    throw new NotImplementedException();
                }

                // clone the data
                List <PointF> opts  = new List <PointF>(path.PointCount > 0 ? path.PathPoints : new PointF[0]);
                List <byte>   otyps = new List <byte>(path.PointCount > 0 ? path.PathTypes : new byte[0]);

                // do the types
                if (otyps.Count == 0 || otyps[otyps.Count - 1] != (byte)PathPointType.Start)
                {
                    otyps.Add((byte)PathPointType.Start);
                    opts.Add(SDGTr.trF(start));
                }
                for (int i = 0; i < pts.Length; i++)
                {
                    otyps.Add((byte)PathPointType.Line); // try to interpolate a bit?
                }
                // append new data
                opts.AddRange(pts);

                // Replace the path via reference
                path = new GraphicsPath(opts.ToArray(), otyps.ToArray(), path.FillMode);
            }
            else if (geo is ULine)
            {
                ULine line = geo as ULine;
                path.AddLine(SDGTr.trF(start), SDGTr.trF(line.endPoint));
            }
            else if (geo is UBeizer)
            {
                UBeizer beizer = geo as UBeizer;
                path.AddBezier(SDGTr.trF(start), SDGTr.trF(beizer.controlPoint1), SDGTr.trF(beizer.controlPoint2), SDGTr.trF(beizer.endPoint));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Пример #3
0
 public void DrawEllipse(NoForms.Common.Point center, float radiusX, float radiusY, UBrush brush, UStroke stroke)
 {
     realRenderer.graphics.DrawEllipse(CreatePen(brush, stroke), center.X - radiusX, center.Y - radiusY, radiusX * 2, radiusY * 2);
 }
Пример #4
0
 public void DrawLine(NoForms.Common.Point start, NoForms.Common.Point end, UBrush brush, UStroke stroke)
 {
     realRenderer.graphics.DrawLine(CreatePen(brush, stroke), SDGTr.trF(start), SDGTr.trF(end));
 }
Пример #5
0
 public void FillEllipse(NoForms.Common.Point center, float radiusX, float radiusY, UBrush brush)
 {
     realRenderer.graphics.FillEllipse(CreateBrush(brush), center.X - radiusX, center.Y - radiusY, radiusX * 2, radiusY * 2);
 }
Пример #6
0
        public IEnumerable <NoForms.Common.Rectangle> HitTextRange(UTextGlyphingInfo ti, int start, int length, NoForms.Common.Point offset)
        {
            int cc = 0;

            foreach (var glyph in ti.glyphRuns)
            {
                // stride through glyphruns that are not involved.
                if (cc + glyph.run.runLength <= start)
                {
                    cc += glyph.run.runLength;
                    continue;
                }
                float cx = 0;
                foreach (var gchar in glyph.run.charSizes)
                {
                    // end iteration when we fall past this bound
                    if (cc >= start + length)
                    {
                        yield break;
                    }

                    // calculate and yield the current char rect
                    yield return(new NoForms.Common.Rectangle(glyph.location.X + cx,
                                                              glyph.location.Y + (glyph.run.runSize.height - gchar.height),
                                                              gchar.width,
                                                              gchar.height));

                    // inc counters for following glyphs
                    cx += gchar.width;
                }
            }
        }
Пример #7
0
        public IEnumerable <NoForms.Common.Rectangle> HitTextRange(int start, int length, NoForms.Common.Point offset, UText text)
        {
            var ti = GetTextData(text);

            return(glyphRunner.HitTextRange(ti.tinfo, start, length, offset));
        }
Пример #8
0
        public UTextHitInfo HitPoint(NoForms.Common.Point hitPoint, UText text)
        {
            var ti = GetTextData(text);

            return(glyphRunner.HitPoint(ti.tinfo, hitPoint));
        }
Пример #9
0
        public void DrawText(UText textObject, NoForms.Common.Point location, UBrush defBrush, UTextDrawOptions opt, bool clientRendering)
        {
            GLTextStore <sdg.Font> GLds = GetTextData(textObject);

            //when uninitialised, all members wll be null/-1.  we need to run a pass of the generator thing
            if (GLds.texture_for_blitting == -1)
            {
                var   tl = GLds.tinfo = glyphRunner.GetTextInfo(textObject);
                float l = float.MaxValue, t = float.MaxValue, b = float.MinValue, r = float.MinValue;

                // if empty
                if (tl.glyphRuns.Count == 0)
                {
                    return;
                }

                // Calculate the render rectangle
                foreach (var gr in tl.glyphRuns)
                {
                    var p1 = gr.location;
                    var p2 = new Point(p1.X + gr.run.runSize.width, p1.Y + gr.run.runSize.height);
                    if (p1.X < l)
                    {
                        l = p1.X;
                    }
                    if (p2.X < l)
                    {
                        l = p2.X;
                    }
                    if (p1.Y < t)
                    {
                        t = p1.Y;
                    }
                    if (p2.Y < t)
                    {
                        t = p2.Y;
                    }
                    if (p2.X > r)
                    {
                        r = p2.X;
                    }
                    if (p1.X > r)
                    {
                        r = p1.X;
                    }
                    if (p2.Y > b)
                    {
                        b = p2.Y;
                    }
                    if (p1.Y > b)
                    {
                        b = p1.Y;
                    }
                }
                Rectangle rrect = new Rectangle(new Point(l, t), new Point(r, b), true);
                System.Diagnostics.Debug.Assert(rrect.width > 0 && rrect.height > 0);

                // ensure we have the software buffer
                EnsureStoredData(textObject, new Size(r - l, b - t));
                // we will draw black onto transparent background, and handle brushes when rendering to blitting texture
                GLds.renderOffset = new Point(l, t);
                GLds.sbb_context.Clear(sdg.Color.Transparent);
                foreach (var glyphrun in tl.glyphRuns)
                {
                    var           style   = glyphrun.run.drawStyle;
                    UFont         font    = style != null ? (style.fontOverride ?? textObject.font) : textObject.font;
                    sdg.FontStyle fs      = (font.bold ? sdg.FontStyle.Bold : 0) | (font.italic ? sdg.FontStyle.Italic : 0);
                    var           sdgFont = FTR(font);

                    // render at 0,0 because we cropped to the minimum drawing area of glyphs...
                    GLds.sbb_context.DrawString(glyphrun.run.content, sdgFont, sdg.Brushes.Black, PTR(glyphrun.location - GLds.renderOffset), sdg.StringFormat.GenericTypographic);
                }

                // now copy into the blit mask
                GLds.texture_for_blitting = GL.GenTexture();
                LoadBitmapIntoTexture(GLds.texture_for_blitting, GLds.softbitbuf);
            }

            // draw background...
            foreach (var glyphrun in GLds.tinfo.glyphRuns)
            {
                var    style = glyphrun.run.drawStyle;
                UBrush brsh  = style != null ? (style.fgOverride ?? defBrush) : defBrush;
                if (style != null && style.bgOverride != null)
                {
                    FillRectangle(new NoForms.Common.Rectangle(location + glyphrun.location + GLds.renderOffset, glyphrun.run.runSize), style.bgOverride);
                }
            }

            // use blit mask to create a blitting texture, using the Util fbo (FIXME? but no multithreads...)
            //throw new NotImplementedException();

            // blit the buffer (FIXME thats not blitting) FIXME needs seperate (what about masked tezture alpbas!)
            var       gs = GLds.softbitbuf.Size;
            Rectangle rr = new Rectangle(location + GLds.renderOffset, new Size(gs.Width, gs.Height));
            int       st = rel.renderData.sofwareBuffer.Count;

            bufferTexRect(rr, new Rectangle(0, 0, 1, 1));
            int cnt = rel.renderData.sofwareBuffer.Count - st;

            rel.renderData.bufferInfo.Add(new RenderInfo(st, cnt, ArrayData.Vertex | ArrayData.Color | ArrayData.Texture, PrimitiveType.Quads, GLds.texture_for_blitting));
        }