• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0
                『啊,蔥爆羊肉真是香啊。』一邊回憶著這個令人感動的美食,一邊心不在焉地寫了個程序。這個小程序實現了一個很簡單的功能,將一棵樹轉換成bmp圖片并自動排版。

                思路非常簡單。我們將樹節點分為葉子節點和非葉子節點。一個葉子節點可以簡單的處理為一個加了矩形邊框的字符串,一個非葉子節點可以處理為一個加了矩形邊框的字符串下面連接一堆樹。先看看結果吧。下面有兩幅圖片,表示的都是使用這篇文章的程序產生的兩棵語法樹。如果由于圖片太大而看不清楚,就另存為到硬盤上慢慢觀賞吧。

                這個算法并沒有通過什么計算來得到一個緊湊的圖片。

                1:(1+2)*(3+4)

                2:(1+sin(2))*(sin(log(2,3))+4)

                上圖可以將元素分為樹、文字以及線條。構造這種圖的要領是每一個節點的坐標信息都使用父節點的坐標空間。這樣的話不僅可以很快計算出圖片所需要的尺寸,而且還可以很方便的繪制。繪制的時候遞歸一下,每加深一層就修改一下坐標空間。

                下面給出代碼。首先是頭文件。其中類“GrammarSimulatorNode”是語法樹的數據結構,包含了字符串和子節點。
             1 #ifndef COMPRE_PAINTER
             2 #define COMPRE_PAINTER
             3 
             4 #include "GrammarAlgorithms.h"
             5 #include "..\..\..\Library\Windows\VL_WinGDI.h"
             6 
             7 using namespace vl::windows;
             8 
             9 namespace compiler
            10 {
            11 
            12 /*********************************************************************************************************
            13 GrammarSimulateNodePainter
            14 *********************************************************************************************************/
            15 
            16     class GrammarSimulateNodePainter : public VL_Base
            17     {
            18     public:
            19         class Line
            20         {
            21         public:
            22             typedef VL_List<Line , true>            List;
            23 
            24             VInt                StartX;
            25             VInt                StartY;
            26             VInt                EndX;
            27             VInt                EndY;
            28         };
            29 
            30         class Rect
            31         {
            32         public:
            33             typedef VL_List<Rect , false>            List;
            34 
            35             VInt                Left;
            36             VInt                Top;
            37             VInt                Width;
            38             VInt                Height;
            39             VInt                TextOffsetX;
            40             VInt                TextOffsetY;
            41             VUnicodeString        Text;
            42         };
            43 
            44         class Graph
            45         {
            46         public:
            47             typedef VL_AutoPtr<Graph>                Ptr;
            48             typedef VL_List<Ptr , false , Graph*>    List;
            49 
            50             VInt                OffsetX;
            51             VInt                OffsetY;
            52             VInt                Width;
            53             VInt                Height;
            54             VInt                LineReceiverX;
            55             Line::List            Lines;
            56             Rect::List            Rects;
            57             Graph::List            Children;
            58         };
            59     public:
            60         VL_WinBitmap::Ptr        Bitmap;
            61         VL_WinDC*                BitmapDC;
            62 
            63         GrammarSimulateNodePainter();
            64 
            65         void                    InitBitmap();
            66         Graph::Ptr                Build(GrammarSimulatorNode::Ptr Node);
            67         void                    ResizeBitmap(VInt Width , VInt Height);
            68         void                    ResizeBitmap(Graph::Ptr g);
            69         void                    Paint(Graph::Ptr g , VInt OffsetX , VInt OffsetY);
            70         void                    Paint(GrammarSimulatorNode::Ptr Node);
            71     };
            72 }
            73 
            74 #endif

                然后是實現:
              1 #include "Painter.h"
              2 
              3 namespace compiler
              4 {
              5 
              6 /*********************************************************************************************************
              7 GrammarSimulateNodePainter
              8 *********************************************************************************************************/
              9 
             10     const VInt GraphTextPadding=5;
             11     const VInt GraphPadding=10;
             12     const VInt GraphLevelPadding=24;
             13 
             14     GrammarSimulateNodePainter::GrammarSimulateNodePainter()
             15     {
             16         Bitmap=new VL_WinBitmap(32,32,VL_WinBitmap::vbb32Bits,true);
             17         InitBitmap();
             18     }
             19 
             20     void GrammarSimulateNodePainter::InitBitmap()
             21     {
             22         BitmapDC=Bitmap->GetWinDC();
             23         BitmapDC->SetBackTransparent(true);
             24         BitmapDC->FillRect(0,0,Bitmap->GetWidth(),Bitmap->GetHeight());
             25     }
             26 
             27     GrammarSimulateNodePainter::Graph::Ptr GrammarSimulateNodePainter::Build(GrammarSimulatorNode::Ptr Node)
             28     {
             29         VUnicodeString Text;
             30         if(Node->SubExpressions.GetCount())
             31         {
             32             Text=Node->TerminatorName;
             33         }
             34         else
             35         {
             36             Text=Node->TerminatorName+L" : "+Node->Value;
             37         }
             38 
             39         SIZE TextSize=BitmapDC->MeasureString(Text);
             40         Graph::Ptr g=new Graph;
             41 
             42         VInt TotalWidth=0;
             43         VInt TotalHeight=0;
             44         for(VInt i=0;i<Node->SubExpressions.GetCount();i++)
             45         {
             46             Graph::Ptr sg=Build(Node->SubExpressions[i]);
             47             sg->OffsetX=TotalWidth;
             48             TotalWidth+=sg->Width;
             49             if(i!=Node->SubExpressions.GetCount()-1)
             50             {
             51                 TotalWidth+=GraphPadding;
             52             }
             53             if(sg->Height>TotalHeight)
             54             {
             55                 TotalHeight=sg->Height;
             56             }
             57             g->Children.Add(sg);
             58         }
             59 
             60         Rect r;
             61         r.Left=0;
             62         r.Top=0;
             63         r.Width=TextSize.cx+GraphTextPadding*2;
             64         r.Height=TextSize.cy+GraphTextPadding*2;
             65         r.TextOffsetX=GraphTextPadding;
             66         r.TextOffsetY=GraphTextPadding;
             67         r.Text=Text;
             68 
             69         g->OffsetX=0;
             70         g->OffsetY=0;
             71         g->Width=r.Width;
             72         g->Height=r.Height;
             73 
             74         if(g->Width<TotalWidth)
             75         {
             76             r.Left=(TotalWidth-g->Width)/2;
             77             g->Width=TotalWidth;
             78         }
             79         g->LineReceiverX=r.Left+r.Width/2;
             80         g->Rects.Add(r);
             81 
             82         if(g->Children.GetCount())
             83         {
             84             for(VInt i=0;i<g->Children.GetCount();i++)
             85             {
             86                 Graph::Ptr sg=g->Children[i];
             87 
             88                 Line l;
             89                 l.StartX=g->LineReceiverX;
             90                 l.StartY=r.Height;
             91                 l.EndX=sg->LineReceiverX+sg->OffsetX;
             92                 l.EndY=l.StartY+GraphLevelPadding;
             93                 sg->OffsetY=l.EndY;
             94                 g->Lines.Add(l);
             95             }
             96             g->Height+=GraphLevelPadding+TotalHeight;
             97         }
             98 
             99         return g;
            100     }
            101 
            102     void GrammarSimulateNodePainter::ResizeBitmap(VInt Width , VInt Height)
            103     {
            104         VL_WinBitmap::Ptr NewBitmap=new VL_WinBitmap(Width,Height,VL_WinBitmap::vbb32Bits,true);
            105         NewBitmap->GetWinDC()->SetFont(BitmapDC->GetFont());
            106         NewBitmap->GetWinDC()->SetBrush(BitmapDC->GetBrush());
            107         NewBitmap->GetWinDC()->SetPen(BitmapDC->GetPen());
            108         Bitmap=NewBitmap;
            109         InitBitmap();
            110     }
            111 
            112     void GrammarSimulateNodePainter::ResizeBitmap(Graph::Ptr g)
            113     {
            114         ResizeBitmap(g->Width+2*GraphPadding,g->Height+2*GraphPadding);
            115     }
            116 
            117     void GrammarSimulateNodePainter::Paint(Graph::Ptr g , VInt OffsetX , VInt OffsetY)
            118     {
            119         OffsetX+=g->OffsetX;
            120         OffsetY+=g->OffsetY;
            121         for(VInt i=0;i<g->Lines.GetCount();i++)
            122         {
            123             Line l=g->Lines[i];
            124             BitmapDC->MoveTo(l.StartX+OffsetX,l.StartY+OffsetY);
            125             BitmapDC->LineTo(l.EndX+OffsetX,l.EndY+OffsetY);
            126         }
            127         for(VInt i=0;i<g->Rects.GetCount();i++)
            128         {
            129             Rect r=g->Rects[i];
            130             BitmapDC->Rectangle(
            131                 r.Left+OffsetX,
            132                 r.Top+OffsetY,
            133                 r.Left+r.Width+OffsetX,
            134                 r.Top+r.Height+OffsetY);
            135             BitmapDC->DrawString(
            136                 r.Left+r.TextOffsetX+OffsetX,
            137                 r.Top+r.TextOffsetY+OffsetY,
            138                 r.Text);
            139         }
            140         for(VInt i=0;i<g->Children.GetCount();i++)
            141         {
            142             Paint(g->Children[i],OffsetX,OffsetY);
            143         }
            144     }
            145 
            146     void GrammarSimulateNodePainter::Paint(GrammarSimulatorNode::Ptr Node)
            147     {
            148         Graph::Ptr g=Build(Node);
            149         ResizeBitmap(g);
            150         Paint(g,GraphPadding,GraphPadding);
            151     }
            152 }
            posted on 2008-09-07 04:18 陳梓瀚(vczh) 閱讀(2877) 評論(3)  編輯 收藏 引用 所屬分類: 2D

            評論:
            # re: 將樹型數據結構轉換為圖片并自動排版 2008-09-07 05:18 | Lnn
            送你一個詭異的笑。。。嘿嘿!  回復  更多評論
              
            # re: 將樹型數據結構轉換為圖片并自動排版 2010-07-28 18:42 | roy
            來學習一下思路先~  回復  更多評論
              
            # re: 將樹型數據結構轉換為圖片并自動排版 2011-05-30 09:31 | ArthasLee
            暑假的數據結構大作業想fxck這個哇。。。  回復  更多評論
              
            日本一区精品久久久久影院| 久久亚洲精精品中文字幕| 狠狠精品久久久无码中文字幕| 久久综合中文字幕| 国产精品久久新婚兰兰| 亚洲国产精品无码久久久秋霞2| 久久久精品2019免费观看| 99久久精品免费看国产免费| 久久国语露脸国产精品电影| 久久国产乱子伦精品免费强| 久久久精品久久久久影院| 久久最新精品国产| 伊人久久综合成人网| 久久久久人妻精品一区三寸蜜桃 | 国产国产成人久久精品| 久久免费看黄a级毛片| 国产福利电影一区二区三区久久老子无码午夜伦不 | 99久久婷婷国产一区二区| 久久久SS麻豆欧美国产日韩| 久久99精品国产麻豆蜜芽| 人妻无码αv中文字幕久久 | 久久ww精品w免费人成| 亚洲国产日韩欧美综合久久| 久久精品成人免费网站| 久久超碰97人人做人人爱| 亚洲精品蜜桃久久久久久| 中文字幕久久精品| 久久综合给合综合久久| 久久久久综合国产欧美一区二区| 久久久久久久尹人综合网亚洲 | 伊人久久大香线蕉综合Av| 午夜精品久久久久久久无码| 久久男人AV资源网站| 久久久久国产视频电影| 久久青青草原精品国产不卡| 久久99精品免费一区二区| 久久国产成人精品国产成人亚洲| 一级做a爰片久久毛片人呢| 999久久久国产精品| 99久久免费国产精品| 免费一级欧美大片久久网|