Exemple #1
0
        /// <summary>
        /// 从缓存区构造多边形填充到字型轮廓(一个字型轮廓包含多个多边形,每个多边形由若干个直线或曲线组成)
        /// </summary>
        /// <param name="outline">轮廓</param>
        /// <param name="buffer">缓存区指针</param>
        /// <param name="bufferSize">缓存区大小</param>
        /// <returns></returns>
        private static void FillPolygons(DOutline outline, IntPtr buffer, int bufferSize)
        {
            //多边形头大小
            int polygonHeaderSize = Marshal.SizeOf(typeof(TTPOLYGONHEADER));
            //线大小
            int lineSize = Marshal.SizeOf(typeof(TTPOLYCURVEHEAD));
            //点大小
            int pointFxSize = Marshal.SizeOf(typeof(POINTFX));

            //缓存区首地址值
            int ptr = buffer.ToInt32();
            //偏移量
            int offset = 0;

            //轮廓的多边形列表
            IList <DPolygon> polygons = outline.Polygons;

            while (offset < bufferSize)
            {
                //多边形头信息
                TTPOLYGONHEADER header = (TTPOLYGONHEADER)Marshal.PtrToStructure(new IntPtr(ptr + offset), typeof(TTPOLYGONHEADER));
                //构建多边形
                DPolygon polygon = new DPolygon(header.dwType);
                //起始点
                polygon.Start = header.pfxStart;
                //获取尾索引
                int endCurvesIndex = offset + header.cb;
                //向后偏移一个项
                offset += polygonHeaderSize;

                while (offset < endCurvesIndex)
                {
                    //线段信息
                    TTPOLYCURVEHEAD lineHeader = (TTPOLYCURVEHEAD)Marshal.PtrToStructure(new IntPtr(ptr + offset), typeof(TTPOLYCURVEHEAD));
                    //偏移到点序列首地址
                    offset += lineSize;

                    //构建线段
                    DLine line = new DLine(lineHeader.wType);

                    //读取点序列,加入线段中
                    for (int i = 0; i < lineHeader.cpfx; i++)
                    {
                        POINTFX point = (POINTFX)Marshal.PtrToStructure(new IntPtr(ptr + offset), typeof(POINTFX));
                        //将点加入线段
                        line.Points.Add(point);

                        //偏移
                        offset += pointFxSize;
                    }
                    //将线加入多边形
                    polygon.Lines.Add(line);
                }
                //将多边形加入轮廓
                polygons.Add(polygon);
            }
        }
Exemple #2
0
        /// <summary>
        /// 获取轮廓多边形列表
        /// </summary>
        /// <param name="hdc">场景</param>
        /// <param name="uChar">字符</param>
        /// <returns></returns>
        private static DOutline GetOutline(IntPtr hdc, uint uChar)
        {
            // 转置矩阵
            MAT2 mat2 = new MAT2();

            mat2.eM11.value = 1;
            mat2.eM22.value = 1;

            GLYPHMETRICS lpGlyph = new GLYPHMETRICS();

            //获取缓存区大小
            int bufferSize = GdiNativeMethods.GetGlyphOutline(hdc, uChar, GGO_NATIVE, out lpGlyph, 0, IntPtr.Zero, ref mat2);

            if (bufferSize > 0)
            {
                //获取成功后,分配托管内存
                IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
                try
                {
                    int ret = GdiNativeMethods.GetGlyphOutline(hdc, uChar, GGO_NATIVE, out lpGlyph, (uint)bufferSize, buffer, ref mat2);
                    if (ret > 0)
                    {
                        //构建轮廓
                        DOutline outline = new DOutline(lpGlyph.gmBlackBoxX, lpGlyph.gmBlackBoxY);
                        //从缓存区构造字型轮廓
                        FillPolygons(outline, buffer, bufferSize);

                        return(outline);
                    }
                    else
                    {
                        throw new Exception("获取字型数据失败!");
                    }
                }
                finally
                {
                    //释放托管内存
                    Marshal.FreeHGlobal(buffer);
                }
            }
            else
            {
                throw new Exception("未能获取缓存区!");
            }
        }
Exemple #3
0
        /// <summary>
        /// 填充所有字符轮廓
        /// </summary>
        /// <param name="x">起始X</param>
        /// <param name="y">Y值</param>
        /// <param name="spacing">字符间隔</param>
        private void FillWordOutlines(int x, int y, int spacing, Font font)
        {
            string text = tbWords.Text;

            if (!string.IsNullOrEmpty(text))
            {
                foreach (char t in text)
                {
                    TreeNode wordNode = new TreeNode(t.ToString());
                    tvList.Nodes.Add(wordNode);
                    //获取字符编码
                    uint ch = GetGB2312Coding(t);

                    //获取轮廓数据
                    DOutline outline = WordGraph.GetOutline(ch, font);
                    //构建轮廓实例
                    WordOutlineDrawing word = BuildWordOutline(outline, new PointF(x, y), wordNode);
                    wordOutlines.Add(word);

                    //下个字的起始位置=当前起始位置+宽度+间隔
                    x += (int)outline.Width + spacing;
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// 通过轮廓数据构建字体轮廓
        /// </summary>
        /// <param name="outline">轮廓数据</param>
        /// <param name="offset">偏移量</param>
        /// <param name="wordNode"></param>
        /// <returns></returns>
        private WordOutlineDrawing BuildWordOutline(DOutline outline, PointF offset, TreeNode wordNode)
        {
            //获取轮廓大小
            SizeF size = new SizeF(outline.Width, outline.Height);

            WordOutlineDrawing word = new WordOutlineDrawing(size);

            //---------------------
            wordNode.Tag = word;
            //---------------------
            int index = 0;

            //遍历填充轮廓数据
            foreach (DPolygon p in outline.Polygons)
            {
                //新增多边形实例
                PolygonDrawing polygon = new PolygonDrawing();

                //---------------------
                TreeNode polygonNode = new TreeNode("多边形" + (++index));
                polygonNode.Tag = polygon;
                wordNode.Nodes.Add(polygonNode);
                //---------------------

                //起始点
                PointF start = new PointF(offset.X + ConvertUtil.FixedToFloat(p.Start.x), offset.Y - ConvertUtil.FixedToFloat(p.Start.y));

                PointF point = start;
                foreach (DLine l in p.Lines)
                {
                    LineDrawing line = null;
                    //如果类型为1则为折线,为2则为曲线
                    if (l.Type == 1)
                    {
                        line = new PolylineDrawing();
                    }
                    else
                    {
                        line = new CurvelineDrawing();
                    }

                    //加入起始点
                    line.Points.Add(point);
                    //---------------------
                    StringBuilder builder = new StringBuilder(l.Type == 1 ? "折" : "曲");
                    builder.AppendFormat(" ({0},{1}) ", point.X, point.Y);
                    //---------------------
                    foreach (POINTFX fx in l.Points)
                    {
                        point = new PointF(offset.X + ConvertUtil.FixedToFloat(fx.x), offset.Y - ConvertUtil.FixedToFloat(fx.y));
                        Console.WriteLine("{0}.{1}, {2}.{3}({4},{5})", fx.x.value, fx.x.fract, fx.y.value, fx.y.fract, ConvertUtil.FixedToFloat(fx.x), ConvertUtil.FixedToFloat(fx.y));
                        line.Points.Add(point);

                        builder.AppendFormat("({0},{1}) ", point.X, point.Y);
                    }
                    polygon.Lines.Add(line);

                    //---------------------
                    TreeNode lineNode = new TreeNode(builder.ToString());
                    lineNode.Tag = line;
                    polygonNode.Nodes.Add(lineNode);
                    //---------------------
                }

                if (point != start)
                {
                    //增加结束到开始的闭合线段
                    LineDrawing endLine = new BeelineDrawing();
                    endLine.Points.Add(point);
                    endLine.Points.Add(start);
                    polygon.Lines.Add(endLine);

                    //---------------------
                    TreeNode endNode = new TreeNode(string.Format("直 ({0},{1}) ({0},{1}) ", point.X, point.Y, start.X, start.Y));
                    endNode.Tag = endLine;
                    polygonNode.Nodes.Add(endNode);
                    //---------------------
                }
                //加入到字符轮廓的多边形列表中
                word.Polygons.Add(polygon);
            }
            return(word);
        }