Exemple #1
0
 protected GlyphDescriptor Localized(GlyphDescriptor gd, double x, double y)
 {
     // value type, just mutate the parameter
     gd.Size     *= Size;
     gd.Offset.X += Offset.X + x;
     gd.Offset.Y += Offset.Y + y;
     return(gd);
 }
        public GlyphDescriptorCollection CollectGlyphs(IAtlasDescriptor descriptor, Action<float> progress, CancellationTokenSource cts)
        {
            ValidateSettings(descriptor);
            GlyphDescriptorCollection glyphs = new GlyphDescriptorCollection();

            HashSet<char> chars = null;

            if (descriptor.UseFonts)
            {
                chars = new HashSet<char>();

                // build set of characters
                foreach (ICharSet charSet in descriptor.CharSets)
                {
                    foreach (char ch in charSet.Characters)
                    {
                        chars.Add(ch);
                    }
                }
            }

            int count = 0;
            count += (descriptor.UseImages) ? descriptor.Images.Count : 0;
            count += (chars != null) ? chars.Count : 0;
            int current = 0;

            if (descriptor.UseImages)
            {
                int ch = descriptor.StartCode;

                foreach (ImageInfo ii in descriptor.Images)
                {
                    int width = ii.Image.Width;
                    int height = ii.Image.Height;

                    Vec2i offset;
                    Image image = CropImage(ii.Image, out offset);

                    ABC abc = new ABC();
                    abc.abcA = -(int)ii.Offset.X;
                    abc.abcB = (uint)(width + ii.Offset.X);
                    abc.abcC = 0;

                    ii.SortCode = ii.HasCustomCode ? ii.Code : UniqueCode(ref ch, descriptor.Images);
                    var gi = new GlyphDescriptor((char)ii.SortCode, abc, image, descriptor.Spacing * 2);
                    gi.Offset = offset - (Vec2i)ii.Offset;
                    gi.ImageInfo = ii;
                    glyphs.Add(gi);

                    if (progress != null)
                    {
                        progress((float)(++current) / count);
                    }

                    if (cts != null)
                    {
                        cts.Token.ThrowIfCancellationRequested();
                    }
                }
            }

            if (descriptor.UseFonts)
            {
                // build image for each glyph
                var gm = new GLYPHMETRICS();
                foreach (char ch in chars)
                {
                    Image image = null;

                    try
                    {
                        if (ch == 159)
                        {
                        }

                        image = TextHelper.GetGlyphOutlineImage(descriptor.Font, ch, out gm);
                        if (image == null)
                        {
                            continue;
                        }
                    }
                    catch
                    {
                        if (image != null)
                        {
                            image.Dispose();
                        }

                        // skip glyph
                        continue;
                    }

                    // flip Y offset
                    ABC abc = new ABC();
                    TextHelper.GetCharABCWidths(descriptor.Font, ch, out abc);

                    GlyphDescriptor glyph = new GlyphDescriptor(ch, abc, image, descriptor.Spacing * 2);
                    glyph.Offset = new Vec2i(gm.gmptGlyphOrigin.X, -gm.gmptGlyphOrigin.Y);
                    glyphs.Add(glyph);

                    if (progress != null)
                    {
                        progress((float)(++current) / count);
                    }

                    if (cts != null)
                    {
                        cts.Token.ThrowIfCancellationRequested();
                    }
                }

                if (descriptor.ForceSpace && glyphs.Find(32) == null)
                {
                    ABC abc = new ABC();
                    TextHelper.GetCharABCWidths(descriptor.Font, (char)32, out abc);
                    abc.abcB = (uint)(abc.abcA + abc.abcB + abc.abcC);
                    abc.abcC = 0;
                    glyphs.Add(new GlyphDescriptor((char)32, abc));
                }
            }

            return glyphs;
        }
        private bool FindSlot(IAtlasDescriptor descriptor, byte[] scan, GlyphDescriptor gi, ref Vec2i minsize)
        {
            long reqWidth = gi.Width;
            long reqHeight = gi.Height;
            long big = (long)descriptor.MaxSize;

            if (reqHeight == 0 || reqWidth == 0)
            {
                gi.X = (int)0;
                gi.Y = (int)0;
                return true;
            }

            // try to find an empty space within the current used box
            for (long y = 0; y <= (minsize.Y - reqHeight); y++)
            {
                for (long x = 0; x <= (minsize.X - reqWidth); x++)
                {
                    long cx, cy;
                    long incr = y * big;
                    for (cy = y; cy < y + reqHeight; cy++)
                    {
                        for (cx = x; cx < x + reqWidth; cx++)
                        {
                            if (scan[incr + cx] != 0)
                            {
                                cy = 9999;
                                break;
                            }
                        }
                        incr += big;
                    }

                    // put it here
                    if (cy < 9999)
                    {
                        gi.X = (int)x;
                        gi.Y = (int)y;
                        return true;
                    }
                }
            }

            // if no space was found, expand the smallest edge of the used box,
            // which will keep the texture close to square
            if (minsize.X < minsize.Y)
            {
                if (minsize.X == descriptor.MaxSize - 1)
                {
                    return false;
                }

                minsize.X += (int)reqWidth;
                if (minsize.X >= descriptor.MaxSize)
                {
                    minsize.X = descriptor.MaxSize - 1;
                }
            }
            else
            {
                if (minsize.Y == descriptor.MaxSize - 1)
                {
                    return false;
                }

                minsize.Y += (int)reqHeight;
                if (minsize.Y >= descriptor.MaxSize)
                {
                    minsize.Y = descriptor.MaxSize - 1;
                }
            }

            return FindSlot(descriptor, scan, gi, ref minsize);
        }
Exemple #4
0
 public GlyphSegment(CmFont font, int charId)
 {
     CharId           = charId;
     _glyphDescriptor = new GlyphDescriptor(font.GlyphTypeface(), CharId);
 }
Exemple #5
0
 protected GlyphDescriptor Localized(GlyphDescriptor gd) => Localized(gd, 0, 0);