Example #1
0
        /// <summary>
        /// Loads letter iamge from win32 font.
        /// </summary>
        /// <param name="cache">should the iamge be cached in tga, xml files.</param>
        /// <returns>loader letter information.</returns>
        protected internal override LetterInfo Load(bool cache)
        {
            LetterInfo result = null;

#if WINDOWS
            IntPtr bitmapHandle = IntPtr.Zero;
            byte[] textureData  = null;

            try
            {
                if (null == PlatformWindows.SelectFont(this.font.fontRenderingDisplayContext, this.font.fontHandle))
                {
                    throw new Exception();
                }

                TextMetric tm = new TextMetric();

                if (false == PlatformWindows.GetTextMetrics(this.font.fontRenderingDisplayContext, out tm))
                {
                    throw new Exception();
                }

                if (PlatformWindows.GDI_ERROR == PlatformWindows.SetTextAlign(this.font.fontRenderingDisplayContext, PlatformWindows.TA_LEFT | PlatformWindows.TA_TOP | PlatformWindows.TA_UPDATECP))
                {
                    throw new Exception();
                }

                ABC[] abc = new ABC[1];

                if (false == PlatformWindows.GetCharABCWidths(this.font.fontRenderingDisplayContext, (uint)this.character, (uint)this.character, abc))
                {
                    throw new Exception();
                }

                this.offsetX = abc[0].abcA;
                this.width   = (int)(abc[0].abcB + abc[0].abcC);

                BitmapInfo header = new BitmapInfo();
                header.bmiHeader.biSize = Marshal.SizeOf(header);

                GlyphMetrics metrics  = new GlyphMetrics();
                MAT2         identity = new MAT2();
                identity.eM12.value = 0;
                identity.eM21.value = 0;
                identity.eM11.value = 1;
                identity.eM22.value = 1;

                if (PlatformWindows.GDI_ERROR == PlatformWindows.GetGlyphOutline(this.font.fontRenderingDisplayContext, this.character, PlatformWindows.GGO_METRICS, out metrics, 0, IntPtr.Zero, ref identity))
                {
                    throw new Exception();
                }

                header.bmiHeader.biWidth  = metrics.gmBlackBoxX;
                header.bmiHeader.biHeight = -1 * metrics.gmBlackBoxY;

                header.bmiHeader.biPlanes      = 1;
                header.bmiHeader.biBitCount    = 32;
                header.bmiHeader.biCompression = 0;// BI_RGB;
                byte[] bitmapData = null;

                IntPtr bitmapDataPointer = IntPtr.Zero;

                bitmapHandle = PlatformWindows.CreateDIBSection(this.font.fontRenderingDisplayContext, ref header, /*DIB_RGB_COLORS*/ 0, out bitmapDataPointer, IntPtr.Zero, 0);

                if (IntPtr.Zero == bitmapHandle)
                {
                    int err = Marshal.GetLastWin32Error();

                    throw new Exception();
                }

                if (null == PlatformWindows.SelectObject(this.font.fontRenderingDisplayContext, bitmapHandle))
                {
                    throw new Exception();
                }

                if (PlatformWindows.CLR_INVALID == PlatformWindows.SetBkColor(this.font.fontRenderingDisplayContext, new RGB(new byte[] { 0, 0, 0 }).ToInt32()))
                {
                    throw new Exception();
                }

                if (PlatformWindows.CLR_INVALID == PlatformWindows.SetTextColor(this.font.fontRenderingDisplayContext, new RGB(new byte[] { 0xff, 0xff, 0xff }).ToInt32()))
                {
                    throw new Exception();
                }

                if (0 == PlatformWindows.SetBkMode(this.font.fontRenderingDisplayContext, PlatformWindows.OPAQUE))
                {
                    throw new Exception();
                }

                if (false == PlatformWindows.MoveToEx(this.font.fontRenderingDisplayContext, 0 - abc[0].abcA, -1 * (tm.tmAscent - metrics.gmptGlyphOrigin.y), IntPtr.Zero))
                {
                    throw new Exception();
                }

                this.offsetY = tm.tmAscent - metrics.gmptGlyphOrigin.y - tm.tmDescent - 1;

                String str  = "" + this.character;
                RECT   rect = new RECT();

                if (false == PlatformWindows.ExtTextOut(this.font.fontRenderingDisplayContext, 0, 0, (uint)0, ref rect, str, 1, null))
                {
                    throw new Exception();
                }

                if (0 == PlatformWindows.SetBkMode(this.font.fontRenderingDisplayContext, PlatformWindows.TRANSPARENT))
                {
                    throw new Exception();
                }

                int bitmapWidth   = header.bmiHeader.biWidth;
                int bitmapHeight  = -header.bmiHeader.biHeight;
                int textureWidth  = RoundToPowerOf2(bitmapWidth);
                int textureHeight = RoundToPowerOf2(bitmapHeight);

                bitmapData = new byte[bitmapWidth * bitmapHeight * 4];

                Marshal.Copy(bitmapDataPointer, bitmapData, 0, bitmapWidth * bitmapHeight * 4);

                textureData = new byte[4 * textureWidth * textureHeight];

                for (int j = 0; j < textureHeight; j++)
                {
                    for (int i = 0; i < textureWidth; i++)
                    {
                        textureData[4 * (i + j * textureWidth) + 0] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 1] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 2] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 3] = (byte)((i >= bitmapWidth || j >= bitmapHeight) ? 0 : bitmapData[(i + bitmapWidth * j) * 4 + 2]);
                    }
                }

                if (true == cache)
                {
                    result               = new LetterInfo();
                    result.width         = bitmapWidth;
                    result.height        = bitmapHeight;
                    result.bytes         = textureData;
                    result.textureWidth  = textureWidth;
                    result.textureHeight = textureHeight;
                }
                else
                {
                    this.image = this.engine.CreateImage("Letter [" + this.character + "]", textureWidth, textureHeight, textureData);
//                    this.internalImage = true;
                }

                this.textureWidth  = textureWidth;
                this.textureHeight = textureHeight;
            }
            catch (Exception)
            {
                this.engine.DeleteImage(ref this.image);
            }

            if (null != bitmapHandle)
            {
                PlatformWindows.DeleteObject(bitmapHandle);
            }

            this.loaded = true;
#endif
            return(result);
        }
Example #2
0
        /// <summary>
        /// Caches the first 256 letters.
        /// </summary>
        /// <param name="save">are the cached letters supposed to be saved to tga files.</param>
        private void CacheFirst256Letters(bool save, String folder)
        {
            int imageIndex = 0;

            byte[] imageBuffer  = new byte[cacheTextureSize * cacheTextureSize * 4];
            int    rowStart     = 0;
            int    colStart     = 0;
            int    rowMaxHeight = 0;

            int[]   imageIndexes = new int[cacheLetters];
            int[][] imageUvs     = new int[cacheLetters][];

            for (int i = 0; i < cacheLetters; i++)
            {
                WinLetter letter = (WinLetter)this.letters[i];

                LetterInfo letterInfo = letter.Load(true);

                if (null == letterInfo)
                {
                    letterInfo               = new LetterInfo();
                    letterInfo.width         = 2;
                    letterInfo.height        = 2;
                    letterInfo.textureHeight = 2;
                    letterInfo.textureWidth  = 2;
                    letterInfo.bytes         = new byte[2 * 2 * 4];
                }

                if (colStart + letterInfo.width + 1 > cacheTextureSize)
                {
                    colStart  = 0;
                    rowStart += rowMaxHeight + 1;
                }

                if (rowStart + 1 + letterInfo.height >= cacheTextureSize)
                {
                    this.cachedImages.Add(this.engine.CreateImage(cacheFolder + ToString() + "_" + (imageIndex + 1), cacheTextureSize, cacheTextureSize, imageBuffer));

                    if (true == save)
                    {
                        byte[] tga = Image.GetTGA(cacheTextureSize, cacheTextureSize, imageBuffer, 32);

                        this.engine.CreateFile(folder + cacheFolder + ToString() + "_" + (imageIndex + 1) + ".tga", tga, (uint)tga.Length);
                    }

                    rowStart     = 0;
                    colStart     = 0;
                    rowMaxHeight = 0;

                    Array.Clear(imageBuffer, 0, imageBuffer.Length);

                    imageIndex++;
                }

                for (int y = 0; y < letterInfo.height; y++)
                {
                    for (int x = 0; x < letterInfo.width; x++)
                    {
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 0] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 0];
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 1] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 1];
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 2] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 2];
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 3] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 3];
                    }
                }

                imageUvs[i]     = new int[4];
                imageUvs[i][0]  = colStart;
                imageUvs[i][1]  = rowStart;
                imageUvs[i][2]  = colStart + letterInfo.width + 1;
                imageUvs[i][3]  = rowStart + letterInfo.height + 1;
                imageIndexes[i] = imageIndex;

                colStart += letterInfo.width + 1;

                if (letterInfo.height > rowMaxHeight)
                {
                    rowMaxHeight = letterInfo.height;
                }
            }

            this.cachedImages.Add(this.engine.CreateImage(folder + cacheFolder + ToString() + "_" + (imageIndex + Int16.MaxValue), cacheTextureSize, cacheTextureSize, imageBuffer));

            for (int i = 0; i < cacheLetters; i++)
            {
                WinLetter letter = (WinLetter)this.letters[i];

                letter.SetCachedData(this.cachedImages[imageIndexes[i]], imageUvs[i][0], imageUvs[i][1], imageUvs[i][2], imageUvs[i][3]);
            }

            if (true == save)
            {
                byte[] tga = Image.GetTGA(cacheTextureSize, cacheTextureSize, imageBuffer, 32);

                this.engine.CreateFile(folder + cacheFolder + ToString() + "_" + (imageIndex++) + ".tga", tga, (uint)tga.Length);

                String xml = "<font>\n";

                for (int i = 0; i < cacheLetters; i++)
                {
                    xml += "\t" + ((WinLetter)this.letters[i]).ToXml(i, imageIndexes[i]) + "\n";
                }

                xml += "</font>";

                byte[] bytes = Encoding.UTF8.GetBytes(xml);

                String cacheFileName = folder + cacheFolder + ToString() + ".xml";

                this.engine.Logger.WriteLine(LogLevel.Info, "Caching font to: " + cacheFileName);

                this.engine.CreateFile(cacheFileName, bytes, (uint)bytes.Length);
            }
        }
Example #3
0
        /// <summary>
        /// Caches the first 256 letters.
        /// </summary>
        /// <param name="save">are the cached letters supposed to be saved to tga files.</param>
        private void CacheFirst256Letters(bool save, String folder)
        {
            int imageIndex = 0;
            byte[] imageBuffer = new byte[cacheTextureSize * cacheTextureSize * 4];
            int rowStart = 0;
            int colStart = 0;
            int rowMaxHeight = 0;

            int[] imageIndexes = new int[cacheLetters];
            int[][] imageUvs = new int[cacheLetters][];

            for (int i = 0; i < cacheLetters; i++)
            {
                WinLetter letter = (WinLetter)this.letters[i];

                LetterInfo letterInfo = letter.Load(true);

                if (null == letterInfo)
                {
                    letterInfo = new LetterInfo();
                    letterInfo.width = 2;
                    letterInfo.height = 2;
                    letterInfo.textureHeight = 2;
                    letterInfo.textureWidth = 2;
                    letterInfo.bytes = new byte[2*2*4];
                }

                if (colStart + letterInfo.width + 1 > cacheTextureSize)
                {
                    colStart = 0;
                    rowStart += rowMaxHeight + 1;
                }

                if (rowStart + 1 + letterInfo.height >= cacheTextureSize)
                {
                    this.cachedImages.Add(this.engine.CreateImage(cacheFolder + ToString() + "_" + (imageIndex+1), cacheTextureSize, cacheTextureSize, imageBuffer));

                    if (true == save)
                    {
                        byte[] tga = Image.GetTGA(cacheTextureSize, cacheTextureSize, imageBuffer, 32);

                        this.engine.CreateFile(folder + cacheFolder + ToString() + "_" + (imageIndex+1) + ".tga", tga, (uint)tga.Length);
                    }

                    rowStart = 0;
                    colStart = 0;
                    rowMaxHeight = 0;

                    Array.Clear(imageBuffer, 0, imageBuffer.Length);

                    imageIndex++;
                }

                for (int y = 0; y < letterInfo.height; y++)
                {
                    for (int x = 0; x < letterInfo.width; x++)
                    {
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 0] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 0];
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 1] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 1];
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 2] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 2];
                        imageBuffer[(rowStart + y) * 4 * cacheTextureSize + (colStart + x) * 4 + 3] = letterInfo.bytes[y * letterInfo.textureWidth * 4 + x * 4 + 3];
                    }
                }

                imageUvs[i] = new int[4];
                imageUvs[i][0] = colStart;
                imageUvs[i][1] = rowStart;
                imageUvs[i][2] = colStart + letterInfo.width + 1;
                imageUvs[i][3] = rowStart + letterInfo.height + 1;
                imageIndexes[i] = imageIndex;

                colStart += letterInfo.width + 1;

                if (letterInfo.height > rowMaxHeight)
                {
                    rowMaxHeight = letterInfo.height;
                }
            }

            this.cachedImages.Add(this.engine.CreateImage(folder + cacheFolder + ToString() + "_" + (imageIndex + Int16.MaxValue), cacheTextureSize, cacheTextureSize, imageBuffer));

            for (int i = 0; i < cacheLetters; i++)
            {
                WinLetter letter = (WinLetter)this.letters[i];

                letter.SetCachedData(this.cachedImages[imageIndexes[i]], imageUvs[i][0], imageUvs[i][1], imageUvs[i][2], imageUvs[i][3]);
            }

            if (true == save)
            {
                byte[] tga = Image.GetTGA(cacheTextureSize, cacheTextureSize, imageBuffer, 32);

                this.engine.CreateFile(folder + cacheFolder + ToString() + "_" + (imageIndex++) + ".tga", tga, (uint)tga.Length);

                String xml = "<font>\n";

                for (int i = 0; i < cacheLetters; i++)
                {
                    xml += "\t" + ((WinLetter)this.letters[i]).ToXml(i, imageIndexes[i]) + "\n";
                }

                xml += "</font>";

                byte[] bytes = Encoding.UTF8.GetBytes(xml);

                String cacheFileName = folder + cacheFolder + ToString() + ".xml";

                this.engine.Logger.WriteLine(LogLevel.Info, "Caching font to: " + cacheFileName);

                this.engine.CreateFile(cacheFileName, bytes, (uint)bytes.Length);
            }
        }
Example #4
0
        /// <summary>
        /// Loads letter iamge from win32 font.
        /// </summary>
        /// <param name="cache">should the iamge be cached in tga, xml files.</param>
        /// <returns>loader letter information.</returns>
        protected internal override LetterInfo Load(bool cache)
        {
            LetterInfo result = null;

            #if WINDOWS
            IntPtr bitmapHandle = IntPtr.Zero;
            byte[] textureData = null;

            try
            {
                if (null == PlatformWindows.SelectFont(this.font.fontRenderingDisplayContext, this.font.fontHandle))
                {
                    throw new Exception();
                }

                TextMetric tm = new TextMetric();

                if (false == PlatformWindows.GetTextMetrics(this.font.fontRenderingDisplayContext, out tm))
                {
                    throw new Exception();
                }

                if (PlatformWindows.GDI_ERROR == PlatformWindows.SetTextAlign(this.font.fontRenderingDisplayContext, PlatformWindows.TA_LEFT | PlatformWindows.TA_TOP | PlatformWindows.TA_UPDATECP))
                {
                    throw new Exception();
                }

                ABC[] abc = new ABC[1];

                if (false == PlatformWindows.GetCharABCWidths(this.font.fontRenderingDisplayContext, (uint)this.character, (uint)this.character, abc))
                {
                    throw new Exception();
                }

                this.offsetX = abc[0].abcA;
                this.width = (int)(abc[0].abcB + abc[0].abcC);

                BitmapInfo header = new BitmapInfo();
                header.bmiHeader.biSize = Marshal.SizeOf(header);

                GlyphMetrics metrics = new GlyphMetrics();
                MAT2 identity = new MAT2();
                identity.eM12.value = 0;
                identity.eM21.value = 0;
                identity.eM11.value = 1;
                identity.eM22.value = 1;

                if (PlatformWindows.GDI_ERROR == PlatformWindows.GetGlyphOutline(this.font.fontRenderingDisplayContext, this.character, PlatformWindows.GGO_METRICS, out metrics, 0, IntPtr.Zero, ref identity))
                {
                    throw new Exception();
                }

                header.bmiHeader.biWidth = metrics.gmBlackBoxX;
                header.bmiHeader.biHeight = -1 * metrics.gmBlackBoxY;

                header.bmiHeader.biPlanes = 1;
                header.bmiHeader.biBitCount = 32;
                header.bmiHeader.biCompression = 0;// BI_RGB;
                byte[] bitmapData = null;

                IntPtr bitmapDataPointer = IntPtr.Zero;

                bitmapHandle = PlatformWindows.CreateDIBSection(this.font.fontRenderingDisplayContext, ref header, /*DIB_RGB_COLORS*/0, out bitmapDataPointer, IntPtr.Zero, 0);

                if (IntPtr.Zero == bitmapHandle)
                {
                    int err = Marshal.GetLastWin32Error();

                    throw new Exception();
                }

                if (null == PlatformWindows.SelectObject(this.font.fontRenderingDisplayContext, bitmapHandle))
                {
                    throw new Exception();
                }

                if (PlatformWindows.CLR_INVALID == PlatformWindows.SetBkColor(this.font.fontRenderingDisplayContext, new RGB(new byte[] { 0, 0, 0 }).ToInt32()))
                {
                    throw new Exception();
                }

                if (PlatformWindows.CLR_INVALID == PlatformWindows.SetTextColor(this.font.fontRenderingDisplayContext, new RGB(new byte[] { 0xff, 0xff, 0xff }).ToInt32()))
                {
                    throw new Exception();
                }

                if (0 == PlatformWindows.SetBkMode(this.font.fontRenderingDisplayContext, PlatformWindows.OPAQUE))
                {
                    throw new Exception();
                }

                if (false == PlatformWindows.MoveToEx(this.font.fontRenderingDisplayContext, 0 - abc[0].abcA, -1 * (tm.tmAscent - metrics.gmptGlyphOrigin.y), IntPtr.Zero))
                {
                    throw new Exception();
                }

                this.offsetY = tm.tmAscent - metrics.gmptGlyphOrigin.y - tm.tmDescent - 1;

                String str = "" + this.character;
                RECT rect = new RECT();

                if (false == PlatformWindows.ExtTextOut(this.font.fontRenderingDisplayContext, 0, 0, (uint)0, ref rect, str, 1, null))
                {
                    throw new Exception();
                }

                if (0 == PlatformWindows.SetBkMode(this.font.fontRenderingDisplayContext, PlatformWindows.TRANSPARENT))
                {
                    throw new Exception();
                }

                int bitmapWidth = header.bmiHeader.biWidth;
                int bitmapHeight = -header.bmiHeader.biHeight;
                int textureWidth = RoundToPowerOf2(bitmapWidth);
                int textureHeight = RoundToPowerOf2(bitmapHeight);

                bitmapData = new byte[bitmapWidth * bitmapHeight * 4];

                Marshal.Copy(bitmapDataPointer, bitmapData, 0, bitmapWidth * bitmapHeight * 4);

                textureData = new byte[4 * textureWidth * textureHeight];

                for (int j = 0; j < textureHeight; j++)
                {
                    for (int i = 0; i < textureWidth; i++)
                    {
                        textureData[4 * (i + j * textureWidth) + 0] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 1] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 2] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 3] = (byte)((i >= bitmapWidth || j >= bitmapHeight) ? 0 : bitmapData[(i + bitmapWidth * j) * 4 + 2]);
                    }
                }

                if (true == cache)
                {
                    result = new LetterInfo();
                    result.width = bitmapWidth;
                    result.height = bitmapHeight;
                    result.bytes = textureData;
                    result.textureWidth = textureWidth;
                    result.textureHeight = textureHeight;
                }
                else
                {
                    this.image = this.engine.CreateImage("Letter [" + this.character + "]", textureWidth, textureHeight, textureData);
            //                    this.internalImage = true;
                }

                this.textureWidth = textureWidth;
                this.textureHeight = textureHeight;
            }
            catch (Exception)
            {
                this.engine.DeleteImage(ref this.image);
            }

            if (null != bitmapHandle)
            {
                PlatformWindows.DeleteObject(bitmapHandle);
            }

            this.loaded = true;
            #endif
            return result;
        }