Example #1
0
        protected bool RenderText(String text, ref List<TextDrawItem> textDrawList, ViewUtil.ItemFont itemFont, double fontSize, double maxWidth, double maxHeight, double x, double baseline, ref double useHeight, SolidColorBrush fontColor, Matrix m)
        {
            double totalHeight = 0;
            double fontHeight = fontSize * itemFont.GlyphType.Height;

            string[] lineText = text.Replace("\r", "").Split('\n');
            foreach (string line in lineText)
            {
                List<ushort> glyphIndexes = new List<ushort>();
                List<double> advanceWidths = new List<double>();

                //ベースラインの位置
                double dpix = x * m.M11;
                double dpiy = (totalHeight + baseline) * m.M22;
                // ビットマップフォントがかすれる問題 とりあえず整数にしておく
                Point origin = new Point(Math.Round(dpix / m.M11), Math.Round(dpiy / m.M22));

                //メイリオみたいに行間のあるフォントと MS P ゴシックみたいな行間のないフォントがあるので
                //なんとなく行間を作ってみる。
                totalHeight += Math.Max(fontHeight, fontSize + 2);
                double totalWidth = 0;

                for (int n = 0; n < line.Length; n++)
                {
                    // XAML に合わせて、行頭の空白を無視する
                    if (glyphIndexes.Count == 0 && (line[n] == ' ' || line[n] == '\x3000'))
                        continue;

                    //この辞書検索が負荷の大部分を占めているのでテーブルルックアップする
                    //(簡単なパフォーマンス計測をした結果、2~10倍くらい速くなったようだ)
                    //ushort glyphIndex = itemFont.GlyphType.CharacterToGlyphMap[line[n]];
                    //double width = itemFont.GlyphType.AdvanceWidths[glyphIndex] * fontSize;
                    ushort glyphIndex = itemFont.GlyphIndexCache[line[n]];
                    if (glyphIndex == 0)
                    {
                        itemFont.GlyphIndexCache[line[n]] = glyphIndex = itemFont.GlyphType.CharacterToGlyphMap[line[n]];
                        itemFont.GlyphWidthCache[glyphIndex] = (float)itemFont.GlyphType.AdvanceWidths[glyphIndex];
                    }
                    double width = itemFont.GlyphWidthCache[glyphIndex] * fontSize;

                    if (totalWidth + width > maxWidth)
                    {
                        if (glyphIndexes.Count > 0)
                        {
                            TextDrawItem item = new TextDrawItem();
                            item.FontColor = fontColor;
                            item.Text = new GlyphRun(itemFont.GlyphType, 0, false, fontSize,
                                glyphIndexes, origin, advanceWidths, null, null, null, null,
                                null, null);
                            textDrawList.Add(item);
                        }
                        if (totalHeight > maxHeight)
                        {
                            //次の行無理
                            useHeight = totalHeight;
                            return false;
                        }
                        else
                        {
                            //次の行いける
                            dpiy = (totalHeight + baseline) * m.M22;
                            origin = new Point(Math.Round(dpix / m.M11), Math.Round(dpiy / m.M22));
                            totalHeight += Math.Max(fontHeight, fontSize + 2);
                            totalWidth = 0;

                            glyphIndexes = new List<ushort>();
                            advanceWidths = new List<double>();

                            // XAML に合わせて、行頭の空白を無視する
                            if (line[n] == ' ' || line[n] == '\x3000')
                                continue;
                        }
                    }
                    glyphIndexes.Add(glyphIndex);
                    advanceWidths.Add(width);
                    totalWidth += width;
                }
                if (glyphIndexes.Count > 0)
                {
                    TextDrawItem item = new TextDrawItem();
                    item.FontColor = fontColor;
                    item.Text = new GlyphRun(itemFont.GlyphType, 0, false, fontSize,
                        glyphIndexes, origin, advanceWidths, null, null, null, null,
                        null, null);
                    textDrawList.Add(item);
                }
            }
            useHeight = Math.Floor(totalHeight);
            return true;
        }
Example #2
0
        protected bool RenderText(String text, ref List <TextDrawItem> textDrawList, GlyphTypeface glyphType, double fontSize, double maxWidth, double maxHeight, double x, double y, ref double useHeight, SolidColorBrush fontColor, Matrix m)
        {
            double totalHeight = 0;

            string[] lineText = text.Replace("\r", "").Split('\n');
            foreach (string line in lineText)
            {
                totalHeight += Math.Floor(2 + fontSize);
                List <ushort> glyphIndexes  = new List <ushort>();
                List <double> advanceWidths = new List <double>();
                double        totalWidth    = 0;
                for (int n = 0; n < line.Length; n++)
                {
                    ushort glyphIndex = glyphType.CharacterToGlyphMap[line[n]];
                    double width      = glyphType.AdvanceWidths[glyphIndex] * fontSize;
                    if (totalWidth + width > maxWidth)
                    {
                        if (totalHeight > maxHeight)
                        {
                            //次の行無理
//                            glyphIndex = glyphType.CharacterToGlyphMap['…'];
//                            glyphIndexes[glyphIndexes.Count - 1] = glyphIndex;
//                            advanceWidths[advanceWidths.Count - 1] = width;

                            double       dpix   = Math.Ceiling((x + 2) * m.M11);
                            double       dpiy   = Math.Ceiling((y + totalHeight) * m.M22);
                            Point        origin = new Point(dpix / m.M11, dpiy / m.M22);
                            TextDrawItem item   = new TextDrawItem();
                            item.FontColor = fontColor;
                            item.Text      = new GlyphRun(glyphType, 0, false, fontSize,
                                                          glyphIndexes, origin, advanceWidths, null, null, null, null,
                                                          null, null);
                            textDrawList.Add(item);

                            useHeight = totalHeight;
                            return(false);
                        }
                        else
                        {
                            //次の行いけるので今までの分出力
                            double       dpix   = Math.Ceiling((x + 2) * m.M11);
                            double       dpiy   = Math.Ceiling((y + totalHeight) * m.M22);
                            Point        origin = new Point(dpix / m.M11, dpiy / m.M22);
                            TextDrawItem item   = new TextDrawItem();
                            item.FontColor = fontColor;
                            item.Text      = new GlyphRun(glyphType, 0, false, fontSize,
                                                          glyphIndexes, origin, advanceWidths, null, null, null, null,
                                                          null, null);
                            textDrawList.Add(item);

                            totalHeight += fontSize + 2;

                            glyphIndexes  = new List <ushort>();
                            advanceWidths = new List <double>();
                            totalWidth    = 0;
                        }
                    }
                    glyphIndexes.Add(glyphIndex);
                    advanceWidths.Add(width);
                    totalWidth += width;
                }
                if (glyphIndexes.Count > 0)
                {
                    double       dpix   = Math.Ceiling((x + 2) * m.M11);
                    double       dpiy   = Math.Ceiling((y + totalHeight) * m.M22);
                    Point        origin = new Point(dpix / m.M11, dpiy / m.M22);
                    TextDrawItem item   = new TextDrawItem();
                    item.FontColor = fontColor;
                    item.Text      = new GlyphRun(glyphType, 0, false, fontSize,
                                                  glyphIndexes, origin, advanceWidths, null, null, null, null,
                                                  null, null);
                    textDrawList.Add(item);
                }
            }
            useHeight = Math.Floor(totalHeight);
            return(true);
        }
Example #3
0
        protected bool RenderText(String text, ref List<TextDrawItem> textDrawList, GlyphTypeface glyphType, double fontSize, double maxWidth, double maxHeight, double x, double y, ref double useHeight, SolidColorBrush fontColor, Matrix m)
        {
            double totalHeight = 0;

            string[] lineText = text.Replace("\r", "").Split('\n');
            foreach (string line in lineText)
            {
                totalHeight += Math.Floor(2 + fontSize);
                List<ushort> glyphIndexes = new List<ushort>();
                List<double> advanceWidths = new List<double>();
                double totalWidth = 0;
                for (int n = 0; n < line.Length; n++)
                {
                    ushort glyphIndex = glyphType.CharacterToGlyphMap[line[n]];
                    double width = glyphType.AdvanceWidths[glyphIndex] * fontSize;
                    if (totalWidth + width > maxWidth)
                    {
                        if (glyphIndexes.Count > 0)
                        {
                            double dpix = Math.Ceiling((x + 2) * m.M11);
                            double dpiy = Math.Ceiling((y + totalHeight) * m.M22);
                            Point origin = new Point(dpix / m.M11, dpiy / m.M22);
                            TextDrawItem item = new TextDrawItem();
                            item.FontColor = fontColor;
                            item.Text = new GlyphRun(glyphType, 0, false, fontSize,
                                glyphIndexes, origin, advanceWidths, null, null, null, null,
                                null, null);
                            textDrawList.Add(item);

                        }
                        if (totalHeight > maxHeight)
                        {
                            //次の行無理
                            useHeight = totalHeight;
                            return false;
                        }
                        else
                        {
                            //次の行いける
                            totalHeight += fontSize + 2;

                            glyphIndexes = new List<ushort>();
                            advanceWidths = new List<double>();
                            totalWidth = 0;
                        }
                    }
                    glyphIndexes.Add(glyphIndex);
                    advanceWidths.Add(width);
                    totalWidth += width;
                }
                if (glyphIndexes.Count > 0)
                {
                    double dpix = Math.Ceiling((x + 2) * m.M11);
                    double dpiy = Math.Ceiling((y + totalHeight) * m.M22);
                    Point origin = new Point(dpix / m.M11, dpiy / m.M22);
                    TextDrawItem item = new TextDrawItem();
                    item.FontColor = fontColor;
                    item.Text = new GlyphRun(glyphType, 0, false, fontSize,
                        glyphIndexes, origin, advanceWidths, null, null, null, null,
                        null, null);
                    textDrawList.Add(item);

                }
            }
            useHeight = Math.Floor(totalHeight);
            return true;
        }
Example #4
0
        protected bool RenderText(String text, ref List <TextDrawItem> textDrawList, ViewUtil.ItemFont itemFont, double fontSize, double maxWidth, double maxHeight, double x, double baseline, ref double useHeight, Brush fontColor, Matrix m)
        {
            double totalHeight = 0;
            double fontHeight  = fontSize * itemFont.GlyphType.Height;

            string[] lineText = text.Replace("\r", "").Split('\n');
            foreach (string line in lineText)
            {
                List <ushort> glyphIndexes  = new List <ushort>();
                List <double> advanceWidths = new List <double>();

                //ベースラインの位置
                double dpix = x * m.M11;
                double dpiy = (totalHeight + baseline) * m.M22;
                // ビットマップフォントがかすれる問題 とりあえず整数にしておく
                Point origin = new Point(Math.Round(dpix / m.M11), Math.Round(dpiy / m.M22));

                //メイリオみたいに行間のあるフォントと MS P ゴシックみたいな行間のないフォントがあるので
                //なんとなく行間を作ってみる。
                totalHeight += Math.Max(fontHeight, fontSize + 2);
                double totalWidth = 0;

                for (int n = 0; n < line.Length; n++)
                {
                    // XAML に合わせて、行頭の空白を無視する
                    if (glyphIndexes.Count == 0 && (line[n] == ' ' || line[n] == '\x3000'))
                    {
                        continue;
                    }

                    //この辞書検索が負荷の大部分を占めているのでテーブルルックアップする
                    //(簡単なパフォーマンス計測をした結果、2~10倍くらい速くなったようだ)
                    //ushort glyphIndex = itemFont.GlyphType.CharacterToGlyphMap[line[n]];
                    //double width = itemFont.GlyphType.AdvanceWidths[glyphIndex] * fontSize;
                    ushort glyphIndex = itemFont.GlyphIndexCache[line[n]];
                    if (glyphIndex == 0)
                    {
                        itemFont.GlyphType.CharacterToGlyphMap.TryGetValue(line[n], out glyphIndex);
                        itemFont.GlyphIndexCache[line[n]]    = glyphIndex;
                        itemFont.GlyphWidthCache[glyphIndex] = (float)itemFont.GlyphType.AdvanceWidths[glyphIndex];
                    }
                    double width = itemFont.GlyphWidthCache[glyphIndex] * fontSize;

                    if (totalWidth + width > maxWidth)
                    {
                        if (glyphIndexes.Count > 0)
                        {
                            TextDrawItem item = new TextDrawItem();
                            item.FontColor = fontColor;
                            item.Text      = new GlyphRun(itemFont.GlyphType, 0, false, fontSize,
                                                          glyphIndexes, origin, advanceWidths, null, null, null, null,
                                                          null, null);
                            textDrawList.Add(item);
                        }
                        if (totalHeight > maxHeight)
                        {
                            //次の行無理
                            useHeight = totalHeight;
                            return(false);
                        }
                        else
                        {
                            //次の行いける
                            dpiy         = (totalHeight + baseline) * m.M22;
                            origin       = new Point(Math.Round(dpix / m.M11), Math.Round(dpiy / m.M22));
                            totalHeight += Math.Max(fontHeight, fontSize + 2);
                            totalWidth   = 0;

                            glyphIndexes  = new List <ushort>();
                            advanceWidths = new List <double>();

                            // XAML に合わせて、行頭の空白を無視する
                            if (line[n] == ' ' || line[n] == '\x3000')
                            {
                                continue;
                            }
                        }
                    }
                    glyphIndexes.Add(glyphIndex);
                    advanceWidths.Add(width);
                    totalWidth += width;
                }
                if (glyphIndexes.Count > 0)
                {
                    TextDrawItem item = new TextDrawItem();
                    item.FontColor = fontColor;
                    item.Text      = new GlyphRun(itemFont.GlyphType, 0, false, fontSize,
                                                  glyphIndexes, origin, advanceWidths, null, null, null, null,
                                                  null, null);
                    textDrawList.Add(item);
                }
            }
            useHeight = Math.Floor(totalHeight);
            return(true);
        }