Example #1
0
        public static IAsyncResult SetTextBlockWithKey(TextBlock control, string key, string defaultText)
        {
            if (control == null || key == null)
            {
                throw new ArgumentNullException();
            }

            textControls[control.GetHashCode()] = key;
            return(GetTextAsync(key, defaultText, (s) =>
            {
                lock (textControls)
                {
                    if (textControls[control.GetHashCode()] == key)
                    {
                        control.Text = s;
                    }
                }
            }));
        }
		public TextExtents MeasureText(ref TextBlock block, TextQuality quality)
		{
			// First, check if we have cached this text block. Do not use block_cache.TryGetValue, to avoid thrashing
			// the user's TextBlockExtents struct.
			int hashcode = block.GetHashCode();
			if (block_cache.ContainsKey(hashcode))
				return block_cache[hashcode];

			// If this block is not cached, we have to measure it and (potentially) place it in the cache.
			TextExtents extents = MeasureTextExtents(ref block, quality);

			if ((block.Options & TextPrinterOptions.NoCache) == 0)
				block_cache.Add(hashcode, extents);

			return extents;
		}
        public void Print(ref TextBlock block, Color color, IGlyphRasterizer rasterizer)
        {
            GL.PushAttrib(AttribMask.CurrentBit | AttribMask.TextureBit | AttribMask.EnableBit | AttribMask.ColorBufferBit | AttribMask.DepthBufferBit);

            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.Blend);
            SetBlendFunction();

            GL.Disable(EnableCap.DepthTest);

            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)All.Modulate);
            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvColor, new Color4(0, 0, 0, 0));

            GL.Disable(EnableCap.TextureGenQ);
            GL.Disable(EnableCap.TextureGenR);
            GL.Disable(EnableCap.TextureGenS);
            GL.Disable(EnableCap.TextureGenT);

            RectangleF position;

            SetColor(color);
            
            int block_hash = block.GetHashCode();
            if (block_cache.ContainsKey(block_hash))
            {
                GL.CallList(block_cache[block_hash]);
            }
            else
            {
                using (TextExtents extents = rasterizer.MeasureText(ref block))
                {
                    // Build layout
                    int current = 0;
                    foreach (Glyph glyph in block)
                    {
                        // Do not render whitespace characters or characters outside the clip rectangle.
                        if (glyph.IsWhiteSpace || extents[current].Width == 0 || extents[current].Height == 0)
                        {
                            current++;
                            continue;
                        }
                        else if (!Cache.Contains(glyph))
                            Cache.Add(glyph, rasterizer, TextQuality);

                        CachedGlyphInfo info = Cache[glyph];
                        position = extents[current++];

                        // Use the real glyph width instead of the measured one (we want to achieve pixel perfect output).
                        position.Size = info.Rectangle.Size;

                        if (!active_lists.ContainsKey(info.Texture))
                        {
                            if (inactive_lists.Count > 0)
                            {
                                List<Vector2> list = inactive_lists.Dequeue();
                                list.Clear();
                                active_lists.Add(info.Texture, list);
                            }
                            else
                            {
                                active_lists.Add(info.Texture, new List<Vector2>());
                            }
                        }

                        {
                            // Interleaved array: Vertex, TexCoord, Vertex, ...
                            List<Vector2> current_list = active_lists[info.Texture];
                            current_list.Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Top));
                            current_list.Add(new Vector2(position.Left, position.Top));
                            current_list.Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Bottom));
                            current_list.Add(new Vector2(position.Left, position.Bottom));
                            current_list.Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Bottom));
                            current_list.Add(new Vector2(position.Right, position.Bottom));

                            current_list.Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Bottom));
                            current_list.Add(new Vector2(position.Right, position.Bottom));
                            current_list.Add(new Vector2(info.RectangleNormalized.Right, info.RectangleNormalized.Top));
                            current_list.Add(new Vector2(position.Right, position.Top));
                            current_list.Add(new Vector2(info.RectangleNormalized.Left, info.RectangleNormalized.Top));
                            current_list.Add(new Vector2(position.Left, position.Top));
                        }
                    }
                }

                // Render
                int display_list = 0;
                if ((block.Options & TextPrinterOptions.NoCache) == 0)
                {
                    display_list = GL.GenLists(1);
                    // Mesa Indirect gerates an InvalidOperation error right after
                    // GL.EndList() when using ListMode.CompileAndExecute.
                    // Using ListMode.Compile as a workaround.
                    GL.NewList(display_list, ListMode.Compile);
                }
                foreach (Texture2D key in active_lists.Keys)
                {
                    List<Vector2> list = active_lists[key];

                    key.Bind();

                    GL.Begin(BeginMode.Triangles);

                    for (int i = 0; i < list.Count; i += 2)
                    {
                        GL.TexCoord2(list[i]);
                        GL.Vertex2(list[i + 1]);
                    }

                    GL.End();
                }
                if ((block.Options & TextPrinterOptions.NoCache) == 0)
                {
                    GL.EndList();
                    block_cache.Add(block_hash, display_list);
                    GL.CallList(display_list);
                }

                // Clean layout
                foreach (List<Vector2> list in active_lists.Values)
                {
                    //list.Clear();
                    inactive_lists.Enqueue(list);
                }

                active_lists.Clear();
            }
            
            GL.PopAttrib();
        }