|
|
93cbac |
/*
|
|
|
93cbac |
polyspan.h
|
|
|
93cbac |
Polyspan Header
|
|
|
93cbac |
|
|
|
93cbac |
Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
|
93cbac |
Copyright (c) 2007, 2008 Chris Moore
|
|
|
93cbac |
Copyright (c) 2012-2013 Carlos Lรณpez
|
|
|
93cbac |
......... ... 2015 Ivan Mahonin
|
|
|
93cbac |
|
|
|
93cbac |
This package is free software; you can redistribute it and/or
|
|
|
93cbac |
modify it under the terms of the GNU General Public License as
|
|
|
93cbac |
published by the Free Software Foundation; either version 2 of
|
|
|
93cbac |
the License, or (at your option) any later version.
|
|
|
93cbac |
|
|
|
93cbac |
This package is distributed in the hope that it will be useful,
|
|
|
93cbac |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
93cbac |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
93cbac |
General Public License for more details.
|
|
|
93cbac |
*/
|
|
|
93cbac |
|
|
|
93cbac |
#ifndef _POLYSPAN_H_
|
|
|
93cbac |
#define _POLYSPAN_H_
|
|
|
93cbac |
|
|
|
93cbac |
#include <vector></vector>
|
|
|
93cbac |
|
|
|
93cbac |
#include "geometry.h"
|
|
|
93cbac |
|
|
|
93cbac |
class Polyspan {
|
|
|
93cbac |
public:
|
|
|
93cbac |
struct PenMark {
|
|
|
93cbac |
int y, x;
|
|
|
93cbac |
Real cover, area;
|
|
|
93cbac |
|
|
|
93cbac |
PenMark(): y(), x(), cover(), area() { }
|
|
|
93cbac |
PenMark(int xin, int yin, Real c, Real a):
|
|
|
93cbac |
y(yin), x(xin), cover(c), area(a) { }
|
|
|
93cbac |
void set(int xin, int yin, Real c, Real a)
|
|
|
93cbac |
{ y = yin; x = xin; cover = c; area = a; }
|
|
|
93cbac |
void setcoord(int xin, int yin)
|
|
|
93cbac |
{ y = yin; x = xin; }
|
|
|
93cbac |
void setcover(Real c, Real a)
|
|
|
93cbac |
{ cover = c; area = a; }
|
|
|
93cbac |
void addcover(Real c, Real a)
|
|
|
93cbac |
{ cover += c; area += a; }
|
|
|
93cbac |
bool operator < (const PenMark &rhs) const
|
|
|
93cbac |
{ return y == rhs.y ? x < rhs.x : y < rhs.y; }
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
93cbac |
typedef std::vector<penmark> cover_array;</penmark>
|
|
|
93cbac |
|
|
|
93cbac |
//for assignment to flags value
|
|
|
93cbac |
enum PolySpanFlags {
|
|
|
93cbac |
NotSorted = 0x8000,
|
|
|
93cbac |
NotClosed = 0x4000
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
93cbac |
enum {
|
|
|
93cbac |
MAX_SUBDIVISION_SIZE = 64,
|
|
|
93cbac |
MIN_SUBDIVISION_DRAW_LEVELS = 4
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
93cbac |
private:
|
|
|
93cbac |
Vector arc[3*MAX_SUBDIVISION_SIZE + 1];
|
|
|
93cbac |
|
|
|
93cbac |
cover_array covers;
|
|
|
93cbac |
PenMark current;
|
|
|
93cbac |
|
|
|
93cbac |
int open_index;
|
|
|
93cbac |
|
|
|
93cbac |
//ending position of last primitive
|
|
|
93cbac |
Real cur_x;
|
|
|
93cbac |
Real cur_y;
|
|
|
93cbac |
|
|
|
93cbac |
//starting position of current primitive list
|
|
|
93cbac |
Real close_x;
|
|
|
93cbac |
Real close_y;
|
|
|
93cbac |
|
|
|
93cbac |
//flags for the current segment
|
|
|
93cbac |
int flags;
|
|
|
93cbac |
|
|
|
93cbac |
//the window that will be drawn (used for clipping)
|
|
|
93cbac |
ContextRect window;
|
|
|
93cbac |
|
|
|
93cbac |
//add the current cell, but only if there is information to add
|
|
|
93cbac |
void addcurrent();
|
|
|
93cbac |
|
|
|
93cbac |
//move to the next cell (cover values 0 initially), keeping the current if necessary
|
|
|
93cbac |
void move_pen(int x, int y);
|
|
|
93cbac |
|
|
|
a7f97a |
static bool clip_conic(const Vector *p, const ContextRect &r);
|
|
|
a7f97a |
static Real max_edges_conic(const Vector *p);
|
|
|
93cbac |
static void subd_conic_stack(Vector *arc);
|
|
|
93cbac |
|
|
|
a7f97a |
static bool clip_cubic(const Vector *p, const ContextRect &r);
|
|
|
a7f97a |
static Real max_edges_cubic(const Vector *p);
|
|
|
93cbac |
static void subd_cubic_stack(Vector *arc);
|
|
|
93cbac |
|
|
|
93cbac |
public:
|
|
|
93cbac |
Polyspan();
|
|
|
93cbac |
|
|
|
93cbac |
const ContextRect& get_window() const { return window; }
|
|
|
93cbac |
const cover_array& get_covers() const { return covers; }
|
|
|
93cbac |
|
|
|
93cbac |
bool notclosed() const
|
|
|
93cbac |
{ return (flags & NotClosed) || (cur_x != close_x) || (cur_y != close_y); }
|
|
|
93cbac |
|
|
|
93cbac |
//0 out all the variables involved in processing
|
|
|
93cbac |
void clear();
|
|
|
93cbac |
void init(const ContextRect &window)
|
|
|
93cbac |
{ clear(); this->window = window; }
|
|
|
93cbac |
void init(int minx, int miny, int maxx, int maxy)
|
|
|
93cbac |
{
|
|
|
93cbac |
clear();
|
|
|
93cbac |
window.minx = minx;
|
|
|
93cbac |
window.miny = miny;
|
|
|
93cbac |
window.maxx = maxx;
|
|
|
93cbac |
window.maxy = maxy;
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
//close the primitives with a line (or rendering will not work as expected)
|
|
|
93cbac |
void close();
|
|
|
93cbac |
|
|
|
93cbac |
// Not recommended - destroys any separation of spans currently held
|
|
|
93cbac |
void merge_all();
|
|
|
93cbac |
|
|
|
93cbac |
//will sort the marks if they are not sorted
|
|
|
93cbac |
void sort_marks();
|
|
|
93cbac |
|
|
|
93cbac |
//encapsulate the current sublist of marks (used for drawing)
|
|
|
93cbac |
void encapsulate_current();
|
|
|
93cbac |
|
|
|
93cbac |
//move to start a new primitive list (enclose the last primitive if need be)
|
|
|
93cbac |
void move_to(Real x, Real y);
|
|
|
93cbac |
|
|
|
93cbac |
//primitive_to functions
|
|
|
93cbac |
void line_to(Real x, Real y);
|
|
|
93cbac |
void conic_to(Real x1, Real y1, Real x, Real y);
|
|
|
93cbac |
void cubic_to(Real x1, Real y1, Real x2, Real y2, Real x, Real y);
|
|
|
93cbac |
|
|
|
93cbac |
void draw_scanline(int y, Real x1, Real y1, Real x2, Real y2);
|
|
|
93cbac |
void draw_line(Real x1, Real y1, Real x2, Real y2);
|
|
|
93cbac |
|
|
|
93cbac |
Real extract_alpha(Real area, bool evenodd) const;
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
93cbac |
#endif
|