예제 #1
0
		// Rasterizes a single character glyph.
		private Glyph ImportGlyph(char character, Face face)
		{
			uint glyphIndex = face.GetCharIndex(character);
			face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
			face.Glyph.RenderGlyph(RenderMode.Normal);

			// Render the character.
            BitmapContent glyphBitmap = null;
			if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = new PixelBitmapContent<byte>(face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows);
				byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                //if the character bitmap has 1bpp we have to expand the buffer data to get the 8bpp pixel data
                //each byte in bitmap.bufferdata contains the value of to 8 pixels in the row
                //if bitmap is of width 10, each row has 2 bytes with 10 valid bits, and the last 6 bits of 2nd byte must be discarded
                if(face.Glyph.Bitmap.PixelMode == PixelMode.Mono)
                {
                    //variables needed for the expansion, amount of written data, length of the data to write
                    int written = 0, length = face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows;
                    for(int i = 0; written < length; i++)
                    {
                        //width in pixels of each row
                        int width = face.Glyph.Bitmap.Width;
                        while(width > 0)
                        {
                            //valid data in the current byte
                            int stride = MathHelper.Min(8, width);
                            //copy the valid bytes to pixeldata
                            //System.Array.Copy(ExpandByte(face.Glyph.Bitmap.BufferData[i]), 0, gpixelAlphas, written, stride);
                            ExpandByteAndCopy(face.Glyph.Bitmap.BufferData[i], stride, gpixelAlphas, written);
                            written += stride;
                            width -= stride;
                            if(width > 0)
                                i++;
                        }
                    }
                }
                else
                    Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);
                glyphBitmap.SetPixelData(gpixelAlphas);
			}

            if (glyphBitmap == null) 
			{
				var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
				var gVA = face.Size.Metrics.Height >> 6;

				gHA = gHA > 0 ? gHA : gVA;
				gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new PixelBitmapContent<byte>(gHA, gVA);
			}

			// not sure about this at all
			var abc = new ABCFloat ();
			abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
			abc.B = face.Glyph.Metrics.Width >> 6;
			abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

			// Construct the output Glyph object.
			return new Glyph(character, glyphBitmap)
			{
				XOffset = -(face.Glyph.Advance.X >> 6),
				XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
				CharacterWidths = abc
			};
		}
예제 #2
0
        // Rasterizes a single character glyph.
        static Glyph ImportGlyph(char character, Face face, Brush brush, StringFormat stringFormat, Bitmap bitmap, System.Drawing.Graphics graphics)
        {
            string characterString = character.ToString();

            uint glyphIndex = face.GetCharIndex(character);

            face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
            face.Glyph.RenderGlyph(RenderMode.Normal);

            // Measure the size of this character.
            var width  = (int)face.Glyph.Advance.X >> 6;
            var height = (int)face.Glyph.Metrics.Height >> 6;

            SizeF size = new SizeF(width, height);

            int characterWidth  = (int)Math.Ceiling(size.Width);
            int characterHeight = (int)Math.Ceiling(size.Height);

            // Pad to make sure we capture any overhangs (negative ABC spacing, etc.)
            int padWidth  = characterWidth;
            int padHeight = characterHeight / 2;

            int bitmapWidth  = characterWidth + padWidth * 2;
            int bitmapHeight = characterHeight + padHeight * 2;

            if (bitmapWidth > MaxGlyphSize || bitmapHeight > MaxGlyphSize)
            {
                throw new Exception("Excessively large glyph won't fit in my lazily implemented fixed size temp surface.");
            }

            // Render the character.
            graphics.Clear(System.Drawing.Color.Black);

            if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows),
                                                  ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);

                for (int j = 0; j < gpixelAlphas.Length; j++)
                {
                    int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
                    Marshal.WriteByte(data.Scan0, pixelOffset + 3, gpixelAlphas [j]);
                }

                bitmap.UnlockBits(data);
            }

            // Clone the newly rendered image.
            Bitmap glyphBitmap = null;

            if (face.Glyph.Bitmap.Width > 0 || face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = bitmap.Clone(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), PixelFormat.Format32bppArgb);
            }
            else
            {
                var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
                var gVA = face.Glyph.Metrics.VerticalAdvance >> 6;

                gHA = gHA > 0 ? gHA : gVA;
                gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new Bitmap(gHA, gVA);
            }

            BitmapUtils.ConvertToGrey(glyphBitmap);

            // not sure about this at all
            var abc = new ABCFloat();

            abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
            abc.B = face.Glyph.Metrics.Width >> 6;
            abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

            // Query its ABC spacing.
            //float? abc = GetCharacterWidth(character, font, graphics);
//			if (glyphBitmap == null)
//				Console.WriteLine("null");


            // Construct the output Glyph object.
            return(new Glyph(character, glyphBitmap)
            {
                XOffset = -padWidth,
                XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
                CharacterWidths = abc
            });
        }
예제 #3
0
        // Rasterizes a single character glyph.
        private Glyph ImportGlyph(char character, Face face)
        {
            uint glyphIndex = face.GetCharIndex(character);

            face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
            face.Glyph.RenderGlyph(RenderMode.Normal);

            // Render the character.
            BitmapContent glyphBitmap = null;

            if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = new PixelBitmapContent <byte>(face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows);
                byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                //if the character bitmap has 1bpp we have to expand the buffer data to get the 8bpp pixel data
                //each byte in bitmap.bufferdata contains the value of to 8 pixels in the row
                //if bitmap is of width 10, each row has 2 bytes with 10 valid bits, and the last 6 bits of 2nd byte must be discarded
                if (face.Glyph.Bitmap.PixelMode == PixelMode.Mono)
                {
                    //variables needed for the expansion, amount of written data, length of the data to write
                    int written = 0, length = face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows;
                    for (int i = 0; written < length; i++)
                    {
                        //width in pixels of each row
                        int width = face.Glyph.Bitmap.Width;
                        while (width > 0)
                        {
                            //valid data in the current byte
                            int stride = MathHelper.Min(8, width);
                            //copy the valid bytes to pixeldata
                            //System.Array.Copy(ExpandByte(face.Glyph.Bitmap.BufferData[i]), 0, gpixelAlphas, written, stride);
                            ExpandByteAndCopy(face.Glyph.Bitmap.BufferData[i], stride, gpixelAlphas, written);
                            written += stride;
                            width   -= stride;
                            if (width > 0)
                            {
                                i++;
                            }
                        }
                    }
                }
                else
                {
                    Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);
                }
                glyphBitmap.SetPixelData(gpixelAlphas);
            }

            if (glyphBitmap == null)
            {
                var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
                var gVA = face.Size.Metrics.Height >> 6;

                gHA = gHA > 0 ? gHA : gVA;
                gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new PixelBitmapContent <byte>(gHA, gVA);
            }

            // not sure about this at all
            var abc = new ABCFloat();

            abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
            abc.B = face.Glyph.Metrics.Width >> 6;
            abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

            // Construct the output Glyph object.
            return(new Glyph(character, glyphBitmap)
            {
                XOffset = -(face.Glyph.Advance.X >> 6),
                XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
                CharacterWidths = abc
            });
        }
예제 #4
0
        // Rasterizes a single character glyph.
        static Glyph ImportGlyph(char character, Face face, Brush brush, StringFormat stringFormat, Bitmap bitmap, System.Drawing.Graphics graphics)
        {
            uint glyphIndex = face.GetCharIndex(character);

            face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
            face.Glyph.RenderGlyph(RenderMode.Normal);

            // Render the character.
            graphics.Clear(System.Drawing.Color.Black);

            if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows),
                                                  ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);

                for (int j = 0; j < gpixelAlphas.Length; j++)
                {
                    int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
                    Marshal.WriteByte(data.Scan0, pixelOffset + 3, gpixelAlphas [j]);
                }

                bitmap.UnlockBits(data);
            }

            // Clone the newly rendered image.
            Bitmap glyphBitmap = null;

            if (face.Glyph.Bitmap.Width > 0 || face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = bitmap.Clone(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), PixelFormat.Format32bppArgb);
            }
            else
            {
                var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
                var gVA = face.Size.Metrics.Height >> 6;

                gHA = gHA > 0 ? gHA : gVA;
                gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new Bitmap(gHA, gVA);
            }

            BitmapUtils.ConvertAlphaToGrey(glyphBitmap);

            // not sure about this at all
            var abc = new ABCFloat();

            abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
            abc.B = face.Glyph.Metrics.Width >> 6;
            abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

            // Construct the output Glyph object.
            return(new Glyph(character, glyphBitmap)
            {
                XOffset = -(face.Glyph.Advance.X >> 6),
                XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
                CharacterWidths = abc
            });
        }
예제 #5
0
		// Rasterizes a single character glyph.
		static Glyph ImportGlyph(char character, Face face, Brush brush, StringFormat stringFormat, Bitmap bitmap, System.Drawing.Graphics graphics)
		{
			string characterString = character.ToString();

			uint glyphIndex = face.GetCharIndex(character);
			face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
			face.Glyph.RenderGlyph(RenderMode.Normal);

			// Measure the size of this character.
			var width = (int)face.Glyph.Advance.X >> 6;
			var height = (int)face.Glyph.Metrics.Height >> 6;

			SizeF size = new SizeF(width, height);

			int characterWidth = (int)Math.Ceiling(size.Width);
			int characterHeight = (int)Math.Ceiling(size.Height);

			// Pad to make sure we capture any overhangs (negative ABC spacing, etc.)
			int padWidth = characterWidth;
			int padHeight = characterHeight / 2;

			int bitmapWidth = characterWidth + padWidth * 2;
			int bitmapHeight = characterHeight + padHeight * 2;

			if (bitmapWidth > MaxGlyphSize || bitmapHeight > MaxGlyphSize)
				throw new Exception("Excessively large glyph won't fit in my lazily implemented fixed size temp surface.");

			// Render the character.
			graphics.Clear(System.Drawing.Color.Black);

			if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0) {
				BitmapData data = bitmap.LockBits (new System.Drawing.Rectangle (0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), 
				                                 ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
				byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
				Marshal.Copy (face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);

				for (int j = 0; j < gpixelAlphas.Length; j++) {
					int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
					Marshal.WriteByte (data.Scan0, pixelOffset + 3, gpixelAlphas [j]);
				}

				bitmap.UnlockBits (data);

			}

			// Clone the newly rendered image.
			Bitmap glyphBitmap = null;
			if (face.Glyph.Bitmap.Width > 0 || face.Glyph.Bitmap.Rows > 0)
				glyphBitmap = bitmap.Clone(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), PixelFormat.Format32bppArgb);
			else 
			{
				var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
				var gVA = face.Glyph.Metrics.VerticalAdvance >> 6;

				gHA = gHA > 0 ? gHA : gVA;
				gVA = gVA > 0 ? gVA : gHA;

				glyphBitmap = new Bitmap (gHA, gVA);
			}

			BitmapUtils.ConvertToGrey(glyphBitmap);

			// not sure about this at all
			var abc = new ABCFloat ();
			abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
			abc.B = face.Glyph.Metrics.Width >> 6;
			abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

			// Query its ABC spacing.
			//float? abc = GetCharacterWidth(character, font, graphics);
//			if (glyphBitmap == null)
//				Console.WriteLine("null");


			// Construct the output Glyph object.
			return new Glyph(character, glyphBitmap)
			{
				XOffset = -padWidth,
				XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
				CharacterWidths = abc
			};
		}
예제 #6
0
		// Rasterizes a single character glyph.
		static Glyph ImportGlyph(char character, Face face, Brush brush, StringFormat stringFormat, Bitmap bitmap, System.Drawing.Graphics graphics)
		{
			uint glyphIndex = face.GetCharIndex(character);
			face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
			face.Glyph.RenderGlyph(RenderMode.Normal);

			// Render the character.
			graphics.Clear(System.Drawing.Color.Black);

			if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0) {
				BitmapData data = bitmap.LockBits (new System.Drawing.Rectangle (0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), 
				                                 ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
				byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
				Marshal.Copy (face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);

				for (int j = 0; j < gpixelAlphas.Length; j++) {
					int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
					Marshal.WriteByte (data.Scan0, pixelOffset + 3, gpixelAlphas [j]);
				}

				bitmap.UnlockBits (data);

			}

			// Clone the newly rendered image.
			Bitmap glyphBitmap = null;
			if (face.Glyph.Bitmap.Width > 0 || face.Glyph.Bitmap.Rows > 0)
				glyphBitmap = bitmap.Clone(new System.Drawing.Rectangle(0, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), PixelFormat.Format32bppArgb);
			else 
			{
				var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
				var gVA = face.Size.Metrics.Height >> 6;

				gHA = gHA > 0 ? gHA : gVA;
				gVA = gVA > 0 ? gVA : gHA;

				glyphBitmap = new Bitmap (gHA, gVA);
			}

			BitmapUtils.ConvertAlphaToGrey(glyphBitmap);

			// not sure about this at all
			var abc = new ABCFloat ();
			abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
			abc.B = face.Glyph.Metrics.Width >> 6;
			abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

			// Construct the output Glyph object.
			return new Glyph(character, glyphBitmap)
			{
				XOffset = -(face.Glyph.Advance.X >> 6),
				XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
				CharacterWidths = abc
			};
		}