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
00031 #include "pdf_library.h"
00032
00033 namespace pdf
00034 {
00035
00036 utils::ObjectTable<PluginViewImpl> PluginViewImpl::g_instances_table;
00037
00038 PluginViewImpl::PluginViewImpl(PluginDocImpl *doc)
00039 : document(doc)
00040 , render_settings()
00041 , render_results()
00042 , listeners()
00043 , renderer(doc->get_renderer())
00044 {
00045 assert(document);
00046
00047
00048 query_interface = query_interface_impl;
00049 release = release_impl;
00050
00051
00052 get_page_number = get_page_number_impl;
00053 get_page_name = get_page_name_impl;
00054 get_rendered_page_start = get_rendered_page_start_impl;
00055 get_physical_page_start = get_physical_page_start_impl;
00056 get_number_of_pages = get_number_of_pages_impl;
00057 get_anchor_by_page = get_anchor_by_page_impl;
00058 get_prev_page = get_prev_page_impl;
00059 get_next_page = get_next_page_impl;
00060 get_cover_page = get_cover_page_impl;
00061
00062
00063 set_display_size = set_display_size_impl;
00064 set_DPI = set_DPI_impl;
00065 set_color_depth = set_color_depth_impl;
00066
00067
00068 render = render_impl;
00069 create_render_settings = create_render_settings_impl;
00070 set_memory_limit = set_memory_limit_impl;
00071 get_original_size = get_original_size_impl;
00072 get_page_content_area = get_page_content_area_impl;
00073 get_original_rotation = get_original_rotation_impl;
00074
00075
00076 get_font_size = get_font_size_impl;
00077 set_font_size = set_font_size_impl;
00078 get_font_family = get_font_family_impl;
00079 set_font_family = set_font_family_impl;
00080
00081
00082 add_event_receiver = add_event_receiver_impl;
00083 remove_event_receiver = remove_event_receiver_impl;
00084
00085 g_instances_table.add_interface<IPluginUnknown>(this);
00086 g_instances_table.add_interface<IPluginView>(this);
00087 g_instances_table.add_interface<IPluginViewSettings>(this);
00088 g_instances_table.add_interface<IPluginRender>(this);
00089 g_instances_table.add_interface<IPluginEventBroadcaster>(this);
00090
00091
00092 document->doc_ctrl.sig_page_ready.add_slot(this
00093 , &PluginViewImpl::handle_page_ready);
00094
00095 }
00096
00097 PluginViewImpl::~PluginViewImpl(void)
00098 {
00099 document->doc_ctrl.sig_page_ready.remove_slot(this
00100 , &PluginViewImpl::handle_page_ready);
00101
00102 g_instances_table.remove(this);
00103 }
00104
00105 PluginStatus
00106 PluginViewImpl::query_interface_impl(IPluginUnknown *thiz,
00107 const UDSString *id,
00108 void **ptr )
00109 {
00110 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00111 if (g_instances_table.query_interface(instance, id->get_buffer(id), ptr))
00112 {
00113 return PLUGIN_OK;
00114 }
00115 return PLUGIN_FAIL;
00116 }
00117
00118 int
00119 PluginViewImpl::release_impl(IPluginUnknown *thiz )
00120 {
00121 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00122 instance->release_signal.safe_broadcast(instance);
00123 return 0;
00124 }
00125
00126 int
00127 PluginViewImpl::get_page_number_impl(IPluginUnknown *thiz,
00128 const UDSString *anchor )
00129 {
00130 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00131 return instance->document->get_page_number(anchor->get_buffer(anchor));
00132 }
00133
00134 int
00135 PluginViewImpl::get_number_of_pages_impl(IPluginUnknown *thiz)
00136 {
00137 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00138 return instance->document->get_page_count();
00139 }
00140
00141 PluginStatus
00142 PluginViewImpl::get_anchor_by_page_impl(IPluginUnknown *thiz,
00143 unsigned int page,
00144 UDSString *anchor)
00145 {
00146 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00147
00148
00149 std::string temp;
00150 if (instance->document->get_anchor_of_page(page, temp))
00151 {
00152 anchor->assign(anchor, temp.c_str());
00153 return PLUGIN_OK;
00154 }
00155 return PLUGIN_FAIL;
00156 }
00157
00158 PluginStatus
00159 PluginViewImpl::get_prev_page_impl(IPluginUnknown *thiz,
00160 UDSString *anchor)
00161 {
00162 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00163
00164 std::string temp(anchor->get_buffer(anchor));
00165 if (instance->document->get_prev_page(temp))
00166 {
00167 anchor->assign(anchor, temp.c_str());
00168 return PLUGIN_OK;
00169 }
00170 return PLUGIN_FAIL;
00171 }
00172
00173 PluginStatus
00174 PluginViewImpl::get_next_page_impl(IPluginUnknown *thiz,
00175 UDSString *anchor)
00176 {
00177 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00178
00179 std::string temp(anchor->get_buffer(anchor));
00180 if (instance->document->get_next_page(temp))
00181 {
00182 anchor->assign(anchor, temp.c_str());
00183 return PLUGIN_OK;
00184 }
00185 return PLUGIN_FAIL;
00186 }
00187
00188 PluginStatus
00189 PluginViewImpl::get_cover_page_impl(IPluginUnknown *thiz,
00190 const int width,
00191 const int height,
00192 PluginBitmapAttributes *cover_page)
00193 {
00194 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00195
00196 if (instance->renderer->render_cover_page(width, height, cover_page))
00197 {
00198 return PLUGIN_OK;
00199 }
00200 return PLUGIN_FAIL;
00201 }
00202
00203 PluginStatus
00204 PluginViewImpl::set_display_size_impl(IPluginUnknown *thiz,
00205 const int width,
00206 const int height )
00207 {
00208 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00209
00210 instance->renderer->get_view_attr().set_display_width(width);
00211 instance->renderer->get_view_attr().set_display_height(height);
00212
00213 return PLUGIN_OK;
00214 }
00215
00216 PluginStatus
00217 PluginViewImpl::set_DPI_impl(IPluginUnknown *thiz,
00218 const unsigned int dpi )
00219 {
00220 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00221
00222 instance->renderer->get_view_attr().set_device_dpi_v(dpi);
00223 instance->renderer->get_view_attr().set_device_dpi_h(dpi);
00224
00225 return PLUGIN_OK;
00226 }
00227
00228 PluginStatus
00229 PluginViewImpl::set_color_depth_impl(IPluginUnknown *thiz,
00230 const unsigned int color_depth )
00231 {
00232 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00233
00234 instance->renderer->get_view_attr().set_color_depth(color_depth);
00235
00236 return PLUGIN_OK;
00237 }
00238
00239 PluginStatus
00240 PluginViewImpl::render_impl(IPluginUnknown *thiz,
00241 const UDSString *start_of_page_anchor,
00242 const int page_offset,
00243 IPluginUnknown *settings,
00244 const RenderArea *area,
00245 const unsigned int refId )
00246 {
00247
00248 if (page_offset != 0)
00249 {
00250 return PLUGIN_NOT_SUPPORTED;
00251 }
00252
00253
00254
00255 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00256
00257 unsigned int page_num = instance->document->get_page_number(
00258 start_of_page_anchor->get_buffer(start_of_page_anchor));
00259
00260
00261 PluginRenderSettingsImpl * settings_obj =
00262 PluginRenderSettingsImpl::query_instance(settings);
00263
00264
00265 instance->send_render_request(page_num, settings_obj->get_render_attr()
00266 , area, refId);
00267
00268 return PLUGIN_OK;
00269 }
00270
00271 IPluginUnknown *
00272 PluginViewImpl::create_render_settings_impl(IPluginUnknown *thiz)
00273 {
00274 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00275 RenderSettingsPtr ptr = new PluginRenderSettingsImpl;
00276 if (ptr == 0)
00277 {
00278 return 0;
00279 }
00280
00281 instance->render_settings.push_back(ptr);
00282 ptr->release_signal.add_slot(instance,
00283 &PluginViewImpl::on_render_settings_released);
00284 return static_cast<IPluginUnknown *>(ptr);
00285 }
00286
00287 PluginStatus
00288 PluginViewImpl::set_memory_limit_impl(IPluginUnknown *thiz,
00289 const unsigned int bytes)
00290 {
00291 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00292 if (instance->document->get_doc_ctrl().set_memory_limit(bytes))
00293 {
00294 return PLUGIN_OK;
00295 }
00296 return PLUGIN_FAIL;
00297 }
00298
00299 PluginStatus
00300 PluginViewImpl::get_original_size_impl(IPluginUnknown *thiz,
00301 const UDSString *start_of_page_anchor,
00302 unsigned int *width,
00303 unsigned int *height )
00304 {
00305 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00306 if (instance->document->get_original_size(start_of_page_anchor->get_buffer(start_of_page_anchor),
00307 *width,
00308 *height))
00309 {
00310 return PLUGIN_OK;
00311 }
00312 return PLUGIN_FAIL;
00313 }
00314
00315 PluginStatus
00316 PluginViewImpl::get_page_content_area_impl(IPluginUnknown *thiz,
00317 const UDSString *start_of_page_anchor,
00318 RenderArea *area )
00319 {
00320 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00321 if (instance->document->get_content_area(
00322 start_of_page_anchor->get_buffer(start_of_page_anchor),
00323 *area))
00324 {
00325 return PLUGIN_OK;
00326 }
00327 return PLUGIN_FAIL;
00328 }
00329
00330 PluginStatus
00331 PluginViewImpl::add_event_receiver_impl(IPluginUnknown *thiz,
00332 const PluginEvent plugin_event,
00333 EventFunc callback,
00334 void *user_data,
00335 unsigned long *handler_id )
00336 {
00337 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00338 if (handler_id == 0)
00339 {
00340 return PLUGIN_FAIL;
00341 }
00342
00343 *handler_id =
00344 instance->listeners.add_listener(plugin_event, callback, user_data);
00345 return PLUGIN_OK;
00346 }
00347
00348 PluginStatus
00349 PluginViewImpl::remove_event_receiver_impl(IPluginUnknown *thiz,
00350 unsigned long handler_id)
00351 {
00352 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00353 if (instance->listeners.remove_listener(handler_id))
00354 {
00355 return PLUGIN_OK;
00356 }
00357 return PLUGIN_FAIL;
00358 }
00359
00360 PluginStatus
00361 PluginViewImpl::get_original_rotation_impl(IPluginUnknown *thiz,
00362 const UDSString *start_of_page_anchor,
00363 PluginRotationDegree *rotation)
00364 {
00365 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00366
00367 PluginRotationDegree res = instance->document->get_page_original_rotation(
00368 start_of_page_anchor->get_buffer(start_of_page_anchor) );
00369
00370 if (res < 0)
00371 {
00372 return PLUGIN_FAIL;
00373 }
00374
00375 *rotation = res;
00376 return PLUGIN_OK;
00377 }
00378
00379 PluginStatus
00380 PluginViewImpl::get_page_name_impl(IPluginUnknown *thiz,
00381 const UDSString *page_start_anchor,
00382 UDSString *name)
00383 {
00384 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00385
00386 unsigned int page_num = instance->document->get_page_number(
00387 page_start_anchor->get_buffer(page_start_anchor));
00388
00389 char buf[32] = {0};
00390 pdf_printf(buf, "%d", page_num);
00391
00392 name->assign(name, buf);
00393
00394 return PLUGIN_OK;
00395 }
00396
00397 PluginStatus
00398 PluginViewImpl::get_rendered_page_start_impl(IPluginUnknown *thiz,
00399 const UDSString *anchor,
00400 UDSString *start_anchor )
00401 {
00402 PluginViewImpl *instance = g_instances_table.get_object(thiz);
00403
00404 unsigned int page_num = instance->document->get_page_number(
00405 anchor->get_buffer(anchor));
00406
00407 PDFAnchor param;
00408 param.page_num = page_num;
00409
00410 start_anchor->assign(start_anchor, param.get_string().c_str());
00411
00412 return PLUGIN_OK;
00413 }
00414
00415
00416 PluginStatus
00417 PluginViewImpl::get_physical_page_start_impl(IPluginUnknown *thiz,
00418 const UDSString *anchor,
00419 UDSString *start_anchor)
00420 {
00421 return get_rendered_page_start_impl(thiz, anchor, start_anchor);
00422 }
00423
00424
00425 void
00426 PluginViewImpl::on_render_settings_released(PluginRenderSettingsImpl *settings)
00427 {
00428 RenderSettingsIter iter = std::find(render_settings.begin(),
00429 render_settings.end(),
00430 settings);
00431 if (iter != render_settings.end())
00432 {
00433 delete *iter;
00434 render_settings.erase(iter);
00435 }
00436 }
00437
00438 void
00439 PluginViewImpl::on_render_result_released(PluginRenderResultImpl * result)
00440 {
00441 RenderResultIter iter = std::find(render_results.begin(),
00442 render_results.end(),
00443 result);
00444 if (iter != render_results.end())
00445 {
00446 delete *iter;
00447 render_results.erase(iter);
00448 }
00449 }
00450
00451 void PluginViewImpl::send_render_request(int page_num
00452 , const PDFRenderAttributes &page_attr
00453 , const RenderArea *area
00454 , const unsigned int refId)
00455 {
00456
00457
00458 RenderResultPtr result = 0;
00459 RenderResultIter idx = render_results.begin();
00460 for (; idx != render_results.end(); ++idx)
00461 {
00462 RenderResultPtr p = *idx;
00463 if (p->is_discard())
00464 {
00465 result = p;
00466 break;
00467 }
00468 }
00469
00470
00471 if (result)
00472 {
00473 result->set_page_number(page_num);
00474 result->set_ref_id(refId);
00475
00476 result->set_discard(false);
00477 }
00478 else
00479 {
00480 result = new PluginRenderResultImpl(page_num, refId);
00481
00482
00483 render_results.push_back(result);
00484 result->release_signal.add_slot(this, &PluginViewImpl::on_render_result_released);
00485 }
00486
00487 renderer->post_render_task(page_num, page_attr, result, refId);
00488 }
00489
00490 void PluginViewImpl::handle_page_ready(RenderResultPtr result, RenderStatus stat)
00491 {
00492 if (result == 0)
00493 {
00494
00495 return;
00496 }
00497
00498 PluginEventAttrs attrs;
00499
00500
00501 attrs.render_end.rid = result->get_ref_id();
00502
00503
00504 attrs.render_end.result = static_cast<IPluginUnknown *>(result);
00505
00506 switch (stat)
00507 {
00508 case TASK_RENDER_DONE:
00509 {
00510
00511 attrs.render_end.status = RENDER_DONE;
00512 }
00513 break;
00514 case TASK_RENDER_OOM:
00515 {
00516
00517 attrs.render_end.status = RENDER_OUT_OF_MEMORY;
00518
00519 WARNPRINTF("Tell UDS out of memory, task %ld is aborted", attrs.render_end.rid);
00520 }
00521 break;
00522 case TASK_RENDER_INVALID_PAGE:
00523 {
00524
00525 attrs.render_end.status = RENDER_INVALID_PAGE;
00526
00527 ERRORPRINTF("Cannot render an invalid page");
00528 }
00529 default:
00530 break;
00531 }
00532
00533 listeners.broadcast(this, EVENT_RENDERING_END, &attrs);
00534 }
00535
00536
00537 int
00538 PluginViewImpl::get_font_size_impl(IPluginUnknown *thiz)
00539 {
00540 return -1;
00541 }
00542
00543 PluginStatus
00544 PluginViewImpl::set_font_size_impl(IPluginUnknown *thiz,
00545 const unsigned int font_size)
00546 {
00547 return PLUGIN_FAIL;
00548 }
00549
00550 PluginStatus
00551 PluginViewImpl::get_font_family_impl(IPluginUnknown *thiz,
00552 UDSString *font_family)
00553 {
00554 return PLUGIN_FAIL;
00555 }
00556
00557 PluginStatus
00558 PluginViewImpl::set_font_family_impl(IPluginUnknown *thiz,
00559 const UDSString *font_family)
00560 {
00561 return PLUGIN_FAIL;
00562 }
00563
00564 }
00565