コード例 #1
0
ファイル: GUIFont.cs プロジェクト: RasterCode/OtterUI
        /// <summary>
        /// Reloads the font
        /// </summary>
        public void ReloadFont()
        {
            if (mProject == null)
                return;

            int borderWidth = 2;

            string fullPath = mProject.ProjectDirectory + "/" + mFontFile;
            if (System.IO.File.Exists(fullPath))
            {
                // Ensure that the character list ALWAYS contains at least the ? character.
                if (!Characters.Contains('?'))
                    Characters.Add('?');

                // Load the image glyph textures
                foreach (FontBuilder.ImageGlyph imageGlyph in Images)
                    imageGlyph.Load(mProject.ProjectDirectory);

                if (mFontData != null)
                    mFontData.Dispose();

                mFontData = new FontBuilder.FontData(Characters, Images);
                FontBuilder.Glyph[] glyphs = mFontData.GetGlyphs(fullPath, mFontSize);

                // Clear out our existing textures and texture atlasses
                foreach (TextureAtlas atlas in mTextureAtlasses)
                {
                    DisposeAtlasNode(atlas.mRoot);
                }
                mTextureAtlasses.Clear();

                mTextures.Clear();
                mCharInfoList.Clear();
                mMaxTop = -99999;

                Image texture = null;
                Bitmap textureBitmap = null;
                if (File.Exists(mProject.ProjectDirectory + "/" + mTextureFile))
                {
                    texture = Image.FromFile(mProject.ProjectDirectory + "/" + mTextureFile);
                    textureBitmap = new Bitmap(texture);
                }

                TextureAtlas curAtlas = null;
                foreach (FontBuilder.Glyph glyph in glyphs)
                {
                    if (glyph == null)
                        continue;

                    if (mMaxTop < glyph.mTop)
                        mMaxTop = glyph.mTop;

                    Bitmap finalBitmap = null;
                    if (glyph.mBitmap != null)
                    {
                        finalBitmap = (borderWidth == 0) ? new Bitmap(glyph.mBitmap) : Utils.ExpandImageBorder(glyph.mBitmap, borderWidth, true);
                        if (finalBitmap == null)
                            continue;

                        Bitmap outlinedBitmap = null;
                        Bitmap texturedBitmap = null;

                        if (OutlineAmount > 0.0f && OutlineColor.A != 0)
                        {
                            float s = Math.Min(1.0f, Math.Max(OutlineSharpness, 0.0f));
                            outlinedBitmap = BlurBitmap(finalBitmap, OutlineAmount, OutlineSharpness, OutlineColor);
                            finalBitmap.Dispose();
                            finalBitmap = outlinedBitmap;
                        }

                        BitmapData texturedBitmapData = null;
                        if (textureBitmap != null && glyph.mImageGlyph == 0)
                        {
                            texturedBitmap = ApplyTexture(textureBitmap, glyph.mBitmap, mTextureBaseline, glyph.mTop);
                            texturedBitmapData = texturedBitmap.LockBits(new Rectangle(0, 0,
                                                                        texturedBitmap.Width,
                                                                        texturedBitmap.Height),
                                                                        ImageLockMode.ReadOnly,
                                                                        texturedBitmap.PixelFormat);
                        }

                        // Now we need to use the original bitmap (from the glyph) and reapply it to the new
                        // bitmap (that may or may not have been blurred) with the fill color
                        BitmapData sourceBitmapData = glyph.mBitmap.LockBits( new Rectangle(0, 0, glyph.mBitmap.Width, glyph.mBitmap.Height),
                                                                              ImageLockMode.ReadOnly,
                                                                              glyph.mBitmap.PixelFormat);

                        BitmapData targetBitmapData = finalBitmap.LockBits(new Rectangle((finalBitmap.Width - glyph.mBitmap.Width) / 2,
                                                                      (finalBitmap.Height - glyph.mBitmap.Height) / 2,
                                                                      glyph.mBitmap.Width,
                                                                      glyph.mBitmap.Height),
                                                                      ImageLockMode.WriteOnly,
                                                                      finalBitmap.PixelFormat);

                        try
                        {
                            for (int x = 0; x < sourceBitmapData.Width; x++)
                            {
                                for (int y = 0; y < sourceBitmapData.Height; y++)
                                {
                                    IntPtr sourcePixel = (IntPtr)((int)sourceBitmapData.Scan0 + sourceBitmapData.Stride * y + x * 4);
                                    IntPtr targetPixel = (IntPtr)((int)targetBitmapData.Scan0 + targetBitmapData.Stride * y + x * 4);
                                    IntPtr texturePixel = IntPtr.Zero;

                                    if(texturedBitmapData != null)
                                        texturePixel = (IntPtr)((int)texturedBitmapData.Scan0 + texturedBitmapData.Stride * y + x * 4);

                                    Color srcColor = Color.FromArgb(Marshal.ReadInt32(sourcePixel));
                                    Color tgtColor = Color.FromArgb(Marshal.ReadInt32(targetPixel));
                                    Color texColor = (texturePixel != IntPtr.Zero) ? Color.FromArgb(Marshal.ReadInt32(texturePixel)) : Color.White;

                                    float alpha = srcColor.A / 255.0f;
                                    if (alpha == 0.0f)
                                        continue;

                                    byte r = (byte)(tgtColor.R * (1.0f - alpha) + FillColor.R * (srcColor.R / 255.0f) * (texColor.R / 255.0f) * alpha);
                                    byte g = (byte)(tgtColor.G * (1.0f - alpha) + FillColor.G * (srcColor.G / 255.0f) * (texColor.G / 255.0f) * alpha);
                                    byte b = (byte)(tgtColor.B * (1.0f - alpha) + FillColor.B * (srcColor.B / 255.0f) * (texColor.B / 255.0f) * alpha);
                                    byte a = (byte)(tgtColor.A * (1.0f - alpha) + FillColor.A * (srcColor.A / 255.0f) * (texColor.A / 255.0f) * alpha);

                                    Color finalColor = Color.FromArgb(a, r, g, b);

                                    Marshal.WriteInt32(targetPixel, finalColor.ToArgb());
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            System.Console.WriteLine("Exception : " + ex);
                        }

                        glyph.mBitmap.UnlockBits(sourceBitmapData);
                        finalBitmap.UnlockBits(targetBitmapData);

                        if (texturedBitmapData != null)
                            texturedBitmap.UnlockBits(texturedBitmapData);
                    }
                    else
                    {
                        finalBitmap = new Bitmap(4, 4);
                    }

                    if (curAtlas == null || !curAtlas.AddTexture(finalBitmap, glyph))
                    {
                        curAtlas = new TextureAtlas(0, AtlasSize.Width, AtlasSize.Height, "tmp");
                        mTextureAtlasses.Add(curAtlas);

                        curAtlas.AddTexture(finalBitmap, glyph);
                    }
                }

                if (textureBitmap != null)
                    textureBitmap.Dispose();

                if (texture != null)
                    texture.Dispose();

                // Unload the image glyph textures
                foreach (FontBuilder.ImageGlyph imageGlyph in Images)
                    imageGlyph.Unload();

                // Then iterate and add to the texture atlas(ses).
                if (Otter.Interface.Graphics.Instance != null)
                {
                    foreach(int textureID in mTextures)
                        Otter.Interface.Graphics.Instance.UnloadTexture(textureID);

                    foreach (TextureAtlas atlas in mTextureAtlasses)
                    {
                        Bitmap bitmap = atlas.GetBitmap();

                        // BitmapData
                        BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);

                        // Get the address of the first line.
                        IntPtr ptr = bitmapData.Scan0;

                        // Declare an array to hold the bytes of the bitmap.
                        int size = Math.Abs(bitmapData.Stride) * bitmap.Height;
                        byte[] bytes = new byte[size];

                        System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, size);

                        int textureID = Otter.Interface.Graphics.Instance.LoadTexture(bytes, bitmap.Width, bitmap.Height, 32);

                        bitmap.UnlockBits(bitmapData);

                        mTextures.Add(textureID);

                        bitmap.Dispose();

                        // SLOW
                        foreach (FontBuilder.Glyph glyph in glyphs)
                        {
                            if (glyph == null)
                                continue;

                            AtlasNode node = atlas.FindNode(glyph);

                            if(node != null)
                            {
                                NewCharInfo info = new NewCharInfo();

                                int diffW = node.mRectangle.Width - borderWidth * 2 - glyph.mW;
                                int diffH = node.mRectangle.Height - borderWidth * 2 - glyph.mH;

                                info.mCharCode = glyph.mCharCode;
                                info.mImageGlyph = glyph.mImageGlyph;
                                info.mX = node.mRectangle.X + borderWidth;
                                info.mY = node.mRectangle.Y + borderWidth;
                                info.mW = glyph.mW + diffW;
                                info.mH = glyph.mH + diffH;

                                info.mTop = glyph.mTop + diffH / 2;
                                info.mAdvance = glyph.mAdvance;
                                info.mLeftBearing = glyph.mLeftBearing - diffW / 2;

                                info.mAtlasIndex = mTextureAtlasses.IndexOf(atlas);

                                mCharInfoList.Add(info);
                            }
                        }
                    }

                    MemoryStream stream = new MemoryStream();

                    Platform platform = new Platform();
                    platform.Endianness = Endian.Little;
                    platform.ColorFormat = ColorFormat.ARGB;

                    PlatformBinaryWriter bw = new PlatformBinaryWriter(stream, platform);
                    this.Export(bw);

                    mFontID = Otter.Interface.Graphics.Instance.LoadFont(this.Name, stream.GetBuffer(), mTextures);

                    bw.Close();
                    stream.Close();
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Reloads the font
        /// </summary>
        public void ReloadFont()
        {
            if (mProject == null)
            {
                return;
            }

            int borderWidth = 2;

            string fullPath = mProject.ProjectDirectory + "/" + mFontFile;

            if (System.IO.File.Exists(fullPath))
            {
                // Ensure that the character list ALWAYS contains at least the ? character.
                if (!Characters.Contains('?'))
                {
                    Characters.Add('?');
                }

                // Load the image glyph textures
                foreach (FontBuilder.ImageGlyph imageGlyph in Images)
                {
                    imageGlyph.Load(mProject.ProjectDirectory);
                }

                if (mFontData != null)
                {
                    mFontData.Dispose();
                }

                mFontData = new FontBuilder.FontData(Characters, Images);
                FontBuilder.Glyph[] glyphs = mFontData.GetGlyphs(fullPath, mFontSize);

                // Clear out our existing textures and texture atlasses
                foreach (TextureAtlas atlas in mTextureAtlasses)
                {
                    DisposeAtlasNode(atlas.mRoot);
                }
                mTextureAtlasses.Clear();

                mTextures.Clear();
                mCharInfoList.Clear();
                mMaxTop = -99999;

                Image  texture       = null;
                Bitmap textureBitmap = null;
                if (File.Exists(mProject.ProjectDirectory + "/" + mTextureFile))
                {
                    texture       = Image.FromFile(mProject.ProjectDirectory + "/" + mTextureFile);
                    textureBitmap = new Bitmap(texture);
                }

                TextureAtlas curAtlas = null;
                foreach (FontBuilder.Glyph glyph in glyphs)
                {
                    if (glyph == null)
                    {
                        continue;
                    }

                    if (mMaxTop < glyph.mTop)
                    {
                        mMaxTop = glyph.mTop;
                    }

                    Bitmap finalBitmap = null;
                    if (glyph.mBitmap != null)
                    {
                        finalBitmap = (borderWidth == 0) ? new Bitmap(glyph.mBitmap) : Utils.ExpandImageBorder(glyph.mBitmap, borderWidth, true);
                        if (finalBitmap == null)
                        {
                            continue;
                        }

                        Bitmap outlinedBitmap = null;
                        Bitmap texturedBitmap = null;

                        if (OutlineAmount > 0.0f && OutlineColor.A != 0)
                        {
                            float s = Math.Min(1.0f, Math.Max(OutlineSharpness, 0.0f));
                            outlinedBitmap = BlurBitmap(finalBitmap, OutlineAmount, OutlineSharpness, OutlineColor);
                            finalBitmap.Dispose();
                            finalBitmap = outlinedBitmap;
                        }

                        BitmapData texturedBitmapData = null;
                        if (textureBitmap != null && glyph.mImageGlyph == 0)
                        {
                            texturedBitmap     = ApplyTexture(textureBitmap, glyph.mBitmap, mTextureBaseline, glyph.mTop);
                            texturedBitmapData = texturedBitmap.LockBits(new Rectangle(0, 0,
                                                                                       texturedBitmap.Width,
                                                                                       texturedBitmap.Height),
                                                                         ImageLockMode.ReadOnly,
                                                                         texturedBitmap.PixelFormat);
                        }

                        // Now we need to use the original bitmap (from the glyph) and reapply it to the new
                        // bitmap (that may or may not have been blurred) with the fill color
                        BitmapData sourceBitmapData = glyph.mBitmap.LockBits(new Rectangle(0, 0, glyph.mBitmap.Width, glyph.mBitmap.Height),
                                                                             ImageLockMode.ReadOnly,
                                                                             glyph.mBitmap.PixelFormat);

                        BitmapData targetBitmapData = finalBitmap.LockBits(new Rectangle((finalBitmap.Width - glyph.mBitmap.Width) / 2,
                                                                                         (finalBitmap.Height - glyph.mBitmap.Height) / 2,
                                                                                         glyph.mBitmap.Width,
                                                                                         glyph.mBitmap.Height),
                                                                           ImageLockMode.WriteOnly,
                                                                           finalBitmap.PixelFormat);

                        try
                        {
                            for (int x = 0; x < sourceBitmapData.Width; x++)
                            {
                                for (int y = 0; y < sourceBitmapData.Height; y++)
                                {
                                    IntPtr sourcePixel  = (IntPtr)((int)sourceBitmapData.Scan0 + sourceBitmapData.Stride * y + x * 4);
                                    IntPtr targetPixel  = (IntPtr)((int)targetBitmapData.Scan0 + targetBitmapData.Stride * y + x * 4);
                                    IntPtr texturePixel = IntPtr.Zero;

                                    if (texturedBitmapData != null)
                                    {
                                        texturePixel = (IntPtr)((int)texturedBitmapData.Scan0 + texturedBitmapData.Stride * y + x * 4);
                                    }

                                    Color srcColor = Color.FromArgb(Marshal.ReadInt32(sourcePixel));
                                    Color tgtColor = Color.FromArgb(Marshal.ReadInt32(targetPixel));
                                    Color texColor = (texturePixel != IntPtr.Zero) ? Color.FromArgb(Marshal.ReadInt32(texturePixel)) : Color.White;

                                    float alpha = srcColor.A / 255.0f;
                                    if (alpha == 0.0f)
                                    {
                                        continue;
                                    }

                                    byte r = (byte)(tgtColor.R * (1.0f - alpha) + FillColor.R * (srcColor.R / 255.0f) * (texColor.R / 255.0f) * alpha);
                                    byte g = (byte)(tgtColor.G * (1.0f - alpha) + FillColor.G * (srcColor.G / 255.0f) * (texColor.G / 255.0f) * alpha);
                                    byte b = (byte)(tgtColor.B * (1.0f - alpha) + FillColor.B * (srcColor.B / 255.0f) * (texColor.B / 255.0f) * alpha);
                                    byte a = (byte)(tgtColor.A * (1.0f - alpha) + FillColor.A * (srcColor.A / 255.0f) * (texColor.A / 255.0f) * alpha);

                                    Color finalColor = Color.FromArgb(a, r, g, b);

                                    Marshal.WriteInt32(targetPixel, finalColor.ToArgb());
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            System.Console.WriteLine("Exception : " + ex);
                        }

                        glyph.mBitmap.UnlockBits(sourceBitmapData);
                        finalBitmap.UnlockBits(targetBitmapData);

                        if (texturedBitmapData != null)
                        {
                            texturedBitmap.UnlockBits(texturedBitmapData);
                        }
                    }
                    else
                    {
                        finalBitmap = new Bitmap(4, 4);
                    }

                    if (curAtlas == null || !curAtlas.AddTexture(finalBitmap, glyph))
                    {
                        curAtlas = new TextureAtlas(0, AtlasSize.Width, AtlasSize.Height, "tmp");
                        mTextureAtlasses.Add(curAtlas);

                        curAtlas.AddTexture(finalBitmap, glyph);
                    }
                }

                if (textureBitmap != null)
                {
                    textureBitmap.Dispose();
                }

                if (texture != null)
                {
                    texture.Dispose();
                }

                // Unload the image glyph textures
                foreach (FontBuilder.ImageGlyph imageGlyph in Images)
                {
                    imageGlyph.Unload();
                }

                // Then iterate and add to the texture atlas(ses).
                if (Otter.Interface.Graphics.Instance != null)
                {
                    foreach (int textureID in mTextures)
                    {
                        Otter.Interface.Graphics.Instance.UnloadTexture(textureID);
                    }

                    foreach (TextureAtlas atlas in mTextureAtlasses)
                    {
                        Bitmap bitmap = atlas.GetBitmap();

                        // BitmapData
                        BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);

                        // Get the address of the first line.
                        IntPtr ptr = bitmapData.Scan0;

                        // Declare an array to hold the bytes of the bitmap.
                        int    size  = Math.Abs(bitmapData.Stride) * bitmap.Height;
                        byte[] bytes = new byte[size];

                        System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, size);

                        int textureID = Otter.Interface.Graphics.Instance.LoadTexture(bytes, bitmap.Width, bitmap.Height, 32);

                        bitmap.UnlockBits(bitmapData);

                        mTextures.Add(textureID);

                        bitmap.Dispose();

                        // SLOW
                        foreach (FontBuilder.Glyph glyph in glyphs)
                        {
                            if (glyph == null)
                            {
                                continue;
                            }

                            AtlasNode node = atlas.FindNode(glyph);

                            if (node != null)
                            {
                                NewCharInfo info = new NewCharInfo();

                                int diffW = node.mRectangle.Width - borderWidth * 2 - glyph.mW;
                                int diffH = node.mRectangle.Height - borderWidth * 2 - glyph.mH;

                                info.mCharCode   = glyph.mCharCode;
                                info.mImageGlyph = glyph.mImageGlyph;
                                info.mX          = node.mRectangle.X + borderWidth;
                                info.mY          = node.mRectangle.Y + borderWidth;
                                info.mW          = glyph.mW + diffW;
                                info.mH          = glyph.mH + diffH;

                                info.mTop         = glyph.mTop + diffH / 2;
                                info.mAdvance     = glyph.mAdvance;
                                info.mLeftBearing = glyph.mLeftBearing - diffW / 2;

                                info.mAtlasIndex = mTextureAtlasses.IndexOf(atlas);

                                mCharInfoList.Add(info);
                            }
                        }
                    }

                    MemoryStream stream = new MemoryStream();

                    Platform platform = new Platform();
                    platform.Endianness  = Endian.Little;
                    platform.ColorFormat = ColorFormat.ARGB;

                    PlatformBinaryWriter bw = new PlatformBinaryWriter(stream, platform);
                    this.Export(bw);

                    mFontID = Otter.Interface.Graphics.Instance.LoadFont(this.Name, stream.GetBuffer(), mTextures);

                    bw.Close();
                    stream.Close();
                }
            }
        }