summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
blob: 222877c50505df4fe1acb3fd1d1bddf248a90111 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
//========================================================================
//
// TileMap.h
//
// Copyright 2014 Glyph & Cog, LLC
//
//========================================================================

#ifndef TILEMAP_H
#define TILEMAP_H

#include <aconf.h>

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "gtypes.h"

class GList;
class DisplayState;

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

// Tile descriptor: this is all of the information needed to specify a
// tile.
class TileDesc {
public:

  TileDesc(int pageA, int rotateA, double dpiA,
	   int txA, int tyA, int twA, int thA):
    page(pageA), rotate(rotateA), dpi(dpiA),
    tx(txA), ty(tyA), tw(twA), th(thA) {}

  GBool matches(TileDesc *tile) {
    return page == tile->page && rotate == tile->rotate &&
           dpi == tile->dpi &&
           tx == tile->tx && ty == tile->ty &&
           tw == tile->tw && th == tile->th;
  }

  int page;			// page number
  int rotate;			// rotation
  double dpi;			// tile resolution
  int tx, ty;			// origin of tile, relative to top left
				//   corner of page
  int tw, th;			// tile size
};

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

// A TileDesc plus the tile's location in the display.
class PlacedTileDesc: public TileDesc {
public:

  PlacedTileDesc(int pageA, int rotateA, double dpiA,
		 int txA, int tyA, int twA, int thA,
		 int pxA, int pyA):
    TileDesc(pageA, rotateA, dpiA, txA, tyA, twA, thA), px(pxA), py(pyA) {}

  int px, py;			// position, in window coordinates, of
				//   tile origin
};

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

// Tile map: this maps window position to tile, and vice versa; and
// computes the list of tiles needed for the current display.
class TileMap {
public:

  TileMap(DisplayState *stateA);
  ~TileMap();

  // Returns a list of PlacedTileDesc objects describing the tiles
  // needed for the current display.  The returned list is owned by
  // the TileMap object (and may be reused) -- the caller should not
  // modify or free it.
  GList *getTileList();

  // Return the max values for the horizontal and vertical scrollbars.
  // Scroll thumbs should be winW and winH.
  void getScrollLimits(int *horizMax, int *vertMax);

  // Coordinate conversion functions.
  // - user space: per-page, as defined by PDF file; unit = point
  // - device space: (0,0) is upper-left corner of a page; unit = pixel
  // - window space: (0,0) is upper-left corner of drawing area; unit = pixel
  // Conversions to window space return false if the specified page
  // isn't visible (in non-continuous modes).  Conversions from window
  // space return false if the point isn't on a page.  Otherwise,
  // these functions do not do bounds-checking or any clipping to
  // window or page coordinates.
  GBool cvtWindowToUser(int xw, int yw,
			int *pg, double *xu, double *yu);
  GBool cvtWindowToDev(int xw, int yw,
		       int *pg, int *xd, int *yd);
  GBool cvtUserToWindow(int pg, double xu, double yu,
			int *xw, int *yw);
  GBool cvtDevToWindow(int pg, int xd, int yd,
		       int *xw, int *yw);
  void cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd);
  void cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu);

  // Return the range of pages intersected by a rectangle in window
  // coordinates.  E.g., these are the pages that will need to be
  // redrawn for a redraw event covering that rectangle.
  void getWindowPageRange(int x, int y, int w, int h,
			  int *firstPage, int *lastPage);

  // Return the scrollY setting that would place the top of <page> at
  // the top of the window.  (In non-continuous modes, this just
  // returns zero.)
  int getPageTopY(int page);

  // Return the scrollY setting that would place the bottom of <page>
  // at the bottom of the window.
  int getPageBottomY(int page);

  // Return the scrollX setting that would place the left side of
  // <page> at the left side of the window.  (In non-continuous modes,
  // this just returns zero.)
  int getPageLeftX(int page);

  // Return the scrollX setting that would place the right side of
  // <page> at the right side of the window.
  int getPageRightX(int page);

  // In continuous modes: return the lowest page number visible
  // anywhere in the window; in non-continuous modes: return the
  // current page.
  int getFirstPage();

  // In continuous modes: return the lowest page number whose top (or
  // left) edge is visible in the window (or if no top/left edge is
  // visilble, the page after the single visible page); in
  // non-continuous modes: return the current page.
  int getFirstPageTop();

  // In continuous modes: return the page number at the center of the
  // window; in non-continuous modes: return the current page.
  int getMidPage();

  // In continuous modes: return the highest page number visible
  // anywhere in the window; in non-continuous modes: return the
  // current page.
  int getLastPage();

  // Get the resolution at which the specified will be rasterized.
  double getDPI(int page);

  // Get the width and height of a page, in points.
  double getPageBoxWidth(int page);
  double getPageBoxHeight(int page);

  // Get the number of pixels (vertically) between adjacent pages in
  // continuous / side-by-side continuous mode.
  int getContinuousPageSpacing();

  // Get the number of pixels (horizontally) between facing pages in
  // the side-by-side modes.
  int getSideBySidePageSpacing();

  // Get the number of pixels (horizontally) between adjacent pages in
  // horizontal continuous mode.
  int getHorizContinuousPageSpacing();

  void docChanged();
  void windowSizeChanged();
  void displayModeChanged();
  void zoomChanged();
  void rotateChanged();
  void scrollPositionChanged();
  void forceRedraw();

private:

  // Clear the pageDPI, pageW, pageH, tileW, and tileH arrays.
  void clearPageParams();

  // Update pageDPI, pageW, pageH, tileW, tileH (if needed).
  void updatePageParams();

  // Clear the pageX/pageY array.
  void clearContinuousModeParams();

  // Update pageX, pageY, maxW, maxW2, maxH, totalW, totalH.
  void updateContinuousModeParams();

  // Compute the user-to-device transform matrix for the specified
  // page.
  void computePageMatrix(int page, double *m);

  // Invert a matrix.
  void invertMatrix(double *m, double *im);

  // Return the page number at y.  If y falls in a gap between pages,
  // return the next page.  If y falls after the last page, return
  // numPages + 1.
  int findContinuousPage(int y);

  // Return the left-side page number at y.  If y falls in a gap between
  // page pairs, return the next page.  If y falls after the last page,
  // return numPages + 1 (or numPages + 2 if numPages is odd).
  int findSideBySideContinuousPage(int y);

  // Return the page number at x.  If x falls in a gap between pages,
  // return the next page.  If x falls after the last page, return
  // numPages + 1.
  int findHorizContinuousPage(int x);

  DisplayState *state;

  double *pageBoxW, *pageBoxH;	// page sizes, in points

  // Page parameters:
  //   pageDPI[pg-1] = rasterization resolution
  //   pageW[pg-1], pageH[pg-1] = size of rasterized page
  //   tileW[pg-1], tileH[pg-1] = size of tiles
  double *pageDPI;
  int *pageW, *pageH;
  int *tileW, *tileH;

  // In displayContinuous mode:
  //   pageY[pg-1] = top edge of page
  //   maxW = max page width
  //   totalH = total page height (including gaps)
  // In displaySideBySideContinuous mode:
  //   pageY[pg-1] = top edge of page-pair
  //   pageY[pg] = top edge of page-pair (if pg+1 <= nPages)
  //   maxW = max left-side page width
  //   maxW2 = max right-side page width
  //   totalH = total page-pair height (including gaps)
  // In displayHorizontalContinuous mode:
  //   pageX[pg-1] = left edge of page
  //   maxH = max page height
  //   totalW = total page width (including gaps)
  // Only one of pageX or pageY is used at a time, so a single array
  // is allocated, i.e., pageX = pageY.
  int *pageX, *pageY;
  int maxW, maxW2, maxH;
  int totalW, totalH;

  GList *tiles;
};

#endif