/// <summary>
        /// Get top-left location to start drawing the image at depending on background-position value.
        /// </summary>
        /// <param name="backgroundPosition">the background-position value</param>
        /// <param name="rectangle">the rectangle to position image in</param>
        /// <param name="imgSize">the size of the image</param>
        /// <returns>the top-left location</returns>
        private static RPoint GetLocation(string backgroundPosition, RRect rectangle, RSize imgSize)
        {
            double left = rectangle.Left;
            if (backgroundPosition.IndexOf("left", StringComparison.OrdinalIgnoreCase) > -1)
            {
                left = (rectangle.Left + .5f);
            }
            else if (backgroundPosition.IndexOf("right", StringComparison.OrdinalIgnoreCase) > -1)
            {
                left = rectangle.Right - imgSize.Width;
            }
            else if (backgroundPosition.IndexOf("0", StringComparison.OrdinalIgnoreCase) < 0)
            {
                left = (rectangle.Left + (rectangle.Width - imgSize.Width) / 2 + .5f);
            }

            double top = rectangle.Top;
            if (backgroundPosition.IndexOf("top", StringComparison.OrdinalIgnoreCase) > -1)
            {
                top = rectangle.Top;
            }
            else if (backgroundPosition.IndexOf("bottom", StringComparison.OrdinalIgnoreCase) > -1)
            {
                top = rectangle.Bottom - imgSize.Height;
            }
            else if (backgroundPosition.IndexOf("0", StringComparison.OrdinalIgnoreCase) < 0)
            {
                top = (rectangle.Top + (rectangle.Height - imgSize.Height) / 2 + .5f);
            }

            return new RPoint(left, top);
        }
예제 #2
0
        /// <summary>
        /// Init.
        /// </summary>
        protected RGraphics(RAdapter adapter, RRect initialClip)
        {
            ArgChecker.AssertArgNotNull(adapter, "global");

            _adapter = adapter;
            _clipStack.Push(initialClip);
        }
 /// <summary>
 /// Draws all the border of the box with respect to style, width, etc.
 /// </summary>
 /// <param name="g">the device to draw into</param>
 /// <param name="box">the box to draw borders for</param>
 /// <param name="rect">the bounding rectangle to draw in</param>
 /// <param name="isFirst">is it the first rectangle of the element</param>
 /// <param name="isLast">is it the last rectangle of the element</param>
 public static void DrawBoxBorders(RGraphics g, CssBox box, RRect rect, bool isFirst, bool isLast)
 {
     if (rect.Width > 0 && rect.Height > 0)
     {
         if (!(string.IsNullOrEmpty(box.BorderTopStyle) || box.BorderTopStyle == CssConstants.None || box.BorderTopStyle == CssConstants.Hidden) && box.ActualBorderTopWidth > 0)
         {
             DrawBorder(Border.Top, box, g, rect, isFirst, isLast);
         }
         if (isFirst && !(string.IsNullOrEmpty(box.BorderLeftStyle) || box.BorderLeftStyle == CssConstants.None || box.BorderLeftStyle == CssConstants.Hidden) && box.ActualBorderLeftWidth > 0)
         {
             DrawBorder(Border.Left, box, g, rect, true, isLast);
         }
         if (!(string.IsNullOrEmpty(box.BorderBottomStyle) || box.BorderBottomStyle == CssConstants.None || box.BorderBottomStyle == CssConstants.Hidden) && box.ActualBorderBottomWidth > 0)
         {
             DrawBorder(Border.Bottom, box, g, rect, isFirst, isLast);
         }
         if (isLast && !(string.IsNullOrEmpty(box.BorderRightStyle) || box.BorderRightStyle == CssConstants.None || box.BorderRightStyle == CssConstants.Hidden) && box.ActualBorderRightWidth > 0)
         {
             DrawBorder(Border.Right, box, g, rect, isFirst, true);
         }
     }
 }
        /// <summary>
        /// Draw the background image of the given box in the given rectangle.<br/>
        /// Handle background-repeat and background-position values.
        /// </summary>
        /// <param name="g">the device to draw into</param>
        /// <param name="box">the box to draw its background image</param>
        /// <param name="imageLoadHandler">the handler that loads image to draw</param>
        /// <param name="rectangle">the rectangle to draw image in</param>
        public static void DrawBackgroundImage(RGraphics g, CssBox box, ImageLoadHandler imageLoadHandler, RRect rectangle)
        {
            // image size depends if specific rectangle given in image loader
            var imgSize = new RSize(imageLoadHandler.Rectangle == RRect.Empty ? imageLoadHandler.Image.Width : imageLoadHandler.Rectangle.Width,
                imageLoadHandler.Rectangle == RRect.Empty ? imageLoadHandler.Image.Height : imageLoadHandler.Rectangle.Height);

            // get the location by BackgroundPosition value
            var location = GetLocation(box.BackgroundPosition, rectangle, imgSize);

            var srcRect = imageLoadHandler.Rectangle == RRect.Empty
                ? new RRect(0, 0, imgSize.Width, imgSize.Height)
                : new RRect(imageLoadHandler.Rectangle.Left, imageLoadHandler.Rectangle.Top, imgSize.Width, imgSize.Height);

            // initial image destination rectangle
            var destRect = new RRect(location, imgSize);

            // need to clip so repeated image will be cut on rectangle
            var lRectangle = rectangle;
            lRectangle.Intersect(g.GetClip());
            g.PushClip(lRectangle);

            switch (box.BackgroundRepeat)
            {
                case "no-repeat":
                    g.DrawImage(imageLoadHandler.Image, destRect, srcRect);
                    break;
                case "repeat-x":
                    DrawRepeatX(g, imageLoadHandler, rectangle, srcRect, destRect, imgSize);
                    break;
                case "repeat-y":
                    DrawRepeatY(g, imageLoadHandler, rectangle, srcRect, destRect, imgSize);
                    break;
                default:
                    DrawRepeat(g, imageLoadHandler, rectangle, srcRect, destRect, imgSize);
                    break;
            }

            g.PopClip();
        }
        /// <summary>
        /// Set the image using callback from load image event, use the given data.
        /// </summary>
        /// <param name="path">the path to the image to load (file path or uri)</param>
        /// <param name="image">the image to load</param>
        /// <param name="imageRectangle">optional: limit to specific rectangle of the image and not all of it</param>
        private void OnHtmlImageLoadEventCallback(string path, object image, RRect imageRectangle)
        {
            if (!_disposed)
            {
                _imageRectangle = imageRectangle;

                if (image != null)
                {
                    _image = _htmlContainer.Adapter.ConvertImage(image);
                    ImageLoadComplete(_asyncCallback);
                }
                else if (!string.IsNullOrEmpty(path))
                {
                    SetImageFromPath(path);
                }
                else
                {
                    ImageLoadComplete(_asyncCallback);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Paint all the words in the box.
        /// </summary>
        /// <param name="g">the device to draw into</param>
        /// <param name="offset">the current scroll offset to offset the words</param>
        private void PaintWords(RGraphics g, RPoint offset)
        {
            if (Width.Length > 0)
            {
                var isRtl = Direction == CssConstants.Rtl;
                foreach (var word in Words)
                {
                    if (!word.IsLineBreak)
                    {
                        var wordPoint = new RPoint(word.Left + offset.X, word.Top + offset.Y);
                        if (word.Selected)
                        {
                            // handle paint selected word background and with partial word selection
                            var wordLine = DomUtils.GetCssLineBoxByWord(word);
                            var left = word.SelectedStartOffset > -1 ? word.SelectedStartOffset : (wordLine.Words[0] != word && word.HasSpaceBefore ? -ActualWordSpacing : 0);
                            var padWordRight = word.HasSpaceAfter && !wordLine.IsLastSelectedWord(word);
                            var width = word.SelectedEndOffset > -1 ? word.SelectedEndOffset : word.Width + (padWordRight ? ActualWordSpacing : 0);
                            var rect = new RRect(word.Left + offset.X + left, word.Top + offset.Y, width - left, wordLine.LineHeight);

                            g.DrawRectangle(GetSelectionBackBrush(g, false), rect.X, rect.Y, rect.Width, rect.Height);

                            if (HtmlContainer.SelectionForeColor != RColor.Empty && (word.SelectedStartOffset > 0 || word.SelectedEndIndexOffset > -1))
                            {
                                g.PushClipExclude(rect);
                                g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl);
                                g.PopClip();
                                g.PushClip(rect);
                                g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl);
                                g.PopClip();
                            }
                            else
                            {
                                g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl);
                            }
                        }
                        else
                        {
                            //                            g.DrawRectangle(HtmlContainer.Adapter.GetPen(RColor.Black), wordPoint.X, wordPoint.Y, word.Width - 1, word.Height - 1);
                            g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl);
                        }
                    }
                }
            }
        }
예제 #7
0
 /// <summary>
 /// Get linear gradient color brush from <paramref name="color1"/> to <paramref name="color2"/>.
 /// </summary>
 /// <param name="rect">the rectangle to get the brush for</param>
 /// <param name="color1">the start color of the gradient</param>
 /// <param name="color2">the end color of the gradient</param>
 /// <param name="angle">the angle to move the gradient from start color to end color in the rectangle</param>
 /// <returns>linear gradient color brush instance</returns>
 public RBrush GetLinearGradientBrush(RRect rect, RColor color1, RColor color2, double angle)
 {
     return _adapter.GetLinearGradientBrush(rect, color1, color2, angle);
 }
예제 #8
0
        /// <summary>
        /// Paints the background of the box
        /// </summary>
        /// <param name="g">the device to draw into</param>
        /// <param name="rect">the bounding rectangle to draw in</param>
        /// <param name="isFirst">is it the first rectangle of the element</param>
        /// <param name="isLast">is it the last rectangle of the element</param>
        protected void PaintBackground(RGraphics g, RRect rect, bool isFirst, bool isLast)
        {
            if (rect.Width > 0 && rect.Height > 0)
            {
                RBrush brush = null;

                if (BackgroundGradient != CssConstants.None)
                {
                    brush = g.GetLinearGradientBrush(rect, ActualBackgroundColor, ActualBackgroundGradient, ActualBackgroundGradientAngle);
                }
                else if (RenderUtils.IsColorVisible(ActualBackgroundColor))
                {
                    brush = g.GetSolidBrush(ActualBackgroundColor);
                }

                if (brush != null)
                {
                    // TODO:a handle it correctly (tables background)
                    // if (isLast)
                    //  rectangle.Width -= ActualWordSpacing + CssUtils.GetWordEndWhitespace(ActualFont);

                    RGraphicsPath roundrect = null;
                    if (IsRounded)
                    {
                        roundrect = RenderUtils.GetRoundRect(g, rect, ActualCornerNw, ActualCornerNe, ActualCornerSe, ActualCornerSw);
                    }

                    Object prevMode = null;
                    if (HtmlContainer != null && !HtmlContainer.AvoidGeometryAntialias && IsRounded)
                    {
                        prevMode = g.SetAntiAliasSmoothingMode();
                    }

                    if (roundrect != null)
                    {
                        g.DrawPath(brush, roundrect);
                    }
                    else
                    {
                        g.DrawRectangle(brush, Math.Ceiling(rect.X), Math.Ceiling(rect.Y), rect.Width, rect.Height);
                    }

                    g.ReturnPreviousSmoothingMode(prevMode);

                    if (roundrect != null)
                        roundrect.Dispose();
                    brush.Dispose();
                }

                if (_imageLoadHandler != null && _imageLoadHandler.Image != null && isFirst)
                {
                    BackgroundImageDrawHandler.DrawBackgroundImage(g, this, _imageLoadHandler, rect);
                }
            }
        }
예제 #9
0
 /// <summary>
 /// Draws the specified Image at the specified location and with the specified size.
 /// </summary>
 /// <param name="image">Image to draw. </param>
 /// <param name="destRect">Rectangle structure that specifies the location and size of the drawn image. </param>
 public abstract void DrawImage(RImage image, RRect destRect);
예제 #10
0
 /// <summary>
 ///     Replaces this <see cref="RRect" /> structure with the intersection of itself and the specified
 ///     <see
 ///         cref="RRect" />
 ///     structure.
 /// </summary>
 /// <param name="rect">The rectangle to intersect. </param>
 public void Intersect(RRect rect)
 {
     RRect rectangleF = Intersect(rect, this);
     X = rectangleF.X;
     Y = rectangleF.Y;
     Width = rectangleF.Width;
     Height = rectangleF.Height;
 }
예제 #11
0
 /// <summary>
 ///     Determines if this rectangle intersects with <paramref name="rect" />.
 /// </summary>
 /// <returns>
 ///     This method returns true if there is any intersection.
 /// </returns>
 /// <param name="rect">The rectangle to test. </param>
 public bool IntersectsWith(RRect rect)
 {
     if (rect.X < X + Width && X < rect.X + rect.Width && rect.Y < Y + Height)
         return Y < rect.Y + rect.Height;
     else
         return false;
 }
예제 #12
0
        /// <summary>
        /// Paints the text decoration (underline/strike-through/over-line)
        /// </summary>
        /// <param name="g">the device to draw into</param>
        /// <param name="rectangle"> </param>
        /// <param name="isFirst"> </param>
        /// <param name="isLast"> </param>
        protected void PaintDecoration(RGraphics g, RRect rectangle, bool isFirst, bool isLast)
        {
            if (string.IsNullOrEmpty(TextDecoration) || TextDecoration == CssConstants.None)
                return;

            double y = 0f;
            if (TextDecoration == CssConstants.Underline)
            {
                y = Math.Round(rectangle.Top + ActualFont.UnderlineOffset);
            }
            else if (TextDecoration == CssConstants.LineThrough)
            {
                y = rectangle.Top + rectangle.Height / 2f;
            }
            else if (TextDecoration == CssConstants.Overline)
            {
                y = rectangle.Top;
            }
            y -= ActualPaddingBottom - ActualBorderBottomWidth;

            double x1 = rectangle.X;
            if (isFirst)
                x1 += ActualPaddingLeft + ActualBorderLeftWidth;

            double x2 = rectangle.Right;
            if (isLast)
                x2 -= ActualPaddingRight + ActualBorderRightWidth;

            var pen = g.GetPen(ActualColor);
            pen.Width = 1;
            pen.DashStyle = RDashStyle.Solid;
            g.DrawLine(pen, x1, y, x2, y);
        }
예제 #13
0
 /// <summary>
 ///     Determines if the rectangular region represented by <paramref name="rect" /> is entirely contained within this
 ///     <see cref="RRect" />
 ///     structure.
 /// </summary>
 /// <returns>
 ///     This method returns true if the rectangular region represented by <paramref name="rect" /> is entirely contained within the rectangular region represented by this
 ///     <see cref="RRect" />
 ///     ; otherwise false.
 /// </returns>
 /// <param name="rect">
 ///     The <see cref="RRect" /> to test.
 /// </param>
 public bool Contains(RRect rect)
 {
     if (X <= rect.X && rect.X + rect.Width <= X + Width && Y <= rect.Y)
         return rect.Y + rect.Height <= Y + Height;
     else
         return false;
 }
        /// <summary>
        /// Makes a border path for rounded borders.<br/>
        /// To support rounded dotted/dashed borders we need to use arc in the border path.<br/>
        /// Return null if the border is not rounded.<br/>
        /// </summary>
        /// <param name="g">the device to draw into</param>
        /// <param name="border">Desired border</param>
        /// <param name="b">Box which the border corresponds</param>
        /// <param name="r">the rectangle the border is enclosing</param>
        /// <returns>Beveled border path, null if there is no rounded corners</returns>
        private static RGraphicsPath GetRoundedBorderPath(RGraphics g, Border border, CssBox b, RRect r)
        {
            RGraphicsPath path = null;
            switch (border)
            {
                case Border.Top:
                    if (b.ActualCornerNw > 0 || b.ActualCornerNe > 0)
                    {
                        path = g.GetGraphicsPath();
                        path.Start(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNw);

                        if (b.ActualCornerNw > 0)
                            path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2 + b.ActualCornerNw, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNw, RGraphicsPath.Corner.TopLeft);

                        path.LineTo(r.Right - b.ActualBorderRightWidth / 2 - b.ActualCornerNe, r.Top + b.ActualBorderTopWidth / 2);

                        if (b.ActualCornerNe > 0)
                            path.ArcTo(r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNe, b.ActualCornerNe, RGraphicsPath.Corner.TopRight);
                    }
                    break;
                case Border.Bottom:
                    if (b.ActualCornerSw > 0 || b.ActualCornerSe > 0)
                    {
                        path = g.GetGraphicsPath();
                        path.Start(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSe);

                        if (b.ActualCornerSe > 0)
                            path.ArcTo(r.Right - b.ActualBorderRightWidth / 2 - b.ActualCornerSe, r.Bottom - b.ActualBorderBottomWidth / 2, b.ActualCornerSe, RGraphicsPath.Corner.BottomRight);

                        path.LineTo(r.Left + b.ActualBorderLeftWidth / 2 + b.ActualCornerSw, r.Bottom - b.ActualBorderBottomWidth / 2);

                        if (b.ActualCornerSw > 0)
                            path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSw, b.ActualCornerSw, RGraphicsPath.Corner.BottomLeft);
                    }
                    break;
                case Border.Right:
                    if (b.ActualCornerNe > 0 || b.ActualCornerSe > 0)
                    {
                        path = g.GetGraphicsPath();

                        bool noTop = b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden;
                        bool noBottom = b.BorderBottomStyle == CssConstants.None || b.BorderBottomStyle == CssConstants.Hidden;
                        path.Start(r.Right - b.ActualBorderRightWidth / 2 - (noTop ? b.ActualCornerNe : 0), r.Top + b.ActualBorderTopWidth / 2 + (noTop ? 0 : b.ActualCornerNe));

                        if (b.ActualCornerNe > 0 && noTop)
                            path.ArcTo(r.Right - b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNe, b.ActualCornerNe, RGraphicsPath.Corner.TopRight);

                        path.LineTo(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSe);

                        if (b.ActualCornerSe > 0 && noBottom)
                            path.ArcTo(r.Right - b.ActualBorderRightWidth / 2 - b.ActualCornerSe, r.Bottom - b.ActualBorderBottomWidth / 2, b.ActualCornerSe, RGraphicsPath.Corner.BottomRight);
                    }
                    break;
                case Border.Left:
                    if (b.ActualCornerNw > 0 || b.ActualCornerSw > 0)
                    {
                        path = g.GetGraphicsPath();

                        bool noTop = b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden;
                        bool noBottom = b.BorderBottomStyle == CssConstants.None || b.BorderBottomStyle == CssConstants.Hidden;
                        path.Start(r.Left + b.ActualBorderLeftWidth / 2 + (noBottom ? b.ActualCornerSw : 0), r.Bottom - b.ActualBorderBottomWidth / 2 - (noBottom ? 0 : b.ActualCornerSw));

                        if (b.ActualCornerSw > 0 && noBottom)
                            path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSw, b.ActualCornerSw, RGraphicsPath.Corner.BottomLeft);

                        path.LineTo(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNw);

                        if (b.ActualCornerNw > 0 && noTop)
                            path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2 + b.ActualCornerNw, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNw, RGraphicsPath.Corner.TopLeft);
                    }
                    break;
            }

            return path;
        }
        /// <summary>
        /// Draw the background image at the required location repeating it over the X and Y axis.<br/>
        /// Adjust location to left-top if starting location doesn't include all the range (adjusted to center or bottom/right).
        /// </summary>
        private static void DrawRepeat(RGraphics g, ImageLoadHandler imageLoadHandler, RRect rectangle, RRect srcRect, RRect destRect, RSize imgSize)
        {
            while (destRect.X > rectangle.X)
                destRect.X -= imgSize.Width;
            while (destRect.Y > rectangle.Y)
                destRect.Y -= imgSize.Height;

            using (var brush = g.GetTextureBrush(imageLoadHandler.Image, srcRect, destRect.Location))
            {
                g.DrawRectangle(brush, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
            }
        }
 /// <summary>
 /// Set rectangle for inset/outset border as it need diagonal connection to other borders.
 /// </summary>
 /// <param name="border">Desired border</param>
 /// <param name="b">Box which the border corresponds</param>
 /// <param name="r">the rectangle the border is enclosing</param>
 /// <param name="isLineStart">Specifies if the border is for a starting line (no bevel on left)</param>
 /// <param name="isLineEnd">Specifies if the border is for an ending line (no bevel on right)</param>
 /// <returns>Beveled border path, null if there is no rounded corners</returns>
 private static void SetInOutsetRectanglePoints(Border border, CssBox b, RRect r, bool isLineStart, bool isLineEnd)
 {
     switch (border)
     {
         case Border.Top:
             _borderPts[0] = new RPoint(r.Left, r.Top);
             _borderPts[1] = new RPoint(r.Right, r.Top);
             _borderPts[2] = new RPoint(r.Right, r.Top + b.ActualBorderTopWidth);
             _borderPts[3] = new RPoint(r.Left, r.Top + b.ActualBorderTopWidth);
             if (isLineEnd)
                 _borderPts[2].X -= b.ActualBorderRightWidth;
             if (isLineStart)
                 _borderPts[3].X += b.ActualBorderLeftWidth;
             break;
         case Border.Right:
             _borderPts[0] = new RPoint(r.Right - b.ActualBorderRightWidth, r.Top + b.ActualBorderTopWidth);
             _borderPts[1] = new RPoint(r.Right, r.Top);
             _borderPts[2] = new RPoint(r.Right, r.Bottom);
             _borderPts[3] = new RPoint(r.Right - b.ActualBorderRightWidth, r.Bottom - b.ActualBorderBottomWidth);
             break;
         case Border.Bottom:
             _borderPts[0] = new RPoint(r.Left, r.Bottom - b.ActualBorderBottomWidth);
             _borderPts[1] = new RPoint(r.Right, r.Bottom - b.ActualBorderBottomWidth);
             _borderPts[2] = new RPoint(r.Right, r.Bottom);
             _borderPts[3] = new RPoint(r.Left, r.Bottom);
             if (isLineStart)
                 _borderPts[0].X += b.ActualBorderLeftWidth;
             if (isLineEnd)
                 _borderPts[1].X -= b.ActualBorderRightWidth;
             break;
         case Border.Left:
             _borderPts[0] = new RPoint(r.Left, r.Top);
             _borderPts[1] = new RPoint(r.Left + b.ActualBorderLeftWidth, r.Top + b.ActualBorderTopWidth);
             _borderPts[2] = new RPoint(r.Left + b.ActualBorderLeftWidth, r.Bottom - b.ActualBorderBottomWidth);
             _borderPts[3] = new RPoint(r.Left, r.Bottom);
             break;
     }
 }
예제 #17
0
        /// <summary>
        /// On image load process is complete with image or without update the image box.
        /// </summary>
        /// <param name="image">the image loaded or null if failed</param>
        /// <param name="rectangle">the source rectangle to draw in the image (empty - draw everything)</param>
        /// <param name="async">is the callback was called async to load image call</param>
        private void OnLoadImageComplete(RImage image, RRect rectangle, bool async)
        {
            _imageWord.Image = image;
            _imageWord.ImageRectangle = rectangle;
            _imageLoadingComplete = true;
            _wordsSizeMeasured = false;

            if (_imageLoadingComplete && image == null)
            {
                SetErrorBorder();
            }

            if (!HtmlContainer.AvoidImagesLateLoading || async)
            {
                var width = new CssLength(Width);
                var height = new CssLength(Height);
                var layout = (width.Number <= 0 || width.Unit != CssUnit.Pixels) || (height.Number <= 0 || height.Unit != CssUnit.Pixels);
                HtmlContainer.RequestRefresh(layout);
            }
        }
예제 #18
0
        /// <summary>
        /// Sets the baseline of the words of the specified box to certain height
        /// </summary>
        /// <param name="g">Device info</param>
        /// <param name="b">box to check words</param>
        /// <param name="baseline">baseline</param>
        internal void SetBaseLine(RGraphics g, CssBox b, double baseline)
        {
            //TODO: Aqui me quede, checar poniendo "by the" con un font-size de 3em
            List<CssRect> ws = WordsOf(b);

            if (!Rectangles.ContainsKey(b))
                return;

            RRect r = Rectangles[b];

            //Save top of words related to the top of rectangle
            double gap = 0f;

            if (ws.Count > 0)
            {
                gap = ws[0].Top - r.Top;
            }
            else
            {
                CssRect firstw = b.FirstWordOccourence(b, this);

                if (firstw != null)
                {
                    gap = firstw.Top - r.Top;
                }
            }

            //New top that words will have
            //float newtop = baseline - (Height - OwnerBox.FontDescent - 3); //OLD
            double newtop = baseline; // -GetBaseLineHeight(b, g); //OLD

            if (b.ParentBox != null &&
                b.ParentBox.Rectangles.ContainsKey(this) &&
                r.Height < b.ParentBox.Rectangles[this].Height)
            {
                //Do this only if rectangle is shorter than parent's
                double recttop = newtop - gap;
                RRect newr = new RRect(r.X, recttop, r.Width, r.Height);
                Rectangles[b] = newr;
                b.OffsetRectangle(this, gap);
            }

            foreach (var word in ws)
            {
                if (!word.IsImage)
                    word.Top = newtop;
            }
        }
예제 #19
0
 /// <summary>
 /// On image load process complete with image request refresh for it to be painted.
 /// </summary>
 /// <param name="image">the image loaded or null if failed</param>
 /// <param name="rectangle">the source rectangle to draw in the image (empty - draw everything)</param>
 /// <param name="async">is the callback was called async to load image call</param>
 private void OnImageLoadComplete(RImage image, RRect rectangle, bool async)
 {
     if (image != null && async)
         HtmlContainer.RequestRefresh(false);
 }
예제 #20
0
 /// <summary>
 /// Offsets the rectangle of the specified linebox by the specified gap,
 /// and goes deep for rectangles of children in that linebox.
 /// </summary>
 /// <param name="lineBox"></param>
 /// <param name="gap"></param>
 internal void OffsetRectangle(CssLineBox lineBox, double gap)
 {
     if (Rectangles.ContainsKey(lineBox))
     {
         var r = Rectangles[lineBox];
         Rectangles[lineBox] = new RRect(r.X, r.Y + gap, r.Width, r.Height);
     }
 }
 /// <summary>
 /// Draw simple border.
 /// </summary>
 /// <param name="border">Desired border</param>
 /// <param name="g">the device to draw to</param>
 /// <param name="box">Box which the border corresponds</param>
 /// <param name="brush">the brush to use</param>
 /// <param name="rectangle">the bounding rectangle to draw in</param>
 /// <returns>Beveled border path, null if there is no rounded corners</returns>
 public static void DrawBorder(Border border, RGraphics g, CssBox box, RBrush brush, RRect rectangle)
 {
     SetInOutsetRectanglePoints(border, box, rectangle, true, true);
     g.DrawPolygon(brush, _borderPts);
 }
        /// <summary>
        /// Draw specific border (top/bottom/left/right) with the box data (style/width/rounded).<br/>
        /// </summary>
        /// <param name="border">desired border to draw</param>
        /// <param name="box">the box to draw its borders, contain the borders data</param>
        /// <param name="g">the device to draw into</param>
        /// <param name="rect">the rectangle the border is enclosing</param>
        /// <param name="isLineStart">Specifies if the border is for a starting line (no bevel on left)</param>
        /// <param name="isLineEnd">Specifies if the border is for an ending line (no bevel on right)</param>
        private static void DrawBorder(Border border, CssBox box, RGraphics g, RRect rect, bool isLineStart, bool isLineEnd)
        {
            var style = GetStyle(border, box);
            var color = GetColor(border, box, style);

            var borderPath = GetRoundedBorderPath(g, border, box, rect);
            if (borderPath != null)
            {
                // rounded border need special path
                Object prevMode = null;
                if (box.HtmlContainer != null && !box.HtmlContainer.AvoidGeometryAntialias && box.IsRounded)
                    prevMode = g.SetAntiAliasSmoothingMode();

                var pen = GetPen(g, style, color, GetWidth(border, box));
                using (borderPath)
                    g.DrawPath(pen, borderPath);

                g.ReturnPreviousSmoothingMode(prevMode);
            }
            else
            {
                // non rounded border
                if (style == CssConstants.Inset || style == CssConstants.Outset)
                {
                    // inset/outset border needs special rectangle
                    SetInOutsetRectanglePoints(border, box, rect, isLineStart, isLineEnd);
                    g.DrawPolygon(g.GetSolidBrush(color), _borderPts);
                }
                else
                {
                    // solid/dotted/dashed border draw as simple line
                    var pen = GetPen(g, style, color, GetWidth(border, box));
                    switch (border)
                    {
                        case Border.Top:
                            g.DrawLine(pen, Math.Ceiling(rect.Left), rect.Top + box.ActualBorderTopWidth / 2, rect.Right - 1, rect.Top + box.ActualBorderTopWidth / 2);
                            break;
                        case Border.Left:
                            g.DrawLine(pen, rect.Left + box.ActualBorderLeftWidth / 2, Math.Ceiling(rect.Top), rect.Left + box.ActualBorderLeftWidth / 2, Math.Floor(rect.Bottom));
                            break;
                        case Border.Bottom:
                            g.DrawLine(pen, Math.Ceiling(rect.Left), rect.Bottom - box.ActualBorderBottomWidth / 2, rect.Right - 1, rect.Bottom - box.ActualBorderBottomWidth / 2);
                            break;
                        case Border.Right:
                            g.DrawLine(pen, rect.Right - box.ActualBorderRightWidth / 2, Math.Ceiling(rect.Top), rect.Right - box.ActualBorderRightWidth / 2, Math.Floor(rect.Bottom));
                            break;
                    }
                }
            }
        }
예제 #23
0
        /// <summary>
        /// Paints the fragment
        /// </summary>
        /// <param name="g">the device to draw to</param>
        protected override void PaintImp(RGraphics g)
        {
            var offset = HtmlContainer != null ? HtmlContainer.ScrollOffset : RPoint.Empty;
            var rect = new RRect(Bounds.X + offset.X, Bounds.Y + offset.Y, Bounds.Width, Bounds.Height);

            if (rect.Height > 2 && RenderUtils.IsColorVisible(ActualBackgroundColor))
            {
                g.DrawRectangle(g.GetSolidBrush(ActualBackgroundColor), rect.X, rect.Y, rect.Width, rect.Height);
            }

            var b1 = g.GetSolidBrush(ActualBorderTopColor);
            BordersDrawHandler.DrawBorder(Border.Top, g, this, b1, rect);

            if (rect.Height > 1)
            {
                var b2 = g.GetSolidBrush(ActualBorderLeftColor);
                BordersDrawHandler.DrawBorder(Border.Left, g, this, b2, rect);

                var b3 = g.GetSolidBrush(ActualBorderRightColor);
                BordersDrawHandler.DrawBorder(Border.Right, g, this, b3, rect);

                var b4 = g.GetSolidBrush(ActualBorderBottomColor);
                BordersDrawHandler.DrawBorder(Border.Bottom, g, this, b4, rect);
            }
        }
예제 #24
0
 /// <summary>
 /// Push the clipping region of this Graphics to interception of current clipping rectangle and the given rectangle.
 /// </summary>
 /// <param name="rect">Rectangle to clip to.</param>
 public abstract void PushClip(RRect rect);
예제 #25
0
 /// <summary>
 ///     Creates and returns an inflated copy of the specified <see cref="RRect" /> structure. The copy is inflated by the specified amount. The original rectangle remains unmodified.
 /// </summary>
 /// <returns>
 ///     The inflated <see cref="RRect" />.
 /// </returns>
 /// <param name="rect">
 ///     The <see cref="RRect" /> to be copied. This rectangle is not modified.
 /// </param>
 /// <param name="x">The amount to inflate the copy of the rectangle horizontally. </param>
 /// <param name="y">The amount to inflate the copy of the rectangle vertically. </param>
 public static RRect Inflate(RRect rect, double x, double y)
 {
     RRect rectangleF = rect;
     rectangleF.Inflate(x, y);
     return rectangleF;
 }
예제 #26
0
 /// <summary>
 /// Push the clipping region of this Graphics to exclude the given rectangle from the current clipping rectangle.
 /// </summary>
 /// <param name="rect">Rectangle to exclude clipping in.</param>
 public abstract void PushClipExclude(RRect rect);
예제 #27
0
 /// <summary>
 ///     Returns a <see cref="RRect" /> structure that represents the intersection of two rectangles. If there is no intersection, and empty
 ///     <see
 ///         cref="RRect" />
 ///     is returned.
 /// </summary>
 /// <returns>
 ///     A third <see cref="RRect" /> structure the size of which represents the overlapped area of the two specified rectangles.
 /// </returns>
 /// <param name="a">A rectangle to intersect. </param>
 /// <param name="b">A rectangle to intersect. </param>
 public static RRect Intersect(RRect a, RRect b)
 {
     double x = Math.Max(a.X, b.X);
     double num1 = Math.Min(a.X + a.Width, b.X + b.Width);
     double y = Math.Max(a.Y, b.Y);
     double num2 = Math.Min(a.Y + a.Height, b.Y + b.Height);
     if (num1 >= x && num2 >= y)
         return new RRect(x, y, num1 - x, num2 - y);
     else
         return Empty;
 }
예제 #28
0
 /// <summary>
 /// Get TextureBrush object that uses the specified image and bounding rectangle.
 /// </summary>
 /// <param name="image">The Image object with which this TextureBrush object fills interiors.</param>
 /// <param name="dstRect">A Rectangle structure that represents the bounding rectangle for this TextureBrush object.</param>
 /// <param name="translateTransformLocation">The dimension by which to translate the transformation</param>
 public abstract RBrush GetTextureBrush(RImage image, RRect dstRect, RPoint translateTransformLocation);
예제 #29
0
 /// <summary>
 ///     Creates the smallest possible third rectangle that can contain both of two rectangles that form a union.
 /// </summary>
 /// <returns>
 ///     A third <see cref="RRect" /> structure that contains both of the two rectangles that form the union.
 /// </returns>
 /// <param name="a">A rectangle to union. </param>
 /// <param name="b">A rectangle to union. </param>
 public static RRect Union(RRect a, RRect b)
 {
     double x = Math.Min(a.X, b.X);
     double num1 = Math.Max(a.X + a.Width, b.X + b.Width);
     double y = Math.Min(a.Y, b.Y);
     double num2 = Math.Max(a.Y + a.Height, b.Y + b.Height);
     return new RRect(x, y, num1 - x, num2 - y);
 }
예제 #30
0
        /// <summary>
        /// Deeply offsets the top of the box and its contents
        /// </summary>
        /// <param name="amount"></param>
        internal void OffsetTop(double amount)
        {
            List<CssLineBox> lines = new List<CssLineBox>();
            foreach (CssLineBox line in Rectangles.Keys)
                lines.Add(line);

            foreach (CssLineBox line in lines)
            {
                RRect r = Rectangles[line];
                Rectangles[line] = new RRect(r.X, r.Y + amount, r.Width, r.Height);
            }

            foreach (CssRect word in Words)
            {
                word.Top += amount;
            }

            foreach (CssBox b in Boxes)
            {
                b.OffsetTop(amount);
            }

            if (_listItemBox != null)
                _listItemBox.OffsetTop(amount);

            Location = new RPoint(Location.X, Location.Y + amount);
        }