예제 #1
0
 /// <summary>Sets the vertices of this box to that specified by the given block
 /// but clipped to fit within a boundary.</summary>
 /// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param>
 /// <param name="block">The position of the vertices.</param>
 /// <param name="zIndex">The depth of the vertices.</param>
 public void SetClipped(BoxRegion boundary, BoxRegion block, Renderman renderer, float zIndex)
 {
     // Clipping with no image/ affect on UVs:
     block.ClipBy(boundary);
     // And just apply the result:
     ApplyVertices(block, renderer, zIndex);
 }
예제 #2
0
        /// <summary>This locates the vertices of this block in world space to the position defined by the given box.</summary>
        /// <param name="block">The position of the vertices in screen coordinates.</param>
        /// <param name="renderer">The renderer used when rendering this block.</param>
        /// <param name="zIndex">The depth of the vertices.</param>
        internal void ApplyVertices(BoxRegion block, Renderman renderer, float zIndex)
        {
            // Compute the min/max pixels:
            Vector3 min = renderer.PixelToWorldUnit(block.X, block.Y, zIndex);
            Vector3 max = renderer.PixelToWorldUnit(block.MaxX, block.MaxY, zIndex);

            // Get the 4 corners:
            VertexTopLeft     = min;
            VertexBottomRight = max;
            VertexTopRight    = new Vector3(max.x, min.y, min.z);
            VertexBottomLeft  = new Vector3(min.x, max.y, min.z);
        }
예제 #3
0
		/// <summary>This locates the vertices of this block in world space to the position defined by the given box.</summary>
		/// <param name="block">The position of the vertices in screen coordinates.</param>
		/// <param name="renderer">The renderer used when rendering this block.</param>
		/// <param name="zIndex">The depth of the vertices.</param>
		private void ApplyVertices(BoxRegion block,Renderman renderer,float zIndex){
		
			// Compute the min/max pixels:
			Vector3 min=renderer.PixelToWorldUnit(block.X,block.Y,zIndex);
			Vector3 max=renderer.PixelToWorldUnit(block.MaxX,block.MaxY,zIndex);
			
			// Get the 4 corners:
			VertexTopLeft=min;
			VertexBottomRight=max;
			VertexTopRight=new Vector3(max.x,min.y,min.z); 
			VertexBottomLeft=new Vector3(min.x,max.y,min.z);
			
		}
예제 #4
0
		/// <summary>Sets the vertices of this box to that specified by the given block
		/// but clipped to fit within a boundary. At the same time, an image is applied
		/// to the block and its UV coordinates are also clipped.</summary>
		/// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param>
		/// <param name="block">The position of the vertices.</param>
		/// <param name="renderer">The renderer that will render this block.</param>
		/// <param name="zIndex">The depth of the vertices.</param>
		/// <param name="imgLocation">The location of the image on the meshes atlas.</param>
		public UVBlock SetClipped(BoxRegion boundary,BoxRegion block,Renderman renderer,float zIndex,AtlasLocation imgLocation,UVBlock uvBlock){
			
			// Image defines how big we want the image to be in pixels on the screen.
			// So firstly we need to find the ratio of how scaled our image actually is:
			float originalHeight=block.Height;
			float scaleX=imgLocation.Width/block.Width;
			float scaleY=imgLocation.Height/originalHeight;
			
			// We'll need to clip block and make sure the image block is clipped too:
			float blockX=block.X;
			float blockY=block.Y;
			
			if(block.ClipByChecked(boundary)){
				
				// It actually got clipped - time to do some UV clipping too.
				
				// Apply the verts:
				ApplyVertices(block,renderer,zIndex);
				
				block.X-=blockX;
				block.Y-=blockY;
				block.MaxX-=blockX;
				block.MaxY-=blockY;
				
				// Flip the gaps (the clipped and now 'missing' sections) - UV's are inverted relative to the vertices.
				
				// Bottom gap is just block.Y:
				float bottomGap=block.Y;
				
				// Top gap is the original height - the new maximum; write it to the bottom gap:
				block.Y=originalHeight-block.MaxY;
				
				// Update the top gap:
				block.MaxY=originalHeight-bottomGap;
				
				// Image was in terms of real screen pixels, so now we need to scale it to being in 'actual image' pixels.
				// From there, the region 
				block.X*=scaleX;
				block.MaxX*=scaleX;
				
				block.Y*=scaleY;
				block.MaxY*=scaleY;
				
				if(uvBlock==null || uvBlock.Shared){
					
					// Create the UV block:
					uvBlock=new UVBlock();
					
				}
				
				// Get the new max/min values:
				uvBlock.MinX=imgLocation.GetU(block.X+0.2f);
				uvBlock.MaxX=imgLocation.GetU(block.MaxX-0.2f);
				uvBlock.MaxY=imgLocation.GetV(block.MaxY-0.2f);
				uvBlock.MinY=imgLocation.GetV(block.Y+0.2f);
				
			}else{
				
				// Apply the verts:
				ApplyVertices(block,renderer,zIndex);
				
				// Globally share the UV!
				uvBlock=imgLocation;
				
			}
			
			return uvBlock;
			
		}
예제 #5
0
		/// <summary>Sets the vertices of this box to that specified by the given block
		/// but clipped to fit within a boundary.</summary>
		/// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param>
		/// <param name="block">The position of the vertices.</param>
		/// <param name="zIndex">The depth of the vertices.</param>
		public void SetClipped(BoxRegion boundary,BoxRegion block,Renderman renderer,float zIndex){
			// Clipping with no image/ affect on UVs:
			block.ClipBy(boundary);
			// And just apply the result:
			ApplyVertices(block,renderer,zIndex);
		}
예제 #6
0
        /// <summary>Sets the vertices of this box to that specified by the given block
        /// but clipped to fit within a boundary. At the same time, an image is applied
        /// to the block and its UV coordinates are also clipped.</summary>
        /// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param>
        /// <param name="block">The position of the vertices.</param>
        /// <param name="renderer">The renderer that will render this block.</param>
        /// <param name="zIndex">The depth of the vertices.</param>
        /// <param name="imgLocation">The location of the image on the meshes atlas.</param>
        public UVBlock SetClipped(BoxRegion boundary, BoxRegion block, Renderman renderer, float zIndex, AtlasLocation imgLocation, UVBlock uvBlock)
        {
            // Image defines how big we want the image to be in pixels on the screen.
            // So firstly we need to find the ratio of how scaled our image actually is:
            float originalHeight = block.Height;
            float scaleX         = imgLocation.Width / block.Width;
            float scaleY         = imgLocation.Height / originalHeight;

            // We'll need to clip block and make sure the image block is clipped too:
            float blockX = block.X;
            float blockY = block.Y;

            if (block.ClipByChecked(boundary))
            {
                // It actually got clipped - time to do some UV clipping too.

                // Apply the verts:
                ApplyVertices(block, renderer, zIndex);

                block.X    -= blockX;
                block.Y    -= blockY;
                block.MaxX -= blockX;
                block.MaxY -= blockY;

                // Flip the gaps (the clipped and now 'missing' sections) - UV's are inverted relative to the vertices.

                // Bottom gap is just block.Y:
                float bottomGap = block.Y;

                // Top gap is the original height - the new maximum; write it to the bottom gap:
                block.Y = originalHeight - block.MaxY;

                // Update the top gap:
                block.MaxY = originalHeight - bottomGap;

                // Image was in terms of real screen pixels, so now we need to scale it to being in 'actual image' pixels.
                // From there, the region
                block.X    *= scaleX;
                block.MaxX *= scaleX;

                block.Y    *= scaleY;
                block.MaxY *= scaleY;

                if (uvBlock == null || uvBlock.Shared)
                {
                    // Create the UV block:
                    uvBlock = new UVBlock();
                }

                // Get the new max/min values:
                uvBlock.MinX = imgLocation.GetU(block.X + 0.2f);
                uvBlock.MaxX = imgLocation.GetU(block.MaxX - 0.2f);
                uvBlock.MaxY = imgLocation.GetV(block.MaxY - 0.2f);
                uvBlock.MinY = imgLocation.GetV(block.Y + 0.2f);
            }
            else
            {
                // Apply the verts:
                ApplyVertices(block, renderer, zIndex);

                // Globally share the UV!
                uvBlock = imgLocation;
            }

            return(uvBlock);
        }
예제 #7
0
        /// <summary>This is the second pass of layout requests.
        /// It positions the element in global screen space and also fires the render events
        /// which in turn generate or reallocates mesh blocks. This call applies to all it's
        /// children elements too.</summary>
        /// <param name="relativeTo">The current style we are positioning relative to.</param>
        public void PositionGlobally(ComputedStyle relativeTo)
        {
            ComputedStyle computed = Style.Computed;

            if (computed.Display == DisplayType.None)
            {
                // Don't draw this element or it's kids.
                return;
            }

            // Position globally:
            if (computed.Position == PositionType.Fixed)
            {
                // Fixed elements are nice and simple to deal with - Their essentially absolutely positioned but relative to the html tag.

                ComputedStyle html = Document.html.style.Computed;

                if (computed.RightPositioned)
                {
                    // The right hand edge of parent minus how far from the edge minus the width.
                    computed.OffsetLeft = computed.MarginLeft + html.OffsetLeft + html.PixelWidth - computed.PositionRight - computed.PixelWidth;
                }
                else
                {
                    computed.OffsetLeft = computed.MarginLeft + html.OffsetLeft + computed.PositionLeft;
                }

                if (computed.BottomPositioned)
                {
                    computed.OffsetTop = computed.MarginTop + html.OffsetTop + html.PixelHeight - computed.PositionBottom - computed.PixelHeight;
                }
                else
                {
                    computed.OffsetTop = computed.MarginTop + html.OffsetTop + computed.PositionTop;
                }

                // Change relativeTo here - we are now hopping to this fixed objects kids.
                relativeTo = computed;
            }
            else if (computed.Position == PositionType.Relative)
            {
                // Relative to where they should have been. PositionLeft/PositionRight etc. may be zero, but not always.

                // The width of border/padding/margin + the position of the parent + the offet from the parent.
                if (relativeTo == null)
                {
                    computed.OffsetLeft = computed.MarginLeft + computed.ParentOffsetLeft;
                }
                else
                {
                    computed.OffsetLeft = computed.MarginLeft + relativeTo.StyleOffsetLeft + relativeTo.OffsetLeft + computed.ParentOffsetLeft;
                }

                if (computed.RightPositioned)
                {
                    computed.OffsetLeft -= computed.PositionRight;
                }
                else
                {
                    computed.OffsetLeft += computed.PositionLeft;
                }

                if (relativeTo == null)
                {
                    computed.OffsetTop = computed.MarginTop + computed.ParentOffsetTop;
                }
                else
                {
                    computed.OffsetTop = computed.MarginTop + relativeTo.StyleOffsetTop + relativeTo.OffsetTop + computed.ParentOffsetTop;
                }

                if (computed.BottomPositioned)
                {
                    computed.OffsetTop -= computed.PositionBottom;
                }
                else
                {
                    computed.OffsetTop += computed.PositionTop;
                }

                // Vertical alignment:
                bool tableCell = (computed.Display == DisplayType.TableCell);
                if (relativeTo != null || computed.AutoMarginY || tableCell)
                {
                    if (computed.AutoMarginY || relativeTo.VerticalAlign == VerticalAlignType.Middle || (tableCell && computed.VerticalAlign == VerticalAlignType.Middle))
                    {
                        // Similar to below - we find the gap, then add *half* of that onto OffsetTop.
                        if (tableCell)
                        {
                            // Move upwards - we're sitting on the line and want to be above it.
                            computed.OffsetTop -= (relativeTo.InnerHeight - computed.PixelHeight) / 2;
                        }
                        else
                        {
                            computed.OffsetTop += (relativeTo.InnerHeight - relativeTo.ContentHeight) / 2;
                        }
                    }
                    else if (relativeTo.VerticalAlign == VerticalAlignType.Bottom)
                    {
                        // Find the gap - parent height-contentHeight.
                        // Then simply add that onto offsetTop.
                        computed.OffsetTop += relativeTo.InnerHeight - relativeTo.ContentHeight;
                    }
                    else if (tableCell && computed.VerticalAlign == VerticalAlignType.Top)
                    {
                        // This time we find the gap and remove it - we're at the bottom by default as a td sits on the line.
                        computed.OffsetTop -= relativeTo.InnerHeight - computed.PixelHeight;
                    }
                }

                // Note: relativeTo does not change here if we're in an inline element:
                if (computed.Display != DisplayType.Inline)
                {
                    relativeTo = computed;
                }
            }
            else
            {
                // Absolute - relative to parent. It's ParentOffsetLeft/Top are both zero.

                if (computed.RightPositioned)
                {
                    // The right hand edge of parent minus how far from the edge minus the width.
                    computed.OffsetLeft = computed.MarginLeft + relativeTo.OffsetLeft - relativeTo.StyleOffsetLeft - relativeTo.ScrollLeft + relativeTo.PixelWidth - computed.PositionRight - computed.PixelWidth;
                }
                else
                {
                    computed.OffsetLeft = computed.MarginLeft + relativeTo.OffsetLeft + relativeTo.StyleOffsetLeft + relativeTo.ScrollLeft + computed.PositionLeft;
                }

                if (computed.BottomPositioned)
                {
                    computed.OffsetTop = computed.MarginTop + relativeTo.OffsetTop - relativeTo.StyleOffsetTop - relativeTo.ScrollTop + relativeTo.PixelHeight - computed.PositionBottom - computed.PixelHeight;
                }
                else
                {
                    computed.OffsetTop = computed.MarginTop + relativeTo.OffsetTop + relativeTo.StyleOffsetTop + relativeTo.ScrollTop + computed.PositionTop;
                }

                // Set relativeTo to this - this is because the kids of absolute objects are relative to the absolute object itself.
                relativeTo = computed;
            }

            // Push the transform to our stack, if we have one.
            if (computed.Transform != null)
            {
                // Add it to the stack:
                Document.Renderer.Transformations.Push(computed.Transform);
                // Update it:
                computed.Transform.RecalculateMatrix(computed);
            }

            // Great, it's good to go!
            computed.Render();

            if (KidsToRender != null || HScrollbar || VScrollbar)
            {
                BoxRegion parentBoundary = null;

                if (relativeTo == computed)
                {
                    // We changed who we're relative to.
                    // Change the clipping boundary:
                    Renderman renderer = Document.Renderer;
                    parentBoundary = renderer.ClippingBoundary;

                    renderer.SetBoundary(computed);
                }

                if (KidsToRender != null)
                {
                    for (int i = 0; i < KidsToRender.Count; i++)
                    {
                        Element child = KidsToRender[i];
                        if (child != null)
                        {
                            child.PositionGlobally(relativeTo);
                        }
                    }
                }

                if (HScrollbar)
                {
                    HorizontalScrollbar.Element.PositionGlobally(relativeTo);
                }

                if (VScrollbar)
                {
                    VerticalScrollbar.Element.PositionGlobally(relativeTo);
                }


                if (relativeTo == computed)
                {
                    // Restore the previous boundary before this one: [Note - can't use SetBoundary here as it would destroy the box.]
                    Document.Renderer.ClippingBoundary = parentBoundary;
                }
            }

            if (computed.Transform != null)
            {
                // Pop it off again:
                Document.Renderer.Transformations.Pop();
            }
        }
예제 #8
0
		/// <summary>Sets the clipping boundary from the given computed style.</summary>
		/// <param name="style">The computed style to find the clipping boundary from.</param>
		public void SetBoundary(ComputedStyle style){
			bool visibleX=(style.OverflowX==OverflowType.Visible);
			bool visibleY=(style.OverflowY==OverflowType.Visible);
			
			if(visibleX && visibleY){
				return;
			}
			
			BoxRegion newBoundary=null;
			
			if(visibleX){
				newBoundary=new BoxRegion(ClippingBoundary.X,style.OffsetTop+style.StyleOffsetTop+style.ScrollTop,ClippingBoundary.Width,style.InnerHeight);
			}else if(visibleY){
				newBoundary=new BoxRegion(style.OffsetLeft+style.StyleOffsetLeft+style.ScrollLeft,ClippingBoundary.Y,style.InnerWidth,ClippingBoundary.Height);
			}else{
				newBoundary=new BoxRegion(style.OffsetLeft+style.StyleOffsetLeft+style.ScrollLeft,style.OffsetTop+style.StyleOffsetTop+style.ScrollTop,style.InnerWidth,style.InnerHeight);
			}
			
			if(style.Clip){
				newBoundary.ClipBy(ClippingBoundary);
			}
			
			ClippingBoundary=newBoundary;
		}
예제 #9
0
		/// <summary>Creates a new renderer and a new document.</summary>
		public Renderman(){
			ClippingBoundary=new BoxRegion(0,0,Screen.width,Screen.height);
			RootDocument=new Document(this);
			RootDocument.location=new FilePath("resources://","",false);
		}