[mapguide-commits] r5943 - in branches/2.2/MgDev/Common: Renderers
Stylization
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Thu Jun 23 12:00:30 EDT 2011
Author: jng
Date: 2011-06-23 09:00:30 -0700 (Thu, 23 Jun 2011)
New Revision: 5943
Modified:
branches/2.2/MgDev/Common/Renderers/AGGW2DRewriter.cpp
branches/2.2/MgDev/Common/Renderers/GDRenderer.cpp
branches/2.2/MgDev/Common/Renderers/GDRenderer.h
branches/2.2/MgDev/Common/Renderers/GDW2DRewriter.cpp
branches/2.2/MgDev/Common/Stylization/LineBuffer.cpp
branches/2.2/MgDev/Common/Stylization/LineBuffer.h
Log:
#1338: Backport r4973 to 2.2 branch
Modified: branches/2.2/MgDev/Common/Renderers/AGGW2DRewriter.cpp
===================================================================
--- branches/2.2/MgDev/Common/Renderers/AGGW2DRewriter.cpp 2011-06-22 17:13:41 UTC (rev 5942)
+++ branches/2.2/MgDev/Common/Renderers/AGGW2DRewriter.cpp 2011-06-23 16:00:30 UTC (rev 5943)
@@ -367,9 +367,9 @@
color = override;
}
- WT_Logical_Point oldpos = filledEllipse.position();
+ WT_Logical_Point center = filledEllipse.position();
- LineBuffer* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)&oldpos, 1, false);
+ LineBuffer* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)¢er, 1, false);
std::auto_ptr<LineBuffer> spDstLB(dstpts);
if (!dstpts)
@@ -378,15 +378,24 @@
double major = rewriter->ScaleW2DNumber(file, filledEllipse.major());
double minor = rewriter->ScaleW2DNumber(file, filledEllipse.minor());
- double start = filledEllipse.start_degree() * (M_PI / 180.0);
- double end = filledEllipse.end_degree() * (M_PI / 180.0);
+ double start = filledEllipse.start_radian();
+ double end = filledEllipse.end_radian();
+ double tilt = filledEllipse.tilt_radian();
+
+ // compute start point
+ double rcos = cos(tilt);
+ double rsin = sin(tilt);
+ double tx = major * cos(start);
+ double ty = minor * sin(start);
+ double startX = dstpts->x_coord(0) + tx*rcos - ty*rsin;
+ double startY = dstpts->y_coord(0) + ty*rcos + tx*rsin;
LineBuffer* ell = LineBufferPool::NewLineBuffer(rewriter->GetBufferPool(), 20);
std::auto_ptr<LineBuffer> spEllLB(ell);
ell->SetDrawingScale(1.0);
- ell->MoveTo(dstpts->x_coord(0) + major * cos(start), dstpts->y_coord(0) + minor * sin(start));
- ell->ArcTo(dstpts->x_coord(0), dstpts->y_coord(0), major, minor, start, end);
+ ell->MoveTo(startX, startY);
+ ell->ArcTo(dstpts->x_coord(0), dstpts->y_coord(0), major, minor, start, end, tilt);
AGGRenderer::DrawScreenPolygon((agg_context*)rewriter->GetW2DTargetImage(), ell, NULL, color.argb());
@@ -419,9 +428,9 @@
color = override;
}
- WT_Logical_Point oldpos = outlineEllipse.position();
+ WT_Logical_Point center = outlineEllipse.position();
- LineBuffer* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)&oldpos, 1, false);
+ LineBuffer* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)¢er, 1, false);
std::auto_ptr<LineBuffer> spDstLB(dstpts);
if (!dstpts)
@@ -430,20 +439,29 @@
double major = rewriter->ScaleW2DNumber(file, outlineEllipse.major());
double minor = rewriter->ScaleW2DNumber(file, outlineEllipse.minor());
- double start = outlineEllipse.start_degree() * (M_PI / 180.0);
- double end = outlineEllipse.end_degree() * (M_PI / 180.0);
+ double start = outlineEllipse.start_radian();
+ double end = outlineEllipse.end_radian();
+ double tilt = outlineEllipse.tilt_radian();
+
+ // compute start point
+ double rcos = cos(tilt);
+ double rsin = sin(tilt);
+ double tx = major * cos(start);
+ double ty = minor * sin(start);
+ double startX = dstpts->x_coord(0) + tx*rcos - ty*rsin;
+ double startY = dstpts->y_coord(0) + ty*rcos + tx*rsin;
+
+ LineBuffer* ell = LineBufferPool::NewLineBuffer(rewriter->GetBufferPool(), 20);
+ std::auto_ptr<LineBuffer> spEllLB(ell);
+
+ ell->SetDrawingScale(1.0);
+ ell->MoveTo(startX, startY);
+ ell->ArcTo(dstpts->x_coord(0), dstpts->y_coord(0), major, minor, start, end, tilt);
//get W2D line weight
double weightpx = rewriter->ScaleW2DNumber(file, file.rendition().line_weight().weight_value());
weightpx = rs_max(1.0, weightpx);
- LineBuffer* ell = LineBufferPool::NewLineBuffer(rewriter->GetBufferPool(), 20);
- std::auto_ptr<LineBuffer> spEllLB(ell);
-
- ell->SetDrawingScale(1.0);
- ell->MoveTo(dstpts->x_coord(0) + major * cos(start), dstpts->y_coord(0) + minor * sin(start));
- ell->ArcTo(dstpts->x_coord(0), dstpts->y_coord(0), major, minor, start, end);
-
SE_LineStroke lineStroke(color.argb(), weightpx);
AGGRenderer::DrawScreenPolyline((agg_context*)rewriter->GetW2DTargetImage(), ell, NULL, lineStroke);
Modified: branches/2.2/MgDev/Common/Renderers/GDRenderer.cpp
===================================================================
--- branches/2.2/MgDev/Common/Renderers/GDRenderer.cpp 2011-06-22 17:13:41 UTC (rev 5942)
+++ branches/2.2/MgDev/Common/Renderers/GDRenderer.cpp 2011-06-23 16:00:30 UTC (rev 5943)
@@ -2203,6 +2203,13 @@
return dDstSpace;
}
+// Fills and returns the point buffer using the supplied line buffer.
+// No transformations are applied.
+const RS_D_Point* GDRenderer::FillPointBuffer(LineBuffer* lb)
+{
+ _TransferPoints(lb, NULL);
+ return m_wtPointBuffer;
+}
void GDRenderer::UpdateSymbolTrans(WT_File& /*file*/, WT_Viewport& viewport)
{
Modified: branches/2.2/MgDev/Common/Renderers/GDRenderer.h
===================================================================
--- branches/2.2/MgDev/Common/Renderers/GDRenderer.h 2011-06-22 17:13:41 UTC (rev 5942)
+++ branches/2.2/MgDev/Common/Renderers/GDRenderer.h 2011-06-23 16:00:30 UTC (rev 5943)
@@ -286,7 +286,8 @@
int numpts,
bool checkInBounds);
- /*Do not export from DLL*/ double ScaleW2DNumber(WT_File& file, long number);
+ /*Do not export from DLL*/ double ScaleW2DNumber(WT_File& file, long number);
+ /*Do not export from DLL*/ const RS_D_Point* FillPointBuffer(LineBuffer* lb);
private:
void AddW2DContent(RS_InputStream* in, CSysTransformer* xformer, const RS_String& w2dfilter);
Modified: branches/2.2/MgDev/Common/Renderers/GDW2DRewriter.cpp
===================================================================
--- branches/2.2/MgDev/Common/Renderers/GDW2DRewriter.cpp 2011-06-22 17:13:41 UTC (rev 5942)
+++ branches/2.2/MgDev/Common/Renderers/GDW2DRewriter.cpp 2011-06-23 16:00:30 UTC (rev 5943)
@@ -410,39 +410,94 @@
color = override;
}
- WT_Logical_Point oldpos = filledEllipse.position();
-
- const RS_D_Point* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)&oldpos, 1, false);
-
- int major = ROUND(rewriter->ScaleW2DNumber(file, filledEllipse.major()));
- int minor = ROUND(rewriter->ScaleW2DNumber(file, filledEllipse.minor()));
-
- //simple bounds check before we draw
- if ( !(dstpts[0].x + major < 0
- || dstpts[0].x - major > ((gdImagePtr)rewriter->GetW2DTargetImage())->sx
- || dstpts[0].y + minor < 0
- || dstpts[0].x - minor > ((gdImagePtr)rewriter->GetW2DTargetImage())->sy))
- {
- //negate because GD is left-handed coords
- float end = 360.f - filledEllipse.start_degree();
- float start = 360.f - filledEllipse.end_degree();
-
- //gd does not like negative angles (it's sin/cos lookup table doesn't)
- while (start < 0.f)
+ WT_Logical_Point center = filledEllipse.position();
+
+ const RS_D_Point* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)¢er, 1, false);
+
+ //negate because GD is left-handed coords
+ double tilt = -filledEllipse.tilt_radian();
+
+ if (tilt == 0.0)
+ {
+ // case where ellipse is unrotated
+
+ int major = ROUND(rewriter->ScaleW2DNumber(file, filledEllipse.major()));
+ int minor = ROUND(rewriter->ScaleW2DNumber(file, filledEllipse.minor()));
+
+ //simple bounds check before we draw
+ if ( !(dstpts[0].x + major < 0
+ || dstpts[0].x - major > ((gdImagePtr)rewriter->GetW2DTargetImage())->sx
+ || dstpts[0].y + minor < 0
+ || dstpts[0].x - minor > ((gdImagePtr)rewriter->GetW2DTargetImage())->sy))
{
- start += 360.f;
- end += 360.f;
+ //negate because GD is left-handed coords
+ float end = 360.f - filledEllipse.start_degree();
+ float start = 360.f - filledEllipse.end_degree();
+
+ //gd does not like negative angles (its sin/cos lookup table doesn't)
+ while (start < 0.f)
+ {
+ start += 360.f;
+ end += 360.f;
+ }
+
+ int gdc = ConvertColor((gdImagePtr)rewriter->GetW2DTargetImage(), color);
+ gdImageFilledArc((gdImagePtr)rewriter->GetW2DTargetImage(),
+ dstpts[0].x, dstpts[0].y,
+ major * 2, minor * 2,
+ (int)start, (int)end,
+ gdc, gdArc);
}
-
- //TODO: tilt. Need to tesselate into a line buffer in order to rotate.
- int gdc = ConvertColor((gdImagePtr)rewriter->GetW2DTargetImage(), color);
- gdImageFilledArc((gdImagePtr)rewriter->GetW2DTargetImage(),
- dstpts[0].x, dstpts[0].y,
- major, minor,
- (int)start, (int)end, //negate because GD is left-handed coords
- gdc, gdArc);
}
-
+ else
+ {
+ // case where ellipse is rotated
+ double rcos = cos(tilt);
+ double rsin = sin(tilt);
+
+ double major = rewriter->ScaleW2DNumber(file, filledEllipse.major());
+ double minor = rewriter->ScaleW2DNumber(file, filledEllipse.minor());
+
+ // the half-width / half-height of the bounding box for the rotated ellipse
+ int wid2 = (int)sqrt(major*major*rcos*rcos + minor*minor*rsin*rsin) + 1;
+ int hgt2 = (int)sqrt(major*major*rsin*rsin + minor*minor*rcos*rcos) + 1;
+
+ //simple bounds check before we draw
+ if ( !(dstpts[0].x + wid2 < 0
+ || dstpts[0].x - wid2 > ((gdImagePtr)rewriter->GetW2DTargetImage())->sx
+ || dstpts[0].y + hgt2 < 0
+ || dstpts[0].x - hgt2 > ((gdImagePtr)rewriter->GetW2DTargetImage())->sy))
+ {
+ //negate because GD is left-handed coords
+ double start = -filledEllipse.start_radian();
+ double end = -filledEllipse.end_radian();
+
+ // compute start point
+ double tx = major * cos(start);
+ double ty = minor * sin(start);
+ double startX = dstpts[0].x + tx*rcos - ty*rsin;
+ double startY = dstpts[0].y + ty*rcos + tx*rsin;
+
+ // use a line buffer to tessellate the arc
+ LineBuffer* ell = LineBufferPool::NewLineBuffer(rewriter->GetBufferPool(), 20);
+ std::auto_ptr<LineBuffer> spEllLB(ell);
+
+ ell->SetDrawingScale(1.0);
+ ell->MoveTo(startX, startY);
+ ell->ArcTo(dstpts[0].x, dstpts[0].y, major, minor, start, end, tilt);
+
+ int numpts = ell->point_count();
+ const RS_D_Point* dstpts = rewriter->FillPointBuffer(ell);
+
+ LineBufferPool::FreeLineBuffer(rewriter->GetBufferPool(), spEllLB.release());
+
+ int gdc = ConvertColor((gdImagePtr)rewriter->GetW2DTargetImage(), color);
+ gdImageFilledPolygon((gdImagePtr)rewriter->GetW2DTargetImage(),
+ (gdPointPtr)dstpts,
+ numpts,
+ gdc);
+ }
+ }
return WT_Result::Success;
}
@@ -468,63 +523,135 @@
if (override.argb() != RS_Color::EMPTY_COLOR_ARGB)
color = override;
}
-
- WT_Logical_Point oldpos = outlineEllipse.position();
-
- const RS_D_Point* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)&oldpos, 1, false);
-
- int major = ROUND(rewriter->ScaleW2DNumber(file, outlineEllipse.major()));
- int minor = ROUND(rewriter->ScaleW2DNumber(file, outlineEllipse.minor()));
-
- //simple bounds check before we draw
- if ( !(dstpts[0].x + major < 0
- || dstpts[0].x - major > ((gdImagePtr)rewriter->GetW2DTargetImage())->sx
- || dstpts[0].y + minor < 0
- || dstpts[0].x - minor > ((gdImagePtr)rewriter->GetW2DTargetImage())->sy))
- {
- //negate because GD is left-handed coords
- float end = 360.f - outlineEllipse.start_degree();
- float start = 360.f - outlineEllipse.end_degree();
-
- //gd does not like negative angles (it's sin/cos lookup table doesn't)
- while (start < 0.f)
+
+ WT_Logical_Point center = outlineEllipse.position();
+
+ const RS_D_Point* dstpts = rewriter->ProcessW2DPoints(file, (WT_Logical_Point*)¢er, 1, false);
+
+ //negate because GD is left-handed coords
+ double tilt = -outlineEllipse.tilt_radian();
+
+ if (tilt == 0.0)
+ {
+ // case where ellipse is unrotated
+
+ int major = ROUND(rewriter->ScaleW2DNumber(file, outlineEllipse.major()));
+ int minor = ROUND(rewriter->ScaleW2DNumber(file, outlineEllipse.minor()));
+
+ //simple bounds check before we draw
+ if ( !(dstpts[0].x + major < 0
+ || dstpts[0].x - major > ((gdImagePtr)rewriter->GetW2DTargetImage())->sx
+ || dstpts[0].y + minor < 0
+ || dstpts[0].x - minor > ((gdImagePtr)rewriter->GetW2DTargetImage())->sy))
{
- start += 360.f;
- end += 360.f;
+ //negate because GD is left-handed coords
+ float end = 360.f - outlineEllipse.start_degree();
+ float start = 360.f - outlineEllipse.end_degree();
+
+ //gd does not like negative angles (its sin/cos lookup table doesn't)
+ while (start < 0.f)
+ {
+ start += 360.f;
+ end += 360.f;
+ }
+
+ ////////////////////////
+ // handle thickness
+
+ //get W2D line weight
+ int thick = ROUND(rewriter->ScaleW2DNumber(file, file.rendition().line_weight().weight_value()));
+ gdImagePtr brush1 = NULL;
+
+ if (thick > 1)
+ {
+ brush1 = rs_gdImageThickLineBrush(thick, color);
+ gdImageSetBrush((gdImagePtr)rewriter->GetW2DTargetImage(), brush1);
+ }
+
+ int gdc = ConvertColor((gdImagePtr)rewriter->GetW2DTargetImage(), color);
+ gdImageArc((gdImagePtr)rewriter->GetW2DTargetImage(),
+ dstpts[0].x, dstpts[0].y,
+ major * 2, minor * 2,
+ (int)start, (int)end,
+ brush1 ? gdBrushed : gdc);
+
+ if (brush1)
+ {
+ gdImageSetBrush((gdImagePtr)rewriter->GetW2DTargetImage(), NULL);
+ gdImageDestroy(brush1);
+ }
}
-
- //TODO: tilt. Need to tesselate into a line buffer in order to rotate.
- int gdc = ConvertColor((gdImagePtr)rewriter->GetW2DTargetImage(), color);
-
- ////////////////////////
- // handle thickness
-
- //get W2D line weight
- int thick = ROUND(rewriter->ScaleW2DNumber(file, file.rendition().line_weight().weight_value()));
-
- gdImagePtr brush1 = NULL;
-
- if (thick > 1)
+ }
+ else
+ {
+ // case where ellipse is rotated
+ double rcos = cos(tilt);
+ double rsin = sin(tilt);
+
+ double major = rewriter->ScaleW2DNumber(file, outlineEllipse.major());
+ double minor = rewriter->ScaleW2DNumber(file, outlineEllipse.minor());
+
+ // the half-width / half-height of the bounding box for the rotated ellipse
+ int wid2 = (int)sqrt(major*major*rcos*rcos + minor*minor*rsin*rsin) + 1;
+ int hgt2 = (int)sqrt(major*major*rsin*rsin + minor*minor*rcos*rcos) + 1;
+
+ //simple bounds check before we draw
+ if ( !(dstpts[0].x + wid2 < 0
+ || dstpts[0].x - wid2 > ((gdImagePtr)rewriter->GetW2DTargetImage())->sx
+ || dstpts[0].y + hgt2 < 0
+ || dstpts[0].x - hgt2 > ((gdImagePtr)rewriter->GetW2DTargetImage())->sy))
{
- brush1 = rs_gdImageThickLineBrush(thick, color);
- gdImageSetBrush((gdImagePtr)rewriter->GetW2DTargetImage(), brush1);
+ //negate because GD is left-handed coords
+ double start = -outlineEllipse.start_radian();
+ double end = -outlineEllipse.end_radian();
+
+ // compute start point
+ double tx = major * cos(start);
+ double ty = minor * sin(start);
+ double startX = dstpts[0].x + tx*rcos - ty*rsin;
+ double startY = dstpts[0].y + ty*rcos + tx*rsin;
+
+ // use a line buffer to tessellate the arc
+ LineBuffer* ell = LineBufferPool::NewLineBuffer(rewriter->GetBufferPool(), 20);
+ std::auto_ptr<LineBuffer> spEllLB(ell);
+
+ ell->SetDrawingScale(1.0);
+ ell->MoveTo(startX, startY);
+ ell->ArcTo(dstpts[0].x, dstpts[0].y, major, minor, start, end, tilt);
+
+ int numpts = ell->point_count();
+ const RS_D_Point* dstpts = rewriter->FillPointBuffer(ell);
+
+ LineBufferPool::FreeLineBuffer(rewriter->GetBufferPool(), spEllLB.release());
+
+ ////////////////////////
+ // handle thickness
+
+ //get W2D line weight
+ int thick = ROUND(rewriter->ScaleW2DNumber(file, file.rendition().line_weight().weight_value()));
+ gdImagePtr brush1 = NULL;
+
+ if (thick > 1)
+ {
+ brush1 = rs_gdImageThickLineBrush(thick, color);
+ gdImageSetBrush((gdImagePtr)rewriter->GetW2DTargetImage(), brush1);
+ }
+
+ int gdc = ConvertColor((gdImagePtr)rewriter->GetW2DTargetImage(), color);
+ gdImageOpenPolygon((gdImagePtr)rewriter->GetW2DTargetImage(),
+ (gdPointPtr)dstpts,
+ numpts,
+ brush1 ? gdBrushed : gdc);
+
+ if (brush1)
+ {
+ gdImageSetBrush((gdImagePtr)rewriter->GetW2DTargetImage(), NULL);
+ gdImageDestroy(brush1);
+ }
}
-
- gdImageArc((gdImagePtr)rewriter->GetW2DTargetImage(),
- dstpts[0].x, dstpts[0].y,
- major * 2, minor * 2,
- (int)start, (int)end,
- brush1 ? gdBrushed : gdc);
-
- if (brush1)
- {
- gdImageSetBrush((gdImagePtr)rewriter->GetW2DTargetImage(), NULL);
- gdImageDestroy(brush1);
- }
}
return WT_Result::Success;
-
}
Modified: branches/2.2/MgDev/Common/Stylization/LineBuffer.cpp
===================================================================
--- branches/2.2/MgDev/Common/Stylization/LineBuffer.cpp 2011-06-22 17:13:41 UTC (rev 5942)
+++ branches/2.2/MgDev/Common/Stylization/LineBuffer.cpp 2011-06-23 16:00:30 UTC (rev 5943)
@@ -755,7 +755,7 @@
}
-void LineBuffer::ArcTo(double cx, double cy, double a, double b, double startRad, double endRad)
+void LineBuffer::ArcTo(double cx, double cy, double a, double b, double startRad, double endRad, double rotRad)
{
// store off arc start point index
EnsureArcsSpArray(2);
@@ -798,6 +798,10 @@
// get the angular separation corresponding to the number of segments
double dRad = extent / nSegs;
+ // account for the overall arc rotation
+ double rcos = cos(rotRad);
+ double rsin = sin(rotRad);
+
// add the segments
EnsurePoints(nSegs);
for (int i=1; i<=nSegs; ++i)
@@ -806,8 +810,8 @@
double tx = a * cos(ang);
double ty = b * sin(ang);
- double x = cx + tx;
- double y = cy + ty;
+ double x = cx + tx*rcos - ty*rsin;
+ double y = cy + ty*rcos + tx*rsin;
LineTo(x, y);
}
Modified: branches/2.2/MgDev/Common/Stylization/LineBuffer.h
===================================================================
--- branches/2.2/MgDev/Common/Stylization/LineBuffer.h 2011-06-22 17:13:41 UTC (rev 5942)
+++ branches/2.2/MgDev/Common/Stylization/LineBuffer.h 2011-06-23 16:00:30 UTC (rev 5943)
@@ -105,7 +105,7 @@
// the fancy stuff
STYLIZATION_API void CircularArcTo(double midx, double midy, double endx, double endy);
STYLIZATION_API void CircularArcTo(double midx, double midy, double midz, double endx, double endy, double endz);
- STYLIZATION_API void ArcTo(double cx, double cy, double a, double b, double startRad, double endRad);
+ STYLIZATION_API void ArcTo(double cx, double cy, double a, double b, double startRad, double endRad, double rotRad = 0.0);
// STYLIZATION_API void QuadTo(double x2, double y2, double x3, double y3);
// STYLIZATION_API void CubicTo(double x2, double y2, double x3, double y3, double x4, double y4);
// STYLIZATION_API void AddEllipse(double cx, double cy, double a, double b);
More information about the mapguide-commits
mailing list