EmptyAlphaPixel() public static method

Returns try if the given pixel is empty (i.e. alpha is zero)
public static EmptyAlphaPixel ( BitmapData bitmapData, int px, int py, byte alphaEmptyPixelTolerance ) : bool
bitmapData System.Drawing.Imaging.BitmapData
px int
py int
alphaEmptyPixelTolerance byte
return bool
Beispiel #1
0
        private static void RetargetGlyphRectangleInwards(BitmapData bitmapData, QFontGlyph glyph, bool setYOffset, byte alphaTolerance)
        {
            int startX, endX;
            int startY, endY;

            var rect = glyph.rect;

            EmptyDel emptyPix;

            if (bitmapData.PixelFormat == PixelFormat.Format32bppArgb)
                emptyPix = delegate(BitmapData data, int x, int y) { return QBitmap.EmptyAlphaPixel(data, x, y, alphaTolerance); };
            else
                emptyPix = delegate(BitmapData data, int x, int y) { return QBitmap.EmptyPixel(data, x, y); };


            unsafe
            {

                for (startX = rect.X; startX < bitmapData.Width; startX++)
                    for (int j = rect.Y; j < rect.Y + rect.Height; j++)
                        if (!emptyPix(bitmapData, startX, j))
                            goto Done1;
                Done1:

                for (endX = rect.X + rect.Width; endX >= 0; endX--)
                    for (int j = rect.Y; j < rect.Y + rect.Height; j++)
                        if (!emptyPix(bitmapData, endX, j))
                            goto Done2;
                Done2:

                for (startY = rect.Y; startY < bitmapData.Height; startY++)
                    for (int i = startX; i < endX; i++)
                        if (!emptyPix(bitmapData, i, startY))
                            goto Done3;
                            
                Done3:

                for (endY = rect.Y + rect.Height; endY >= 0; endY--)
                    for (int i = startX; i < endX; i++)
                        if (!emptyPix(bitmapData, i, endY))
                            goto Done4;
                Done4:;


            }

            if (endY < startY)
                startY = endY = rect.Y;

            if (endX < startX)
                startX = endX = rect.X;

            glyph.rect = new Rectangle(startX, startY, endX - startX + 1, endY - startY + 1);

            if (setYOffset)
                glyph.yOffset = glyph.rect.Y;

        }
Beispiel #2
0
        /// <summary>
        /// Calculates the kerning values for the given character set
        /// </summary>
        /// <param name="charSet">The character set to calculate kerning values for</param>
        /// <param name="glyphs">The glyphs used for kerning</param>
        /// <param name="bitmapPages">The bitmap pages of the glyphs</param>
        /// <param name="config">The kerning configuration</param>
        /// <param name="font">The <see cref="IFont"/> used to create the glyphs and bitmaps</param>
        /// <returns>A <see cref="Dictionary{TKey,TValue}"/> mapping of every glyph pair to a kerning amount</returns>
        public static Dictionary <string, int> CalculateKerning(char[] charSet, QFontGlyph[] glyphs, List <QBitmap> bitmapPages, QFontKerningConfiguration config, IFont font = null)
        {
            var kerningPairs = new Dictionary <string, int>();

            //we start by computing the index of the first and last non-empty pixel in each row of each glyph
            XLimits[][] limits    = new XLimits[charSet.Length][];
            int         maxHeight = 0;

            for (int n = 0; n < charSet.Length; n++)
            {
                var rect = glyphs[n].Rect;
                var page = bitmapPages[glyphs[n].Page];

                limits[n] = new XLimits[rect.Height + 1];

                maxHeight = Math.Max(rect.Height, maxHeight);

                int yStart = rect.Y;
                int yEnd   = rect.Y + rect.Height;
                int xStart = rect.X;
                int xEnd   = rect.X + rect.Width;

                for (int j = yStart; j <= yEnd; j++)
                {
                    int last = xStart;

                    bool yetToFindFirst = true;
                    for (int i = xStart; i <= xEnd; i++)
                    {
                        if (!QBitmap.EmptyAlphaPixel(page.BitmapData, i, j, config.AlphaEmptyPixelTolerance))
                        {
                            if (yetToFindFirst)
                            {
                                limits[n][j - yStart].Min = i - xStart;
                                yetToFindFirst            = false;
                            }
                            last = i;
                        }
                    }

                    limits[n][j - yStart].Max = last - xStart;

                    if (yetToFindFirst)
                    {
                        limits[n][j - yStart].Min = xEnd - 1;
                    }
                }
            }

            //we now bring up each row to the max (or min) of it's two adjacent rows, this is to stop glyphs sliding together too closely
            var tmp = new XLimits[maxHeight + 1];

            for (int n = 0; n < charSet.Length; n++)
            {
                //clear tmp
                for (int j = 0; j < limits[n].Length; j++)
                {
                    tmp[j] = limits[n][j];
                }

                for (int j = 0; j < limits[n].Length; j++)
                {
                    if (j != 0)
                    {
                        tmp[j].Min = Math.Min(limits[n][j - 1].Min, tmp[j].Min);
                        tmp[j].Max = Math.Max(limits[n][j - 1].Max, tmp[j].Max);
                    }

                    if (j != limits[n].Length - 1)
                    {
                        tmp[j].Min = Math.Min(limits[n][j + 1].Min, tmp[j].Min);
                        tmp[j].Max = Math.Max(limits[n][j + 1].Max, tmp[j].Max);
                    }
                }

                for (int j = 0; j < limits[n].Length; j++)
                {
                    limits[n][j] = tmp[j];
                }
            }

            // For each character in the character set,
            // combine it with every other character and add it to the kerning pair dictionary
            for (int i = 0; i < charSet.Length; i++)
            {
                for (int j = 0; j < charSet.Length; j++)
                {
                    kerningPairs.Add("" + charSet[i] + charSet[j], Kerning(glyphs[i], glyphs[j], limits[i], limits[j], config, font));
                }
            }

            return(kerningPairs);
        }
        public static Dictionary <String, int> CalculateKerning(char[] charSet, QFontGlyph[] glyphs, List <QBitmap> bitmapPages, QFontKerningConfiguration config)
        {
            var kerningPairs = new Dictionary <String, int>();



            //we start by computing the index of the first and last non-empty pixel in each row of each glyph
            XLimits[][] limits    = new XLimits[charSet.Length][];
            int         maxHeight = 0;

            for (int n = 0; n < charSet.Length; n++)
            {
                var rect = glyphs[n].rect;
                var page = bitmapPages[glyphs[n].page];

                limits[n] = new XLimits[rect.Height];

                maxHeight = Math.Max(rect.Height, maxHeight);

                int yStart = rect.Y;
                int yEnd   = rect.Y + rect.Height;
                int xStart = rect.X;
                int xEnd   = rect.X + rect.Width;

                for (int j = yStart; j < yEnd; j++)
                {
                    int last = xStart;

                    bool yetToFindFirst = true;
                    for (int i = xStart; i < xEnd; i++)
                    {
                        if (!QBitmap.EmptyAlphaPixel(page.bitmapData, i, j, config.alphaEmptyPixelTolerance))
                        {
                            if (yetToFindFirst)
                            {
                                limits[n][j - yStart].Min = i - xStart;
                                yetToFindFirst            = false;
                            }
                            last = i;
                        }
                    }

                    limits[n][j - yStart].Max = last - xStart;

                    if (yetToFindFirst)
                    {
                        limits[n][j - yStart].Min = xEnd - 1;
                    }
                }
            }


            //we now bring up each row to the max (or min) of it's two adjacent rows, this is to stop glyphs sliding together too closely
            var tmp = new XLimits[maxHeight];

            for (int n = 0; n < charSet.Length; n++)
            {
                //clear tmp
                for (int j = 0; j < limits[n].Length; j++)
                {
                    tmp[j] = limits[n][j];
                }

                for (int j = 0; j < limits[n].Length; j++)
                {
                    if (j != 0)
                    {
                        tmp[j].Min = Math.Min(limits[n][j - 1].Min, tmp[j].Min);
                        tmp[j].Max = Math.Max(limits[n][j - 1].Max, tmp[j].Max);
                    }

                    if (j != limits[n].Length - 1)
                    {
                        tmp[j].Min = Math.Min(limits[n][j + 1].Min, tmp[j].Min);
                        tmp[j].Max = Math.Max(limits[n][j + 1].Max, tmp[j].Max);
                    }
                }

                for (int j = 0; j < limits[n].Length; j++)
                {
                    limits[n][j] = tmp[j];
                }
            }

            //поправил сам
            if (config.KerningPairs == null)
            {
                for (int i = 0; i < charSet.Length; i++)
                {
                    for (int j = 0; j < charSet.Length; j++)
                    {
                        kerningPairs.Add("" + charSet[i] + charSet[j], 1 - Kerning(glyphs[i], glyphs[j], limits[i], limits[j], config));
                    }
                }
            }
            else
            {
                var chatSetList = charSet.ToList();
                var indices     = config.KerningPairs.Select(x => Tuple.Create(chatSetList.IndexOf(x[0]), chatSetList.IndexOf(x[1]))).ToList();
                foreach (var pair in indices)
                {
                    int i = pair.Item1;
                    int j = pair.Item2;
                    kerningPairs.Add("" + charSet[i] + charSet[j], 1 - Kerning(glyphs[i], glyphs[j], limits[i], limits[j], config));
                }
            }
            return(kerningPairs);
        }
Beispiel #4
0
        private static void RetargetGlyphRectangleOutwards(BitmapData bitmapData, QFontGlyph glyph, bool setYOffset, byte alphaTolerance)
        {
            int startX, endX;
            int startY, endY;

            var rect = glyph.rect;

            EmptyDel emptyPix;

            if (bitmapData.PixelFormat == PixelFormat.Format32bppArgb)
            {
                emptyPix = delegate(BitmapData data, int x, int y) { return(QBitmap.EmptyAlphaPixel(data, x, y, alphaTolerance)); }
            }
            ;
            else
            {
                emptyPix = delegate(BitmapData data, int x, int y) { return(QBitmap.EmptyPixel(data, x, y)); }
            };

            unsafe
            {
                for (startX = rect.X; startX >= 0; startX--)
                {
                    bool foundPix = false;
                    for (int j = rect.Y; j <= rect.Y + rect.Height; j++)
                    {
                        if (!emptyPix(bitmapData, startX, j))
                        {
                            foundPix = true;
                            break;
                        }
                    }

                    if (!foundPix)
                    {
                        startX++;
                        break;
                    }
                }

                for (endX = rect.X + rect.Width; endX < bitmapData.Width; endX++)
                {
                    bool foundPix = false;
                    for (int j = rect.Y; j <= rect.Y + rect.Height; j++)
                    {
                        if (!emptyPix(bitmapData, endX, j))
                        {
                            foundPix = true;
                            break;
                        }
                    }

                    if (!foundPix)
                    {
                        endX--;
                        break;
                    }
                }

                for (startY = rect.Y; startY >= 0; startY--)
                {
                    bool foundPix = false;
                    for (int i = startX; i <= endX; i++)
                    {
                        if (!emptyPix(bitmapData, i, startY))
                        {
                            foundPix = true;
                            break;
                        }
                    }

                    if (!foundPix)
                    {
                        startY++;
                        break;
                    }
                }

                for (endY = rect.Y + rect.Height; endY < bitmapData.Height; endY++)
                {
                    bool foundPix = false;
                    for (int i = startX; i <= endX; i++)
                    {
                        if (!emptyPix(bitmapData, i, endY))
                        {
                            foundPix = true;
                            break;
                        }
                    }

                    if (!foundPix)
                    {
                        endY--;
                        break;
                    }
                }
            }

            glyph.rect = new Rectangle(startX, startY, endX - startX + 1, endY - startY + 1);

            if (setYOffset)
            {
                glyph.yOffset = glyph.rect.Y;
            }
        }
Beispiel #5
0
        private static void RetargetGlyphRectangleInwards(BitmapData bitmapData, QFontGlyph glyph, bool setYOffset)
        {
            int startX, endX;
            int startY, endY;

            var rect = glyph.rect;

            EmptyDel emptyPix;

            if (bitmapData.PixelFormat == PixelFormat.Format32bppArgb)
            {
                emptyPix = delegate(BitmapData data, int x, int y) { return(QBitmap.EmptyAlphaPixel(data, x, y)); }
            }
            ;
            else
            {
                emptyPix = delegate(BitmapData data, int x, int y) { return(QBitmap.EmptyPixel(data, x, y)); }
            };


            unsafe
            {
                for (startX = rect.X; startX < bitmapData.Width; startX++)
                {
                    for (int j = rect.Y; j <= rect.Y + rect.Height; j++)
                    {
                        if (!emptyPix(bitmapData, startX, j))
                        {
                            goto Done1;
                        }
                    }
                }
Done1:

                for (endX = rect.X + rect.Width; endX >= 0; endX--)
                {
                    for (int j = rect.Y; j <= rect.Y + rect.Height; j++)
                    {
                        if (!emptyPix(bitmapData, endX, j))
                        {
                            goto Done2;
                        }
                    }
                }
Done2:

                for (startY = rect.Y; startY < bitmapData.Height; startY++)
                {
                    for (int i = startX; i <= endX; i++)
                    {
                        if (!emptyPix(bitmapData, i, startY))
                        {
                            goto Done3;
                        }
                    }
                }

Done3:

                for (endY = rect.Y + rect.Height; endY >= 0; endY--)
                {
                    for (int i = startX; i <= endX; i++)
                    {
                        if (!emptyPix(bitmapData, i, endY))
                        {
                            goto Done4;
                        }
                    }
                }
                Done4 :;
            }



            glyph.rect = new Rectangle(startX, startY, endX - startX + 1, endY - startY + 1);

            if (setYOffset)
            {
                glyph.yOffset = glyph.rect.Y;
            }
        }