1 //========================================================================
2 //
3 // TileMap.h
4 //
5 // Copyright 2014 Glyph & Cog, LLC
6 //
7 //========================================================================
8 
9 #ifndef TILEMAP_H
10 #define TILEMAP_H
11 
12 #include <aconf.h>
13 
14 #ifdef USE_GCC_PRAGMAS
15 #pragma interface
16 #endif
17 
18 #include "gtypes.h"
19 
20 class GList;
21 class DisplayState;
22 
23 //------------------------------------------------------------------------
24 
25 // Tile descriptor: this is all of the information needed to specify a
26 // tile.
27 class TileDesc {
28 public:
29 
TileDesc(int pageA,int rotateA,double dpiA,int txA,int tyA,int twA,int thA)30   TileDesc(int pageA, int rotateA, double dpiA,
31 	   int txA, int tyA, int twA, int thA):
32     page(pageA), rotate(rotateA), dpi(dpiA),
33     tx(txA), ty(tyA), tw(twA), th(thA) {}
34 
matches(TileDesc * tile)35   GBool matches(TileDesc *tile) {
36     return page == tile->page && rotate == tile->rotate &&
37            dpi == tile->dpi &&
38            tx == tile->tx && ty == tile->ty &&
39            tw == tile->tw && th == tile->th;
40   }
41 
42   int page;			// page number
43   int rotate;			// rotation
44   double dpi;			// tile resolution
45   int tx, ty;			// origin of tile, relative to top left
46 				//   corner of page
47   int tw, th;			// tile size
48 };
49 
50 //------------------------------------------------------------------------
51 
52 // A TileDesc plus the tile's location in the display.
53 class PlacedTileDesc: public TileDesc {
54 public:
55 
PlacedTileDesc(int pageA,int rotateA,double dpiA,int txA,int tyA,int twA,int thA,int pxA,int pyA)56   PlacedTileDesc(int pageA, int rotateA, double dpiA,
57 		 int txA, int tyA, int twA, int thA,
58 		 int pxA, int pyA):
59     TileDesc(pageA, rotateA, dpiA, txA, tyA, twA, thA), px(pxA), py(pyA) {}
60 
61   int px, py;			// position, in window coordinates, of
62 				//   tile origin
63 };
64 
65 //------------------------------------------------------------------------
66 
67 // Tile map: this maps window position to tile, and vice versa; and
68 // computes the list of tiles needed for the current display.
69 class TileMap {
70 public:
71 
72   TileMap(DisplayState *stateA);
73   ~TileMap();
74 
75   // Returns a list of PlacedTileDesc objects describing the tiles
76   // needed for the current display.  The returned list is owned by
77   // the TileMap object (and may be reused) -- the caller should not
78   // modify or free it.
79   GList *getTileList();
80 
81   // Return the max values for the horizontal and vertical scrollbars.
82   // Scroll thumbs should be winW and winH.
83   void getScrollLimits(int *horizMax, int *vertMax);
84 
85   // Coordinate conversion functions.
86   // - user space: per-page, as defined by PDF file; unit = point
87   // - device space: (0,0) is upper-left corner of a page; unit = pixel
88   // - window space: (0,0) is upper-left corner of drawing area; unit = pixel
89   // Conversions to window space return false if the specified page
90   // isn't visible (in non-continuous modes).  Conversions from window
91   // space return false if the point isn't on a page.  Otherwise,
92   // these functions do not do bounds-checking or any clipping to
93   // window or page coordinates.
94   GBool cvtWindowToUser(int xw, int yw,
95 			int *pg, double *xu, double *yu);
96   GBool cvtWindowToDev(int xw, int yw,
97 		       int *pg, int *xd, int *yd);
98   GBool cvtUserToWindow(int pg, double xu, double yu,
99 			int *xw, int *yw);
100   GBool cvtDevToWindow(int pg, int xd, int yd,
101 		       int *xw, int *yw);
102   void cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd);
103   void cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu);
104 
105   // Return the range of pages intersected by a rectangle in window
106   // coordinates.  E.g., these are the pages that will need to be
107   // redrawn for a redraw event covering that rectangle.
108   void getWindowPageRange(int x, int y, int w, int h,
109 			  int *firstPage, int *lastPage);
110 
111   // Return the scrollY setting that would place the top of <page> at
112   // the top of the window.  (In non-continuous modes, this just
113   // returns zero.)
114   int getPageTopY(int page);
115 
116   // Return the scrollY setting that would place the bottom of <page>
117   // at the bottom of the window.
118   int getPageBottomY(int page);
119 
120   // Return the scrollX setting that would place the left side of
121   // <page> at the left side of the window.  (In non-continuous modes,
122   // this just returns zero.)
123   int getPageLeftX(int page);
124 
125   // Return the scrollX setting that would place the right side of
126   // <page> at the right side of the window.
127   int getPageRightX(int page);
128 
129   // In continuous modes: return the lowest page number visible
130   // anywhere in the window; in non-continuous modes: return the
131   // current page.
132   int getFirstPage();
133 
134   // In continuous modes: return the lowest page number whose top (or
135   // left) edge is visible in the window (or if no top/left edge is
136   // visilble, the page after the single visible page); in
137   // non-continuous modes: return the current page.
138   int getFirstPageTop();
139 
140   // In continuous modes: return the page number at the center of the
141   // window; in non-continuous modes: return the current page.
142   int getMidPage();
143 
144   // In continuous modes: return the highest page number visible
145   // anywhere in the window; in non-continuous modes: return the
146   // current page.
147   int getLastPage();
148 
149   // Get the resolution at which the specified will be rasterized.
150   double getDPI(int page);
151 
152   // Get the width and height of a page, in points.
153   double getPageBoxWidth(int page);
154   double getPageBoxHeight(int page);
155 
156   // Get the number of pixels (vertically) between adjacent pages in
157   // continuous / side-by-side continuous mode.
158   int getContinuousPageSpacing();
159 
160   // Get the number of pixels (horizontally) between facing pages in
161   // the side-by-side modes.
162   int getSideBySidePageSpacing();
163 
164   // Get the number of pixels (horizontally) between adjacent pages in
165   // horizontal continuous mode.
166   int getHorizContinuousPageSpacing();
167 
168   void docChanged();
169   void windowSizeChanged();
170   void displayModeChanged();
171   void zoomChanged();
172   void rotateChanged();
173   void scrollPositionChanged();
174   void forceRedraw();
175 
176 private:
177 
178   // Clear the pageDPI, pageW, pageH, tileW, and tileH arrays.
179   void clearPageParams();
180 
181   // Update pageDPI, pageW, pageH, tileW, tileH (if needed).
182   void updatePageParams();
183 
184   // Clear the pageX/pageY array.
185   void clearContinuousModeParams();
186 
187   // Update pageX, pageY, maxW, maxW2, maxH, totalW, totalH.
188   void updateContinuousModeParams();
189 
190   // Compute the user-to-device transform matrix for the specified
191   // page.
192   void computePageMatrix(int page, double *m);
193 
194   // Invert a matrix.
195   void invertMatrix(double *m, double *im);
196 
197   // Return the page number at y.  If y falls in a gap between pages,
198   // return the next page.  If y falls after the last page, return
199   // numPages + 1.
200   int findContinuousPage(int y);
201 
202   // Return the left-side page number at y.  If y falls in a gap between
203   // page pairs, return the next page.  If y falls after the last page,
204   // return numPages + 1 (or numPages + 2 if numPages is odd).
205   int findSideBySideContinuousPage(int y);
206 
207   // Return the page number at x.  If x falls in a gap between pages,
208   // return the next page.  If x falls after the last page, return
209   // numPages + 1.
210   int findHorizContinuousPage(int x);
211 
212   DisplayState *state;
213 
214   double *pageBoxW, *pageBoxH;	// page sizes, in points
215 
216   // Page parameters:
217   //   pageDPI[pg-1] = rasterization resolution
218   //   pageW[pg-1], pageH[pg-1] = size of rasterized page
219   //   tileW[pg-1], tileH[pg-1] = size of tiles
220   double *pageDPI;
221   int *pageW, *pageH;
222   int *tileW, *tileH;
223 
224   // In displayContinuous mode:
225   //   pageY[pg-1] = top edge of page
226   //   maxW = max page width
227   //   totalH = total page height (including gaps)
228   // In displaySideBySideContinuous mode:
229   //   pageY[pg-1] = top edge of page-pair
230   //   pageY[pg] = top edge of page-pair (if pg+1 <= nPages)
231   //   maxW = max left-side page width
232   //   maxW2 = max right-side page width
233   //   totalH = total page-pair height (including gaps)
234   // In displayHorizontalContinuous mode:
235   //   pageX[pg-1] = left edge of page
236   //   maxH = max page height
237   //   totalW = total page width (including gaps)
238   // Only one of pageX or pageY is used at a time, so a single array
239   // is allocated, i.e., pageX = pageY.
240   int *pageX, *pageY;
241   int maxW, maxW2, maxH;
242   int totalW, totalH;
243 
244   GList *tiles;
245 };
246 
247 #endif
248