Пример #1
0
        /// <summary>
        /// 文字グリフからテクスチャを生成する
        /// </summary>
        /// <param name="layouter"></param>
        void ProcessTexture(BoxLayouter layouter)
        {
            // レイアウト、複数の矩形を1つの矩形内に並べる
            int width, height;

            layouter.Layout(out width, out height);

            // 配置後のグリフを画像へ書き込む
            var bitmap = new PixelBitmapContent <Color>(width, height);

            for (int i = 0; i < layouter.Items.Count; ++i)
            {
                // グリフ位置情報の追加
                var rc = fontContent.Glyphs[i];
                rc.X = layouter.Items[i].Bounds.X;
                rc.Y = layouter.Items[i].Bounds.Y;
                fontContent.Glyphs[i] = rc;

                // 個々のグリフ画像をひとつの画像へ追加する
                var pixels = layouter.Items[i].Tag as uint[];
                int idx    = 0;
                for (int y = 0; y < rc.Height; ++y)
                {
                    for (int x = 0; x < rc.Width; ++x)
                    {
                        int r = (int)((pixels[idx] & 0x00ff0000) >> 16);
                        int g = (int)((pixels[idx] & 0x0000ff00) >> 8);
                        int b = (int)((pixels[idx] & 0x000000ff) >> 0);
                        int a = (int)((pixels[idx] & 0xff000000) >> 24);
                        bitmap.SetPixel(rc.X + x, rc.Y + y, new Color(r, g, b, a));
                        ++idx;
                    }
                }
            }

            // 文字画像をまとめた画像をテクスチャへ変換する
            fontContent.Texture = new Texture2DContent();
            switch (TextureFormat)
            {
            case WpfTextureFormat.Auto:
                if (UseGradient)
                {
                    // グラデーション使用していればColorフォーマット
                    fontContent.Texture.Mipmaps = bitmap;
                }
                else if (OutlineThickness > 0)
                {
                    // アウトラインのみ使用していればBgra4444フォーマット
                    fontContent.Texture.Mipmaps = bitmap;
                    fontContent.Texture.ConvertBitmapType(
                        typeof(PixelBitmapContent <Bgra4444>));
                }
                else
                {
                    // それ以外の単色フォントであれば単色に特化したDXT3圧縮をする
                    fontContent.Texture.Mipmaps =
                        SingleColorDxtCompressor.Compress(bitmap, FontColor);
                }
                break;

            case WpfTextureFormat.Bgra4444:
                fontContent.Texture.Mipmaps = bitmap;
                fontContent.Texture.ConvertBitmapType(
                    typeof(PixelBitmapContent <Bgra4444>));
                break;

            case WpfTextureFormat.Color:
                fontContent.Texture.Mipmaps = bitmap;
                break;
            }
        }
Пример #2
0
        void ProcessGlyphs(ContentProcessorContext context)
        {
            // 文字描画に必要な情報設定
            if (UseGradient)
            {
                textBrush = new LinearGradientBrush(
                    ToWpfColor(this.GradientBeginColor),
                    ToWpfColor(this.GradientEndColor),
                    GradientAngle);
            }
            else
            {
                textBrush = new SolidColorBrush(ToWpfColor(FontColor));
            }

            if (OutlineThickness > 0)
            {
                outlinePen = new Pen(new SolidColorBrush(ToWpfColor(OutlineColor)),
                                     OutlineThickness);
                outlinePen.LineJoin = OutlineShape;
            }
            else
            {
                outlinePen = null;
            }

            renderTarget  = null;
            drawingVisual = new DrawingVisual();


            // 登録文字をUnicode順に並び替える、これはXNAが実行時に文字グリフを
            // バイナリ検索しているので重要なステップ
            var characters = from c in input.Characters orderby c select c;

            var layouter = new BoxLayouter();

            // 一文字ずつつ描画し、グリフ情報を生成する
            foreach (char c in characters)
            {
                // 文字描画
                var glyphBounds = RenderCharacter(c);

                // ピクセル情報の取得
                int    stride = renderTarget.PixelWidth;
                uint[] pixels = new uint[stride * renderTarget.PixelHeight];
                renderTarget.CopyPixels(pixels, stride * sizeof(uint), 0);

                // Black-Boxを取得し、必要な領域の画像イメージを取得
                glyphBounds = NarrowerGlyph(pixels, stride, glyphBounds);
                var blackBox = GetBlackBox(pixels, stride, glyphBounds);
                pixels = new uint[blackBox.Width * blackBox.Height];
                renderTarget.CopyPixels(
                    ToInt32Rect(blackBox), pixels, blackBox.Width * sizeof(uint), 0);

                // カーニング情報の取得
                var kerning = GetKerning(c, blackBox);

                // FontContentへの設定
                fontContent.CharacterMap.Add(c);
                fontContent.Kerning.Add(kerning);
                fontContent.Glyphs.Add(new Rectangle(
                                           0, 0, blackBox.Width, blackBox.Height));
                fontContent.Cropping.Add(new Rectangle(
                                             blackBox.X - glyphBounds.X,
                                             blackBox.Y - glyphBounds.Y,
                                             glyphBounds.Width, glyphBounds.Height));

                // レイアウト用アイテムとして追加
                layouter.Add(new BoxLayoutItem {
                    Bounds = blackBox, Tag = pixels
                });
            }

            // テクスチャ処理
            ProcessTexture(layouter);
        }