ClippingRectangle and RotateImage

Next question:
I’m trying to put vertical text on the screen. I’m creating a bitmap big enough to hold the text, printing the text on the bitmap. Then I rotate the bitmap onto the DrawingContext.

A few snags. To rotate the bitmap it must be square. But I don’t want to paint a square image on the screen.
So I push a clip rectangle into the DC. But RotateImage ignores the clip rectangle. Why?

Is there a better way to do this?

BTW, using EMX.


defaultFont.ComputeExtent(LabelX[x], out TextXWidth, out TextXHeight);
Bitmap Label = new Bitmap(TextXWidth, TextXWidth);
Label.DrawRectangle(Color.Black, 0, 0, 0, Label.Width, Label.Height, 0, 0, Background, 0, 0, Background, 0, 0, 256);

Label.DrawText(LabelX[x], defaultFont, GridPen.Color, 0, 0);

dc.PushClippingRectangle(x - (TextXHeight / 2), this.Height - TextXWidth, TextXHeight, TextXWidth);
dc.RotateImage(270, x - (TextXHeight / 2), this.Height - TextXWidth, Label, 0, 0, TextXWidth, TextXWidth, ushort.MaxValue);
dc.PopClippingRectangle();

I have just looked at the implementation and you are right it doesn’t take clipping rectangle into account at all.

How do you create your dc?

I’m working in OnRender where it gets passed into as a parameter.

        public override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            if (ShowGrid)
            {

                if (HorizontalGridSpacing > 0)
                {
                    // Draw horizontal grid lines
                    for (int y = 0; y < this.Height; y += HorizontalGridSpacing)
                    {
                        if (y > 0 && y != this.Height - 1)
                        {//Only draw label if not at start or end of graph
                            int Text1Width, Text1Height, Text2Width, Text2Height;
                            string Text1 = (MaxYValue1 - ((MaxYValue1 - MinYValue1) / (this.Height - 1)) * y).ToString("f1");
                            string Text2 = (MaxYValue2 - ((MaxYValue2 - MinYValue2) / (this.Height - 1)) * y).ToString("f1");
                            defaultFont.ComputeExtent(Text1, out Text1Width, out Text1Height);
                            defaultFont.ComputeExtent(Text2, out Text2Width, out Text2Height);

                            dc.DrawText(Text1, defaultFont, GraphPen1.Color, 0, y - (Text1Height / 2));
                            dc.DrawText(Text2, defaultFont, GraphPen2.Color, this.Width - Text2Width, y - (Text2Height / 2));
                            dc.DrawLine(GridPen, Text1Width + 2, y, this.Width - Text2Width - 2, y);
                        }
                        else
                        {
                            dc.DrawLine(GridPen, 0, y, this.Width, y);
                        }
                    }
                }
                if (VerticalGridSpacing > 0)
                {
                    // Draw vertical grid lines
                    for (int x = 0; x < this.Width; x += VerticalGridSpacing)
                    {
                        int TextXWidth = 0, TextXHeight = 0;
                        if (x != 0 && x != this.Width - 1 && LabelX[x] != null)
                        {//Only draw label if not at start or end of graph
                            defaultFont.ComputeExtent(LabelX[x], out TextXWidth, out TextXHeight);
                            Bitmap Label = new Bitmap(TextXWidth, TextXWidth);
                            Label.DrawRectangle(Color.Black, 0, 0, 0, Label.Width, Label.Height, 0, 0, Background, 0, 0, Background, 0, 0, 256);

                            Label.DrawText(LabelX[x], defaultFont, GridPen.Color, 0, 0);
                            Bitmap rotated = new Bitmap(TextXHeight, TextXWidth);

                            dc.PushClippingRectangle(x - (TextXHeight / 2), this.Height - TextXWidth, TextXHeight, TextXWidth);
//Problem here:
                            dc.RotateImage(270, x - (TextXHeight / 2), this.Height - TextXWidth, Label, 0, 0, TextXWidth, TextXWidth, ushort.MaxValue);
                            dc.PopClippingRectangle();
                        }
                        dc.DrawLine(GridPen, x, 0, x, this.Height - TextXWidth);
                    }
                }
            }

            // Draw the graph lines
            for (int i = 1; i < PointIndex; i++)
            {
                dc.DrawLine(GraphPen1, PointsX[i - 1], PointsY1[i - 1], PointsX[i], PointsY1[i]);
                dc.DrawLine(GraphPen1, PointsX[i - 1], PointsY1[i - 1] - 1, PointsX[i], PointsY1[i] - 1);

                dc.DrawLine(GraphPen2, PointsX[i - 1], PointsY2[i - 1], PointsX[i], PointsY2[i]);
                dc.DrawLine(GraphPen2, PointsX[i - 1], PointsY2[i - 1] - 1, PointsX[i], PointsY2[i] - 1);
            }
        }

Try something like this:

    public class MyWindow : Window
    {
        private Color BackgroundColor = Colors.Blue;

        Font defaultFont = Resources.GetFont(Resources.FontResources.small);

        Pen GridPen = new Pen(Colors.Red,1);

        public override void OnRender(Microsoft.SPOT.Presentation.Media.DrawingContext dc)
        {
            base.OnRender(dc);
            int TextXHeight = 0, TextXWidth = 0;

            // Draw vertical grid lines
            for (int x = 0; x < this.Width; x += 20)
            {
                if (x != 0 && x != this.Width - 1 ) // && LabelX[x] != null)
                {//Only draw label if not at start or end of graph
                    
                    defaultFont.ComputeExtent(x.ToString(), out TextXWidth, out TextXHeight);

                    Bitmap Label = new Bitmap(TextXWidth + 2, TextXWidth + 2);
                    Label.DrawRectangle(Color.Black, 0, 0, 0, Label.Width, Label.Height, 0, 0, BackgroundColor, 0, 0, BackgroundColor, 0, 0, 256);
                    Label.DrawText(x.ToString(), defaultFont, GridPen.Color, 1, 1);

                    Bitmap rotated = new Bitmap(Label.Width, Label.Width);
                    rotated.RotateImage(270, 1, 1, Label, 1, 1, Label.Width-2, Label.Height-2, 10);

                    dc.DrawImage(rotated, x - (TextXHeight / 2), this.Height - TextXWidth, 1, 1, TextXHeight, TextXWidth);
                }
                dc.DrawLine(GridPen, x, 0, x, this.Height - TextXWidth);
            }
        }
    }  

Again, thanks Architect. I tried that but I must have messed something up.

Will post a picture and the source today or tomorrow…

Picture:

@ GMod(Errol) - that looks pretty cool!

Thanks! I’m busy uploading the code to CodeShare…

Code posted:
http://www.tinyclr.com/codeshare/entry/544

Looks great!

@ Architect - Thanks to all your help…

You are welcome!

What environment are you measuring. From 0C to 20C in 3 minutes (or hours)? Or is it just some artificial data on the graph?

Each vertical line is 2 hours.

Sensor is hanging out of my study’s window. The sharp rise, after around 8:30, is probably when the sun hits it directly. I must still make some kind of shield for it…

Wow, that cold at night! Very interesting.