示例#1
0
  virtual void
  EndFan()
  {
    if (fans.full())
      return;

    // remove unnecessary inclusion of origin if next and last points are identical
    unsigned start = 0;
    const size_t gsize = g.size();
    if (gsize > 2 && g[gsize - 1] == g[1])
      start = 1;

    if (gsize < start + 3)
      return;

    // Perform clipping on the GeoPointVector (Result: clipped)
    unsigned size = clip.ClipPolygon(clipped, g.raw() + start, gsize - start);
    // With less than three points we can't draw a polygon
    if (size < 3)
      return;

    // Work directly on the RasterPoints in the fans vector
    fans.Append(size);

    // Convert GeoPoints to RasterPoints
    for (unsigned i = 0; i < size; ++i)
      fans.Append(proj.GeoToScreen(clipped[i]));
  }
示例#2
0
static void
test_clip_line(const GeoClip &clip, GeoPoint a, GeoPoint b,
               const GeoPoint a2, const GeoPoint b2)
{
  clip.clip_line(a, b);
  ok1(equals(a, a2));
  ok1(equals(b, b2));
}
示例#3
0
static void
test_clip_polygon(const GeoClip &clip, const GeoPoint *src, unsigned src_size,
                  const GeoPoint *result, unsigned result_size)
{
  GeoPoint dest[64];
  unsigned dest_size = clip.clip_polygon(dest, src, src_size);
  ok1(equals(result, result_size, dest, dest_size));
}
void
TopographyFileRenderer::Paint(Canvas &canvas,
                              const WindowProjection &projection)
{
  if (file.IsEmpty())
    return;

  fixed map_scale = projection.GetMapScale();
  if (!file.IsVisible(map_scale))
    return;

  UpdateVisibleShapes(projection);

  if (visible_shapes.empty())
    return;

  // TODO code: only draw inside screen!
  // this will save time with rendering pixmaps especially
  // we already do an outer visibility test, but may need a test
  // in screen coords

#ifdef ENABLE_OPENGL
  pen.Set();
  brush.Set();
#else
  shape_renderer.Configure(&pen, &brush);
#endif

  // get drawing info

#ifdef ENABLE_OPENGL
  const unsigned level = file.GetThinningLevel(map_scale);
  const unsigned min_distance = file.GetMinimumPointDistance(level)
    / Layout::Scale(1);

#ifndef HAVE_GLES
  float opengl_matrix[16];
  glGetFloatv(GL_MODELVIEW_MATRIX, opengl_matrix);
#endif

  glPushMatrix();
  fixed angle = projection.GetScreenAngle().Degrees();
  fixed scale = projection.GetScale();
  const RasterPoint &screen_origin = projection.GetScreenOrigin();
#ifdef HAVE_GLES
#ifdef FIXED_MATH
  GLfixed fixed_angle = angle.as_glfixed();
  GLfixed fixed_scale = scale.as_glfixed_scale();
#else
  GLfixed fixed_angle = angle * (1<<16);
  GLfixed fixed_scale = scale * (1LL<<32);
#endif
  glTranslatex((int)screen_origin.x << 16, (int)screen_origin.y << 16, 0);
  glRotatex(fixed_angle, 0, 0, -(1<<16));
  glScalex(fixed_scale, fixed_scale, 1<<16);
#else
  glTranslatef(screen_origin.x, screen_origin.y, 0.);
  glRotatef((GLfloat)angle, 0., 0., -1.);
  glScalef((GLfloat)scale, (GLfloat)scale, 1.);
#endif
#else // !ENABLE_OPENGL
  const GeoClip clip(projection.GetScreenBounds().Scale(fixed(1.1)));
  AllocatedArray<GeoPoint> geo_points;

  int iskip = file.GetSkipSteps(map_scale);
#endif

  for (auto it = visible_shapes.begin(), end = visible_shapes.end();
       it != end; ++it) {
    const XShape &shape = **it;

    if (!projection.GetScreenBounds().Overlaps(shape.get_bounds()))
      continue;

#ifdef ENABLE_OPENGL
    const ShapePoint *points = shape.get_points();

    const ShapePoint translation =
      shape.shape_translation(projection.GetGeoLocation());
    glPushMatrix();
#ifdef HAVE_GLES
    glTranslatex(translation.x, translation.y, 0);
#else
    glTranslatef(translation.x, translation.y, 0.);
#endif
#else // !ENABLE_OPENGL
    const unsigned short *lines = shape.get_lines();
    const unsigned short *end_lines = lines + shape.get_number_of_lines();
    const GeoPoint *points = shape.get_points();
#endif

    switch (shape.get_type()) {
    case MS_SHAPE_NULL:
      break;

    case MS_SHAPE_POINT:
#ifdef ENABLE_OPENGL
#ifdef HAVE_GLES
      PaintPoint(canvas, projection, shape, NULL);
#else
      PaintPoint(canvas, projection, shape, opengl_matrix);
#endif
#else // !ENABLE_OPENGL
      PaintPoint(canvas, projection, lines, end_lines, points);
#endif
      break;

    case MS_SHAPE_LINE:
      {
#ifdef ENABLE_OPENGL
#ifdef HAVE_GLES
        glVertexPointer(2, GL_FIXED, 0, &points[0].x);
#else
        glVertexPointer(2, GL_INT, 0, &points[0].x);
#endif

        const GLushort *indices, *count;
        if (level == 0 ||
            (indices = shape.get_indices(level, min_distance, count)) == NULL) {
          count = shape.get_lines();
          const GLushort *end_count = count + shape.get_number_of_lines();
          for (int offset = 0; count < end_count; offset += *count++)
            glDrawArrays(GL_LINE_STRIP, offset, *count);
        } else {
          const GLushort *end_count = count + shape.get_number_of_lines();
          for (; count < end_count; indices += *count++)
            glDrawElements(GL_LINE_STRIP, *count, GL_UNSIGNED_SHORT, indices);
        }
#else // !ENABLE_OPENGL
      for (; lines < end_lines; ++lines) {
        unsigned msize = *lines;
        shape_renderer.Begin(msize);

        const GeoPoint *end = points + msize - 1;
        for (; points < end; ++points)
          shape_renderer.AddPointIfDistant(projection.GeoToScreen(*points));

        // make sure we always draw the last point
        shape_renderer.AddPoint(projection.GeoToScreen(*points));

        shape_renderer.FinishPolyline(canvas);
      }
#endif
      }
      break;

    case MS_SHAPE_POLYGON:
#ifdef ENABLE_OPENGL
      {
        const GLushort *index_count;
        const GLushort *triangles = shape.get_indices(level, min_distance,
                                                        index_count);

#ifdef HAVE_GLES
        glVertexPointer(2, GL_FIXED, 0, &points[0].x);
#else
        glVertexPointer(2, GL_INT, 0, &points[0].x);
#endif
        glDrawElements(GL_TRIANGLE_STRIP, *index_count, GL_UNSIGNED_SHORT,
                       triangles);
      }
#else // !ENABLE_OPENGL
      for (; lines < end_lines; ++lines) {
        unsigned msize = *lines / iskip;

        /* copy all polygon points into the geo_points array and clip
           them, to avoid integer overflows (as RasterPoint may store
           only 16 bit integers on some platforms) */

        geo_points.GrowDiscard(msize * 3);

        for (unsigned i = 0; i < msize; ++i)
          geo_points[i] = points[i * iskip];

        msize = clip.ClipPolygon(geo_points.begin(),
                                 geo_points.begin(), msize);
        if (msize < 3)
          continue;

        shape_renderer.Begin(msize);

        for (unsigned i = 0; i < msize; ++i) {
          GeoPoint g = geo_points[i];
          shape_renderer.AddPointIfDistant(projection.GeoToScreen(g));
        }

        shape_renderer.FinishPolygon(canvas);
      }
#endif
      break;
    }
#ifdef ENABLE_OPENGL
    glPopMatrix();
#endif
  }
#ifdef ENABLE_OPENGL
  glPopMatrix();
#else
  shape_renderer.Commit();
#endif
}