00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <cassert>
00028 #include "view_impl.h"
00029 #include "document_impl.h"
00030 #include "collection_impl.h"
00031 #include "log.h"
00032 namespace text
00033 {
00034
00035 utils::ObjectTable<PluginViewImpl> PluginViewImpl::g_instances_table;
00036
00037 PluginViewImpl::PluginViewImpl(PluginDocImpl *doc)
00038 : document(doc)
00039 , view(&document->get_model())
00040 , controller(&document->get_model(), &view)
00041 {
00042 assert(document);
00043
00044
00045 query_interface = query_interface_impl;
00046 release = release_impl;
00047
00048
00049 get_page_number = get_page_number_impl;
00050 get_page_name = get_page_name_impl;
00051 get_number_of_pages = get_number_of_pages_impl;
00052 get_anchor_by_page = get_anchor_by_page_impl;
00053 get_prev_page = get_prev_page_impl;
00054 get_next_page = get_next_page_impl;
00055 get_rendered_page_start = get_rendered_page_start_impl;
00056 get_physical_page_start = get_physical_page_start_impl;
00057 get_cover_page = get_cover_page_impl;
00058
00059
00060 set_display_size = set_display_size_impl;
00061 set_DPI = set_DPI_impl;
00062 set_color_depth = set_color_depth_impl;
00063
00064
00065 render = render_impl;
00066 create_render_settings = create_render_settings_impl;
00067 set_memory_limit = set_memory_limit_impl;
00068 get_original_size = get_original_size_impl;
00069 get_page_content_area = get_page_content_area_impl;
00070
00071
00072 get_font_size = get_font_size_impl;
00073 set_font_size = set_font_size_impl;
00074 get_font_family = get_font_family_impl;
00075 set_font_family = set_font_family_impl;
00076
00077
00078 add_event_receiver = add_event_receiver_impl;
00079 remove_event_receiver = remove_event_receiver_impl;
00080
00081 g_instances_table.add_interface<IPluginUnknown>(this);
00082 g_instances_table.add_interface<IPluginView>(this);
00083 g_instances_table.add_interface<IPluginViewSettings>(this);
00084 g_instances_table.add_interface<IPluginRender>(this);
00085 g_instances_table.add_interface<IPluginEventBroadcaster>(this);
00086 g_instances_table.add_interface<IPluginFont>(this);
00087
00088
00089 view.render_done_signal.add_slot(this,
00090 &PluginViewImpl::on_render_done);
00091 view.pagination_start_signal.add_slot(this,
00092 &PluginViewImpl::on_pagination_start);
00093 view.pagination_end_signal.add_slot(this,
00094 &PluginViewImpl::on_pagination_done);
00095 }
00096
00097 PluginViewImpl::~PluginViewImpl(void)
00098 {
00099 g_instances_table.remove(this);
00100 }
00101
00102 PluginStatus
00103 PluginViewImpl::query_interface_impl(IPluginUnknown *thiz,
00104 const UDSString *id,
00105 void **ptr )
00106 {
00107 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00108 if (g_instances_table.query_interface(instance, id->get_buffer(id), ptr))
00109 {
00110 return PLUGIN_OK;
00111 }
00112 return PLUGIN_FAIL;
00113 }
00114
00115 int
00116 PluginViewImpl::release_impl(IPluginUnknown *thiz )
00117 {
00118 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00119 delete instance;
00120 return 0;
00121 }
00122
00123 int
00124 PluginViewImpl::get_page_number_impl(IPluginUnknown *thiz,
00125 const UDSString *anchor )
00126 {
00127 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00128 return instance->view.get_page_index_by_anchor(Position(
00129 anchor->get_buffer(anchor))) + 1;
00130 }
00131
00132 PluginStatus
00133 PluginViewImpl::get_page_name_impl(IPluginUnknown *thiz,
00134 const UDSString *page_start_anchor,
00135 UDSString *name)
00136 {
00137 return PLUGIN_FAIL;
00138 }
00139
00140 PluginStatus
00141 PluginViewImpl::get_rendered_page_start_impl(IPluginUnknown *thiz,
00142 const UDSString *anchor,
00143 UDSString *start_anchor)
00144 {
00145 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00146 Position page_anchor = instance->view.get_page_anchor_by_anchor(
00147 Position(anchor->get_buffer(anchor)));
00148 start_anchor->assign(start_anchor, page_anchor.to_string().c_str());
00149 return PLUGIN_OK;
00150 }
00151
00152 PluginStatus
00153 PluginViewImpl::get_physical_page_start_impl(IPluginUnknown *thiz,
00154 const UDSString *anchor,
00155 UDSString *start_anchor)
00156 {
00157 return get_rendered_page_start_impl(thiz, anchor, start_anchor);
00158 }
00159
00160 int
00161 PluginViewImpl::get_number_of_pages_impl(IPluginUnknown *thiz)
00162 {
00163 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00164 return MAX(instance->view.get_page_count(), 1);
00165 }
00166
00167 PluginStatus
00168 PluginViewImpl::get_anchor_by_page_impl(IPluginUnknown *thiz,
00169 unsigned int page,
00170 UDSString *anchor)
00171 {
00172 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00173 Position pos;
00174 if (instance->view.get_anchor_by_page(page-1, pos))
00175 {
00176 std::string str = pos.to_string();
00177 anchor->assign(anchor, str.c_str());
00178 return PLUGIN_OK;
00179 }
00180 return PLUGIN_FAIL;
00181 }
00182
00183 PluginStatus
00184 PluginViewImpl::get_prev_page_impl(IPluginUnknown *thiz,
00185 UDSString *anchor)
00186 {
00187 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00188 Position pos(anchor->get_buffer(anchor));
00189 Position new_pos;
00190 if (instance->view.calculate_prev_page_pos(pos, new_pos))
00191 {
00192 anchor->assign(anchor, new_pos.to_string().c_str());
00193 return PLUGIN_OK;
00194 }
00195 return PLUGIN_FAIL;
00196 }
00197
00198 PluginStatus
00199 PluginViewImpl::get_next_page_impl(IPluginUnknown *thiz,
00200 UDSString *anchor)
00201 {
00202 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00203 Position pos(anchor->get_buffer(anchor));
00204 Position new_pos;
00205 if (instance->view.calculate_next_page_pos(pos, new_pos))
00206 {
00207 anchor->assign(anchor, new_pos.to_string().c_str());
00208 return PLUGIN_OK;
00209 }
00210 return PLUGIN_FAIL;
00211 }
00212
00213 PluginStatus
00214 PluginViewImpl::get_cover_page_impl( IPluginUnknown *thiz,
00215 const int width,
00216 const int height,
00217 PluginBitmapAttributes *cover_page)
00218 {
00219 return PLUGIN_FAIL;
00220 }
00221
00222 PluginStatus
00223 PluginViewImpl::set_display_size_impl(IPluginUnknown *thiz,
00224 const int width,
00225 const int height )
00226 {
00227 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00228 instance->view.set_display_size(width, height);
00229 return PLUGIN_OK;
00230 }
00231
00232 PluginStatus
00233 PluginViewImpl::set_DPI_impl(IPluginUnknown *thiz,
00234 const unsigned int dpi )
00235 {
00236 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00237 instance->view.set_DPI(dpi);
00238 return PLUGIN_OK;
00239 }
00240
00241 PluginStatus
00242 PluginViewImpl::set_color_depth_impl(IPluginUnknown *thiz,
00243 const unsigned int color_depth )
00244 {
00245 return PLUGIN_OK;
00246 }
00247
00248 PluginStatus
00249 PluginViewImpl::render_impl(IPluginUnknown *thiz,
00250 const UDSString *anchor,
00251 const int page_offset,
00252 IPluginUnknown *settings,
00253 const RenderArea *area,
00254 const unsigned int id )
00255 {
00256
00257 if (page_offset != 0)
00258 {
00259 return PLUGIN_NOT_SUPPORTED;
00260 }
00261
00262
00263
00264 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00265
00266
00267 Position render_pos(anchor->get_buffer(anchor));
00268
00269
00270
00271 PluginBitmapAttributes ba;
00272 instance->view.get_display_size(ba.width, ba.height);
00273 ba.row_stride = (ba.width + 3) / 4 * 4;
00274
00275 unsigned char* bmp = new unsigned char[ba.row_stride * ba.height];
00276 memset(bmp, 0xFF, ba.row_stride * ba.height);
00277 ba.data = bmp;
00278
00279 PluginRenderResultImpl * result
00280 = new PluginRenderResultImpl(instance, ba, id, 0);
00281
00282 result->release_signal.add_slot(instance,
00283 &PluginViewImpl::on_render_result_released);
00284
00285 instance->render_results.push_back(result);
00286
00287 instance->view.get_controller()->render(id, render_pos, result, bmp);
00288
00289 return PLUGIN_OK;
00290 }
00291
00292 IPluginUnknown *
00293 PluginViewImpl::create_render_settings_impl(IPluginUnknown *thiz)
00294 {
00295 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00296 RenderSettingsPtr ptr = new PluginRenderSettingsImpl;
00297 assert(ptr);
00298 instance->render_settings.push_back(ptr);
00299 ptr->release_signal.add_slot(instance,
00300 &PluginViewImpl::on_render_settings_released);
00301 return static_cast<IPluginUnknown *>(ptr);
00302 }
00303
00304 PluginStatus
00305 PluginViewImpl::set_memory_limit_impl(IPluginUnknown *thiz,
00306 const unsigned int bytes)
00307 {
00308 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00309
00310 if ( bytes == 0 )
00311 {
00312 instance->view.get_controller()->pause_pagination();
00313 }
00314 else
00315 {
00316 instance->view.get_controller()->restart_pagination();
00317 }
00318 return PLUGIN_OK;
00319 }
00320
00321
00322 PluginStatus
00323 PluginViewImpl::get_original_size_impl(IPluginUnknown *thiz,
00324 const UDSString *anchor,
00325 unsigned int *width,
00326 unsigned int *height )
00327 {
00328 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00329 int tmp_width, tmp_height;
00330 instance->view.get_display_size(tmp_width, tmp_height);
00331 *width = tmp_width;
00332 *height = tmp_height;
00333 return PLUGIN_OK;
00334 }
00335
00336 PluginStatus
00337 PluginViewImpl::get_page_content_area_impl(IPluginUnknown *thiz,
00338 const UDSString *start_of_page_anchor,
00339 RenderArea *area )
00340 {
00341 return PLUGIN_FAIL;
00342 }
00343
00344 int
00345 PluginViewImpl::get_font_size_impl(IPluginUnknown *thiz)
00346 {
00347 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00348 return instance->view.get_font_size();
00349 }
00350
00351 PluginStatus
00352 PluginViewImpl::set_font_size_impl(IPluginUnknown *thiz,
00353 const unsigned int font_size)
00354 {
00355 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00356 return instance->view.set_font_size(font_size) ? PLUGIN_OK : PLUGIN_FAIL;
00357 }
00358
00359 PluginStatus
00360 PluginViewImpl::get_font_family_impl(IPluginUnknown *thiz,
00361 UDSString *font_family)
00362 {
00363 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00364 font_family->assign(font_family, instance->view.get_font_family().c_str());
00365 return PLUGIN_OK;
00366 }
00367
00368 PluginStatus
00369 PluginViewImpl::set_font_family_impl(IPluginUnknown *thiz,
00370 const UDSString *font_family)
00371 {
00372 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00373 instance->view.set_font_family(font_family->get_buffer(font_family));
00374 return PLUGIN_OK;
00375 }
00376
00377 PluginStatus
00378 PluginViewImpl::add_event_receiver_impl(IPluginUnknown *thiz,
00379 const PluginEvent plugin_event,
00380 EventFunc callback,
00381 void *user_data,
00382 unsigned long *handler_id )
00383 {
00384 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00385 assert(handler_id);
00386 *handler_id =
00387 instance->listeners.add_listener(plugin_event, callback, user_data);
00388 return PLUGIN_OK;
00389 }
00390
00391 PluginStatus
00392 PluginViewImpl::remove_event_receiver_impl(IPluginUnknown *thiz,
00393 unsigned long handler_id)
00394 {
00395 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00396 if (instance->listeners.remove_listener(handler_id))
00397 {
00398 return PLUGIN_OK;
00399 }
00400 return PLUGIN_FAIL;
00401 }
00402
00403 void
00404 PluginViewImpl::on_render_settings_released(PluginRenderSettingsImpl *settings)
00405 {
00406 RenderSettingsIter iter = std::find(render_settings.begin(),
00407 render_settings.end(),
00408 settings);
00409 if (iter != render_settings.end())
00410 {
00411 delete *iter;
00412 render_settings.erase(iter);
00413 }
00414 }
00415
00416 void
00417 PluginViewImpl::on_render_result_released(PluginRenderResultImpl * result)
00418 {
00419 RenderResultIter iter = std::find(render_results.begin(),
00420 render_results.end(),
00421 result);
00422 if (iter != render_results.end())
00423 {
00424 delete *iter;
00425 render_results.erase(iter);
00426 }
00427 }
00428
00429 void PluginViewImpl::on_render_done(unsigned int id,
00430 const Position& start_position,
00431 const Position& end_position,
00432 void *data)
00433 {
00434
00435
00436
00437 PluginEventAttrs attrs;
00438 attrs.render_end.result = static_cast<IPluginUnknown *>(data);
00439
00440 PluginRenderResultImpl* render_result = static_cast<PluginRenderResultImpl *>(data);
00441 render_result->set_render_result_range(start_position, end_position);
00442 attrs.render_end.rid = id;
00443 attrs.render_end.status = RENDER_DONE;
00444 listeners.broadcast(this, EVENT_RENDERING_END, &attrs);
00445 }
00446
00447 void PluginViewImpl::on_pagination_start(unsigned int total)
00448 {
00449 PluginEventAttrs attrs;
00450 attrs.paginate.current = 1;
00451 attrs.paginate.total = total;
00452 listeners.broadcast(this, EVENT_PAGINATE_START, &attrs);
00453 }
00454
00455 void PluginViewImpl::on_pagination_done(unsigned int current, unsigned int total)
00456 {
00457
00458
00459
00460 PluginEventAttrs attrs;
00461 attrs.paginate.current = current + 1;
00462 attrs.paginate.total = total;
00463 listeners.broadcast(this, EVENT_PAGINATE_END, &attrs);
00464 }
00465
00466 PluginStatus PluginViewImpl::get_anchor_from_coordinates_impl(const Position& page_start_pos,
00467 const int x,
00468 const int y,
00469 UDSString* anchor)
00470 {
00471 Position doc_pos;
00472
00473 ViewPosition view_pos;
00474 view_pos.x = x;
00475 view_pos.y = y;
00476
00477 if (!view.map_view_pos_to_doc_pos(page_start_pos, view_pos, doc_pos))
00478 {
00479 return PLUGIN_FAIL;
00480 }
00481
00482 anchor->assign(anchor, doc_pos.to_string().c_str());
00483 return PLUGIN_OK;
00484 }
00485
00486 IPluginUnknown* PluginViewImpl::get_bounding_rectangles_from_range_impl(const Position& page_start_pos,
00487 const PluginRange* range)
00488 {
00489 std::vector<Rect> rects;
00490 Range range_internal(Position(range->start_anchor->get_buffer(range->start_anchor)),
00491 Position(range->end_anchor->get_buffer(range->end_anchor)));
00492 view.get_bounding_rectangles(page_start_pos, rects, range_internal);
00493
00494 PluginCollectionImpl *coll_p = new PluginCollectionImpl();
00495 coll_p->create<Rect>();
00496 std::vector<Rect>& data = coll_p->take_data_ref<Rect>();
00497 data.swap(rects);
00498
00499 return coll_p;
00500 }
00501
00502 }
00503