2222import com .github .barteksc .pdfviewer .util .Util ;
2323import com .shockwave .pdfium .util .SizeF ;
2424
25+ import java .util .LinkedList ;
26+ import java .util .List ;
27+
2528import static com .github .barteksc .pdfviewer .util .Constants .Cache .CACHE_SIZE ;
2629import static com .github .barteksc .pdfviewer .util .Constants .PRELOAD_OFFSET ;
2730
@@ -37,21 +40,55 @@ class PagesLoader {
3740 private float partRenderHeight ;
3841 private final RectF thumbnailRect = new RectF (0 , 0 , 1 , 1 );
3942 private final int preloadOffset ;
40- private final Holder firstHolder = new Holder ();
41- private final Holder lastHolder = new Holder ();
42- private final GridSize firstGrid = new GridSize ();
43- private final GridSize lastGrid = new GridSize ();
44- private final GridSize middleGrid = new GridSize ();
4543
4644 private class Holder {
47- int page ;
4845 int row ;
4946 int col ;
47+
48+ @ Override
49+ public String toString () {
50+ return "Holder{" +
51+ "row=" + row +
52+ ", col=" + col +
53+ '}' ;
54+ }
55+ }
56+
57+ private class RenderRange {
58+ int page ;
59+ GridSize gridSize ;
60+ Holder leftTop ;
61+ Holder rightBottom ;
62+
63+ RenderRange () {
64+ this .page = 0 ;
65+ this .gridSize = new GridSize ();
66+ this .leftTop = new Holder ();
67+ this .rightBottom = new Holder ();
68+ }
69+
70+ @ Override
71+ public String toString () {
72+ return "RenderRange{" +
73+ "page=" + page +
74+ ", gridSize=" + gridSize +
75+ ", leftTop=" + leftTop +
76+ ", rightBottom=" + rightBottom +
77+ '}' ;
78+ }
5079 }
5180
5281 private class GridSize {
5382 int rows ;
5483 int cols ;
84+
85+ @ Override
86+ public String toString () {
87+ return "GridSize{" +
88+ "rows=" + rows +
89+ ", cols=" + cols +
90+ '}' ;
91+ }
5592 }
5693
5794 PagesLoader (PDFView pdfView ) {
@@ -69,124 +106,144 @@ private void getPageColsRows(GridSize grid, int pageIndex) {
69106 grid .cols = MathUtils .ceil (1f / partWidth );
70107 }
71108
72- private Holder getPageAndCoordsByOffset (Holder holder , GridSize grid , float localXOffset ,
73- float localYOffset , boolean endOffset ) {
74- float fixedXOffset = -MathUtils .max (localXOffset , 0 );
75- float fixedYOffset = -MathUtils .max (localYOffset , 0 );
76- float offset = pdfView .isSwipeVertical () ? fixedYOffset : fixedXOffset ;
77- holder .page = pdfView .pdfFile .getPageAtOffset (offset , pdfView .getZoom ());
78- getPageColsRows (grid , holder .page );
79- SizeF scaledPageSize = pdfView .pdfFile .getScaledPageSize (holder .page , pdfView .getZoom ());
80- float rowHeight = scaledPageSize .getHeight () / grid .rows ;
81- float colWidth = scaledPageSize .getWidth () / grid .cols ;
82- float row , col ;
83- float secondaryOffset = pdfView .pdfFile .getSecondaryPageOffset (holder .page , pdfView .getZoom ());
84- if (pdfView .isSwipeVertical ()) {
85- row = Math .abs (fixedYOffset - pdfView .pdfFile .getPageOffset (holder .page , pdfView .getZoom ())) / rowHeight ;
86- col = MathUtils .min (fixedXOffset - secondaryOffset , 0 ) / colWidth ;
87- } else {
88- col = Math .abs (fixedXOffset - pdfView .pdfFile .getPageOffset (holder .page , pdfView .getZoom ())) / colWidth ;
89- row = MathUtils .min (fixedYOffset - secondaryOffset , 0 ) / rowHeight ;
90- }
91-
92- if (endOffset ) {
93- holder .row = MathUtils .ceil (row );
94- holder .col = MathUtils .ceil (col );
95- } else {
96- holder .row = MathUtils .floor (row );
97- holder .col = MathUtils .floor (col );
98- }
99- return holder ;
100- }
101-
102109 private void calculatePartSize (GridSize grid ) {
103110 pageRelativePartWidth = 1f / (float ) grid .cols ;
104111 pageRelativePartHeight = 1f / (float ) grid .rows ;
105112 partRenderWidth = Constants .PART_SIZE / pageRelativePartWidth ;
106113 partRenderHeight = Constants .PART_SIZE / pageRelativePartHeight ;
107114 }
108115
109- private void loadVisible () {
110- int parts = 0 ;
111- float scaledPreloadOffset = preloadOffset * pdfView .getZoom ();
112- float firstXOffset = -xOffset + scaledPreloadOffset ;
113- float lastXOffset = -xOffset - pdfView .getWidth () - scaledPreloadOffset ;
114- float firstYOffset = -yOffset + scaledPreloadOffset ;
115- float lastYOffset = -yOffset - pdfView .getHeight () - scaledPreloadOffset ;
116116
117- getPageAndCoordsByOffset (firstHolder , firstGrid , firstXOffset , firstYOffset , false );
118- getPageAndCoordsByOffset (lastHolder , lastGrid , lastXOffset , lastYOffset , true );
117+ /**
118+ * calculate the render range of each page
119+ */
120+ private List <RenderRange > getRenderRangeList (float firstXOffset , float firstYOffset , float lastXOffset , float lastYOffset ) {
121+
122+ float fixedFirstXOffset = -MathUtils .max (firstXOffset , 0 );
123+ float fixedFirstYOffset = -MathUtils .max (firstYOffset , 0 );
124+
125+ float fixedLastXOffset = -MathUtils .max (lastXOffset , 0 );
126+ float fixedLastYOffset = -MathUtils .max (lastYOffset , 0 );
127+
128+ float offsetFirst = pdfView .isSwipeVertical () ? fixedFirstYOffset : fixedFirstXOffset ;
129+ float offsetLast = pdfView .isSwipeVertical () ? fixedLastYOffset : fixedLastXOffset ;
130+
131+ int firstPage = pdfView .pdfFile .getPageAtOffset (offsetFirst , pdfView .getZoom ());
132+ int lastPage = pdfView .pdfFile .getPageAtOffset (offsetLast , pdfView .getZoom ());
133+ int pageCount = lastPage - firstPage + 1 ;
134+
135+ List <RenderRange > renderRanges = new LinkedList <>();
136+
137+ for (int page = firstPage ; page <= lastPage ; page ++) {
138+ RenderRange range = new RenderRange ();
139+ range .page = page ;
140+
141+ float pageFirstXOffset , pageFirstYOffset , pageLastXOffset , pageLastYOffset ;
142+ if (page == firstPage ) {
143+ pageFirstXOffset = fixedFirstXOffset ;
144+ pageFirstYOffset = fixedFirstYOffset ;
145+ if (pageCount == 1 ) {
146+ pageLastXOffset = fixedLastXOffset ;
147+ pageLastYOffset = fixedLastYOffset ;
148+ } else {
149+ float pageOffset = pdfView .pdfFile .getPageOffset (page , pdfView .getZoom ());
150+ SizeF pageSize = pdfView .pdfFile .getScaledPageSize (page , pdfView .getZoom ());
151+ if (pdfView .isSwipeVertical ()) {
152+ pageLastXOffset = fixedLastXOffset ;
153+ pageLastYOffset = pageOffset + pageSize .getHeight ();
154+ } else {
155+ pageLastYOffset = fixedLastYOffset ;
156+ pageLastXOffset = pageOffset + pageSize .getWidth ();
157+ }
158+ }
159+ } else if (page == lastPage ) {
160+ float pageOffset = pdfView .pdfFile .getPageOffset (page , pdfView .getZoom ());
161+
162+ if (pdfView .isSwipeVertical ()) {
163+ pageFirstXOffset = fixedFirstXOffset ;
164+ pageFirstYOffset = pageOffset ;
165+ } else {
166+ pageFirstYOffset = fixedFirstYOffset ;
167+ pageFirstXOffset = pageOffset ;
168+ }
119169
120- for (int i = firstHolder .page ; i <= lastHolder .page ; i ++) {
121- loadThumbnail (i );
122- }
170+ pageLastXOffset = fixedLastXOffset ;
171+ pageLastYOffset = fixedLastYOffset ;
123172
124- int pagesCount = lastHolder .page - firstHolder .page + 1 ;
125- for (int page = firstHolder .page ; page <= lastHolder .page && parts < CACHE_SIZE ; page ++) {
173+ } else {
174+ float pageOffset = pdfView .pdfFile .getPageOffset (page , pdfView .getZoom ());
175+ SizeF pageSize = pdfView .pdfFile .getScaledPageSize (page , pdfView .getZoom ());
176+ if (pdfView .isSwipeVertical ()) {
177+ pageFirstXOffset = fixedFirstXOffset ;
178+ pageFirstYOffset = pageOffset ;
179+
180+ pageLastXOffset = fixedLastXOffset ;
181+ pageLastYOffset = pageOffset + pageSize .getHeight ();
182+ } else {
183+ pageFirstXOffset = pageOffset ;
184+ pageFirstYOffset = fixedFirstYOffset ;
185+
186+ pageLastXOffset = pageOffset + pageSize .getWidth ();
187+ pageLastYOffset = fixedLastYOffset ;
188+ }
189+ }
190+
191+ getPageColsRows (range .gridSize , range .page ); // get the page's grid size that rows and cols
192+ SizeF scaledPageSize = pdfView .pdfFile .getScaledPageSize (range .page , pdfView .getZoom ());
193+ float rowHeight = scaledPageSize .getHeight () / range .gridSize .rows ;
194+ float colWidth = scaledPageSize .getWidth () / range .gridSize .cols ;
195+
196+
197+ // get the page offset int the whole file
198+ // ---------------------------------------
199+ // | | | |
200+ // |<--offset-->| (page) |<--offset-->|
201+ // | | | |
202+ // | | | |
203+ // ---------------------------------------
204+ float secondaryOffset = pdfView .pdfFile .getSecondaryPageOffset (page , pdfView .getZoom ());
205+
206+ // calculate the row,col of the point in the leftTop and rightBottom
207+ if (pdfView .isSwipeVertical ()) {
208+ range .leftTop .row = MathUtils .floor (Math .abs (pageFirstYOffset - pdfView .pdfFile .getPageOffset (range .page , pdfView .getZoom ())) / rowHeight );
209+ range .leftTop .col = MathUtils .floor (MathUtils .min (pageFirstXOffset - secondaryOffset , 0 ) / colWidth );
126210
127- if (page == firstHolder .page && pagesCount > 1 ) {
128- parts += loadPageEnd (firstHolder , firstGrid , CACHE_SIZE - parts );
129- } else if (page == lastHolder .page && pagesCount > 1 ) {
130- parts += loadPageStart (lastHolder , lastGrid , CACHE_SIZE - parts );
131- } else if (pagesCount == 1 ) {
132- parts += loadPageCenter (firstHolder , lastHolder , firstGrid , CACHE_SIZE - parts );
211+ range .rightBottom .row = MathUtils .ceil (Math .abs (pageLastYOffset - pdfView .pdfFile .getPageOffset (range .page , pdfView .getZoom ())) / rowHeight );
212+ range .rightBottom .col = MathUtils .floor (MathUtils .min (pageLastXOffset - secondaryOffset , 0 ) / colWidth );
133213 } else {
134- getPageColsRows (middleGrid , page );
135- parts += loadWholePage (page , middleGrid , CACHE_SIZE - parts );
214+ range .leftTop .col = MathUtils .floor (Math .abs (pageFirstXOffset - pdfView .pdfFile .getPageOffset (range .page , pdfView .getZoom ())) / colWidth );
215+ range .leftTop .row = MathUtils .floor (MathUtils .min (pageFirstYOffset - secondaryOffset , 0 ) / rowHeight );
216+
217+ range .rightBottom .col = MathUtils .floor (Math .abs (pageLastXOffset - pdfView .pdfFile .getPageOffset (range .page , pdfView .getZoom ())) / colWidth );
218+ range .rightBottom .row = MathUtils .floor (MathUtils .min (pageLastYOffset - secondaryOffset , 0 ) / rowHeight );
136219 }
220+
221+ renderRanges .add (range );
137222 }
138223
224+ return renderRanges ;
139225 }
140226
141- /**
142- * When whole page is visible
143- *
144- * @return loaded parts count
145- */
146- private int loadWholePage (int page , GridSize grid , int nbOfPartsLoadable ) {
147- calculatePartSize (grid );
148- return loadPage (page , 0 , grid .rows - 1 , 0 , grid .cols - 1 , nbOfPartsLoadable );
149- }
227+ private void loadVisible () {
228+ int parts = 0 ;
229+ float scaledPreloadOffset = preloadOffset ;
230+ float firstXOffset = -xOffset + scaledPreloadOffset ;
231+ float lastXOffset = -xOffset - pdfView .getWidth () - scaledPreloadOffset ;
232+ float firstYOffset = -yOffset + scaledPreloadOffset ;
233+ float lastYOffset = -yOffset - pdfView .getHeight () - scaledPreloadOffset ;
150234
151- /**
152- * When only part of one page is visible
153- *
154- * @return loaded parts count
155- */
156- private int loadPageCenter (Holder firstHolder , Holder lastHolder , GridSize grid , int nbOfPartsLoadable ) {
157- calculatePartSize (grid );
158- return loadPage (firstHolder .page , firstHolder .row , lastHolder .row , firstHolder .col , lastHolder .col , nbOfPartsLoadable );
159- }
235+ List <RenderRange > rangeList = getRenderRangeList (firstXOffset , firstYOffset , lastXOffset , lastYOffset );
160236
161- /**
162- * When only end of page is visible
163- *
164- * @return loaded parts count
165- */
166- private int loadPageEnd (Holder holder , GridSize grid , int nbOfPartsLoadable ) {
167- calculatePartSize (grid );
168- if (pdfView .isSwipeVertical ()) {
169- int firstRow = holder .row ;
170- return loadPage (holder .page , firstRow , grid .rows - 1 , 0 , grid .cols - 1 , nbOfPartsLoadable );
171- } else {
172- int firstCol = holder .col ;
173- return loadPage (holder .page , 0 , grid .rows - 1 , firstCol , grid .cols - 1 , nbOfPartsLoadable );
237+ for (RenderRange range : rangeList ) {
238+ loadThumbnail (range .page );
174239 }
175- }
176240
177- /**
178- * If only start of the page is visible
179- *
180- * @return loaded parts count
181- */
182- private int loadPageStart (Holder holder , GridSize grid , int nbOfPartsLoadable ) {
183- calculatePartSize (grid );
184- if (pdfView .isSwipeVertical ()) {
185- int lastRow = holder .row ;
186- return loadPage (holder .page , 0 , lastRow , 0 , grid .cols - 1 , nbOfPartsLoadable );
187- } else {
188- int lastCol = holder .col ;
189- return loadPage (holder .page , 0 , grid .rows - 1 , 0 , lastCol , nbOfPartsLoadable );
241+ for (RenderRange range : rangeList ) {
242+ calculatePartSize (range .gridSize );
243+ parts += loadPage (range .page , range .leftTop .row , range .rightBottom .row , range .leftTop .col , range .rightBottom .col , CACHE_SIZE - parts );
244+ if (parts >= CACHE_SIZE ) {
245+ break ;
246+ }
190247 }
191248
192249 }
0 commit comments