text::TextView Class Reference

#include <text_view.h>

Collaboration diagram for text::TextView:
Collaboration graph
[legend]

Public Member Functions

 TextView (TextModel *m)
 Constructors and destructors.
 ~TextView ()
void initialize ()
 Initialize pango related stuff.
void deinitialize ()
 Release pango related stuff.
void set_controller (TextController *c)
TextControllerget_controller ()
bool paginate (const Position &start_pos)
 Pagination.
void clear_pages ()
 Reset the page table.
Position render (unsigned char *bmp, const Position &start_pos)
 Render a page start with start_pos.
const TextModelget_model () const
int get_font_size () const
 Get font size.
bool set_font_size (int font_size)
 Set font size.
const std::string & get_font_family () const
 Get font family.
void set_font_family (const std::string &font_family)
 Set font family.
void get_display_size (int &width, int &height)
 Get output display size.
void set_display_size (unsigned int width, unsigned int height)
 Set output display size.
unsigned int get_DPI ()
 Get dpi settings.
void set_DPI (unsigned int dpi)
 Set dpi.
unsigned int get_color_depth ()
 Get color depth.
void set_color_depth (unsigned int color_depth)
 Set color depth.
int get_page_count ()
void check_page_table (const Position &rendering_pos)
 Check if re-pagination is needed given by anchor to be rendered.
bool get_anchor_by_page (unsigned int page_index, Position &pos)
 Get start anchor of specified page.
unsigned int get_page_index_by_anchor (const Position &anchor)
 Get page index given by anchor.
Position get_page_anchor_by_anchor (const Position &anchor)
 Get the start anchor of page which contains the specified anchor.
unsigned int get_current_page_index ()
 Get current page index.
bool map_doc_pos_to_view_pos (const Position &page_anchor, const Position &doc_pos, ViewPosition &view_pos, bool trailing)
 Find view position given by document position (anchor).
bool map_view_pos_to_doc_pos (const Position &page_anchor, const ViewPosition &view_pos, Position &doc_pos)
 Find doc position (anchor) given by view position.
bool get_bounding_rectangles (const Position &page_anchor, std::vector< Rect > &bounding_rect, const Range &range)
 Get bounding rectangels given by range.
bool calculate_next_page_pos (const Position &in_pos, Position &out_pos)
 Calculate start position of next page.
bool calculate_prev_page_pos (const Position &in_pos, Position &out_pos)
 Calculate start position of previous page.
bool need_repagination ()
 Check if repagination is needed.

Data Fields

utils::Signal< unsigned int > pagination_start_signal
 signals.
utils::Signal< unsigned int,
unsigned int > 
pagination_end_signal
utils::Signal< unsigned int,
const Position &, const
Position &, void * > 
render_done_signal

Detailed Description

Definition at line 49 of file text_view.h.


Constructor & Destructor Documentation

text::TextView::TextView ( TextModel m  ) 

Constructors and destructors.

Definition at line 39 of file text_view.cpp.

References DEFAULT_CHINESE_FONT, text::TextModel::get_encoding(), and initialize().

00040 : model(m),
00041   ctrl(0),
00042   font_family(DEFAULT_ASCII_FONT),
00043   font_size(DEFAULT_FONT_SIZE),
00044   display_width(DEFAULT_SURFACE_WIDTH),
00045   display_height(DEFAULT_SURFACE_HEIGHT),
00046   dpi(DEFAULT_DPI),
00047   color_depth(DEFAULT_COLOR_DEPTH),
00048   line_height(0),
00049   lines_per_page(0),
00050   left_margin(DEFAULT_LEFT_MARGIN),
00051   right_margin(DEFAULT_RIGHT_MARGIN),
00052   top_margin(DEFAULT_TOP_MARGIN),
00053   bottom_margin(DEFAULT_BOTTOM_MARGIN),
00054   client_width(display_width - left_margin - right_margin),
00055   client_height(display_height - top_margin - bottom_margin),
00056   pango_context(0),
00057   pango_mutex(0),
00058   font_hash_code(0),
00059   is_repagination_needed(false),
00060   blank_lines(0)
00061 {
00062     // Special handling for Chinese font.
00063     const char *enc = model->get_encoding().c_str();
00064 #ifdef WIN32
00065     if (_stricmp(enc, "GB2312") == 0 || _stricmp(enc, "GBK") == 0)
00066 #else
00067     if (strcasecmp(enc, "GB2312") == 0 || strcasecmp(enc, "GBK") == 0)
00068 #endif
00069     {
00070         font_family = DEFAULT_CHINESE_FONT;
00071     }
00072     initialize();
00073 }

Here is the call graph for this function:

text::TextView::~TextView (  ) 

Definition at line 75 of file text_view.cpp.

References deinitialize().

00076 {
00077     deinitialize();
00078 }

Here is the call graph for this function:


Member Function Documentation

bool text::TextView::calculate_next_page_pos ( const Position in_pos,
Position out_pos 
)

Calculate start position of next page.

Parameters:
in_pos start position of current page
out_pos start position of next page
Returns:
If no next page, false is returned, otherwise return true.

Check if we can get next page anchor from page table.

Definition at line 341 of file text_view.cpp.

References text::TextModel::get_paragraph(), text::TextModel::get_paragraph_count(), text::Position::offset, text::Position::paragraph, and text::SafeDeque< T >::size().

Referenced by paginate().

00342 {
00343     /// Check if we can get next page anchor from page table.
00344     size_t page_count = pages.size();
00345     for (unsigned int i=0; i<page_count; i++)
00346     {
00347         if (pages[i].start == in_pos)
00348         {
00349             out_pos = pages[i].end;
00350             return out_pos != Position(0, 0);
00351         }
00352     }
00353 
00354     unsigned int start_paragraph = in_pos.paragraph;
00355     unsigned int start_offset    = in_pos.offset;
00356     unsigned int total_lines = 0;
00357 
00358     g_mutex_lock(pango_mutex);
00359     PangoLayout *layout = NULL;
00360     while (total_lines < lines_per_page)
00361     {
00362         if (start_paragraph >= model->get_paragraph_count())
00363         {
00364             break;
00365         }
00366 
00367         if (layout != NULL)
00368         {
00369             g_object_unref(layout);
00370             layout = NULL;
00371         }
00372         const std::string *str = model->get_paragraph(start_paragraph);
00373         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00374 
00375         int line_count = pango_layout_get_line_count(layout);
00376         int line_offset = 0;
00377         if (start_offset != 0)
00378         {
00379             // We are calculating from the second half part of a paragraph
00380             int x_pos;
00381             pango_layout_index_to_line_x(layout, start_offset, FALSE, &line_offset, &x_pos);
00382             line_count -= line_offset;
00383         }
00384 
00385         if (total_lines + line_count < lines_per_page)
00386         {
00387             // We have enough space to load more paragraphs for current page
00388             total_lines += line_count;
00389             start_paragraph++;
00390             start_offset = 0;
00391         }
00392         else if (total_lines + line_count == lines_per_page)
00393         {
00394             if (++start_paragraph < model->get_paragraph_count())
00395             {
00396                 out_pos.paragraph = start_paragraph;
00397                 out_pos.offset = 0;
00398             }
00399             break;
00400         }
00401         else
00402         {
00403             // The remained space is not enough for current paragraph
00404             PangoLayoutIter *iter = pango_layout_get_iter(layout);
00405             for (unsigned int i=0; i<lines_per_page-total_lines+line_offset; i++)
00406             {
00407                 pango_layout_iter_next_line(iter);
00408             }
00409 
00410             out_pos.offset = pango_layout_iter_get_index(iter);
00411             out_pos.paragraph = start_paragraph;
00412             pango_layout_iter_free(iter);
00413             break;
00414         }
00415     }
00416 
00417     if (layout != NULL)
00418     {
00419         g_object_unref(layout);
00420         layout = NULL;
00421     }
00422     g_mutex_unlock(pango_mutex);
00423     return (start_paragraph < model->get_paragraph_count());
00424 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool text::TextView::calculate_prev_page_pos ( const Position in_pos,
Position out_pos 
)

Calculate start position of previous page.

Parameters:
in_pos start position of current page
out_pos start position of previous page
Returns:
If no previous page, false is returned, otherwise return true.

Definition at line 245 of file text_view.cpp.

References text::TextModel::get_paragraph(), text::Position::offset, text::Position::paragraph, and text::SafeDeque< T >::size().

Referenced by paginate().

00246 {
00247     // Check if we are already the first page.
00248     if (in_pos == Position(0, 0))
00249     {
00250         return false;
00251     }
00252 
00253     // Check if we can get next page anchor from page table.
00254     size_t page_count = pages.size();
00255     for (unsigned int i=0; i<page_count; i++)
00256     {
00257         if (pages[i].end == in_pos)
00258         {
00259             out_pos = pages[i].start;
00260             return true;
00261         }
00262     }
00263 
00264     g_mutex_lock(pango_mutex);
00265     unsigned int start_paragraph = in_pos.paragraph;
00266     unsigned int start_offset    = in_pos.offset;
00267     PangoLayout *layout = NULL;
00268     if (start_offset == 0)
00269     {
00270         start_paragraph--;
00271     }
00272 
00273     unsigned int total_lines = 0;
00274     while (total_lines < lines_per_page)
00275     {
00276         if (static_cast<int>(start_paragraph) < 0)
00277         {
00278             if (in_pos > Position(0, 0))
00279             {
00280                 blank_lines = lines_per_page - total_lines;
00281             }
00282             break;
00283         }
00284 
00285         if (layout != NULL)
00286         {
00287             g_object_unref(layout);
00288             layout = NULL;
00289         }
00290         const std::string *str = model->get_paragraph(start_paragraph);
00291         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00292 
00293         int line_count = pango_layout_get_line_count(layout);
00294         if (start_offset != 0)
00295         {
00296             // We are calculating from the second half part of a paragraph
00297             int line_offset, x_pos;
00298             pango_layout_index_to_line_x(layout, start_offset, FALSE, &line_offset, &x_pos);
00299             line_count = line_offset;
00300         }
00301 
00302         if (total_lines + line_count < lines_per_page)
00303         {
00304             // We have enough space to load more paragraphs for current page
00305             total_lines += line_count;
00306             start_paragraph--;
00307             start_offset = 0;
00308         }
00309         else if (total_lines + line_count == lines_per_page)
00310         {
00311             out_pos.paragraph = start_paragraph;
00312             out_pos.offset = 0;
00313             break;
00314         }
00315         else
00316         {
00317             // The remained space is not enough for current paragraph
00318             PangoLayoutIter *iter = pango_layout_get_iter(layout);
00319             unsigned int line_index = line_count - (lines_per_page - total_lines);
00320             for (unsigned int i=0; i<line_index; i++)
00321             {
00322                 pango_layout_iter_next_line(iter);
00323             }
00324 
00325             out_pos.paragraph = start_paragraph;
00326             out_pos.offset = pango_layout_iter_get_index(iter);
00327             pango_layout_iter_free(iter);
00328             break;
00329         }
00330     }
00331 
00332     if (layout != NULL)
00333     {
00334         g_object_unref(layout);
00335         layout = NULL;
00336     }
00337     g_mutex_unlock(pango_mutex);
00338     return (static_cast<int>(start_paragraph) >= 0);
00339 }

Here is the call graph for this function:

Here is the caller graph for this function:

void text::TextView::check_page_table ( const Position rendering_pos  ) 

Check if re-pagination is needed given by anchor to be rendered.

Definition at line 426 of file text_view.cpp.

References text::SafeDeque< T >::size().

Referenced by text::TextController::render(), and text::TextController::restart_pagination().

00427 {
00428     size_t page_count = pages.size();
00429     for (unsigned int i=0; i<page_count; i++)
00430     {
00431         if (pages[i].start == rendering_pos)
00432         {
00433             return;
00434         }
00435     }
00436 
00437     // Can't find page boundaries for specified anchor.
00438     // Re-pagination is needed.
00439     is_repagination_needed = true;
00440 }

Here is the call graph for this function:

Here is the caller graph for this function:

void text::TextView::clear_pages (  )  [inline]

Reset the page table.

Definition at line 80 of file text_view.h.

References text::SafeDeque< T >::clear().

00083     {

Here is the call graph for this function:

void text::TextView::deinitialize (  ) 

Release pango related stuff.

Definition at line 91 of file text_view.cpp.

Referenced by text::DeinitializationTask::execute(), and ~TextView().

00092 {
00093     // Release pango stuff
00094     pango_context_final();
00095     g_mutex_free(pango_mutex);
00096 }

Here is the caller graph for this function:

bool text::TextView::get_anchor_by_page ( unsigned int  page_index,
Position pos 
)

Get start anchor of specified page.

Definition at line 181 of file text_view.cpp.

References text::SafeDeque< T >::size().

Referenced by text::TextController::render().

00182 {
00183     if (pages.size() == 0)
00184     {
00185         // Pagination hasn't been started yet.
00186         if (page_index == 0)
00187         {
00188             // We can render page 0 despite pagination is not ready.
00189             pos = Position(0, 0);
00190             return true;
00191         }
00192         else
00193         {
00194             return false;
00195         }
00196     }
00197     else
00198     {
00199         // Pagination starts, but maybe partial is successful.
00200         if (page_index >= pages.size())
00201         {
00202             return false;
00203         }
00204         else
00205         {
00206             pos = pages[page_index].start;
00207             return true;
00208         }
00209     }
00210 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool text::TextView::get_bounding_rectangles ( const Position page_anchor,
std::vector< Rect > &  bounding_rect,
const Range range 
)

Get bounding rectangels given by range.

Definition at line 863 of file text_view.cpp.

References DEFAULT_LINE_SPACING, text::Range::end, map_doc_pos_to_view_pos(), text::Range::start, text::ViewPosition::x, and text::ViewPosition::y.

Referenced by text::PluginViewImpl::get_bounding_rectangles_from_range_impl(), and main().

00866 {
00867     // A flag indicating that the start position and end position of specified
00868     // range is in different pages.
00869     bool span_pages = false;
00870     ViewPosition view_pos_start, view_pos_end;
00871       
00872     if (!map_doc_pos_to_view_pos(page_anchor, range.start, view_pos_start, false))
00873     {
00874         // The range's start position is not inside the page which starts with
00875         // page_anchor.
00876         return false;
00877     }
00878 
00879     if (!map_doc_pos_to_view_pos(page_anchor, range.end, view_pos_end, true))
00880     {
00881         // The range's end position is not inside the page which starts with
00882         // page_anchor.
00883         span_pages = true;
00884     }
00885 
00886     unsigned int line_height_with_spacing = line_height + DEFAULT_LINE_SPACING;
00887 
00888     // Check if thhe start position and end position are in the same line.
00889     if (view_pos_start.y == view_pos_end.y)
00890     {
00891         // The start position and end position are in the same line.
00892         bounding_rect.push_back(Rect(view_pos_start.x,
00893                                      view_pos_start.y + DEFAULT_LINE_SPACING,
00894                                      view_pos_end.x - view_pos_start.x,
00895                                      line_height));
00896     }
00897     else
00898     {
00899         // More lines.
00900         bounding_rect.push_back(Rect(view_pos_start.x,
00901                                      view_pos_start.y + DEFAULT_LINE_SPACING,
00902                                      display_width - view_pos_start.x - right_margin,
00903                                      line_height));
00904 
00905         for (unsigned int y_offset = view_pos_start.y+line_height_with_spacing;
00906              static_cast<int>(y_offset) < view_pos_end.y &&
00907              y_offset < top_margin + line_height_with_spacing * lines_per_page;
00908              y_offset += line_height_with_spacing)
00909         {
00910             bounding_rect.push_back(Rect(left_margin,
00911                                          y_offset + DEFAULT_LINE_SPACING,
00912                                          client_width,
00913                                          line_height));
00914         }
00915 
00916         if (!span_pages)
00917         {
00918             bounding_rect.push_back(Rect(left_margin,
00919                                          view_pos_end.y + DEFAULT_LINE_SPACING,
00920                                          view_pos_end.x - left_margin,
00921                                          line_height));
00922         }
00923     }
00924 
00925     return true;
00926 }

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned int text::TextView::get_color_depth (  )  [inline]

Get color depth.

Definition at line 138 of file text_view.h.

00141     {

TextController* text::TextView::get_controller (  )  [inline]

Definition at line 68 of file text_view.h.

00071     {

unsigned int text::TextView::get_current_page_index (  ) 

Get current page index.

Returns:
The index of page which has just been rendered. return 1 if page table is not ready.

Definition at line 484 of file text_view.cpp.

References get_page_index_by_anchor().

Referenced by text::PaginationTask::execute(), and text::TextController::pause_pagination().

00485 {
00486     return get_page_index_by_anchor(rendering_pos);
00487 }

Here is the call graph for this function:

Here is the caller graph for this function:

void text::TextView::get_display_size ( int &  width,
int &  height 
) [inline]

Get output display size.

Definition at line 116 of file text_view.h.

00119     {
00120         width  = display_width;

unsigned int text::TextView::get_DPI (  )  [inline]

Get dpi settings.

Definition at line 126 of file text_view.h.

00129     {

const std::string& text::TextView::get_font_family (  )  const [inline]

Get font family.

Definition at line 104 of file text_view.h.

00107     {

int text::TextView::get_font_size (  )  const [inline]

Get font size.

Definition at line 95 of file text_view.h.

Referenced by widget_event_handler().

00098     {

Here is the caller graph for this function:

const TextModel* text::TextView::get_model (  )  const [inline]

Definition at line 89 of file text_view.h.

Referenced by widget_event_handler().

00092     {

Here is the caller graph for this function:

Position text::TextView::get_page_anchor_by_anchor ( const Position anchor  ) 

Get the start anchor of page which contains the specified anchor.

Check if we can get next page anchor from page table.

Definition at line 464 of file text_view.cpp.

References text::Position::paragraph, and text::SafeDeque< T >::size().

00465 {
00466     /// Check if we can get next page anchor from page table.
00467     size_t page_count = pages.size();
00468     for (unsigned int i=0; i<page_count; i++)
00469     {
00470         if (pages[i].end > anchor && pages[i].start <= anchor)
00471         {
00472             return pages[i].start;
00473         }
00474     }
00475 
00476     if (page_count>0 && pages[page_count-1].end == Position(0, 0))
00477     {
00478         return pages[page_count-1].start;
00479     }
00480 
00481     return Position(anchor.paragraph, 0);
00482 }

Here is the call graph for this function:

int text::TextView::get_page_count (  )  [inline]

Definition at line 149 of file text_view.h.

Referenced by text::PaginationTask::execute(), main(), text::TextController::pause_pagination(), and widget_event_handler().

00152     {
00153         if (!pages.empty() && pages.back().end == Position(0, 0))
00154         {
00155             return static_cast<int>(pages.size());
00156         }

Here is the caller graph for this function:

unsigned int text::TextView::get_page_index_by_anchor ( const Position anchor  ) 

Get page index given by anchor.

Returns:
The page index of the specified anchor. return 0 if page table is not ready.

Check if we can get next page anchor from page table.

Definition at line 442 of file text_view.cpp.

References text::SafeDeque< T >::size().

Referenced by get_current_page_index().

00443 {
00444     /// Check if we can get next page anchor from page table.
00445     size_t page_count = pages.size();
00446 
00447     // Always return 0 if pagination is not complete.
00448     if (page_count == 0 || pages[page_count-1].end != Position(0, 0))
00449     {
00450         return 0;
00451     }
00452 
00453     for (unsigned int i=0; i<page_count; i++)
00454     {
00455         if (pages[i].end > anchor && pages[i].start <= anchor)
00456         {
00457             return i;
00458         }
00459     }
00460 
00461     return static_cast<unsigned int>(page_count-1);
00462 }

Here is the call graph for this function:

Here is the caller graph for this function:

void text::TextView::initialize (  ) 

Initialize pango related stuff.

Definition at line 80 of file text_view.cpp.

Referenced by text::InitializationTask::execute(), main(), and TextView().

00081 {
00082     // Create mutex for synchronous access to pango stuff.
00083     pango_mutex = g_mutex_new();
00084 
00085     // Initialize pango context.
00086     pango_context_init();
00087 
00088     calculate_lines_per_page();
00089 }

Here is the caller graph for this function:

bool text::TextView::map_doc_pos_to_view_pos ( const Position page_anchor,
const Position doc_pos,
ViewPosition view_pos,
bool  trailing 
)

Find view position given by document position (anchor).

Parameters:
page_anchor Start anchor of current page.
doc_pos Input anchor.
view_pos Output view position (x,y).
Returns:
True if successfully mapped, otherwise false is returned.

Definition at line 687 of file text_view.cpp.

References DEFAULT_LINE_SPACING, text::TextModel::get_paragraph(), text::Position::offset, text::Position::paragraph, text::ViewPosition::x, and text::ViewPosition::y.

Referenced by get_bounding_rectangles().

00691 {
00692     if (doc_pos < page_anchor)
00693     {
00694         return false;
00695     }
00696 
00697     unsigned int line_height_with_spacing = line_height + DEFAULT_LINE_SPACING;
00698 
00699     // Calculate the line offset and x offset inside layout corresponding to doc pos.
00700     const std::string *str = model->get_paragraph(doc_pos.paragraph);
00701     PangoLayout *layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00702 
00703     int line_offset_pos, x_offset_pos;
00704     pango_layout_index_to_line_x(layout, doc_pos.offset, trailing, &line_offset_pos, &x_offset_pos);
00705 
00706     unsigned int total_lines = 0;
00707     unsigned int start_paragraph = page_anchor.paragraph;
00708     unsigned int start_offset    = page_anchor.offset;
00709     if (start_paragraph == 0 && start_offset == 0)
00710     {
00711         total_lines += blank_lines;
00712     }
00713 
00714     if (start_offset != 0)
00715     {
00716         // The page does not start with a new paragraph.
00717         if (layout != NULL)
00718         {
00719             g_object_unref(layout);
00720             layout = NULL;
00721         }
00722         const std::string *str = model->get_paragraph(start_paragraph);
00723         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00724 
00725         int line_offset_start, x_pos;
00726         pango_layout_index_to_line_x(layout, start_offset, FALSE, &line_offset_start, &x_pos);
00727 
00728         if (doc_pos.paragraph == start_paragraph)
00729         {
00730             total_lines = line_offset_pos - line_offset_start;
00731             goto MapEnd;
00732         }
00733         else
00734         {
00735             total_lines = pango_layout_get_line_count(layout) - line_offset_start;
00736             start_paragraph++;
00737         }
00738     }
00739 
00740     for (; start_paragraph != doc_pos.paragraph; start_paragraph++)
00741     {
00742         if (layout != NULL)
00743         {
00744             g_object_unref(layout);
00745             layout = NULL;
00746         }
00747         const std::string *str = model->get_paragraph(start_paragraph);
00748         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00749 
00750         total_lines += pango_layout_get_line_count(layout);
00751     }
00752 
00753     total_lines += line_offset_pos;
00754 
00755 MapEnd:
00756     if (layout != NULL)
00757     {
00758         g_object_unref(layout);
00759         layout = NULL;
00760     }
00761     if (total_lines < lines_per_page)
00762     {
00763         view_pos.x = PANGO_PIXELS(x_offset_pos) + left_margin;
00764         view_pos.y = top_margin + line_height_with_spacing * total_lines;
00765         return true;
00766     }
00767     else
00768     {
00769         return false;
00770     }
00771 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool text::TextView::map_view_pos_to_doc_pos ( const Position page_anchor,
const ViewPosition view_pos,
Position doc_pos 
)

Find doc position (anchor) given by view position.

Parameters:
page_anchor Start anchor of current page.
view_pos Input view position.
doc_pos Output anchor.
Returns:
True if successfully mapped, otherwise false is returned.

Definition at line 773 of file text_view.cpp.

References DEFAULT_LINE_SPACING, text::TextModel::get_paragraph(), text::TextModel::get_paragraph_count(), text::Position::offset, text::Position::paragraph, text::ViewPosition::x, and text::ViewPosition::y.

Referenced by text::PluginViewImpl::get_anchor_from_coordinates_impl(), and widget_event_handler().

00776 {
00777     int x_offset_pos = view_pos.x - left_margin;
00778     int y_offset_pos = view_pos.y - top_margin;
00779 
00780     unsigned int start_paragraph = page_anchor.paragraph;
00781     unsigned int start_offset    = page_anchor.offset;
00782     unsigned int line_height_with_spacing = line_height + DEFAULT_LINE_SPACING;
00783 
00784     if (start_paragraph == 0 && start_offset == 0)
00785     {
00786         y_offset_pos -= blank_lines * line_height_with_spacing;
00787     }
00788 
00789     PangoLayout *layout = NULL;
00790     bool found = false;
00791 
00792     if (start_offset != 0)
00793     {
00794         const std::string *str = model->get_paragraph(start_paragraph);
00795         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00796 
00797         int line_offset_start, x_pos;
00798         pango_layout_index_to_line_x(layout, start_offset, FALSE, &line_offset_start, &x_pos);
00799 
00800         int lines_left = pango_layout_get_line_count(layout) - line_offset_start;
00801         if (static_cast<int>(lines_left * line_height_with_spacing) > y_offset_pos)
00802         {
00803             // The corresponding doc pos is inside this paragraph.
00804             doc_pos.paragraph = start_paragraph;
00805 
00806             // Calculate offset.
00807             int bytes_index, trailing;
00808             pango_layout_xy_to_index(layout, 
00809                                      x_offset_pos * PANGO_SCALE,
00810                                      (line_offset_start*line_height_with_spacing+y_offset_pos) * PANGO_SCALE,
00811                                      &bytes_index, &trailing);
00812             doc_pos.offset = bytes_index;
00813             found = true;
00814             goto MapEnd;
00815         }
00816         else
00817         {
00818             y_offset_pos -= lines_left * line_height_with_spacing;
00819             start_paragraph++;
00820         }
00821     }
00822 
00823     for (; start_paragraph < model->get_paragraph_count(); start_paragraph++)
00824     {
00825         if (layout != NULL)
00826         {
00827             g_object_unref(layout);
00828             layout = NULL;
00829         }
00830         const std::string *str = model->get_paragraph(start_paragraph);
00831         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00832 
00833         int line_count = pango_layout_get_line_count(layout);
00834         if (static_cast<int>(line_count * line_height_with_spacing) > y_offset_pos)
00835         {
00836             break;
00837         }
00838         else
00839         {
00840             y_offset_pos -= line_count * line_height_with_spacing;
00841         }
00842     }
00843 
00844     if (start_paragraph == model->get_paragraph_count())
00845     {
00846         goto MapEnd;
00847     }
00848 
00849     int bytes_index, trailing;
00850     pango_layout_xy_to_index(layout, x_offset_pos * PANGO_SCALE, y_offset_pos * PANGO_SCALE, &bytes_index, &trailing);
00851     doc_pos.paragraph = start_paragraph;
00852     doc_pos.offset    = bytes_index;
00853     found = true;
00854 
00855 MapEnd:
00856     if (layout)
00857     {
00858         g_object_unref(layout);
00859     }
00860     return found;
00861 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool text::TextView::need_repagination (  )  [inline]

Check if repagination is needed.

Definition at line 214 of file text_view.h.

00217     {

bool text::TextView::paginate ( const Position start_pos  ) 

Pagination.

Parameters:
start_pos If page table is empty, then this parameter tells the view from which position the pagination starts.
Returns:
True if pagination is complete. else false is returned.

Definition at line 139 of file text_view.cpp.

References text::SafeDeque< T >::back(), calculate_next_page_pos(), calculate_prev_page_pos(), text::Range::end, text::SafeDeque< T >::front(), text::SafeDeque< T >::push_back(), text::SafeDeque< T >::push_front(), text::SafeDeque< T >::size(), and text::Range::start.

Referenced by text::PaginationTask::execute(), and main().

00140 {
00141 
00142     Position in_pos(0, 0);
00143     Position out_pos;
00144     bool forward = true;
00145     
00146     size_t page_count = pages.size();
00147     if (page_count == 0)
00148     {
00149         in_pos = start_pos;
00150     }
00151     else if (pages.back().end != Position(0, 0))
00152     {
00153         // The forward pagination is not finished yet.
00154         in_pos = pages.back().end;
00155     }
00156     else if (pages.front().start != Position(0, 0))
00157     {
00158         // The backward pagination is not finished yet.
00159         in_pos = pages.front().start;
00160         forward = false;
00161     }
00162     else
00163     {
00164         // The pagination is complete.
00165         return true;
00166     }
00167 
00168     if (forward)
00169     {
00170         calculate_next_page_pos(in_pos, out_pos);
00171         pages.push_back(PageInfo(in_pos, out_pos));
00172     }
00173     else
00174     {
00175         calculate_prev_page_pos(in_pos, out_pos);
00176         pages.push_front(PageInfo(out_pos, in_pos));
00177     }
00178     return false;
00179 }

Here is the call graph for this function:

Here is the caller graph for this function:

Position text::TextView::render ( unsigned char *  bmp,
const Position start_pos 
)

Render a page start with start_pos.

Returns:
The position where render ends.

Definition at line 489 of file text_view.cpp.

References text::SafeDeque< T >::clear(), DEFAULT_LINE_SPACING, text::TextModel::get_paragraph(), text::Position::offset, text::TextController::paginate(), text::Position::paragraph, and render_single_line().

Referenced by text::RenderTask::execute(), main(), and widget_event_handler().

00490 {
00491     if (is_repagination_needed)
00492     {
00493         pages.clear();
00494         blank_lines = 0;
00495         ctrl->paginate(start_pos, true /* Send start notification */);
00496         is_repagination_needed = false;
00497     }
00498 
00499     g_mutex_lock(pango_mutex);
00500     unsigned int start_paragraph = start_pos.paragraph;
00501     unsigned int start_offset    = start_pos.offset;
00502     PangoLayout *layout = NULL;
00503 
00504     rendering_pos = start_pos;
00505 
00506     unsigned int total_lines = 0;
00507     if (start_pos == Position(0, 0))
00508     {
00509         total_lines = blank_lines;
00510     }
00511     int y_offset = (line_height + DEFAULT_LINE_SPACING)*total_lines*PANGO_SCALE;
00512 
00513     // If we don't start with a new paragraph, then we must render the
00514     // remained part of current paragraph first.
00515     if (start_offset != 0)
00516     {
00517         if (layout != NULL)
00518         {
00519             g_object_unref(layout);
00520             layout = NULL;
00521         }
00522         const std::string *str = model->get_paragraph(start_paragraph);
00523         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00524 
00525         PangoLayoutIter *iter = pango_layout_get_iter(layout);
00526 
00527         int line_offset, x_pos;
00528         pango_layout_index_to_line_x(layout, start_offset, FALSE, &line_offset, &x_pos);
00529         y_offset = (line_height + DEFAULT_LINE_SPACING)*line_offset*PANGO_SCALE;
00530 
00531         int baseline = 0;
00532         for (int i=0; i<line_offset; i++)
00533         {
00534             pango_layout_iter_next_line(iter);
00535         }
00536 
00537         do
00538         {
00539             baseline = pango_layout_iter_get_baseline(iter) - y_offset;
00540             PangoLayoutLine *pango_line = pango_layout_iter_get_line_readonly(iter);
00541             render_single_line(bmp,
00542                                pango_line,
00543                                font_hash_code,
00544                                left_margin * PANGO_SCALE,
00545                                baseline+top_margin*PANGO_SCALE,
00546                                (display_width+3)/4*4);
00547             if (++total_lines == lines_per_page)
00548             {
00549                 // Calculate the offset of the rightmost character.
00550                 int index, trailing;
00551                 pango_layout_line_x_to_index(pango_line, client_width - 1, &index, &trailing);
00552                 start_offset = index;
00553                 pango_layout_iter_free(iter);
00554                 goto RenderEnd;
00555             }
00556         } while (pango_layout_iter_next_line(iter));
00557         
00558         // Release iter since we finish with it.
00559         pango_layout_iter_free(iter);
00560 
00561         start_paragraph++;
00562         y_offset = (line_height + DEFAULT_LINE_SPACING)*total_lines*PANGO_SCALE;
00563     }
00564 
00565     // Render the remained paragraphs
00566     while (start_paragraph < model->get_paragraph_count())
00567     {
00568         // Render current paragraph
00569         if (layout != NULL)
00570         {
00571             g_object_unref(layout);
00572             layout = NULL;
00573         }
00574         const std::string *str = model->get_paragraph(start_paragraph);
00575         layout = create_layout(str->c_str(), static_cast<int>(str->size()));
00576 
00577         PangoLayoutIter *iter = pango_layout_get_iter(layout);
00578         int baseline = 0;
00579         do 
00580         {
00581             baseline = pango_layout_iter_get_baseline(iter) + y_offset;
00582             PangoLayoutLine *pango_line = pango_layout_iter_get_line_readonly(iter);
00583             render_single_line(bmp, 
00584                                pango_line,
00585                                font_hash_code,
00586                                left_margin * PANGO_SCALE,
00587                                baseline+top_margin*PANGO_SCALE,
00588                                (display_width+3)/4*4);
00589             if (++total_lines == lines_per_page)
00590             {
00591                 int index, trailing;
00592                 pango_layout_line_x_to_index(pango_line, client_width - 1, &index, &trailing);
00593                 start_offset = index;
00594                 pango_layout_iter_free(iter);
00595                 goto RenderEnd;
00596             }
00597         } while (pango_layout_iter_next_line(iter));
00598         pango_layout_iter_free(iter);
00599 
00600         start_paragraph++;
00601         y_offset = (line_height + DEFAULT_LINE_SPACING)*total_lines*PANGO_SCALE;
00602     }
00603 
00604 RenderEnd:
00605     // Release pango layout generated by render.
00606     if (layout != NULL)
00607     {
00608         g_object_unref(layout);
00609         layout = NULL;
00610     }
00611     g_mutex_unlock(pango_mutex);
00612 
00613     return Position(start_paragraph, start_offset);
00614 }

Here is the call graph for this function:

Here is the caller graph for this function:

void text::TextView::set_color_depth ( unsigned int  color_depth  )  [inline]

Set color depth.

Definition at line 144 of file text_view.h.

00147     {

void text::TextView::set_controller ( TextController c  )  [inline]

Definition at line 63 of file text_view.h.

Referenced by text::TextController::TextController().

00066     {

Here is the caller graph for this function:

void text::TextView::set_display_size ( unsigned int  width,
unsigned int  height 
)

Set output display size.

Definition at line 658 of file text_view.cpp.

References LOGPRINTF.

Referenced by widget_event_handler().

00659 {
00660     LOGPRINTF("\n\nwidth=%d, height=%d\n\n", width, height);
00661     if (width == display_width && height == display_height)
00662     {
00663         return;
00664     }
00665 
00666    g_mutex_lock(pango_mutex);
00667     if (height != display_height)
00668     {
00669         // Display height changed. The current layout can be reused.
00670         // But we need to re-calculate lines per page.
00671         display_height = height;
00672         client_height = display_height - top_margin - bottom_margin;
00673         calculate_lines_per_page();
00674     }
00675 
00676     if (width != display_width)
00677     {
00678         display_width = width;
00679         client_width = display_width - left_margin - right_margin;
00680     }
00681 
00682     // Change the repagination flag to true.
00683     is_repagination_needed = true;
00684     g_mutex_unlock(pango_mutex);
00685 }

Here is the caller graph for this function:

void text::TextView::set_DPI ( unsigned int  dpi  )  [inline]

Set dpi.

Definition at line 132 of file text_view.h.

00135     {

void text::TextView::set_font_family ( const std::string &  font_family  )  [inline]

Set font family.

Definition at line 110 of file text_view.h.

00113     {

bool text::TextView::set_font_size ( int  font_size  ) 

Set font size.

Definition at line 616 of file text_view.cpp.

References FontCache::clear(), FontCache::instance(), and make_hash_code().

Referenced by widget_event_handler().

00617 {
00618     if (this->font_size == font_size)
00619     {
00620         return true;
00621     }
00622 
00623     this->font_size = font_size;
00624 
00625     g_mutex_lock(pango_mutex);
00626 
00627     // Release font caches in font map.
00628     PangoFT2FontMap* font_map = PANGO_FT2_FONT_MAP(pango_context_get_font_map(pango_context));
00629     pango_ft2_font_map_substitute_changed(font_map);
00630 
00631     // Create new pango font description and copy it to pango context.
00632     PangoFontDescription* font_desc = pango_font_description_new();
00633     pango_font_description_set_family(font_desc, font_family.c_str());
00634     pango_font_description_set_size(font_desc, font_size * PANGO_SCALE);
00635     pango_context_set_font_description(pango_context, font_desc);
00636 
00637     char *desc_str = pango_font_description_to_string(font_desc);
00638     font_hash_code = make_hash_code(desc_str, 
00639         static_cast<unsigned int>(strlen(desc_str)));
00640     g_free(desc_str);
00641 
00642     // Since pango_context has copied the font description from us,
00643     // our font description can be freed safely.
00644     pango_font_description_free(font_desc);
00645     calculate_lines_per_page();
00646 
00647     // Change the repagination flag to true.
00648     is_repagination_needed = true;
00649 
00650     // Clear font cache.
00651     FontCache& font_cache = FontCache::instance();
00652     font_cache.clear();
00653 
00654     g_mutex_unlock(pango_mutex);
00655     return true;
00656 }

Here is the call graph for this function:

Here is the caller graph for this function:


Field Documentation

signals.

Definition at line 221 of file text_view.h.

Referenced by text::PaginationTask::execute(), main(), and text::PluginViewImpl::PluginViewImpl().

utils::Signal<unsigned int, const Position&, const Position&, void *> text::TextView::render_done_signal

The documentation for this class was generated from the following files:
Generated by  doxygen 1.6.2-20100208