/// <summary>Draws a character with x-inverted UV's. Used for rendering e.g. "1 < 2" in right-to-left.</summary>
        protected virtual void DrawInvertCharacter(ref float left, Renderman renderer)
        {
            BoxRegion screenRegion = renderer.CurrentRegion;
            float     top          = renderer.TopOffset;
            int       index        = renderer.CharacterIndex;

            Glyph character = Characters[index];

            if (character == null)
            {
                return;
            }

            if (Kerning != null)
            {
                left += Kerning[index] * FontSize;
            }

            // Get atlas location (if it has one):
            AtlasLocation locatedAt = character.Location;

            if (locatedAt != null)
            {
                // We're on the atlas!

                float y = top + renderer.TextAscender - ((character.Height + character.MinY) * FontSize);

                float scaleFactor = renderer.TextScaleFactor;

                screenRegion.Set(left + (character.LeftSideBearing * FontSize), y, locatedAt.Width * scaleFactor, locatedAt.Height * scaleFactor);

                if (screenRegion.Overlaps(renderer.ClippingBoundary))
                {
                    // True if this character is visible.

                    // Ensure correct batch:
                    renderer.SetupBatch(this, null, locatedAt.Atlas);

                    MeshBlock block = Add(renderer);
                    block.SetColour(renderer.FontColour);
                    block.ApplyOutline();

                    // And clip our meshblock to fit within boundary:

                    // Clip our meshblock to fit within boundary:
                    if (Background != null && Isolated)
                    {
                        // Setup the batch material for this char:
                        Material imageMaterial = Background.Image.Contents.GetImageMaterial(renderer.CurrentShaderSet.Normal);
                        SetBatchMaterial(renderer, imageMaterial);

                        // Reapply text atlas:
                        renderer.CurrentBatch.SetFontAtlas(locatedAt.Atlas);

                        // Apply the image UV's (we're always isolated so these can tile by going out of range):
                        block.ImageUV = block.SetClipped(
                            renderer.ClippingBoundary,
                            screenRegion,
                            renderer,
                            RenderData.computedStyle.ZIndex,
                            Background.ImageLocation,
                            block.ImageUV
                            );
                    }
                    else
                    {
                        block.ImageUV = null;
                    }

                    UVBlock uvs = block.SetClipped(renderer.ClippingBoundary, screenRegion, renderer, RenderData.computedStyle.ZIndex, locatedAt, block.TextUV);

                    if (uvs.Shared)
                    {
                        uvs = new UVBlock(uvs);
                    }

                    // Invert along X:
                    float temp = uvs.MinX;
                    uvs.MinX = uvs.MaxX;
                    uvs.MaxX = temp;

                    // Assign to the block:
                    block.TextUV = uvs;

                    block.Done(renderer.Transform);
                }
            }

            left += (character.AdvanceWidth * FontSize) + LetterSpacing;

            if (character.Charcode == (int)' ')
            {
                left += WordSpacing;
            }
        }
示例#2
0
 /// <summary>Sets the UV and image on this block to that of the solid colour pixel.</summary>
 public void SetSolidColourUV()
 {
     // Set the UVs - solid colour is always at y>1:
     ImageUV = null;
     TextUV  = null;
 }
示例#3
0
        /// <summary>Draws a character with x-inverted UV's. Used for rendering e.g. "1 < 2" in right-to-left.</summary>
        protected virtual void DrawInvertCharacter(ref float left, Renderman renderer)
        {
            BoxRegion screenRegion = renderer.CurrentRegion;
            float     top          = renderer.TopOffset;
            int       index        = renderer.CharacterIndex;

            Glyph character = Text.Characters[index];

            if (character == null)
            {
                return;
            }

            if (Text.Kerning != null)
            {
                left += Text.Kerning[index] * Text.FontSize;
            }

            // Get atlas location (if it has one):
            AtlasLocation locatedAt = character.Location;

            if (locatedAt != null)
            {
                // We're on the atlas!

                float y = top + renderer.TextAscender - ((character.Height + character.MinY) * Text.FontSize);

                float scaleFactor = renderer.TextScaleFactor;

                screenRegion.Set(left + (character.LeftSideBearing * Text.FontSize), y, locatedAt.Width * scaleFactor, locatedAt.Height * scaleFactor);

                if (screenRegion.Overlaps(renderer.ClippingBoundary))
                {
                    // True if this character is visible.

                    // Ensure correct batch:
                    renderer.SetupBatch(this, null, locatedAt.Atlas);

                    MeshBlock block = Add(renderer);
                    block.SetColour(renderer.FontColour);
                    block.ApplyOutline();

                    // And clip our meshblock to fit within boundary:
                    block.ImageUV = null;
                    UVBlock uvs = block.SetClipped(renderer.ClippingBoundary, screenRegion, renderer, RenderData.computedStyle.ZIndex, locatedAt, block.TextUV);

                    if (uvs.Shared)
                    {
                        uvs = new UVBlock(uvs);
                    }

                    // Invert along X:
                    float temp = uvs.MinX;
                    uvs.MinX = uvs.MaxX;
                    uvs.MaxX = temp;

                    // Assign to the block:
                    block.TextUV = uvs;

                    block.Done(renderer.Transform);
                }
            }

            left += (character.AdvanceWidth * Text.FontSize) + Text.LetterSpacing;

            if (character.Charcode == (int)' ')
            {
                left += Text.WordSpacing;
            }
        }
示例#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>Draws a character with x-inverted UV's. Used for rendering e.g. "1 < 2" in right-to-left.</summary>
        private void DrawInvertCharacter(int index, ref float left, float top, Renderman renderer, float zIndex, BoxRegion screenRegion)
        {
            Glyph character = Characters[index];

            if (character == null)
            {
                return;
            }

            if (Kerning != null)
            {
                left += Kerning[index] * FontSize;
            }

            if (character.Space)
            {
                left += SpaceSize + LetterSpacing;
                return;
            }

            float y = top + Ascender - ((character.Height + character.MinY) * FontSize);

            AtlasLocation locatedAt = character.Location;

            if (locatedAt == null)
            {
                // Not in font.
                return;
            }

            screenRegion.Set(left + (character.LeftSideBearing * FontSize), y, locatedAt.Width * ScaleFactor, locatedAt.Height * ScaleFactor);

            if (screenRegion.Overlaps(renderer.ClippingBoundary))
            {
                // True if this character is visible.

                // Ensure correct batch:
                SetupBatch(null, locatedAt.Atlas);

                MeshBlock block = Add();
                block.SetColour(FontColour);

                // And clip our meshblock to fit within boundary:
                block.ImageUV = null;
                UVBlock uvs = block.SetClipped(renderer.ClippingBoundary, screenRegion, renderer, zIndex, locatedAt, block.TextUV);

                if (uvs.Shared)
                {
                    uvs = new UVBlock(uvs);
                }

                // Invert along X:
                float temp = uvs.MinX;
                uvs.MinX = uvs.MaxX;
                uvs.MaxX = temp;

                // Assign to the block:
                block.TextUV = uvs;
            }

            left += (character.AdvanceWidth * FontSize) + LetterSpacing;
        }