Ejemplo n.º 1
0
void SE_Renderer::DrawSymbol(SE_RenderPrimitiveList& symbol,
                             const SE_Matrix& xform,
                             double angleRad,
                             bool excludeRegion)
{
    RS_Bounds extents(DBL_MAX, DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX, -DBL_MAX);
    unsigned int nprims = symbol.size();

    for (unsigned int i=0; i<nprims; ++i)
    {
        SE_RenderPrimitive* primitive = symbol[i];

        if (primitive->type == SE_RenderPrimitive_Polygon || primitive->type == SE_RenderPrimitive_Polyline)
        {
            SE_RenderPolyline* rp = (SE_RenderPolyline*)primitive;

            LineBuffer* lb = rp->geometry->xf_buffer();

            // update the extents with this primitive
            RS_Bounds lbnds;
            lb->ComputeBounds(lbnds);
            extents.add_bounds(lbnds);

            if (m_bSelectionMode)
            {
                if (primitive->type == SE_RenderPrimitive_Polygon)
                    DrawScreenPolygon(lb, &xform, m_selFillColor);

                m_selLineStroke.cap        = rp->lineStroke.cap;
                m_selLineStroke.join       = rp->lineStroke.join;
                m_selLineStroke.miterLimit = rp->lineStroke.miterLimit;
                DrawScreenPolyline(lb, &xform, m_selLineStroke);
            }
            else
            {
                if (primitive->type == SE_RenderPrimitive_Polygon)
                    DrawScreenPolygon(lb, &xform, ((SE_RenderPolygon*)primitive)->fill);

                DrawScreenPolyline(lb, &xform, rp->lineStroke);
            }
        }
        else if (primitive->type == SE_RenderPrimitive_Text)
        {
            SE_RenderText* tp = (SE_RenderText*)primitive;

            // update the extents with this primitive's bounds
            for (int j=0; j<4; ++j)
                extents.add_point(primitive->bounds[j]);

            // get position and angle to use
            double x, y;
            xform.transform(tp->position[0], tp->position[1], x, y);
            RS_TextDef tdef = tp->tdef;
            tdef.rotation() += angleRad * M_180PI;

            if (m_bSelectionMode)
            {
                tdef.textcolor()   = m_textForeColor;
                tdef.ghostcolor()  = m_textBackColor;
//              tdef.framecolor()  = m_textBackColor;
//              tdef.opaquecolor() = m_textBackColor;
            }

            // Here we cannot use the cached RS_TextMetrics in the SE_RenderText object.
            // We must recalculate the text metrics with the new tdef before we can call DrawScreenText.
            RS_TextMetrics tm;
            if (this->GetRSFontEngine()->GetTextMetrics(tp->content, tdef, tm, false))
                DrawScreenText(tm, tdef, x, y, NULL, 0, 0.0);
        }
        else if (primitive->type == SE_RenderPrimitive_Raster)
        {
            SE_RenderRaster* rp = (SE_RenderRaster*)primitive;

            if (m_bSelectionMode)
            {
                // if the raster symbol is selected, then draw the mask selection polygon only
                LineBuffer *lb = LineBufferPool::NewLineBuffer(m_pPool, 5);
                std::auto_ptr<LineBuffer> spLB(lb);

                lb->MoveTo(rp->bounds[3].x, rp->bounds[3].y);
                for (int i = 0; i < 4; ++i)
                {
                    lb->LineTo(rp->bounds[i].x, rp->bounds[i].y);
                }
                
                DrawScreenPolygon(lb, &xform, m_selFillColor);
                DrawScreenPolyline(lb, &xform, m_selLineStroke);

                LineBufferPool::FreeLineBuffer(m_pPool, spLB.release());
            }
            else 
            {
                ImageData& imgData = rp->imageData;
                if (imgData.data != NULL)
                {
                    // update the extents with this primitive's bounds
                    for (int j=0; j<4; ++j)
                        extents.add_point(primitive->bounds[j]);

                    // get position and angle to use
                    double x, y;
                    xform.transform(rp->position[0], rp->position[1], x, y);
                    double angleDeg = (rp->angleRad + angleRad) * M_180PI;

                    DrawScreenRaster(imgData.data, imgData.size, imgData.format, imgData.width, imgData.height, x, y, rp->extent[0], rp->extent[1], angleDeg, rp->opacity);
                }
            }
        }
    }

    if (nprims > 0)
    {
        // always compute the last symbol extent
        xform.transform(extents.minx, extents.miny, m_lastSymbolExtent[0].x, m_lastSymbolExtent[0].y);
        xform.transform(extents.maxx, extents.miny, m_lastSymbolExtent[1].x, m_lastSymbolExtent[1].y);
        xform.transform(extents.maxx, extents.maxy, m_lastSymbolExtent[2].x, m_lastSymbolExtent[2].y);
        xform.transform(extents.minx, extents.maxy, m_lastSymbolExtent[3].x, m_lastSymbolExtent[3].y);

        if (excludeRegion)
            AddExclusionRegion(m_lastSymbolExtent, 4);
    }
    else
    {
        // symbol contains no primitives - update last symbol extent assuming
        // zero symbol extent, but don't add any exclusion region
        xform.transform(0.0, 0.0, m_lastSymbolExtent[0].x, m_lastSymbolExtent[0].y);
        m_lastSymbolExtent[1].x = m_lastSymbolExtent[2].x = m_lastSymbolExtent[3].x = m_lastSymbolExtent[0].x;
        m_lastSymbolExtent[1].y = m_lastSymbolExtent[2].y = m_lastSymbolExtent[3].y = m_lastSymbolExtent[0].y;
    }
}