| |
| |
| #include "tregionprop.h" |
| #include "tstroke.h" |
| #include "tregion.h" |
| |
| |
| |
| #include "tmathutil.h" |
| #include "drawutil.h" |
| #include "tvectorrenderdata.h" |
| |
| #include "tsimplecolorstyles.h" |
| |
| |
| |
| |
| #ifndef _WIN32 |
| #define CALLBACK |
| #endif |
| |
| |
| |
| TRegionProp::TRegionProp(const TRegion *region) |
| : m_region(region), m_regionChanged(true) |
| { |
| } |
| |
| |
| |
| |
| namespace |
| { |
| |
| |
| |
| bool computeOutline(const TRegion *region, |
| TRegionOutline::PointVector &polyline, |
| const double pixelSize) |
| { |
| bool doAntialiasing = false; |
| polyline.clear(); |
| |
| std::vector<TPointD> polyline2d; |
| std::vector<int> indices; |
| |
| int i, edgeSize = region->getEdgeCount(), oldSize = 0; |
| for (i = 0; i < edgeSize; i++) { |
| TEdge &edge = *region->getEdge(i); |
| |
| if (edge.m_index >= 0 && edge.m_s) { |
| bool outline = (edge.m_s->getAverageThickness() == 0.0); |
| if (outline && !doAntialiasing) { |
| |
| doAntialiasing = true; |
| |
| |
| indices.reserve(edgeSize); |
| } |
| |
| if (outline && (edge.m_w0 > edge.m_w1)) { |
| int newSize = polyline2d.size(); |
| if (oldSize < newSize) { |
| |
| indices.push_back(newSize - oldSize); |
| oldSize = newSize; |
| } |
| |
| stroke2polyline(polyline2d, *edge.m_s, pixelSize, edge.m_w1, edge.m_w0, true); |
| |
| |
| newSize = polyline2d.size(); |
| indices.push_back(oldSize - newSize); |
| oldSize = newSize; |
| } else |
| stroke2polyline(polyline2d, *edge.m_s, pixelSize, edge.m_w0, edge.m_w1); |
| } |
| } |
| |
| |
| int pointNumber = polyline2d.size(); |
| polyline.reserve(pointNumber); |
| |
| int j, k, l, indicesCount = indices.size(); |
| for (i = 0, k = 0; k < indicesCount; ++k) { |
| l = indices[k]; |
| if (l == 0) |
| continue; |
| |
| if (l > 0) { |
| l = i + l; |
| for (j = i; j < l; ++j) |
| polyline.push_back(T3DPointD(polyline2d[j], 0.0)); |
| i = l; |
| } else { |
| l = i - l; |
| j = l - 1; |
| |
| |
| |
| if (polyline2d[i] == polyline2d[j]) |
| ++i; |
| |
| for (; j >= i; --j) |
| polyline.push_back(T3DPointD(polyline2d[j], 0.0)); |
| i = l; |
| } |
| } |
| |
| |
| for (; i < pointNumber; ++i) |
| polyline.push_back(T3DPointD(polyline2d[i], 0.0)); |
| |
| return doAntialiasing; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| |
| |
| |
| void OutlineRegionProp::computeRegionOutline() |
| { |
| int subRegionNumber = getRegion()->getSubregionCount(); |
| TRegionOutline::PointVector app; |
| |
| m_outline.m_exterior.clear(); |
| |
| computeOutline(getRegion(), app, m_pixelSize); |
| m_outline.m_doAntialiasing = true; |
| |
| m_outline.m_exterior.push_back(app); |
| m_outline.m_interior.clear(); |
| m_outline.m_interior.reserve(subRegionNumber); |
| for (int i = 0; i < subRegionNumber; i++) { |
| app.clear(); |
| computeOutline(getRegion()->getSubregion(i), app, m_pixelSize); |
| m_outline.m_doAntialiasing = true; |
| m_outline.m_interior.push_back(app); |
| } |
| |
| m_outline.m_bbox = getRegion()->getBBox(); |
| } |
| |
| |
| |
| OutlineRegionProp::OutlineRegionProp(const TRegion *region, const TOutlineStyleP colorStyle) |
| : TRegionProp(region), m_pixelSize(0), m_colorStyle(colorStyle) |
| { |
| m_styleVersionNumber = m_colorStyle->getVersionNumber(); |
| } |
| |
| |
| |
| void OutlineRegionProp::draw(const TVectorRenderData &rd) |
| { |
| if (rd.m_clippingRect != TRect() && !rd.m_is3dView && !(rd.m_aff * getRegion()->getBBox()).overlaps(convert(rd.m_clippingRect))) |
| return; |
| |
| glPushMatrix(); |
| tglMultMatrix(rd.m_aff); |
| double pixelSize = sqrt(tglGetPixelSize2()); |
| |
| if (!isAlmostZero(pixelSize - m_pixelSize, 1e-5) || |
| m_regionChanged || |
| m_styleVersionNumber != m_colorStyle->getVersionNumber()) { |
| m_pixelSize = pixelSize; |
| m_regionChanged = false; |
| computeRegionOutline(); |
| TOutlineStyle::RegionOutlineModifier *modifier = m_colorStyle->getRegionOutlineModifier(); |
| if (modifier) |
| modifier->modify(m_outline); |
| |
| m_styleVersionNumber = m_colorStyle->getVersionNumber(); |
| } |
| |
| assert(!m_outline.m_exterior.empty()); |
| |
| m_colorStyle->drawRegion(rd.m_cf, |
| rd.m_antiAliasing && rd.m_regionAntialias, |
| m_outline); |
| |
| glPopMatrix(); |
| } |
| |
| |
| |
| TRegionProp *OutlineRegionProp::clone(const TRegion *region) const |
| { |
| OutlineRegionProp *prop = new OutlineRegionProp(region, m_colorStyle); |
| prop->m_regionChanged = m_regionChanged; |
| prop->m_pixelSize = m_pixelSize; |
| prop->m_outline = m_outline; |
| return prop; |
| } |
| |
| |
| |
| const TColorStyle *OutlineRegionProp::getColorStyle() const |
| { |
| return m_colorStyle.getPointer(); |
| } |
| |
| |
| |
| void OutlineRegionProp::draw(TFlash &flash) |
| { |
| m_colorStyle->drawRegion(flash, getRegion()); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |