function draw(g, state, drawInfo) {
    var x = drawInfo.texArea[0];
    var y = drawInfo.texArea[1];
    var w = drawInfo.texArea[2] - drawInfo.texArea[0];
    var h = drawInfo.texArea[3] - drawInfo.texArea[1];

    var routeInfo = drawInfo.routeInfo;

    g.setColor(Color.WHITE);
    g.fillRect(x, y, w, h);

    var baseFont = loadResource("font", "mtrsteamloco:fonts/source-han-sans-bold.otf");

    var originalClip = g.getClip();
    var originalTransform = g.getTransform();

    if (routeInfo != null && routeInfo != undefined) {
        var routeColor = routeInfo.routeColor;
        var arrowSide = drawInfo.arrowDirection ? Number(drawInfo.arrowDirection) : 0;

        var distance = h * 0.75;
        g.setColor(routeColor);
        g.fillRect(widthPercent(0), heightPercent(0.25), w, h * 0.5);

        if (w <= distance * 8) return;
        var currentX = widthPercent(0.5) - distance * 4 * (arrowSide == 2 ? 1 : -1);

        if (drawInfo.index > 0) {
            g.setColor(Color.WHITE);
            drawStrDL(g, baseFont, baseFont, routeInfo.drawStations[drawInfo.index - 1].stationName, currentX, heightPercent(0.35), h * 0.3, 1, 1);
        }
        currentX += distance * (arrowSide == 2 ? 1 : -1) * 2;

        if (arrowSide == 2)
            g.setClip(
                new Polygon(
                    [currentX - distance * 0.5, currentX - distance * 0.75, currentX + distance * 0.5, currentX + distance * 0.75, currentX + distance * 0.5, currentX - distance * 0.75],
                    [heightPercent(0.5), heightPercent(0), heightPercent(0), heightPercent(0.5), heightPercent(1), heightPercent(1)],
                    6
                )
            );
        else
            g.setClip(
                new Polygon(
                    [currentX - distance * 0.75, currentX - distance * 0.5, currentX + distance * 0.75, currentX + distance * 0.5, currentX + distance * 0.75, currentX - distance * 0.5],
                    [heightPercent(0.5), heightPercent(0), heightPercent(0), heightPercent(0.5), heightPercent(1), heightPercent(1)],
                    6
                )
            );
        g.setColor(routeColor);
        g.fillRect(currentX - distance, y, distance * 2, h);
        g.setColor(Color.WHITE);
        g.fillRect(currentX - distance, heightPercent(0.04), distance * 2, h * 0.02);
        g.fillRect(currentX - distance, heightPercent(0.09), distance * 2, h * 0.02);
        g.fillRect(currentX - distance, heightPercent(0.14), distance * 2, h * 0.02);
        g.fillRect(currentX - distance, heightPercent(0.19), distance * 2, h * 0.02);

        g.fillRect(currentX - distance, heightPercent(0.79), distance * 2, h * 0.02);
        g.fillRect(currentX - distance, heightPercent(0.84), distance * 2, h * 0.02);
        g.fillRect(currentX - distance, heightPercent(0.89), distance * 2, h * 0.02);
        g.fillRect(currentX - distance, heightPercent(0.94), distance * 2, h * 0.02);
        g.setClip(originalClip);

        drawStrDL(g, baseFont, baseFont, routeInfo.drawStations[drawInfo.index].stationName, currentX, heightPercent(0.35), h * 0.3, 1, 1);

        currentX += distance * (arrowSide == 2 ? 1 : -1);

        g.drawImage(loadResource("img", arrowSide == 2 ? "fangsu:sign/ar.png" : "fangsu:sign/al.png"), currentX - h * 0.2, heightPercent(0.4), h * 0.2, h * 0.2, null);

        currentX += distance * (arrowSide == 2 ? 1 : -1);

        if (drawInfo.index < routeInfo.drawStations.length - 2) drawStrDL(g, baseFont, baseFont, routeInfo.drawStations[drawInfo.index + 1].stationName, currentX, heightPercent(0.35), h * 0.3, 1, 1);

        var forwardStations = routeInfo.drawStations.length - drawInfo.index - 1;
        var drawStations = [];
        if (forwardStations > 1) {
            if (forwardStations == 2) drawStations = [routeInfo.drawStations[drawInfo.index + 2]];
            else if (forwardStations == 3) drawStations = [routeInfo.drawStations[drawInfo.index + 2], routeInfo.drawStations[drawInfo.index + 3]];
            else if (forwardStations == 4) drawStations = [routeInfo.drawStations[drawInfo.index + 3], routeInfo.drawStations[drawInfo.index + 4]];
            else drawStations = [routeInfo.drawStations[drawInfo.index + 3], routeInfo.drawStations[drawInfo.index + 5]];
            for (var i = 0; i < drawStations.length; i++) {
                currentX += distance * (arrowSide == 2 ? 1 : -1);
                g.fillOval(currentX - h * 0.06, heightPercent(0.48), h * 0.02, h * 0.02);
                g.fillOval(currentX - h * 0.01, heightPercent(0.48), h * 0.02, h * 0.02);
                g.fillOval(currentX + h * 0.04, heightPercent(0.48), h * 0.02, h * 0.02);
                currentX += distance * (arrowSide == 2 ? 1 : -1);
                drawStrDL(g, baseFont, baseFont, drawStations[i].stationName, currentX, heightPercent(0.35), h * 0.3, 1, 1);
            }
        }
    }

    function widthPercent(p) {
        return x + w * p;
    }
    function heightPercent(p) {
        return y + h * p;
    }
}
