1 /** \file lvdocview.h
2     \brief XML/CSS document view
3 
4     CoolReader Engine
5 
6     (c) Vadim Lopatin, 2000-2009
7 
8     This source code is distributed under the terms of
9     GNU General Public License.
10     See LICENSE file for details.
11 */
12 
13 #ifndef __LV_TEXT_VIEW_H_INCLUDED__
14 #define __LV_TEXT_VIEW_H_INCLUDED__
15 
16 #include "crsetup.h"
17 #include "crskin.h"
18 #include "lvtinydom.h"
19 #include "lvpagesplitter.h"
20 #include "lvdrawbuf.h"
21 #include "hist.h"
22 #include "lvthread.h"
23 #include "lvdocviewcmd.h"
24 #include "lvdocviewprops.h"
25 
26 
27 const lChar32 * getDocFormatName( doc_format_t fmt );
28 
29 /// text format import options
30 typedef enum {
31     txt_format_pre,  // no formatting, leave lines as is
32     txt_format_auto  // autodetect format
33 } txt_format_t;
34 
35 /// no battery
36 #define CR_BATTERY_STATE_NO_BATTERY -2
37 /// battery is charging
38 #define CR_BATTERY_STATE_CHARGING -1
39 // values 0..100 -- battery life percent
40 
41 #ifndef CR_ENABLE_PAGE_IMAGE_CACHE
42 #ifdef ANDROID
43 #define CR_ENABLE_PAGE_IMAGE_CACHE 0
44 #else
45 #define CR_ENABLE_PAGE_IMAGE_CACHE 1
46 #endif
47 #endif//#ifndef CR_ENABLE_PAGE_IMAGE_CACHE
48 
49 #if CR_ENABLE_PAGE_IMAGE_CACHE==1
50 /// Page imege holder which allows to unlock mutex after destruction
51 class LVDocImageHolder
52 {
53 private:
54     LVRef<LVDrawBuf> _drawbuf;
55     LVMutex & _mutex;
56 	LVDocImageHolder & operator = (LVDocImageHolder&) {
57 		// no assignment
58         return *this;
59     }
60 public:
getDrawBuf()61     LVDrawBuf * getDrawBuf() { return _drawbuf.get(); }
getDrawBufRef()62     LVRef<LVDrawBuf> getDrawBufRef() { return _drawbuf; }
LVDocImageHolder(LVRef<LVDrawBuf> drawbuf,LVMutex & mutex)63     LVDocImageHolder( LVRef<LVDrawBuf> drawbuf, LVMutex & mutex )
64     : _drawbuf(drawbuf), _mutex(mutex)
65     {
66     }
~LVDocImageHolder()67     ~LVDocImageHolder()
68     {
69         _drawbuf = NULL;
70         _mutex.unlock();
71     }
72 };
73 
74 typedef LVRef<LVDocImageHolder> LVDocImageRef;
75 
76 /// page image cache
77 class LVDocViewImageCache
78 {
79     private:
80         LVMutex _mutex;
81         class Item {
82             public:
83                 LVRef<LVDrawBuf> _drawbuf;
84                 LVRef<LVThread> _thread;
85                 int _offset;
86                 int _page;
87                 bool _ready;
88                 bool _valid;
89         };
90         Item _items[2];
91         int _last;
92     public:
93         /// return mutex
getMutex()94         LVMutex & getMutex() { return _mutex; }
95         /// set page to cache
set(int offset,int page,LVRef<LVDrawBuf> drawbuf,LVRef<LVThread> thread)96         void set( int offset, int page, LVRef<LVDrawBuf> drawbuf, LVRef<LVThread> thread )
97         {
98             LVLock lock( _mutex );
99             _last = (_last + 1) & 1;
100             _items[_last]._ready = false;
101             _items[_last]._thread = thread;
102             _items[_last]._drawbuf = drawbuf;
103             _items[_last]._offset = offset;
104             _items[_last]._page = page;
105             _items[_last]._valid = true;
106         }
107         /// return page image, wait until ready
getWithoutLock(int offset,int page)108         LVRef<LVDrawBuf> getWithoutLock( int offset, int page )
109         {
110             for ( int i=0; i<2; i++ ) {
111                 if ( _items[i]._valid &&
112                      ( (_items[i]._offset == offset && offset!=-1)
113                       || (_items[i]._page==page && page!=-1)) ) {
114                     if ( !_items[i]._ready ) {
115                         _items[i]._thread->join();
116                         _items[i]._thread = NULL;
117                         _items[i]._ready = true;
118                     }
119                     _last = i;
120                     return _items[i]._drawbuf;
121                 }
122             }
123             return LVRef<LVDrawBuf>();
124         }
125         /// return page image, wait until ready
get(int offset,int page)126         LVDocImageRef get( int offset, int page )
127         {
128             _mutex.lock();
129             LVRef<LVDrawBuf> buf = getWithoutLock( offset, page );
130             if ( !buf.isNull() )
131                 return LVDocImageRef( new LVDocImageHolder(getWithoutLock( offset, page ), _mutex) );
132             return LVDocImageRef( NULL );
133         }
has(int offset,int page)134         bool has( int offset, int page )
135         {
136             _mutex.lock();
137             for ( int i=0; i<2; i++ ) {
138                 if ( _items[i]._valid && ( (_items[i]._offset == offset && offset!=-1)
139                       || (_items[i]._page==page && page!=-1)) ) {
140                     return true;
141                 }
142             }
143             return false;
144         }
clear()145         void clear()
146         {
147             LVLock lock( _mutex );
148             for ( int i=0; i<2; i++ ) {
149                 if ( _items[i]._valid && !_items[i]._ready ) {
150                     _items[i]._thread->join();
151                 }
152                 _items[i]._thread.Clear();
153                 _items[i]._valid = false;
154                 _items[i]._drawbuf.Clear();
155                 _items[i]._offset = -1;
156                 _items[i]._page = -1;
157             }
158         }
LVDocViewImageCache()159         LVDocViewImageCache()
160         : _last(0)
161         {
162             for ( int i=0; i<2; i++ )
163                 _items[i]._valid = false;
164         }
~LVDocViewImageCache()165         ~LVDocViewImageCache()
166         {
167             clear();
168         }
169 };
170 #endif
171 
172 class LVPageWordSelector {
173     LVDocView * _docview;
174     ldomWordExList _words;
175     void updateSelection();
176 public:
177     // selects middle word of current page
178     LVPageWordSelector( LVDocView * docview );
179     // clears selection
180     ~LVPageWordSelector();
181     // move current word selection in specified direction, (distance) times
182     void moveBy( MoveDirection dir, int distance = 1 );
183     // returns currently selected word
getSelectedWord()184     ldomWordEx * getSelectedWord() { return _words.getSelWord(); }
185     // access to words
getWords()186     ldomWordExList & getWords() { return _words; }
187     // append chars to search pattern
188     ldomWordEx * appendPattern( lString32 chars );
189     // remove last item from pattern
190     ldomWordEx * reducePattern();
191     // selects word of current page with specified coords;
192     void selectWord(int x, int y);
193 };
194 
195 
196 
197 /// document view mode: pages/scroll
198 enum LVDocViewMode
199 {
200     DVM_SCROLL,
201     DVM_PAGES
202 };
203 
204 /// document scroll position info
205 class LVScrollInfo
206 {
207 public:
208     int pos;
209     int maxpos;
210     int pagesize;
211     int scale;
212     lString32 posText;
LVScrollInfo()213     LVScrollInfo()
214     : pos(0), maxpos(0), pagesize(0), scale(1)
215     {
216     }
217 };
218 
219 /// page header flags
220 enum {
221     PGHDR_NONE=0,
222     PGHDR_PAGE_NUMBER=1,
223     PGHDR_PAGE_COUNT=2,
224     PGHDR_AUTHOR=4,
225     PGHDR_TITLE=8,
226     PGHDR_CLOCK=16,
227     PGHDR_BATTERY=32,
228     PGHDR_CHAPTER_MARKS=64,
229     PGHDR_PERCENT=128
230 };
231 
232 
233 //typedef lUInt64 LVPosBookmark;
234 
235 typedef LVArray<int> LVBookMarkPercentInfo;
236 
237 #define DEF_COLOR_BUFFER_BPP 32
238 
239 /**
240     \brief XML document view
241 
242     Platform independant document view implementation.
243 
244     Supports scroll view of document.
245 */
246 class LVDocView : public CacheLoadingCallback
247 {
248     friend class LVDrawThread;
249 private:
250     int m_bitsPerPixel;
251     int m_dx;
252     int m_dy;
253 
254     // current position
255     int _pos;  // >=0 is correct vertical offset inside document, <0 - get based on m_page
256     int _page; // >=0 is correct page number, <0 - get based on _pos
257     bool _posIsSet;
258     ldomXPointer _posBookmark; // bookmark for current position
259 
260     int m_battery_state;
261     int m_requested_font_size;
262     int m_font_size; // = m_requested_font_size, possibly scaled according to DPI
263     int m_status_font_size;
264     int m_def_interline_space;
265 #if USE_LIMITED_FONT_SIZES_SET
266     LVArray<int> m_font_sizes;
267     bool m_font_sizes_cyclic;
268 #else
269     int m_min_font_size;
270     int m_max_font_size;
271 #endif
272     bool m_is_rendered;
273 
274     LVDocViewMode m_view_mode; // DVM_SCROLL, DVM_PAGES
isPageMode()275     inline bool isPageMode() { return m_view_mode==DVM_PAGES; }
isScrollMode()276     inline bool isScrollMode() { return m_view_mode==DVM_SCROLL; }
277 
278     /*
279 #if (COLOR_BACKBUFFER==1)
280     LVColorDrawBuf m_drawbuf;
281 #else
282     LVGrayDrawBuf  m_drawbuf;
283 #endif
284     */
285     lUInt32 m_backgroundColor;
286     lUInt32 m_textColor;
287     lUInt32 m_statusColor;
288     font_ref_t     m_font;
289     font_ref_t     m_infoFont;
290     LVFontRef      m_batteryFont;
291     LVContainerRef m_container;
292     LVStreamRef    m_stream;
293     LVContainerRef m_arc;
294     ldomDocument * m_doc;
295     lString8 m_stylesheet;
296     LVRendPageList m_pages;
297     LVScrollInfo m_scrollinfo;
298     LVImageSourceRef m_defaultCover;
299     LVImageSourceRef m_backgroundImage;
300     LVRef<LVColorDrawBuf> m_backgroundImageScaled;
301     bool m_backgroundTiled;
302     bool m_stylesheetNeedsUpdate;
303     int m_highlightBookmarks;
304     LVPtrVector<LVBookMarkPercentInfo> m_bookmarksPercents;
305 
306 protected:
307     lString32 m_last_clock;
308 
309     ldomMarkedRangeList m_markRanges;
310     ldomMarkedRangeList m_bmkRanges;
311 
312 private:
313     lString32 m_filename;
314 #define ORIGINAL_FILENAME_PATCH
315 #ifdef ORIGINAL_FILENAME_PATCH
316     lString32 m_originalFilename;
317 #endif
318     lvsize_t  m_filesize;
319 
320 
321     lvRect m_pageMargins;
322     lvRect m_pageRects[2];
323     int    m_pagesVisible;
324     int    m_pagesVisibleOverride;
325     int m_pageHeaderPos;
326     int m_pageHeaderInfo;
327     bool m_showCover;
328     LVRefVec<LVImageSource> m_headerIcons;
329     LVRefVec<LVImageSource> m_batteryIcons;
330 
331 #if CR_INTERNAL_PAGE_ORIENTATION==1
332     cr_rotate_angle_t m_rotateAngle;
333 #endif
334 
335     CRFileHist m_hist;
336 
337     LVArray<int> m_section_bounds;
338     bool m_section_bounds_valid;
339     bool m_section_bounds_externally_updated;
340 
341     LVMutex _mutex;
342 #if CR_ENABLE_PAGE_IMAGE_CACHE==1
343     LVDocViewImageCache m_imageCache;
344 #endif
345 
346 
347     lString8 m_defaultFontFace;
348 	lString8 m_statusFontFace;
349     ldomNavigationHistory _navigationHistory;
350 
351     doc_format_t m_doc_format;
352 
353     LVDocViewCallback * m_callback;
354 
355     // options
356     CRPropRef m_props;
357     // document properties
358     CRPropRef m_doc_props;
359 
360     bool m_swapDone;
361 
362     /// edit cursor position
363     ldomXPointer m_cursorPos;
364 
365     lString32 m_pageHeaderOverride;
366 
367     int m_drawBufferBits;
368 
369     CRPageSkinRef _pageSkin;
370 
371     /// sets current document format
372     void setDocFormat( doc_format_t fmt );
373 
374 
375     // private functions
376     void updateScroll();
377     /// makes table of contents for current document
378     void makeToc();
379     /// updates page layout
380     void updateLayout();
381     /// parse document from m_stream
382     bool ParseDocument( );
383     /// format of document from cache is known
384     virtual void OnCacheFileFormatDetected( doc_format_t fmt );
385     void insertBookmarkPercentInfo(int start_page, int end_y, int percent);
386 
387     void updateDocStyleSheet();
388 
389 protected:
390 
391 
392     virtual void drawNavigationBar( LVDrawBuf * drawbuf, int pageIndex, int percent );
393 
394     virtual void getNavigationBarRectangle( lvRect & rc );
395 
396     virtual void getNavigationBarRectangle( int pageIndex, lvRect & rc );
397 
398     /// returns document offset for next page
399     int getNextPageOffset();
400     /// returns document offset for previous page
401     int getPrevPageOffset();
402     /// selects link on page, if any (delta==0 - current, 1-next, -1-previous). returns selected link range, null if no links.
403     virtual ldomXRange * selectPageLink( int delta, bool wrapAround);
404     /// create document and set flags
405     void createEmptyDocument();
406     /// get document rectangle for specified cursor position, returns false if not visible
407     bool getCursorDocRect( ldomXPointer ptr, lvRect & rc );
408     /// load document from stream (internal)
409     bool loadDocumentInt( LVStreamRef stream, bool metadataOnly = false );
410 public:
411     /// get outer (before margins are applied) page rectangle
412     virtual void getPageRectangle( int pageIndex, lvRect & pageRect );
413     /// get screen rectangle for specified cursor position, returns false if not visible
414     bool getCursorRect( ldomXPointer ptr, lvRect & rc, bool scrollToCursor = false );
415     /// set status bar and clock mode
416     void setStatusMode( int pos, bool showClock, bool showTitle, bool showBattery, bool showChapterMarks, bool showPercent, bool showPageNumber, bool showPageCount );
417     /// draw to specified buffer by either Y pos or page number (unused param should be -1)
418     void Draw( LVDrawBuf & drawbuf, int pageTopPosition, int pageNumber, bool rotate, bool autoresize = true);
419     /// ensure current position is set to current bookmark value
420     void checkPos();
getBatteryFont()421     LVFontRef getBatteryFont() { return m_batteryFont; }
setBatteryFont(LVFontRef font)422     void setBatteryFont( LVFontRef font ) { m_batteryFont=font; }
423 
424     /// draw current page to specified buffer
425     void Draw( LVDrawBuf & drawbuf, bool autoResize = true);
426 
427     /// close document
428     void close();
429     /// set buffer format
setDrawBufferBits(int bits)430     void setDrawBufferBits( int bits ) { m_drawBufferBits = bits; }
431     /// substitute page header with custom text (e.g. to be used while loading)
432     void setPageHeaderOverride( lString32 s );
433     /// get screen rectangle for current cursor position, returns false if not visible
434     bool getCursorRect( lvRect & rc, bool scrollToCursor = false )
435     {
436         return getCursorRect( m_cursorPos, rc, scrollToCursor );
437     }
438     /// returns cursor position
getCursorPos()439     ldomXPointer getCursorPos() { return m_cursorPos; }
440     /// set cursor position
setCursorPos(ldomXPointer ptr)441     void setCursorPos( ldomXPointer ptr ) { m_cursorPos = ptr; }
442     /// try swappping of document to cache, if size is big enough, and no swapping attempt yet done
443     void swapToCache();
444     /// save document to cache file, with timeout option
445     ContinuousOperationResult swapToCache(CRTimerUtil & maxTime);
446     /// save unsaved data to cache file (if one is created), with timeout option
447     ContinuousOperationResult updateCache(CRTimerUtil & maxTime);
448     /// save unsaved data to cache file (if one is created), w/o timeout
449     ContinuousOperationResult updateCache();
450 
451     /// returns selected (marked) ranges
getMarkedRanges()452     ldomMarkedRangeList * getMarkedRanges() { return &m_markRanges; }
453 
454     /// returns XPointer to middle paragraph of current page
455     ldomXPointer getCurrentPageMiddleParagraph();
456     /// render document, if not rendered
457     void checkRender();
458     /// saves current position to navigation history, to be able return back
459     bool savePosToNavigationHistory();
460     /// saves position to navigation history, to be able return back
461     bool savePosToNavigationHistory(lString32 path);
462     /// navigate to history path URL
463     bool navigateTo( lString32 historyPath );
464     /// packs current file path and name
465     lString32 getNavigationPath();
466     /// returns pointer to bookmark/last position containter of currently opened file
467     CRFileHistRecord * getCurrentFileHistRecord();
468 	/// -1 moveto previous chapter, 0 to current chaoter first pae, 1 to next chapter
469 	bool moveByChapter( int delta );
470 	/// -1 moveto previous page, 1 to next page
471 	bool moveByPage( int delta );
472 	/// saves new bookmark
473     CRBookmark * saveRangeBookmark( ldomXRange & range, bmk_type type, lString32 comment );
474 	/// export bookmarks to text file
475 	bool exportBookmarks( lString32 filename );
476 	/// saves current page bookmark under numbered shortcut
477     CRBookmark * saveCurrentPageShortcutBookmark( int number );
478     /// saves current page bookmark under numbered shortcut
479     CRBookmark * saveCurrentPageBookmark( lString32 comment );
480     /// removes bookmark from list, and deletes it, false if not found
481     bool removeBookmark( CRBookmark * bm );
482     /// sets new list of bookmarks, removes old values
483     void setBookmarkList(LVPtrVector<CRBookmark> & bookmarks);
484     /// restores page using bookmark by numbered shortcut
485 	bool goToPageShortcutBookmark( int number );
486     /// find bookmark by window point, return NULL if point doesn't belong to any bookmark
487     CRBookmark * findBookmarkByPoint(lvPoint pt);
488     /// returns true if coverpage display is on
getShowCover()489     bool getShowCover() { return  m_showCover; }
490     /// sets coverpage display flag
setShowCover(bool show)491     void setShowCover( bool show ) { m_showCover = show; }
492     /// returns true if page image is available (0=current, -1=prev, 1=next)
493     bool isPageImageReady( int delta );
494 
495     // property support methods
496     /// sets default property values if properties not found, checks ranges
497     void propsUpdateDefaults( CRPropRef props );
498 
499     /// applies only one property by name, return false if property is unknown
500     virtual bool propApply( lString8 name, lString32 value );
501     /// applies properties, returns list of not recognized properties
502     virtual CRPropRef propsApply( CRPropRef props );
503     /// returns current values of supported properties
504     CRPropRef propsGetCurrent();
505 
506     /// get current default cover image
getDefaultCover()507     LVImageSourceRef getDefaultCover() const { return m_defaultCover; }
508     /// set default cover image (for books w/o cover)
setDefaultCover(LVImageSourceRef cover)509     void setDefaultCover(LVImageSourceRef cover) { m_defaultCover = cover; clearImageCache(); }
510 
511     /// get background image
getBackgroundImage()512     LVImageSourceRef getBackgroundImage() const { return m_backgroundImage; }
513     /// set background image
514     void setBackgroundImage(LVImageSourceRef bgImage, bool tiled=true) { m_backgroundImage = bgImage; m_backgroundTiled=tiled; m_backgroundImageScaled.Clear(); clearImageCache(); }
515     /// clears page background
516     virtual void drawPageBackground( LVDrawBuf & drawbuf, int offsetX, int offsetY, int alpha = 0);
517 
518     // callback functions
519     /// set callback
setCallback(LVDocViewCallback * callback)520     LVDocViewCallback * setCallback( LVDocViewCallback * callback ) { LVDocViewCallback * old = m_callback; m_callback = callback; return old; }
521     /// get callback
getCallback()522     LVDocViewCallback * getCallback( ) { return m_callback; }
523 
524     // doc format functions
525     /// set text format options
526     void setTextFormatOptions( txt_format_t fmt );
527     /// get text format options
528     txt_format_t getTextFormatOptions();
529     /// get current document format
getDocFormat()530     doc_format_t getDocFormat() { return m_doc_format; }
531 
532     // Links and selections functions
533     /// sets selection for whole element, clears previous selection
534     virtual void selectElement( ldomNode * elem );
535     /// sets selection for range, clears previous selection
536     virtual void selectRange( const ldomXRange & range );
537     /// sets selection for list of words, clears previous selection
538     virtual void selectWords( const LVArray<ldomWord> & words );
539     /// sets selections for ranges, clears previous selections
540     virtual void selectRanges(ldomXRangeList & ranges);
541     /// clears selection
542     virtual void clearSelection();
543     /// update selection -- command handler
544     int onSelectionCommand( int cmd, int param );
545 
546 
547     /// navigation history
getNavigationHistory()548     ldomNavigationHistory & getNavigationHistory() { return _navigationHistory; }
549     /// get list of links
550     virtual void getCurrentPageLinks( ldomXRangeList & list );
551     /// selects first link on page, if any. returns selected link range, null if no links.
552     virtual ldomXRange * selectFirstPageLink();
553     /// selects next link on page, if any. returns selected link range, null if no links.
554     virtual ldomXRange * selectNextPageLink( bool wrapAround);
555     /// selects previous link on page, if any. returns selected link range, null if no links.
556     virtual ldomXRange * selectPrevPageLink( bool wrapAround );
557     /// returns selected link on page, if any. null if no links.
558     virtual ldomXRange * getCurrentPageSelectedLink();
559     /// follow link, returns true if navigation was successful
560     virtual bool goLink( lString32 href, bool savePos=true );
561     /// follow selected link, returns true if navigation was successful
562     virtual bool goSelectedLink();
563     /// go back. returns true if navigation was successful
564     virtual bool goBack();
565     /// go forward. returns true if navigation was successful
566     virtual bool goForward();
567     /// check if navigation forward is possible
568     virtual bool canGoBack();
569     /// check if navigation back is possible
570     virtual bool canGoForward();
571 
572 
573     /// create empty document with specified message (e.g. to show errors)
574     virtual void createDefaultDocument( lString32 title, lString32 message );
575     /// create empty document with specified message (to show errors)
576     virtual void createHtmlDocument(lString32 code);
577 
578     /// returns default font face
getDefaultFontFace()579     lString8 getDefaultFontFace() { return m_defaultFontFace; }
580     /// set default font face
581     void setDefaultFontFace( const lString8 & newFace );
582     /// returns status bar font face
getStatusFontFace()583     lString8 getStatusFontFace() { return m_statusFontFace; }
584     /// set status bar font face
585     void setStatusFontFace( const lString8 & newFace );
586     /// invalidate formatted data, request render
587     void requestRender();
588     /// invalidate document data, request reload
589     void requestReload();
590     /// invalidate image cache, request redraw
591     void clearImageCache();
592 #if CR_ENABLE_PAGE_IMAGE_CACHE==1
593     /// get page image (0=current, -1=prev, 1=next)
594     LVDocImageRef getPageImage( int delta );
595     /// returns true if current page image is ready
596     bool IsDrawed();
597     /// cache page image (render in background if necessary) (0=current, -1=prev, 1=next)
598     void cachePageImage( int delta );
599 #endif
600     /// return view mutex
getMutex()601     LVMutex & getMutex() { return _mutex; }
602     /// update selection ranges
603     void updateSelections();
604     void updateBookMarksRanges();
605     /// get page document range, -1 for current page
606     LVRef<ldomXRange> getPageDocumentRange( int pageIndex=-1 );
607     /// get page text, -1 for current page
608     lString32 getPageText( bool wrapWords, int pageIndex=-1 );
609     /// returns number of non-space characters on current page
610     int getCurrentPageCharCount();
611     /// returns number of images on current page
612     int getCurrentPageImageCount();
613     /// returns number of images on given page
614     int getPageImageCount(LVRef<ldomXRange>& range);
615     /// calculate page header rectangle
616     virtual void getPageHeaderRectangle( int pageIndex, lvRect & headerRc );
617     /// calculate page header height
618     virtual int getPageHeaderHeight( );
619     /// set list of icons to display at left side of header
620     void setHeaderIcons( LVRefVec<LVImageSource> icons );
621     /// set list of battery icons to display battery state
622     void setBatteryIcons( const LVRefVec<LVImageSource> & icons );
623     /// sets page margins
624     void setPageMargins(lvRect rc);
625     /// update page margins based on current settings
626     void updatePageMargins();
627     /// returns page margins
getPageMargins()628     lvRect getPageMargins() const { return m_pageMargins; }
629 #if CR_INTERNAL_PAGE_ORIENTATION==1
630     /// sets rotate angle
631     void SetRotateAngle( cr_rotate_angle_t angle );
632 #endif
633     /// rotate rectangle by current angle, winToDoc==false for doc->window translation, true==ccw
634     lvRect rotateRect( lvRect & rc, bool winToDoc );
635     /// rotate point by current angle, winToDoc==false for doc->window translation, true==ccw
636     lvPoint rotatePoint( lvPoint & pt, bool winToDoc );
637 #if CR_INTERNAL_PAGE_ORIENTATION==1
638     /// returns rotate angle
GetRotateAngle()639     cr_rotate_angle_t GetRotateAngle() { return m_rotateAngle; }
640 #endif
641     /// returns true if document is opened
642     bool isDocumentOpened();
643     /// returns section bounds, in 1/100 of percent
644     LVArray<int> & getSectionBounds( bool for_external_update=false );
645     /// sets battery state
646     virtual bool setBatteryState( int newState );
647     /// returns battery state
getBatteryState()648     int getBatteryState( ) { return m_battery_state; }
649     /// returns current time representation string
650     virtual lString32 getTimeString();
651     /// returns true if time changed since clock has been last drawed
652     bool isTimeChanged();
653     /// returns if Render has been called
IsRendered()654     bool IsRendered() { return m_is_rendered; }
655     /// returns file list with positions/bookmarks
getHistory()656     CRFileHist * getHistory() { return &m_hist; }
657     /// returns formatted page list
getPageList()658     LVRendPageList * getPageList() { return &m_pages; }
659     /// returns pointer to TOC root node
660     LVTocItem * getToc();
661     /// returns pointer to TOC root node
662     bool getFlatToc( LVPtrVector<LVTocItem, false> & items );
663     /// update page numbers for items
664     void updatePageNumbers( LVTocItem * item );
665     /// returns pointer to LVPageMapItems container
666     LVPageMap * getPageMap();
667     /// update PageMap items page infos
668     void updatePageMapInfo( LVPageMap * pagemap );
669 
670     /// set view mode (pages/scroll) - DVM_SCROLL/DVM_PAGES
671     void setViewMode( LVDocViewMode view_mode, int visiblePageCount=-1 );
672     /// get view mode (pages/scroll)
673     LVDocViewMode getViewMode();
674     /// toggle pages/scroll view mode
675     void toggleViewMode();
676     /// returns current pages visible setting value (independent on window and font size)
677     int getPagesVisibleSetting();
678     /// get window visible page count (1 or 2)
679     int getVisiblePageCount();
680     /// set window visible page count (1 or 2)
681     void setVisiblePageCount( int n );
682     /// set window visible page count, to use exact value independent of font size and window sides
683     void overrideVisiblePageCount(int n);
684 
685     /// get page header position
getPageheaderPosition()686     int getPageheaderPosition() { return m_pageHeaderPos; }
687     /// set page header position
688     void setPageHeaderPosition( int pos );
689     /// get page header info mask
getPageHeaderInfo()690     int getPageHeaderInfo() { return m_pageHeaderInfo; }
691     /// set page header info mask
692     void setPageHeaderInfo( int hdrFlags );
693     /// get info line font
getInfoFont()694     font_ref_t getInfoFont() { return m_infoFont; }
695     /// set info line font
setInfoFont(font_ref_t font)696     void setInfoFont( font_ref_t font ) { m_infoFont = font; }
697     /// draw page header to buffer
698     virtual void drawPageHeader( LVDrawBuf * drawBuf, const lvRect & headerRc, int pageIndex, int headerInfoFlags, int pageCount );
699     /// draw battery state to buffer
700     virtual void drawBatteryState( LVDrawBuf * drawBuf, const lvRect & rc, bool isVertical );
701 
702     /// returns background color
getBackgroundColor()703     lUInt32 getBackgroundColor()
704     {
705         return m_backgroundColor;
706     }
707     /// sets background color
setBackgroundColor(lUInt32 cl)708     void setBackgroundColor( lUInt32 cl )
709     {
710         m_backgroundColor = cl;
711         clearImageCache();
712     }
713     /// returns text color
getTextColor()714     lUInt32 getTextColor()
715     {
716         return m_textColor;
717     }
718     /// sets text color
setTextColor(lUInt32 cl)719     void setTextColor( lUInt32 cl )
720     {
721         m_textColor = cl;
722         m_props->setColor(PROP_FONT_COLOR, cl);
723         clearImageCache();
724     }
725 
726     /// returns text color
getStatusColor()727     lUInt32 getStatusColor()
728     {
729         return m_statusColor;
730     }
731     /// sets text color
setStatusColor(lUInt32 cl)732     void setStatusColor( lUInt32 cl )
733     {
734         m_statusColor = cl;
735         clearImageCache();
736     }
737 
738     CRPageSkinRef getPageSkin();
739     void setPageSkin( CRPageSkinRef skin );
740 
741     /// returns xpointer for specified window point
742     ldomXPointer getNodeByPoint( lvPoint pt, bool strictBounds=false );
743     /// returns image source for specified window point, if point is inside image
744     LVImageSourceRef getImageByPoint(lvPoint pt);
745     /// draws scaled image into buffer, clear background according to current settings
746     bool drawImage(LVDrawBuf * buf, LVImageSourceRef img, int x, int y, int dx, int dy);
747     /// converts point from window to document coordinates, returns true if success
748     bool windowToDocPoint( lvPoint & pt );
749     /// converts point from document to window coordinates, returns true if success
750     bool docToWindowPoint( lvPoint & pt, bool isRectBottom=false, bool fitToPage=false );
751 
752     /// returns document
getDocument()753     ldomDocument * getDocument() {
754     	if (NULL == m_doc)
755     	    CRLog::error("attempt to return NULL pointer as document!");
756     	return m_doc;
757     }
758     /// return document properties
getDocProps()759     CRPropRef getDocProps() { return m_doc_props; }
760     /// returns book title
getTitle()761     lString32 getTitle() { return m_doc_props->getStringDef(DOC_PROP_TITLE); }
762     /// returns book language
getLanguage()763     lString32 getLanguage() { return m_doc_props->getStringDef(DOC_PROP_LANGUAGE); }
764     /// returns book author(s)
getAuthors()765     lString32 getAuthors() { return m_doc_props->getStringDef(DOC_PROP_AUTHORS); }
766     /// returns book description
getDescription()767     lString32 getDescription() { return m_doc_props->getStringDef(DOC_PROP_DESCRIPTION); }
768     /// returns book keywords (separated by "; ")
getKeywords()769     lString32 getKeywords() { return m_doc_props->getStringDef(DOC_PROP_KEYWORDS); }
770     /// returns book series name and number (series name #1)
getSeries()771     lString32 getSeries()
772     {
773         lString32 name = m_doc_props->getStringDef(DOC_PROP_SERIES_NAME);
774         lString32 number = m_doc_props->getStringDef(DOC_PROP_SERIES_NUMBER);
775         if ( !name.empty() && !number.empty() )
776             name << " #" << number;
777         return name;
778     }
779     /// returns book series name and number (series name #1)
getSeriesName()780     lString32 getSeriesName()
781     {
782         lString32 name = m_doc_props->getStringDef(DOC_PROP_SERIES_NAME);
783         return name;
784     }
785     /// returns book series name and number (series name #1)
getSeriesNumber()786     int getSeriesNumber()
787     {
788         lString32 name = m_doc_props->getStringDef(DOC_PROP_SERIES_NAME);
789         lString32 number = m_doc_props->getStringDef(DOC_PROP_SERIES_NUMBER);
790         if (!name.empty() && !number.empty())
791             return number.atoi();
792         return 0;
793     }
794     /// returns book content CRC32
getFileCRC32()795     lUInt32 getFileCRC32() {
796         return (lUInt32)m_doc_props->getIntDef(DOC_PROP_FILE_CRC32, 0);
797     }
798 
799     /// export to WOL format
800     bool exportWolFile( const char * fname, bool flgGray, int levels );
801     /// export to WOL format
802     bool exportWolFile( const lChar32 * fname, bool flgGray, int levels );
803     /// export to WOL format
804     bool exportWolFile( LVStream * stream, bool flgGray, int levels );
805 
806     /// get a stream for reading to document internal file (path inside the ZIP for EPUBs,
807     /// path relative to document directory for non-container documents like HTML)
808     LVStreamRef getDocumentFileStream( lString32 filePath );
809 
810     /// draws page to image buffer
811     void drawPageTo( LVDrawBuf * drawBuf, LVRendPageInfo & page, lvRect * pageRect, int pageCount, int basePage);
812     /// draws coverpage to image buffer
813     void drawCoverTo( LVDrawBuf * drawBuf, lvRect & rc );
814     /// returns cover page image source, if any
815     LVImageSourceRef getCoverPageImage();
816     /// returns cover page image stream, if any
817     LVStreamRef getCoverPageImageStream();
818 
819     /// returns bookmark
820     ldomXPointer getBookmark( bool precise = true );
821     /// returns bookmark for specified page
822     ldomXPointer getPageBookmark( int page );
823     /// sets current bookmark
824     void setBookmark( ldomXPointer bm );
825     /// moves position to bookmark
826     void goToBookmark( ldomXPointer bm );
827     /// get page number by bookmark
828     int getBookmarkPage(ldomXPointer bm);
829     /// get bookmark position text
830     bool getBookmarkPosText( ldomXPointer bm, lString32 & titleText, lString32 & posText );
831 
832     /// returns scrollbar control info
getScrollInfo()833     const LVScrollInfo * getScrollInfo() { updateScroll(); return &m_scrollinfo; }
834     /// move to position specified by scrollbar
835     bool goToScrollPos( int pos );
836     /// converts scrollbar pos to doc pos
837     int scrollPosToDocPos( int scrollpos );
838     /// returns position in 1/100 of percents (0..10000)
839     int getPosPercent();
840     /// returns position in 1/100 of percents (0..10000)
841     int getPosEndPagePercent();
842 
843     /// execute command
844     int doCommand( LVDocCmd cmd, int param=0 );
845 
846     /// set document stylesheet text
847     void setStyleSheet( lString8 css_text );
848 
849     /// set default interline space, percent (100..200)
850     void setDefaultInterlineSpace( int percent );
851 
852     /// change font size, if rollCyclic is true, largest font is followed by smallest and vice versa
853     void ZoomFont( int delta );
854     /// retrieves current base font size
getFontSize()855     int  getFontSize() { return m_font_size; }
856     /// retrieves requested font size (before scaling for DPI)
getRequestedFontSize()857     int  getRequestedFontSize() { return m_requested_font_size; }
858     /// scale font size according to gRenderDPI
859     int scaleFontSizeForDPI( int fontSize );
860     /// sets new base font size
861     void setFontSize( int newSize );
862     /// retrieves current status bar font size
getStatusFontSize()863     int  getStatusFontSize() { return m_status_font_size; }
864     /// sets new status bar font size
865     void setStatusFontSize( int newSize );
866 
867 #if USE_LIMITED_FONT_SIZES_SET
868     /// sets posible base font sizes (for ZoomFont)
869     void setFontSizes( LVArray<int> & sizes, bool cyclic );
870 #else
871     void setMinFontSize( int size );
872     void setMaxFontSize( int size );
873 #endif
874 
875     /// get drawing buffer
876     //LVDrawBuf * GetDrawBuf() { return &m_drawbuf; }
877     /// draw document into buffer
878     //void Draw();
879 
880     /// resize view
881     void Resize( int dx, int dy );
882     /// get view height
883     int GetHeight();
884     /// get view width
885     int GetWidth();
886 
887     /// get full document height
888     int GetFullHeight();
889 
890     /// get vertical position of view inside document
891     int GetPos();
892     /// get position of view inside document
893     void GetPos( lvRect & rc );
894     /// set vertical position of view inside document
895     int SetPos( int pos, bool savePos=true, bool allowScrollAfterEnd = false);
896 
897     // get page start y (in full document height)
898     int getPageStartY(int pageIndex);
899     // get page height
900     int getPageHeight(int pageIndex);
901 
902     /// get number of current page
903     int getCurPage();
904     /// move to specified page
905     bool goToPage(int page, bool updatePosBookmark = true, bool regulateTwoPages = true);
906     /// returns page count
907     int getPageCount();
908     /// get the flow the specified page belongs to
909     int getPageFlow(int pageIndex);
910     /// returns whether there are any flows besides the linear flow 0
911     bool hasNonLinearFlows();
912 
913     /// clear view
914     void Clear();
915     /// load document from file
916     bool LoadDocument( const char * fname, bool metadataOnly = false );
917     /// load document from file
918     bool LoadDocument( const lChar32 * fname, bool metadataOnly = false );
919     /// load document from stream
920     bool LoadDocument( LVStreamRef stream, const lChar32 * contentPath, bool metadataOnly = false );
921 
922     /// save last file position
923     void savePosition();
924     /// restore last file position
925     void restorePosition();
926 
927 #ifdef ORIGINAL_FILENAME_PATCH
setOriginalFilename(const lString32 & fn)928     void setOriginalFilename( const lString32 & fn ) {
929         m_originalFilename = fn;
930     }
getOriginalFilename()931     const lString32 & getOriginalFilename() {
932         return m_originalFilename;
933     }
setMinFileSizeToCache(int size)934     void setMinFileSizeToCache( int size ) {
935         m_props->setInt(PROP_MIN_FILE_SIZE_TO_CACHE, size);
936     }
937 #endif
938 
939     /// render (format) document
940     void Render( int dx=0, int dy=0, LVRendPageList * pages=NULL );
941     /// set properties before rendering
942     void setRenderProps( int dx, int dy );
943 
944     /// Constructor
945     LVDocView( int bitsPerPixel=-1, bool noDefaultDocument=false );
946     /// Destructor
947     virtual ~LVDocView();
948 };
949 
950 class SimpleTitleFormatter {
951     lString32 _text;
952     lString32Collection _lines;
953     lString8 _fontFace;
954     bool _bold;
955     bool _italic;
956     lUInt32 _color;
957     LVFontRef _font;
958     int _lineHeight;
959     int _height;
960     int _width;
961     int _maxWidth;
962     int _maxHeight;
963     int _fntSize;
964 public:
getHeight()965     int getHeight() { return _height; }
getWidth()966     int getWidth() { return _width; }
967     SimpleTitleFormatter(lString32 text, lString8 fontFace, bool bold, bool italic, lUInt32 color, int maxWidth, int maxHeight, int fntSize = 0);
968 
969     bool measure();
970     bool splitLines(const char * delimiter);
971     bool format(int fontSize);
972     bool findBestSize();
973     void draw(LVDrawBuf & buf, lString32 str, int x, int y, int align);
974     void draw(LVDrawBuf & buf, lvRect rc, int halign, int valign);
975 };
976 
977 
978 /// draw book cover, either from image, or generated from title/authors
979 void LVDrawBookCover(LVDrawBuf & buf, LVImageSourceRef image, lString8 fontFace, lString32 title, lString32 authors, lString32 seriesName, int seriesNumber);
980 
981 #endif
982