summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h
blob: 82d7889c447e2252a84b4d3df3a2a3509f73617d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//========================================================================
//
// SplashXPath.h
//
// Copyright 2003-2013 Glyph & Cog, LLC
//
//========================================================================

#ifndef SPLASHXPATH_H
#define SPLASHXPATH_H

#include <aconf.h>

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "SplashTypes.h"

class SplashPath;
struct SplashXPathPoint;
struct SplashPathHint;

//------------------------------------------------------------------------

#define splashMaxCurveSplits (1 << 10)

//------------------------------------------------------------------------
// SplashXPathSeg
//------------------------------------------------------------------------

struct SplashXPathSeg {
  SplashCoord x0, y0;		// first endpoint (y0 <= y1)
  SplashCoord x1, y1;		// second endpoint
  SplashCoord dxdy;		// slope: delta-x / delta-y
  SplashCoord dydx;		// slope: delta-y / delta-x
  int count;			// EO/NZWN counter increment

  //----- used by SplashXPathScanner
  int iy;
  SplashCoord sx0, sx1, mx;
  SplashXPathSeg *prev, *next;

#if HAVE_STD_SORT

  static bool cmpMX(const SplashXPathSeg &s0,
		    const SplashXPathSeg &s1) {
    if (s0.iy != s1.iy) {
      return s0.iy < s1.iy;
    }
    return s0.mx < s1.mx;
  }

  static bool cmpY(const SplashXPathSeg &seg0,
		   const SplashXPathSeg &seg1) {
    return seg0.y0 < seg1.y0;
  }

#else

  static int cmpMX(const void *p0, const void *p1) {
    SplashXPathSeg *s0 = (SplashXPathSeg *)p0;
    SplashXPathSeg *s1 = (SplashXPathSeg *)p1;
    SplashCoord cmp;

    if (s0->iy != s1->iy) {
      return s0->iy - s1->iy;
    }
    cmp = s0->mx - s1->mx;
    return (cmp < 0) ? -1 : (cmp > 0) ? 1 : 0;
  }

  static int cmpY(const void *seg0, const void *seg1) {
    SplashCoord cmp;

    cmp = ((SplashXPathSeg *)seg0)->y0
          - ((SplashXPathSeg *)seg1)->y0;
    return (cmp > 0) ? 1 : (cmp < 0) ? -1 : 0;
  }

#endif
};

//------------------------------------------------------------------------
// SplashXPath
//------------------------------------------------------------------------

class SplashXPath {
public:

  // Expands (converts to segments) and flattens (converts curves to
  // lines) <path>.  Transforms all points from user space to device
  // space, via <matrix>.  If <closeSubpaths> is true, closes all open
  // subpaths.
  SplashXPath(SplashPath *path, SplashCoord *matrix,
	      SplashCoord flatness, GBool closeSubpaths,
	      GBool simplify, SplashStrokeAdjustMode strokeAdjMode);

  // Copy an expanded path.
  SplashXPath *copy() { return new SplashXPath(this); }

  ~SplashXPath();

  int getXMin() { return xMin; }
  int getXMax() { return xMax; }
  int getYMin() { return yMin; }
  int getYMax() { return yMax; }

private:

  static void clampCoords(SplashCoord *x, SplashCoord *y);
  SplashXPath(SplashXPath *xPath);
  void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
		 SplashCoord *xo, SplashCoord *yo);
  GBool strokeAdjust(SplashXPathPoint *pts,
		     SplashPathHint *hints, int nHints,
		     SplashStrokeAdjustMode strokeAdjMode);
  void grow(int nSegs);
  void addCurve(SplashCoord x0, SplashCoord y0,
		SplashCoord x1, SplashCoord y1,
		SplashCoord x2, SplashCoord y2,
		SplashCoord x3, SplashCoord y3,
		SplashCoord flatness,
		GBool first, GBool last, GBool end0, GBool end1);
  void mergeSegments(int first);
  void addSegment(SplashCoord x0, SplashCoord y0,
		  SplashCoord x1, SplashCoord y1);
  void finishSegments();

  SplashXPathSeg *segs;
  int length, size;		// length and size of segs array
  int xMin, xMax;
  int yMin, yMax;

  GBool isRect;
  SplashCoord rectX0, rectY0, rectX1, rectY1;

  friend class SplashXPathScanner;
  friend class SplashClip;
  friend class Splash;
};

#endif