dangsn
2024-12-26 4e9ff2ce6a830bb2340d7c8612c72eea0c5a553e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.vci.client.workflow.editor;
 
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
 
import com.mxgraph.canvas.mxGraphics2DCanvas;
import com.mxgraph.canvas.mxICanvas;
import com.mxgraph.canvas.mxImageCanvas;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxGraph;
import com.mxgraph.view.mxGraphView;
import com.mxgraph.view.mxTemporaryCellStates;
 
public class FlowCellRenderer {
    // static class, 参照 mxCellRenderer class
 
    /**
     * Draws the given cells using a Graphics2D canvas and returns the buffered image
     * that represents the cells.
     * 
     * @param graph Graph to be painted onto the canvas.
     * @return Returns the image that represents the canvas.
     */
    public static mxICanvas drawCells(mxGraph graph, Object[] cells,
            double scale, CanvasFactory factory)
    {
        mxICanvas canvas = null;
 
        if (cells == null)
        {
            cells = new Object[] { graph.getModel().getRoot() };
        }
 
        // Gets the current state of the view
        mxGraphView view = graph.getView();
 
        // Keeps the existing translation as the cells might
        // be aligned to the grid in a different way in a graph
        // that has a translation other than zero
        boolean eventsEnabled = view.isEventsEnabled();
 
        // Disables firing of scale events so that there is no
        // repaint or update of the original graph
        view.setEventsEnabled(false);
 
        // Uses the view to create temporary cell states for each cell
        mxTemporaryCellStates temp = new mxTemporaryCellStates(view, scale,
                cells);
 
        try {
            mxRectangle clip = graph.getPaintBounds(cells);
            //将clip扩展到左上角(0, 0)
            clip.setWidth(clip.getWidth() + clip.getX());
            clip.setHeight(clip.getHeight() + clip.getY());
            clip.setX(0);
            clip.setY(0);
 
            if (clip != null && clip.getWidth() > 0 && clip.getHeight() > 0) {
                Rectangle rect = clip.getRectangle();
                canvas = factory.createCanvas(rect.width + 4, rect.height + 4);//增加一点富裕空间
 
                if (canvas != null) {
                    double previousScale = canvas.getScale();
                    //mxPoint previousTranslate = canvas.getTranslate();
                    Point previousTranslate = canvas.getTranslate();
 
                    try {
//                        canvas.setTranslate(-rect.x, -rect.y);
                        canvas.setScale(view.getScale());
 
                        for (int i = 0; i < cells.length; i++)
                        {
                            graph.drawCell(canvas, cells[i]);
                        }
                    } finally {
                        canvas.setScale(previousScale);
                        canvas.setTranslate(previousTranslate.x,
                                previousTranslate.y);
                    }
                }
            }
        } finally {
            temp.destroy();
            view.setEventsEnabled(eventsEnabled);
        }
 
        return canvas;
    }
 
    /**
     * 
     */
    public static BufferedImage createBufferedImage(mxGraph graph,
            Object[] cells, double scale, final Color background,
            final boolean antiAlias, final mxGraphics2DCanvas graphicsCanvas)
    {
        mxImageCanvas canvas = (mxImageCanvas) drawCells(graph, cells, scale,
                new CanvasFactory()
                {
                    public mxICanvas createCanvas(int width, int height)
                    {
                        return new mxImageCanvas(graphicsCanvas, width, height,
                                background, antiAlias);
                    }
 
                });
 
        return (canvas != null) ? canvas.destroy() : null;
    }
 
 
    /**
     * 
     */
    public static abstract class CanvasFactory
    {
 
        /**
         * Separates the creation of the canvas from its initialization, when the
         * size of the required graphics buffer / document / container is known.
         */
        public abstract mxICanvas createCanvas(int width, int height);
 
    }
 
}