public Map(RenderingTextureAllocator Allocator) { // Create map _map = new List <Entry> [Allocator.Size.Z, Allocator.Size.Y / _mapGranularity, Allocator.Size.X / _mapGranularity]; for (int z = 0; z < _map.GetLength(0); ++z) { for (int y = 0; y < _map.GetLength(1); ++y) { for (int x = 0; x < _map.GetLength(2); ++x) { _map[z, y, x] = new List <Entry>(); } } } // Fill map foreach (KeyValuePair <RenderingTexture, VectorInt3> availableTexture in Allocator.AvailableTextures) { Entry @ref = new Entry(availableTexture); VectorInt2 startPixel = new VectorInt2(availableTexture.Value.X, availableTexture.Value.Y); VectorInt2 endPixel = startPixel + (availableTexture.Key.To - availableTexture.Key.From); VectorInt2 startBlock = startPixel / _mapGranularity; VectorInt2 endBlock = (endPixel + new VectorInt2(_mapGranularity - 1, _mapGranularity - 1)) / _mapGranularity; for (int x = startBlock.X; x < endBlock.X; ++x) { for (int y = startBlock.Y; y < endBlock.Y; ++y) { _map[availableTexture.Value.Z, y, x].Add(@ref); } } } }
public void RenderText(IEnumerable <Text> texts) { // Collect actual glyphs to render var glyphRenderInfos = new List <RenderingFont.GlyphRenderInfo>(); var overlayRectangles = new List <RectangleInt2>(); RenderingTextureAllocator textureAllocator = null; foreach (Text text in texts) { // Build glyphs using the right font Vector2 pixelPos = text.PixelPos + text.Pos * Size * 0.5f; pixelPos += (text.ScreenAlignment * 2 - new Vector2(1)) * Size * new Vector2(0.5f, -0.5f); RectangleInt2 rect = text.Font.ParseString(text.String, text.Overlay, glyphRenderInfos, VectorInt2.FromRounded(pixelPos), text.TextAlignment); if (rect != RectangleInt2.Zero) { overlayRectangles.Add(rect); } // Check texture allocator if (textureAllocator == null) { textureAllocator = text.Font.TextureAllocator; } else if (textureAllocator != text.Font.TextureAllocator) { throw new ArgumentException("Texts are using different texture allocators. This is not allowed in a single 'RenderText' call."); } } if (glyphRenderInfos.Count == 0) { return; } RenderGlyphs(textureAllocator, glyphRenderInfos, overlayRectangles); }
private void Create(Description description) { TextureAllocator = description.TextureAllocator; TextureAllocator.GarbageCollectionCollectEvent.Add(delegate(RenderingTextureAllocator allocator, RenderingTextureAllocator.Map map, HashSet <RenderingTextureAllocator.Map.Entry> inOutUsedTextures) { // Clean dictionary for weak references that died. List <GlyphIndex> GlyphKeysToRemove = new List <GlyphIndex>(); GlyphData unused; foreach (KeyValuePair <GlyphIndex, WeakReference <GlyphData> > glyph in _glyphDictionary) { if (!glyph.Value.TryGetTarget(out unused)) { GlyphKeysToRemove.Add(glyph.Key); } } foreach (GlyphIndex GlyphKeyToRemove in GlyphKeysToRemove) { _glyphDictionary.Remove(GlyphKeyToRemove); } return(null); }); // Setup GDI device and font _gdiHdc = GDI.CreateCompatibleDC(IntPtr.Zero); if (_gdiHdc == IntPtr.Zero) { throw new GDI.GDIException("CreateCompatibleDC"); } _gdiFont = GDI.CreateFontW((int)(description.FontSize + 0.5f), 0, 0, 0, description.FontIsBold ? 700 : 0, description.FontIsItalic ? 1u : 0u, description.FontIsUnderline ? 1u : 0u, description.FontIsStrikeout ? 1u : 0u, 0, 0, 0, GDI.FontQuality.CLEARTYPE_QUALITY, 0, description.FontName); if (_gdiFont == IntPtr.Zero) { throw new GDI.GDIException("CreateFont"); } IntPtr selectObjectResult = GDI.SelectObject(_gdiHdc, _gdiFont); if (selectObjectResult == IntPtr.Zero || selectObjectResult == new IntPtr(65535)) { throw new GDI.GDIException("SelectObject"); } _gdiGetCharacterPlacementOrder = Marshal.AllocHGlobal(sizeof(uint) * _gdiGetCharacterPlacementGlyphCount); _gdiGetCharacterPlacementDx = Marshal.AllocHGlobal(sizeof(int) * _gdiGetCharacterPlacementGlyphCount); _gdiGetCharacterPlacementGlpyhs = Marshal.AllocHGlobal(sizeof(GlyphIndex) * _gdiGetCharacterPlacementGlyphCount); GDI.TEXTMETRICW textMetric; if (!GDI.GetTextMetricsW(_gdiHdc, out textMetric)) { throw new GDI.GDIException("GetTextMetricsW"); } _lineAscent = textMetric.tmAscent; _lineSpaceing = textMetric.tmAscent + textMetric.tmDescent + textMetric.tmExternalLeading; if (GDI.SetBkColor(_gdiHdc, 0x00ffffff) == 0xffffffff) // White background (GDI does not support alpha though) { throw new GDI.GDIException("SetBkColor"); } // Preload characters ParseString(description.PreLoadedCharacters, false, new List <GlyphRenderInfo>()); }
/// <summary>Note that all fonts used in one call must be in the same texture allocator!</summary> public abstract void RenderGlyphs(RenderingTextureAllocator textureAllocator, List <RenderingFont.GlyphRenderInfo> glyphRenderInfos, List <RectangleInt2> overlays);
public abstract void RenderSprites(RenderingTextureAllocator textureAllocator, bool linearFilter, params Sprite[] sprites);